diff --git a/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt b/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt new file mode 100644 index 0000000..19c07fa --- /dev/null +++ b/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt @@ -0,0 +1,331 @@ +package FooTextPlugin + +import plugin.Plugin +import rt4.Component +import rt4.JagString +import rt4.Player +import java.nio.charset.StandardCharsets +import com.google.gson.Gson +import java.io.BufferedReader +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL + +/** + * Iron Helmets in Chatbox + * + * Will be integrated into Kondo + * + * @author downthecrop + */ +class plugin : Plugin() { + + private val TARGET_COMPONENT_ID = 8978483 + private val TARGET_COMPONENT_INDEX = 51 + private val BUBBLE_ICON = "" + private val gson = Gson() + + val TYPE_ICONS: Map = hashMapOf( + 0 to "", + 1 to "", // IM + 2 to "", // HCIM + 3 to "", // UIM + ) + + private var ACCOUNT_TYPE = 0 + + + private var component: Component? = null + + // See JagString.java parse(), There is special encoding + // and this correctly resolves specials. + val SPECIAL_ESCAPES: Map = 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 Draw(timeDelta: Long) { + if (component != null && component?.id == TARGET_COMPONENT_ID) { + val username = Player.usernameInput.toString().toLowerCase() + val modifiedStr = replaceUsernameInBytes(component!!.text.chars, username) + component?.text = JagString.parse(modifiedStr) + } + } + + override fun ComponentDraw(componentIndex: Int, component: Component?, screenX: Int, screenY: Int) { + if (component?.id == TARGET_COMPONENT_ID && componentIndex == TARGET_COMPONENT_INDEX) { + this.component = component + } + } + + private fun fetchAccountTypeFromAPI(){ + println("Fetching Iron status from API...") + val cleanUsername = Player.usernameInput.toString().replace(" ", "_") + val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${cleanUsername.toLowerCase()}" + Thread { + try { + val url = URL(apiUrl) + val connection = url.openConnection() as HttpURLConnection + connection.requestMethod = "GET" + + // If a request take longer than 5 seconds timeout. + connection.connectTimeout = 5000 + connection.readTimeout = 5000 + + val responseCode = connection.responseCode + if (responseCode == HttpURLConnection.HTTP_OK) { + val reader = BufferedReader(InputStreamReader(connection.inputStream)) + val response = reader.use { it.readText() } + reader.close() + updatePlayerData(response) + } + } catch (_: Exception) { } + }.start() + } + + private fun updatePlayerData(jsonResponse: String) { + val hiscoresResponse = gson.fromJson(jsonResponse, HiscoresResponse::class.java) + ACCOUNT_TYPE = hiscoresResponse.info.iron_mode.toInt() + println("Resolved you are account type: $ACCOUNT_TYPE") + } + + override fun OnLogin() { + // The server doesn't tell us what account type we are. + // Requesting from API is the easier way to tell. + fetchAccountTypeFromAPI() + } + + private fun replaceUsernameInBytes(bytes: ByteArray, username: String): String { + // Convert bytes to string to work with them + val text = String(bytes, StandardCharsets.ISO_8859_1) + val colonIndex = text.indexOf(": ") + if (colonIndex != -1) { + val suffix = text.substring(colonIndex) + // modify and add the rest (username is always before the first ':' ) + val newText = "${TYPE_ICONS[ACCOUNT_TYPE]}$username$BUBBLE_ICON$suffix" + return encodeToJagStr(newText) + } + return encodeToJagStr(text) + } + + private fun encodeToJagStr(str: String): String { + val result = StringBuilder() + for (char in str) { + val escaped = SPECIAL_ESCAPES[char] + if (escaped != null) { + result.append(escaped) + } else { + result.append(char) + } + } + return result.toString() + } + + // Lifted from KondoHiscores view + data class HiscoresResponse( + val info: PlayerInfo, + val skills: List + ) + + 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 + ) +} \ No newline at end of file diff --git a/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.properties b/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.properties new file mode 100644 index 0000000..8ef8645 --- /dev/null +++ b/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.properties @@ -0,0 +1,3 @@ +AUTHOR=YourName +DESCRIPTION=Replaces the username part of Component Index: 51 ID: 8978483 with "foo" +VERSION=1.0 \ No newline at end of file diff --git a/plugin-playground/src/main/kotlin/KondoKit/plugin.kt b/plugin-playground/src/main/kotlin/KondoKit/plugin.kt index cd74c6f..022a390 100644 --- a/plugin-playground/src/main/kotlin/KondoKit/plugin.kt +++ b/plugin-playground/src/main/kotlin/KondoKit/plugin.kt @@ -11,10 +11,7 @@ import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite import KondoKit.Themes.Theme import KondoKit.Themes.ThemeType import KondoKit.Themes.getTheme -import KondoKit.components.ProgressBar import KondoKit.components.ScrollablePanel -import KondoKit.components.ToggleSwitch -import KondoKit.components.* import KondoKit.views.XPTrackerView import KondoKit.plugin.StateManager.focusedView import KondoKit.views.Constants.COMBAT_LVL_SPRITE