Fix Caps and spaces usernames

This commit is contained in:
downthecrop 2025-10-07 21:40:32 -07:00
parent 0392204f03
commit 9cb152a3c1
3 changed files with 255 additions and 238 deletions

View file

@ -0,0 +1,19 @@
package ChatboxHelmets
// Lifted from KondoHiscores view
data class HiscoresResponse(
val info: PlayerInfo,
val skills: List<Skill>
)
data class PlayerInfo(
val exp_multiplier: String,
val iron_mode: String
)
data class Skill(
val id: String,
val dynamic: String,
val experience: String,
val static: String
)

View file

@ -0,0 +1,198 @@
package ChatboxHelmets
// See JagString.java parse() in the client, There is special encoding
// and this correctly resolves specials.
val SPECIAL_ESCAPES: Map<Char, String> = hashMapOf(
' ' to "(P",
'!' to "(Q",
'"' to "(R",
'#' to "(S",
'$' to "(T",
'%' to "(U",
'&' to "(V",
'\'' to "(W",
'(' to "(X",
')' to "(Y",
'*' to "(Z",
'+' to ")0",
',' to ")1",
'-' to ")2",
'.' to ")3",
'/' to ")4",
':' to "(j",
';' to "(k",
'=' to ")B",
'?' to ")D",
'@' to ")E",
'[' to "*5",
'\\' to "*6",
']' to "*7",
'^' to "*8",
'_' to "*9",
'`' to ")e",
'{' to "*U",
'|' to "*V",
'}' to "*W",
'~' to "*X",
'\u0000' to "(0",
'\u0001' to "(1",
'\u0002' to "(2",
'\u0003' to "(3",
'\u0004' to "(4",
'\u0005' to "(5",
'\u0006' to "(6",
'\u0007' to "(7",
'\b' to "(8",
'\t' to "(9",
'\n' to "(:",
'\u000B' to "(;",
'\u000C' to "(<",
'\r' to "(=",
'\u000E' to "(>",
'\u000F' to "(?",
'\u0010' to "(@",
'\u0011' to "(A",
'\u0012' to "(B",
'\u0013' to "(C",
'\u0014' to "(D",
'\u0015' to "(E",
'\u0016' to "(F",
'\u0017' to "(G",
'\u0018' to "(H",
'\u0019' to "(I",
'\u001A' to "(J",
'\u001B' to "(K",
'\u001C' to "(L",
'\u001D' to "(M",
'\u001E' to "(N",
'\u001F' to "(O",
'\u007F' to "*Y",
'\u0080' to "*Z",
'\u0081' to "+0",
'\u0082' to "+1",
'\u0083' to "+2",
'\u0084' to "+3",
'\u0085' to "+4",
'\u0086' to "+5",
'\u0087' to "+6",
'\u0088' to "+7",
'\u0089' to "+8",
'\u008A' to "+9",
'\u008B' to "*e",
'\u008C' to "*f",
'\u008D' to "*g",
'\u008E' to "*h",
'\u008F' to "*i",
'\u0090' to "*j",
'\u0091' to "*k",
'\u0092' to "+A",
'\u0093' to "+B",
'\u0094' to "+C",
'\u0095' to "+D",
'\u0096' to "+E",
'\u0097' to "+F",
'\u0098' to "+G",
'\u0099' to "+H",
'\u009A' to "+I",
'\u009B' to "+J",
'\u009C' to "+K",
'\u009D' to "+L",
'\u009E' to "+M",
'\u009F' to "+N",
'\u00A0' to "+O",
'\u00A1' to "+P",
'\u00A2' to "+Q",
'\u00A3' to "+R",
'\u00A4' to "+S",
'\u00A5' to "+T",
'\u00A6' to "+U",
'\u00A7' to "+V",
'\u00A8' to "+W",
'\u00A9' to "+X",
'\u00AA' to "+Y",
'\u00AB' to "+Z",
'\u00AC' to ",0",
'\u00AD' to ",1",
'\u00AE' to ",2",
'\u00AF' to ",3",
'\u00B0' to ",4",
'\u00B1' to ",5",
'\u00B2' to ",6",
'\u00B3' to ",7",
'\u00B4' to ",8",
'\u00B5' to ",9",
'\u00B6' to "+e",
'\u00B7' to "+f",
'\u00B8' to "+g",
'\u00B9' to "+h",
'\u00BA' to "+i",
'\u00BB' to "+j",
'\u00BC' to "+k",
'\u00BD' to ",A",
'\u00BE' to ",B",
'\u00BF' to ",C",
'\u00C0' to ",D",
'\u00C1' to ",E",
'\u00C2' to ",F",
'\u00C3' to ",G",
'\u00C4' to ",H",
'\u00C5' to ",I",
'\u00C6' to ",J",
'\u00C7' to ",K",
'\u00C8' to ",L",
'\u00C9' to ",M",
'\u00CA' to ",N",
'\u00CB' to ",O",
'\u00CC' to ",P",
'\u00CD' to ",Q",
'\u00CE' to ",R",
'\u00CF' to ",S",
'\u00D0' to ",T",
'\u00D1' to ",U",
'\u00D2' to ",V",
'\u00D3' to ",W",
'\u00D4' to ",X",
'\u00D5' to ",Y",
'\u00D6' to ",Z",
'\u00D7' to "-0",
'\u00D8' to "-1",
'\u00D9' to "-2",
'\u00DA' to "-3",
'\u00DB' to "-4",
'\u00DC' to "-5",
'\u00DD' to "-6",
'\u00DE' to "-7",
'\u00DF' to "-8",
'\u00E0' to "-9",
'\u00E1' to ",e",
'\u00E2' to ",f",
'\u00E3' to ",g",
'\u00E4' to ",h",
'\u00E5' to ",i",
'\u00E6' to ",j",
'\u00E7' to ",k",
'\u00E8' to "-A",
'\u00E9' to "-B",
'\u00EA' to "-C",
'\u00EB' to "-D",
'\u00EC' to "-E",
'\u00ED' to "-F",
'\u00EE' to "-G",
'\u00EF' to "-H",
'\u00F0' to "-I",
'\u00F1' to "-J",
'\u00F2' to "-K",
'\u00F3' to "-L",
'\u00F4' to "-M",
'\u00F5' to "-N",
'\u00F6' to "-O",
'\u00F7' to "-P",
'\u00F8' to "-Q",
'\u00F9' to "-R",
'\u00FA' to "-S",
'\u00FB' to "-T",
'\u00FC' to "-U",
'\u00FD' to "-V",
'\u00FE' to "-W",
'\u00FF' to "-X"
)

View file

@ -34,203 +34,6 @@ class plugin : Plugin() {
private var ACCOUNT_TYPE = 0
private var component: Component? = null
// See JagString.java parse() in the client, There is special encoding
// and this correctly resolves specials.
val SPECIAL_ESCAPES: Map<Char, String> = hashMapOf(
' ' to "(P",
'!' to "(Q",
'"' to "(R",
'#' to "(S",
'$' to "(T",
'%' to "(U",
'&' to "(V",
'\'' to "(W",
'(' to "(X",
')' to "(Y",
'*' to "(Z",
'+' to ")0",
',' to ")1",
'-' to ")2",
'.' to ")3",
'/' to ")4",
':' to "(j",
';' to "(k",
'=' to ")B",
'?' to ")D",
'@' to ")E",
'[' to "*5",
'\\' to "*6",
']' to "*7",
'^' to "*8",
'_' to "*9",
'`' to ")e",
'{' to "*U",
'|' to "*V",
'}' to "*W",
'~' to "*X",
'\u0000' to "(0",
'\u0001' to "(1",
'\u0002' to "(2",
'\u0003' to "(3",
'\u0004' to "(4",
'\u0005' to "(5",
'\u0006' to "(6",
'\u0007' to "(7",
'\b' to "(8",
'\t' to "(9",
'\n' to "(:",
'\u000B' to "(;",
'\u000C' to "(<",
'\r' to "(=",
'\u000E' to "(>",
'\u000F' to "(?",
'\u0010' to "(@",
'\u0011' to "(A",
'\u0012' to "(B",
'\u0013' to "(C",
'\u0014' to "(D",
'\u0015' to "(E",
'\u0016' to "(F",
'\u0017' to "(G",
'\u0018' to "(H",
'\u0019' to "(I",
'\u001A' to "(J",
'\u001B' to "(K",
'\u001C' to "(L",
'\u001D' to "(M",
'\u001E' to "(N",
'\u001F' to "(O",
'\u007F' to "*Y",
'\u0080' to "*Z",
'\u0081' to "+0",
'\u0082' to "+1",
'\u0083' to "+2",
'\u0084' to "+3",
'\u0085' to "+4",
'\u0086' to "+5",
'\u0087' to "+6",
'\u0088' to "+7",
'\u0089' to "+8",
'\u008A' to "+9",
'\u008B' to "*e",
'\u008C' to "*f",
'\u008D' to "*g",
'\u008E' to "*h",
'\u008F' to "*i",
'\u0090' to "*j",
'\u0091' to "*k",
'\u0092' to "+A",
'\u0093' to "+B",
'\u0094' to "+C",
'\u0095' to "+D",
'\u0096' to "+E",
'\u0097' to "+F",
'\u0098' to "+G",
'\u0099' to "+H",
'\u009A' to "+I",
'\u009B' to "+J",
'\u009C' to "+K",
'\u009D' to "+L",
'\u009E' to "+M",
'\u009F' to "+N",
'\u00A0' to "+O",
'\u00A1' to "+P",
'\u00A2' to "+Q",
'\u00A3' to "+R",
'\u00A4' to "+S",
'\u00A5' to "+T",
'\u00A6' to "+U",
'\u00A7' to "+V",
'\u00A8' to "+W",
'\u00A9' to "+X",
'\u00AA' to "+Y",
'\u00AB' to "+Z",
'\u00AC' to ",0",
'\u00AD' to ",1",
'\u00AE' to ",2",
'\u00AF' to ",3",
'\u00B0' to ",4",
'\u00B1' to ",5",
'\u00B2' to ",6",
'\u00B3' to ",7",
'\u00B4' to ",8",
'\u00B5' to ",9",
'\u00B6' to "+e",
'\u00B7' to "+f",
'\u00B8' to "+g",
'\u00B9' to "+h",
'\u00BA' to "+i",
'\u00BB' to "+j",
'\u00BC' to "+k",
'\u00BD' to ",A",
'\u00BE' to ",B",
'\u00BF' to ",C",
'\u00C0' to ",D",
'\u00C1' to ",E",
'\u00C2' to ",F",
'\u00C3' to ",G",
'\u00C4' to ",H",
'\u00C5' to ",I",
'\u00C6' to ",J",
'\u00C7' to ",K",
'\u00C8' to ",L",
'\u00C9' to ",M",
'\u00CA' to ",N",
'\u00CB' to ",O",
'\u00CC' to ",P",
'\u00CD' to ",Q",
'\u00CE' to ",R",
'\u00CF' to ",S",
'\u00D0' to ",T",
'\u00D1' to ",U",
'\u00D2' to ",V",
'\u00D3' to ",W",
'\u00D4' to ",X",
'\u00D5' to ",Y",
'\u00D6' to ",Z",
'\u00D7' to "-0",
'\u00D8' to "-1",
'\u00D9' to "-2",
'\u00DA' to "-3",
'\u00DB' to "-4",
'\u00DC' to "-5",
'\u00DD' to "-6",
'\u00DE' to "-7",
'\u00DF' to "-8",
'\u00E0' to "-9",
'\u00E1' to ",e",
'\u00E2' to ",f",
'\u00E3' to ",g",
'\u00E4' to ",h",
'\u00E5' to ",i",
'\u00E6' to ",j",
'\u00E7' to ",k",
'\u00E8' to "-A",
'\u00E9' to "-B",
'\u00EA' to "-C",
'\u00EB' to "-D",
'\u00EC' to "-E",
'\u00ED' to "-F",
'\u00EE' to "-G",
'\u00EF' to "-H",
'\u00F0' to "-I",
'\u00F1' to "-J",
'\u00F2' to "-K",
'\u00F3' to "-L",
'\u00F4' to "-M",
'\u00F5' to "-N",
'\u00F6' to "-O",
'\u00F7' to "-P",
'\u00F8' to "-Q",
'\u00F9' to "-R",
'\u00FA' to "-S",
'\u00FB' to "-T",
'\u00FC' to "-U",
'\u00FD' to "-V",
'\u00FE' to "-W",
'\u00FF' to "-X"
)
override fun Init() {
// Load username matches from local storage
val storedData = API.GetData(SETTINGS_KEY)
@ -245,18 +48,20 @@ class plugin : Plugin() {
}
else -> HashMap()
}
getConfig()
}
override fun OnPluginsReloaded(): Boolean {
grabConfig()
cleanup()
return false
}
override fun OnLogin() {
Init()
}
override fun Draw(timeDelta: Long) {
if (component != null && component?.id == TARGET_COMPONENT_ID) {
val modifiedStr = replaceUsernameInBytes(component!!.text.chars, Player.usernameInput.toString())
component?.text = JagString.parse(modifiedStr)
}
replace()
}
override fun ComponentDraw(componentIndex: Int, component: Component?, screenX: Int, screenY: Int) {
@ -265,10 +70,6 @@ class plugin : Plugin() {
}
}
override fun OnLogin() {
grabConfig()
}
// Allow setting from the chatbox
override fun ProcessCommand(commandStr: String?, args: Array<out String>?) {
super.ProcessCommand(commandStr, args)
@ -278,7 +79,7 @@ class plugin : Plugin() {
if(args.isEmpty()) return
val type = args[0].toIntOrNull() ?: return
ACCOUNT_TYPE = type
usernameMatches[getCleanUserName()] = ACCOUNT_TYPE
usernameMatches[getCleanUserName().toLowerCase()] = ACCOUNT_TYPE
storeData()
}
}
@ -287,28 +88,47 @@ class plugin : Plugin() {
fun OnKondoValueUpdated() {
storeData()
OnPluginsReloaded() //refresh the ui
Init()
}
private fun cleanup() {
ACCOUNT_TYPE = 0
replace()
component = null
}
private fun replace() {
if (component != null && component?.id == TARGET_COMPONENT_ID) {
val modifiedStr = replaceUsernameInBytes(component!!.text.chars, Player.usernameInput.toString())
component?.text = JagString.parse(modifiedStr)
}
}
private fun getCleanUserName(): String {
return Player.usernameInput.toString().replace(" ", "_")
}
private fun grabConfig() {
// Check if we already have the account type for this user
private fun getConfig() {
val cleanUsername = getCleanUserName()
if (usernameMatches.containsKey(cleanUsername.toLowerCase())) {
ACCOUNT_TYPE = usernameMatches[cleanUsername]!!
println(cleanUsername)
// Abort if we are pre-login
if (cleanUsername.isEmpty()) return
// Check if we already have the account type for this user
val lowercaseUsername = cleanUsername.toLowerCase()
if (usernameMatches.containsKey(lowercaseUsername)) {
ACCOUNT_TYPE = usernameMatches[lowercaseUsername]!!
return
}
// No match found, check the hiscores (live server)
fetchAccountTypeFromAPI()
fetchAccountTypeFromAPI(cleanUsername)
}
private fun fetchAccountTypeFromAPI(){
val cleanUsername = getCleanUserName()
val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${cleanUsername.toLowerCase()}"
private fun fetchAccountTypeFromAPI(username : String){
val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${username.toLowerCase()}"
Thread {
try {
val url = URL(apiUrl)
@ -324,7 +144,7 @@ class plugin : Plugin() {
val reader = BufferedReader(InputStreamReader(connection.inputStream))
val response = reader.use { it.readText() }
reader.close()
updatePlayerData(response, cleanUsername)
updatePlayerData(response, username)
}
} catch (_: Exception) { }
}.start()
@ -333,9 +153,7 @@ class plugin : Plugin() {
private fun updatePlayerData(jsonResponse: String, username: String) {
val hiscoresResponse = gson.fromJson(jsonResponse, HiscoresResponse::class.java)
ACCOUNT_TYPE = hiscoresResponse.info.iron_mode.toInt()
// Store the result in our local cache
usernameMatches[username] = ACCOUNT_TYPE
usernameMatches[username.toLowerCase()] = ACCOUNT_TYPE
storeData()
}
@ -369,22 +187,4 @@ class plugin : Plugin() {
}
return result.toString()
}
// Lifted from KondoHiscores view
data class HiscoresResponse(
val info: PlayerInfo,
val skills: List<Skill>
)
data class PlayerInfo(
val exp_multiplier: String,
val iron_mode: String
)
data class Skill(
val id: String,
val dynamic: String,
val experience: String,
val static: String
)
}