redeem code input wip

This commit is contained in:
minjaesong
2025-01-15 16:07:04 +09:00
parent 51dd99fd80
commit 15e3276f46
5 changed files with 140 additions and 3 deletions

Binary file not shown.

View File

@@ -1044,7 +1044,7 @@ fun distBetween(a: ActorWithBody, bpos: Vector2): Double {
val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3)) val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3))
return dist.sqrt() return dist.sqrt()
} }
const val hashStrMap = "YBNDRFG8EJKMCPQXOTLVWIS2A345H769" const val hashStrMap = "YBNDRFGWEJKMCPQXOTLVUIS2A345H769"
fun getHashStr(length: Int = 5) = (0 until length).map { hashStrMap[Math.random().times(32).toInt()] }.joinToString("") fun getHashStr(length: Int = 5) = (0 until length).map { hashStrMap[Math.random().times(32).toInt()] }.joinToString("")
fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt -> fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->

View File

@@ -108,7 +108,7 @@ HEADER:
Notes: post is either: Notes: post is either:
1. always pre-paid when posted 1. always pre-paid when posted
2. not yet encrypted when in not-posted status (can always calculate postage on the fly) 2. not yet encrypted when in not-posted status (can always calculate postage on the fly)
so no postage information is needed for the Serialised Format so no postage information is needed for the Serialised Format
CONTENTSRAW CONTENTSRAW
- Uint48 unzipped size - Uint48 unzipped size

View File

@@ -0,0 +1,133 @@
package net.torvald.terrarum.ui
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.imagefont.BigAlphNum
import net.torvald.terrarum.utils.PasswordBase32
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2025-01-15.
*/
class UIItemRedeemCodeArea(
parentUI: UICanvas,
initialX: Int,
initialY: Int,
val textCols: Int,
val textRows: Int,
) : UIItem(parentUI, initialX, initialY) {
private val CELL_W = 16
private val CELL_H = 22
override val width = textCols * CELL_W
override val height = textRows * CELL_H
init {
CommonResourcePool.addToLoadingList("spritesheet:terrarum_redeem_code_form") {
TextureRegionPack(Gdx.files.internal("assets/graphics/code_input_cells.tga"), CELL_W, CELL_H)
}
CommonResourcePool.loadAll()
}
private var inputFormTiles = CommonResourcePool.getAsTextureRegionPack("spritesheet:terrarum_redeem_code_form")
private val inputText = StringBuilder(textCols * textRows)
private var textCaret = 0
fun clearInput() { inputText.clear(); textCaret = 0 }
fun acceptChar(char: Char): Boolean {
if (textCaret in 0 until textCols * textRows) {
inputText.insert(textCaret, char)
textCaret++
return true
}
else return false
}
fun backspace(): Boolean {
if (textCaret in 1 until textCols * textRows) {
inputText.deleteCharAt(textCaret - 1)
textCaret--
return true
}
else return false
}
fun reverseBackspace(): Boolean {
if (textCaret in 0 until (textCols * textRows - 1)) {
inputText.deleteCharAt(textCaret)
return true
}
else return false
}
fun __moveCursorBackward(delta: Int = 1) {
textCaret = (textCaret - 1).coerceIn(0, textCols * textRows)
}
fun __moveCursorForward(delta: Int = 1) {
textCaret = (textCaret + 1).coerceIn(0, textCols * textRows)
}
fun getInputAsString() = inputText.toString()
fun getInputAsBinary(codebook: RedeemCodebook) = codebook.toBinary(inputText.toString())
private val caretCol = Toolkit.Theme.COL_SELECTED
override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
super.render(frameDelta, batch, camera)
val lineCol = if (isActive) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_INACTIVE
// draw border
batch.color = lineCol
Toolkit.drawBoxBorder(batch, posX, posY, width, height)
// draw cells
for (y in 0 until textRows) {
for (x in 0 until textCols) {
batch.draw(inputFormTiles.get(if (x == 0) 0 else if (x == textCols - 1) 2 else 1, 0),
posX.toFloat() + CELL_W * x, posY.toFloat() + CELL_H * y
)
}
}
// draw texts
batch.color = Color.WHITE
for (y in 0 until textRows) {
for (x in 0 until textCols) {
BigAlphNum.draw(
batch,
"${inputText[y * textRows + x]}",
posX + CELL_W * x + 2f,
posY + CELL_H * y + 3f
)
}
}
// draw caret
batch.color = caretCol
val cx = textCaret % textCols
val cy = textCaret / textCols
Toolkit.drawStraightLine(batch,
posX + CELL_W * cx - 1,
posY + CELL_H * cy + 1,
posY + CELL_H * cy + 1 + 20, 2, true)
}
override fun dispose() {
}
}
interface RedeemCodebook {
fun toBinary(inputString: String): ByteArray
companion object {
object Base32RedeemCodebook : RedeemCodebook {
override fun toBinary(inputString: String): ByteArray {
return PasswordBase32.decode(inputString, inputString.length)
}
}
}
}

View File

@@ -12,7 +12,7 @@ import kotlin.experimental.xor
object PasswordBase32 { object PasswordBase32 {
private val si = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=" private val si = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
private val so = "YBNDRFG8EJKMCPQXOTLVUIS2A345H769 " private val so = "YBNDRFGWEJKMCPQXOTLVUIS2A345H769 "
private val standardToModified = HashMap<Char, Char>(32) private val standardToModified = HashMap<Char, Char>(32)
private val modifiedToStandard = HashMap<Char, Char>(32) private val modifiedToStandard = HashMap<Char, Char>(32)
@@ -26,6 +26,7 @@ object PasswordBase32 {
modifiedToStandard['0'] = modifiedToStandard['O']!! modifiedToStandard['0'] = modifiedToStandard['O']!!
modifiedToStandard['1'] = modifiedToStandard['I']!! modifiedToStandard['1'] = modifiedToStandard['I']!!
modifiedToStandard['Z'] = modifiedToStandard['2']!! modifiedToStandard['Z'] = modifiedToStandard['2']!!
modifiedToStandard['8'] = modifiedToStandard['B']!!
} }
private val nullPw = byteArrayOf(0.toByte()) private val nullPw = byteArrayOf(0.toByte())