diff --git a/.travis.yml b/.travis.yml index bcf4ad9e9f..6766833ee3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ cache: - $HOME/.m2 jdk: - oraclejdk8 +- openjdk11 install: true script: ./travis/build.sh notifications: diff --git a/cache-client/pom.xml b/cache-client/pom.xml index f4381ce9ae..faeae7c994 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT cache-client diff --git a/cache-updater/application.properties b/cache-updater/application.properties deleted file mode 100644 index 8bfa1c2542..0000000000 --- a/cache-updater/application.properties +++ /dev/null @@ -1,7 +0,0 @@ -jdbc.url=jdbc:mysql://192.168.1.2:3306/cache -jdbc.username=runelite -jdbc.password=runelite -minio.url=http://192.168.1.2:9000 -minio.accesskey=QPQ15JX1ESAVMR0TLCL1 -minio.secretkey= -minio.bucket=runelite \ No newline at end of file diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index 63450786f6..f6c268d3fa 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT Cache Updater diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java index 354ca0b394..229ea1d268 100644 --- a/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java +++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java @@ -33,9 +33,10 @@ import java.util.Map; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.sql2o.Sql2o; import org.sql2o.converters.Converter; import org.sql2o.quirks.NoQuirks; @@ -43,16 +44,7 @@ import org.sql2o.quirks.NoQuirks; @Configuration public class CacheConfiguration { - @Value("${jdbc.url}") - private String jdbcUrl; - - @Value("${jdbc.username}") - private String jdbcUsername; - - @Value("${jdbc.password}") - private String jdbcPassword; - - @Value("${minio.url}") + @Value("${minio.endpoint}") private String minioUrl; @Value("${minio.accesskey}") @@ -62,13 +54,10 @@ public class CacheConfiguration private String minioSecretKey; @Bean + @ConfigurationProperties(prefix = "datasource.runelite-cache") public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setUrl(jdbcUrl); - dataSource.setUsername(jdbcUsername); - dataSource.setPassword(jdbcPassword); - return dataSource; + return DataSourceBuilder.create().build(); } @Bean diff --git a/cache-updater/src/main/resources/application.yaml b/cache-updater/src/main/resources/application.yaml new file mode 100644 index 0000000000..df290d680f --- /dev/null +++ b/cache-updater/src/main/resources/application.yaml @@ -0,0 +1,16 @@ +--- +# Database +datasource: + runelite-cache: + driverClassName: com.mysql.jdbc.Driver + type: com.mysql.jdbc.jdbc2.optional.MysqlDataSource + url: jdbc:mysql://localhost/runelite-cache + username: runelite + password: runelite + +# Minio client storage for cache +minio: + endpoint: http://localhost:9000 + accesskey: AM54M27O4WZK65N6F8IP + secretkey: /PZCxzmsJzwCHYlogcymuprniGCaaLUOET2n6yMP + bucket: runelite diff --git a/cache/pom.xml b/cache/pom.xml index 947dd7b667..03da240165 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT cache diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java index 6f8512695a..e77964a5ca 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java @@ -28,7 +28,7 @@ import java.util.HashMap; import java.util.Map; import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.io.InputStream; -import static net.runelite.cache.script.Opcodes.LOAD_STRING; +import static net.runelite.cache.script.Opcodes.SCONST; import static net.runelite.cache.script.Opcodes.POP_INT; import static net.runelite.cache.script.Opcodes.POP_STRING; import static net.runelite.cache.script.Opcodes.RETURN; @@ -94,7 +94,7 @@ public class ScriptLoader for (int i = 0; in.getOffset() < endIdx; instructions[i++] = opcode) { opcode = in.readUnsignedShort(); - if (opcode == LOAD_STRING) + if (opcode == SCONST) { stringOperands[i] = in.readString(); } diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java index c1fae2e995..3b130c4c53 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.Map.Entry; import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.io.OutputStream; -import static net.runelite.cache.script.Opcodes.LOAD_STRING; +import static net.runelite.cache.script.Opcodes.SCONST; import static net.runelite.cache.script.Opcodes.POP_INT; import static net.runelite.cache.script.Opcodes.POP_STRING; import static net.runelite.cache.script.Opcodes.RETURN; @@ -48,7 +48,7 @@ public class ScriptSaver { int opcode = instructions[i]; out.writeShort(opcode); - if (opcode == LOAD_STRING) + if (opcode == SCONST) { out.writeString(stringOperands[i]); } diff --git a/cache/src/main/java/net/runelite/cache/script/Instruction.java b/cache/src/main/java/net/runelite/cache/script/Instruction.java index 8eb8a2bb3f..b369c97de5 100644 --- a/cache/src/main/java/net/runelite/cache/script/Instruction.java +++ b/cache/src/main/java/net/runelite/cache/script/Instruction.java @@ -28,10 +28,6 @@ public class Instruction { private final int opcode; private String name; - private int intStackPops; - private int stringStackPops; - private int intStackPushes; - private int stringStackPushes; public Instruction(int opcode) { @@ -52,44 +48,4 @@ public class Instruction { this.name = name; } - - public int getIntStackPops() - { - return intStackPops; - } - - public void setIntStackPops(int intStackPops) - { - this.intStackPops = intStackPops; - } - - public int getStringStackPops() - { - return stringStackPops; - } - - public void setStringStackPops(int stringStackPops) - { - this.stringStackPops = stringStackPops; - } - - public int getIntStackPushes() - { - return intStackPushes; - } - - public void setIntStackPushes(int intStackPushes) - { - this.intStackPushes = intStackPushes; - } - - public int getStringStackPushes() - { - return stringStackPushes; - } - - public void setStringStackPushes(int stringStackPushes) - { - this.stringStackPushes = stringStackPushes; - } } diff --git a/cache/src/main/java/net/runelite/cache/script/Instructions.java b/cache/src/main/java/net/runelite/cache/script/Instructions.java index f9aac6883c..17dfabfcd1 100644 --- a/cache/src/main/java/net/runelite/cache/script/Instructions.java +++ b/cache/src/main/java/net/runelite/cache/script/Instructions.java @@ -1,5 +1,7 @@ /* * Copyright (c) 2017, Adam + * Copyright (c) 2018-2019, Hunter WB + * Copyright (c) 2019, Abex * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,514 +37,480 @@ public class Instructions public void init() { - add(LOAD_INT, "load_int", 0, 1); - add(GET_VARP, "get_varp", 0, 1); - add(PUT_VARP, "put_varp", 0, 1); - add(LOAD_STRING, "load_string", 0, 0, 0, 1); - add(JUMP, "jump", 0, 0); - add(IF_ICMPNE, "if_icmpne", 2, 0); - add(IF_ICMPEQ, "if_icmpeq", 2, 0); - add(IF_ICMPLT, "if_icmplt", 2, 0); - add(IF_ICMPGT, "if_icmpgt", 2, 0); - add(RETURN, "return", 0, 0); - add(GET_VARBIT, "get_varbit", 0, 1); - add(SET_VARBIT, "set_varbit", 1, 0); - add(IF_ICMPLE, "if_icmple", 2, 0); - add(IF_ICMPGE, "if_icmpge", 2, 0); - add(ILOAD, "iload", 0, 1); - add(ISTORE, "istore", 1, 0); - add(SLOAD, "sload", 0, 0, 0, 1); - add(SSTORE, "sstore", 0, 0, 1, 0); - add(STRING_APPEND, "string_append", 0, 0, -1, 1); - add(POP_INT, "pop_int", 1, 0); - add(POP_STRING, "pop_string", 0, 0, 1, 0); - add(INVOKE, "invoke", -1, -1, -1, -1); - add(GET_VARC, "get_varc", 0, 1); - add(PUT_VARC, "put_varc", 1, 0); - add(ARRAY_INITIALIZE, "array_initialize", 1, 0); - add(ARRAY_LOAD, "array_load", 1, 1); - add(ARRAY_STORE, "array_store", 2, 0); - add(GET_VARC_STRING, "get_varc_string", 0, 0, 0, 1); - add(PUT_VARC_STRING, "put_varc_string", 0, 0, 1, 0); - add(SWITCH, "switch", 1, 0); - add(WIDGET_CREATE_CHILD, "widget_create_child", 3, 0); - add(WIDGET_DESTROY_CHILD, "widget_destroy_child", 0, 0); - add(WIDGET_UNSET_CHILDREN, "widget_unset_children", 1, 0); - add(WIDGET_LOAD_CHILD, "widget_load_child", 2, 1); - add(WIDGET_LOAD, "widget_load", 1, 1); - // 2000-2100 are the same as 1000-1100, but - // pop an additional int which is used to get the current widget - add(WIDGET_PUT_POSITION, "widget_put_position", 4, 0); - add(WIDGET_PUT_SIZE, "widget_put_size", 4, 0); - add(WIDGET_PUT_HIDDEN, "widget_put_hidden", 1, 0); - add(WIDGET_PUT_NO_CLICK_THROUGH, "widget_put_no_click_through", 1, 0); - add(1006, 1, 0); - // 2100-2200 and 1100-1200 do the same thing - add(WIDGET_PUT_SCROLL, "widget_put_scroll", 2, 0); - add(WIDGET_PUT_TEXTCOLOR, "widget_put_textcolor", 1, 0); - add(WIDGET_PUT_FILLED, "widget_put_filled", 1, 0); - add(WIDGET_PUT_OPACITY, "widget_put_opacity", 1, 0); - add(WIDGET_PUT_LINE_WIDTH, "widget_put_line_width", 1, 0); - add(WIDGET_PUT_SPRITEID, "widget_put_spriteid", 1, 0); - add(WIDGET_PUT_TEXTUREID, "widget_put_textureid", 1, 0); - add(WIDGET_PUT_SPRITE_TILING, "widget_put_sprite_tiling", 1, 0); - add(WIDGET_PUT_MODELID_1, "widget_put_modelid_1", 1, 0); - add(WIDGET_PUT_3D_ROTATION, "widget_put_3d_rotation", 6, 0); - add(WIDGET_PUT_ANIMATION, "widget_put_animation", 1, 0); - add(1111, 1, 0); - add(WIDGET_PUT_TEXT, "widget_put_text", 0, 0, 1, 0); - add(WIDGET_PUT_FONTID, "widget_put_fontid", 1, 0); - add(WIDGET_PUT_TEXT_ALIGNMENT, "widget_put_text_alignment", 3, 0); - add(WIDGET_PUT_TEXT_SHADOWED, "widget_put_text_shadowed", 1, 0); - add(WIDGET_PUT_BORDERTHICKNESS, "widget_put_borderthickness", 1, 0); - add(WIDGET_PUT_SPRITE2, "widget_put_sprite2", 1, 0); - add(WIDGET_PUT_FLIPPEDVERTICALLY, "widget_put_flippedvertically", 1, 0); - add(WIDGET_PUT_FLIPPEDHORIZONALLY, "widget_put_flippedhorizonally", 1, 0); - add(WIDGET_PUT_SCROLLWIDTHHEIGHT, "widget_put_scrollwidthheight", 2, 0); - add(WIDGET_ADVANCE_DIALOGUE, "widget_advance_dialogue", 0, 0); - add(1122, 1, 0); - add(1123, 1, 0); - add(1124, 1, 0); - add(1125, 1, 0); - // and 1200-1300 and 2200-2300 - add(WIDGET_PUT_MODELID_2, "widget_put_modelid_2", 1, 0); - add(WIDGET_PUT_MODELID_3, "widget_put_modelid_3", 0, 0); - add(1200, 2, 0); - add(1205, 2, 0); - add(1212, 2, 0); - // and 1300-1400 and 2300-2400 - add(WIDGET_PUT_ACTION, "widget_put_action", 1, 0, 1, 0); - add(WIDGET_PUT_DRAG_PARENT, "widget_put_drag_parent", 2, 0); - add(1302, 1, 0); - add(1303, 1, 0); - add(1304, 1, 0); - add(WIDGET_PUT_NAME, "widget_put_name", 0, 0, 1, 0); - add(WIDGET_PUT_SELECTED_ACTION, "widget_put_selected_action", 0, 0, 1, 0); - add(WIDGET_PUT_ACTIONS_NULL, "widget_put_actions_null", 0, 0); - // and 1400-1500 and 2400-2500 - add(WIDGET_PUT_MOUSE_PRESS_LISTENER, "widget_put_mouse_press_listener", -1, 0, -1, 0); - add(WIDGET_PUT_DRAGGED_OVER_LISTENER, "widget_put_mouse_dragged_over_listener", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_RELEASE_LISTENER, "widget_put_mouse_release_listener", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_ENTER_LISTENER, "widget_put_mouse_enter_listener", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_EXIT_LISTENER, "widget_put_mouse_exit_listener", -1, 0, -1, 0); - add(WIDGET_PUT_DRAG_START_LISTENER, "widget_put_drag_start_listener", -1, 0, -1, 0); - add(WIDGET_PUT_USE_WITH_LISTENER, "widget_put_use_with_listener", -1, 0, -1, 0); - add(WIDGET_PUT_CONFIG_LISTENER, "widget_put_config_listener", -1, 0, -1, 0); - add(WIDGET_PUT_RENDER_LISTENER, "widget_put_render_listener", -1, 0, -1, 0); - add(WIDGET_PUT_OPTION_CLICK_LISTENER, "widget_put_option_click_listener", -1, 0, -1, 0); - add(WIDGET_PUT_DRAG_RELEASE_LISTENER, "widget_put_drag_release_listener", -1, 0, -1, 0); - add(WIDGET_PUT_DRAG_LISTENER, "widget_put_drag_listener", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_HOVER_LISTENER, "widget_put_mouse_hover_listener", -1, 0, -1, 0); - add(WIDGET_PUT_TABLE_LISTENER, "widget_put_table_listener", -1, 0, -1, 0); - add(WIDGET_PUT_SKILL_LISTENER, "widget_put_skill_listener", -1, 0, -1, 0); - add(WIDGET_PUT_USE_LISTENER, "widget_put_use_listener", -1, 0, -1, 0); - add(WIDGET_PUT_SCROLL_LISTENER, "widget_put_scroll_listener", -1, 0, -1, 0); - add(WIDGET_PUT_MSG_LISTENER, "widget_put_msg_listener", -1, 0, -1, 0); - add(WIDGET_PUT_KEY_LISTENER, "widget_put_key_listener", -1, 0, -1, 0); - add(WIDGET_PUT_FRIENDS_LISTENER, "widget_put_friends_listener", -1, 0, -1, 0); - add(WIDGET_PUT_CLAN_LISTENER, "widget_put_clan_listener", -1, 0, -1, 0); - add(WIDGET_PUT_DIALOG_ABORT_LISTENER, "widget_put_dialog_abort_listener", -1, 0, -1, 0); - add(WIDGET_PUT_OPENCLOSE_LISTENER, "widget_put_openclose_listener", -1, 0, -1, 0); - add(WIDGET_PUT_GE_LISTENER, "widget_put_ge_listener", -1, 0, -1, 0); - add(WIDGET_PUT_RESIZE_LISTENER, "widget_put_resize_listener", -1, 0, -1, 0); - // and 1500-1600 and 2500-2600 - add(WIDGET_GET_RELATIVEX, "widget_get_relativex", 0, 1); - add(WIDGET_GET_RELATIVEY, "widget_get_relativey", 0, 1); - add(WIDGET_GET_WIDTH, "widget_get_width", 0, 1); - add(WIDGET_GET_HEIGHT, "widget_get_height", 0, 1); - add(WIDGET_GET_HIDDEN, "widget_get_hidden", 0, 1); - add(WIDGET_GET_PARENTID, "widget_get_parentid", 0, 1); - // and 1600-1700 and 2600-2700 - add(WIDGET_GET_SCROLLX, "widget_get_scrollx", 0, 1); - add(WIDGET_GET_SCROLLY, "widget_get_scrolly", 0, 1); - add(WIDGET_GET_TEXT, "widget_get_text", 0, 0, 0, 1); - add(WIDGET_GET_SCROLLWIDTH, "widget_get_scrollwidth", 0, 1); - add(WIDGET_GET_SCROLLHEIGHT, "widget_get_scrollheight", 0, 1); - add(WIDGET_GET_MODELZOOM, "widget_get_modelzoom", 0, 1); - add(WIDGET_GET_ROTATIONX, "widget_get_rotationx", 0, 1); - add(WIDGET_GET_ROTATIONY, "widget_get_rotationy", 0, 1); - add(WIDGET_GET_ROTATIONZ, "widget_get_rotationz", 0, 1); - add(WIDGET_GET_OPACITY, "widget_get_opacity", 0, 1); - add(1610, 0, 1); - add(WIDGET_GET_TEXTCOLOR, "widget_get_textcolor", 0, 1); - add(1612, 0, 1); - add(1613, 0, 1); - // 1700 - add(WIDGET_GET_ITEMID, "widget_get_itemid", 0, 1); - add(WIDGET_GET_STACKSIZE, "widget_get_stacksize", 0, 1); - add(WIDGET_GET_INDEX, "widget_get_index", 0, 1); - add(WIDGET_GET_CONFIG, "widget_get_config", 0, 1); - add(WIDGET_GET_ACTION, "widget_get_action", 1, 0, 0, 1); - add(WIDGET_GET_NAME, "widget_get_name", 0, 0, 0, 1); - // and 1900-2000 and 2900-3000 - add(1927, 0, 0); - // 2000-2100 - add(WIDGET_PUT_POSITION_WIDGET, "widget_put_position_widget", 5, 0); - add(WIDGET_PUT_SIZE_WIDGET, "widget_put_size_widget", 5, 0); - add(WIDGET_PUT_HIDDEN_WIDGET, "widget_put_hidden_widget", 2, 0); - add(WIDGET_PUT_NO_CLICK_THROUGH_WIDGET, "widget_put_no_click_through_widget", 2, 0); - add(2006, 2, 0); - // 2100-2200 - add(WIDGET_PUT_SCROLL_WIDGET, "widget_put_scroll_widget", 3, 0); - add(WIDGET_PUT_TEXTCOLOR_WIDGET, "widget_put_textcolor_widget", 2, 0); - add(WIDGET_PUT_FILLED_WIDGET, "widget_put_filled_widget", 2, 0); - add(WIDGET_PUT_OPACITY_WIDGET, "widget_put_opacity_widget", 2, 0); - add(WIDGET_PUT_LINE_WIDTH_WIDGET, "widget_put_line_width_widget", 2, 0); - add(WIDGET_PUT_SPRITEID_WIDGET, "widget_put_spriteid_widget", 2, 0); - add(WIDGET_PUT_TEXTUREID_WIDGET, "widget_put_textureid_widget", 2, 0); - add(WIDGET_PUT_SPRITE_TILING_WIDGET, "widget_put_sprite_tiling_widget", 2, 0); - add(WIDGET_PUT_MODELID_1_WIDGET, "widget_put_modelid_1_widget", 2, 0); - add(WIDGET_PUT_3D_ROTATION_WIDGET, "widget_put_3d_rotation_widget", 7, 0); - add(WIDGET_PUT_ANIMATION_WIDGET, "widget_put_animation_widget", 2, 0); - add(2111, 2, 0); - add(WIDGET_PUT_TEXT_WIDGET, "widget_put_text_widget", 1, 0, 1, 0); - add(WIDGET_PUT_FONTID_WIDGET, "widget_put_fontid_widget", 2, 0); - add(WIDGET_PUT_TEXT_ALIGNMENT_WIDGET, "widget_put_text_alignment_widget", 4, 0); - add(WIDGET_PUT_TEXT_SHADOWED_WIDGET, "widget_put_text_shadowed_widget", 2, 0); - add(WIDGET_PUT_BORDERTHICKNESS_WIDGET, "widget_put_borderthickness_widget", 2, 0); - add(WIDGET_PUT_SPRITE2_WIDGET, "widget_put_sprite2_widget", 2, 0); - add(WIDGET_PUT_FLIPPEDVERTICALLY_WIDGET, "widget_put_flippedvertically_widget", 2, 0); - add(WIDGET_PUT_FLIPPEDHORIZONALLY_WIDGET, "widget_put_flippedhorizonally_widget", 2, 0); - add(WIDGET_PUT_SCROLLWIDTHHEIGHT_WIDGET, "widget_put_scrollwidthheight_widget", 3, 0); - add(WIDGET_ADVANCE_DIALOGUE_WIDGET, "widget_advance_dialogue_window", 1, 0); - add(2122, 2, 0); - add(2123, 2, 0); - add(2124, 2, 0); - add(2125, 2, 0); - // 2200-2300 - add(WIDGET_PUT_MODELID_2_WIDGET, "widget_put_modelid_2_widget", 2, 0); - add(WIDGET_PUT_MODELID_3_WIDGET, "widget_put_modelid_3_widget", 1, 0); - add(2200, 3, 0); - add(2205, 3, 0); - add(2212, 3, 0); - // 2300-2400 - add(WIDGET_PUT_ACTION_WIDGET, "widget_put_action_widget", 2, 0, 1, 0); - add(WIDGET_PUT_DRAG_PARENT_WIDGET, "widget_put_drag_parent_widget", 3, 0); - add(2302, 2, 0); - add(2303, 2, 0); - add(2304, 2, 0); - add(WIDGET_PUT_NAME_WIDGET, "widget_put_name_widget", 1, 0, 1, 0); - add(WIDET_PUT_SELECTED_ACTION_WIDGET, "widget_put_selected_action_widget", 1, 0, 1, 0); - add(WIDGET_PUT_ACTIONS_NULL_WIDGET, "widget_put_actions_null_widget", 1, 0); - // 2400-2500 - add(WIDGET_PUT_MOUSE_PRESS_LISTENER_WIDGET, "widget_put_mouse_press_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_DRAGGED_OVER_LISTENER_WIDGET, "widget_put_dragged_over_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_RELEASE_LISTENER_WIDGET, "widget_put_mouse_release_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_ENTER_LISTENER_WIDGET, "widget_put_mouse_enter_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_EXIT_LISTENER_WIDGET, "widget_put_mouse_exit_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_DRAG_START_LISTENER_WIDGET, "widget_put_drag_start_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_USE_WITH_LISTENER_WIDGET, "widget_put_mouse_use_with_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_CONFIG_LISTENER_WIDGET, "widget_put_config_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_RENDER_LISTENER_WIDGET, "widget_put_render_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_OPTION_CLICK_LISTENER_WIDGET, "widget_put_option_click_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_DRAG_RELEASE_LISTENER_WIDGET, "widget_put_drag_release_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_DRAG_LISTENER_WIDGET, "widget_put_drag_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_MOUSE_HOVER_LISTENER_WIDGET, "widget_put_mouse_hover_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_TABLE_LISTENER_WIDGET, "widget_put_table_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_SKILL_LISTENER_WIDGET, "widget_put_skill_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_USE_LISTENER_WIDGET, "widget_put_use_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_SCROLL_LISTENER_WIDGET, "widget_put_scroll_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_MSG_LISTENER_WIDGET, "widget_put_msg_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_KEY_LISTENER_WIDGET, "widget_put_key_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_FRIENDS_LISTENER_WIDGET, "widget_put_friends_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_CLAN_LISTENER_WIDGET, "widget_put_clan_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_DIALOG_ABORT_LISTENER_WIDGET, "widget_put_dialog_abort_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_OPENCLOSE_LISTENER_WIDGET, "widget_put_openclose_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_GE_LISTENER_WIDGET, "widget_put_ge_listener_widget", -1, 0, -1, 0); - add(WIDGET_PUT_RESIZE_LISTENER_WIDGET, "widget_put_resize_listener_widget", -1, 0, -1, 0); - // 2500-2600 - add(WIDGET_GET_RELATIVEX_WIDGET, "widget_get_relativex_widget", 1, 1); - add(WIDGET_GET_RELATIVEY_WIDGET, "widget_get_relativey_widget", 1, 1); - add(WIDGET_GET_WIDTH_WIDGET, "widget_get_width_widget", 1, 1); - add(WIDGET_GET_HEIGHT_WIDGET, "widget_get_height_widget", 1, 1); - add(WIDGET_GET_HIDDEN_WIDGET, "widget_get_hidden_widget", 1, 1); - add(WIDGET_GET_PARENTID_WIDGET, "widget_get_parentid_widget", 1, 1); - // 2600-2700 - add(WIDGET_GET_SCROLLX_WIDGET, "widget_get_scrollx_widget", 1, 1); - add(WIDGET_GET_SCROLLY_WIDGET, "widget_get_scrolly_widget", 1, 1); - add(WIDGET_GET_TEXT_WIDGET, "widget_get_text_widget", 1, 0, 0, 1); - add(WIDGET_GET_SCROLLWIDTH_WIDGET, "widget_get_scrollwidth_widget", 1, 1); - add(WIDGET_GET_SCROLLHEIGHT_WIDGET, "widget_get_scrollheight_widget", 1, 1); - add(WIDGET_GET_MODELZOOM_WIDGET, "widget_get_modelzoom_widget", 1, 1); - add(WIDGET_GET_ROTATIONX_WIDGET, "widget_get_rotationx_widget", 1, 1); - add(WIDGET_GET_ROTATIONY_WIDGET, "widget_get_rotationy_widget", 1, 1); - add(WIDGET_GET_ROTATIONZ_WIDGET, "widget_get_rotationz_widget", 1, 1); - add(WIDGET_GET_OPACITY_WIDGET, "widget_get_opacity_widget", 1, 1); - add(2610, 1, 1); - add(WIDGET_GET_TEXTCOLOR_WIDGET, "widget_get_textcolor_widget", 1, 1); - add(2612, 1, 1); - add(2613, 1, 1); - // 2700-2800 - add(WIDGET_GET_ITEMID_WIDGET, "widget_get_itemid_widget", 1, 1); - add(WIDGET_GET_STACKSIZE_WIDGET, "widget_get_stacksize_widget", 1, 1); - add(WIGET_GET_INDEX_WIDGET, "widget_get_index_widget", 1, 1); - add(GET_WIDGET_ROOT, "get_widget_root", 0, 1); - // 2800-2900 - add(WIDGET_GET_CONFIG_WIGET, "widget_get_config_widget", 1, 1); - add(WIDGET_GET_ACTION_WIDGET, "widget_get_action_widget", 2, 0, 0, 1); - add(WIDGET_GET_NAME_WIDGET, "widget_get_name_widget", 1, 0, 0, 1); - // 2900-3000 - add(2927, 1, 0); - // 3000-3200 - add(SEND_GAME_MESSAGE, "send_game_message", 0, 0, 1, 0); - add(PLAYER_ANIMATE, "player_animate", 2, 0); - add(CLOSE_WINDOW, "close_window", 0, 0); - add(NUMERIC_INPUT, "numeric_input", 0, 0, 1, 0); - add(STRING_INPUT_1, "string_input_1", 0, 0, 1, 0); - add(STRING_INPUT_2, "string_input_2", 0, 0, 1, 0); - add(PLAYER_ACTION, "player_action", 1, 0, 1, 0); - add(SET_TOP_CONTEXT_MENU_ROW, "set_top_context_menu_row", 3, 0); - add(SET_TOP_CONTEXT_MENU_ROW_2, "set_top_context_menu_row_2", 2, 0); - add(SET_MOUSE_BUTTON_CONTROLS_CAMERA, "set_mouse_button_controls_camera", 1, 0); - add(GET_HIDEROOFS, "get_hideroofs", 0, 1); - add(SET_HIDEROOFS, "set_hideroofs", 1, 0); - add(OPEN_URL, "open_url", 1, 0, 1, 0); - add(ITEM_PRICE, "item_price", 1, 0); - add(SEND_BUG_REPORT, "send_bug_report", 1, 0, 2, 0); - add(SET_SHIFT_DROP_ENABLED, "set_shift_drop_enabled", 1, 0); - add(SET_CONNECTION_TEXT_ENABLED, "set_connection_text_enabled", 1, 0); - // 3200-3300 - add(PLAY_SOUND_EFFECT, "play_sound_effect", 3, 0); - add(3201, 1, 0); - add(3202, 2, 0); - // 3300-3400 - add(GET_GAMECYCLE, "get_gamecycle", 0, 1); - add(GET_ITEMCONTAINER_ITEMID, "get_itemcontainer_itemid", 2, 0); - add(GET_ITEMCONTAINER_STACKSIZE, "get_itemcontainer_stacksize", 2, 1); - add(GET_ITEMCONTAINER_STACKSIZES_TOTAL, "get_itemcontainer_stacksizes_total", 2, 1); - add(GET_INVENTORY_SIZE, "get_inventory_size", 1, 1); - add(GET_BOOSTEDSKILLLEVELS, "get_boostedskilllevels", 1, 1); - add(GET_REALSKILLLEVELS, "get_realskilllevels", 1, 1); - add(GET_SKILLEXPERIENCES, "get_skillexperiences", 1, 1); - add(GET_COORDINATES, "get_coordinates", 0, 1); - add(DIVIDE_BY_16384, "divide_by_16384", 1, 1); - add(RIGHT_SHIFT_28, "right_shift_28", 1, 1); - add(AND_16384, "and_16384", 1, 1); - add(GET_ISMEMBERS, "get_ismembers", 0, 1); - add(GET_ITEMCONTAINER_ITEMID_2, "get_itemcontainer_itemid_2", 2, 1); - add(GET_ITEMCONTAINER_STACKSIZE_2, "get_itemcontainer_stacksize_2", 2, 1); - add(GET_ITEMCONTAINER_STACKSIZES_TOTAL_2, "get_itemcontainer_stacksizes_total_2", 2, 1); - add(GET_RIGHTS, "get_rights", 0, 1); - add(GET_SYSTEM_UPDATE_TIMER, "get_system_update_timer", 0, 1); - add(GET_WORLDNUM, "get_worldnum", 0, 1); - add(GET_ENERGY, "get_energy", 0, 1); - add(GET_WEIGHT, "get_weight", 0, 1); - add(GET_PLAYERMOD, "get_playermod", 0, 1); - add(GET_FLAGS, "get_flags", 0, 1); - add(PACK_LOCATION, "pack_location", 4, 1); - // 3400-3500 - add(3400, 2, 0, 0, 1); - add(GET_ENUM_VALUE, "get_enum_value", 4, -1, 0, -1); // this pushes an int or a string, depending on the argument - // 3500-3700 - add(GET_FRIENDCOUNT, "get_friendcount", 0, 1); - add(GET_FRIEND, "get_friend", 1, 0, 0, 2); - add(GET_FRIEND_WORLD, "get_friend_world", 1, 1); - add(GET_FRIEND_RANK, "get_friend_rank", 1, 1); - add(3604, 1, 0, 1, 0); - add(ADD_FRIEND, "add_friend", 0, 0, 1, 0); - add(REMOVE_FRIEND, "remove_friend", 0, 0, 1, 0); - add(ADD_IGNORE, "add_ignore", 0, 0, 1, 0); - add(REMOVE_IGNORE, "remove_ignore", 0, 0, 1, 0); - add(IS_FRIEND, "is_friend", 0, 1, 1, 0); - add(GET_CLANCHAT_OWNER, "get_clanchat_owner", 0, 0, 0, 1); - add(GET_CLANCHATCOUNT, "get_clanchatcount", 0, 1); - add(GET_CLAN_MEMBER_NAME, "get_clan_member_name", 1, 0, 0, 1); - add(GET_CLAN_MEMBER_WORLD, "get_clan_member_world", 1, 1); - add(GET_CLAN_MEMBER_RANK, "get_clan_member_rank", 1, 1); - add(CLANCHAT_KICK_RANK, "clanchat_kick_rank", 0, 1); - add(CLANCHAT_KICK_CLANMEMBER, "clanchat_kick_clanmember", 0, 0, 1, 0); - add(GET_CLANCHAT_RANK, "get_clanchat_rank", 0, 1); - add(JOIN_CLANCHAT, "join_clanchat", 0, 0, 1, 0); - add(PART_CLANCHAT, "part_clanchat", 0, 0); - add(GET_IGNORECOUNT, "get_ignorecount", 0, 1); - add(GET_IGNORE, "get_ignore", 1, 0, 0, 2); - add(IS_IGNORE, "is_ignore", 0, 1, 1, 0); - add(CLANMEMBER_ISME, "clanmember_isme", 1, 1); - add(GET_CLANCHATOWNER, "get_clanchatowner", 0, 0, 0, 1); - // 3700-4000 - add(GET_GRANDEXCHANGE_OFFER_IS_SELLING, "get_grandexchange_offer_is_selling", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_ITEMID, "get_grandexchange_offer_itemid", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_PRICE, "get_grandexchange_offer_price", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_TOTALQUANTITY, "get_grandexchange_offer_totalquantity", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_QUANTITYSOLD, "get_grandexchange_offer_quantitysold", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_SPENT, "get_grandexchange_offer_spent", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_NOT_STARTED, "get_grandexchange_offer_not_started", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_STATUS_2, "get_grandexchange_offer_status_2", 1, 1); - add(GET_GRANDEXCHANGE_OFFER_DONE, "get_grandexchange_offer_done", 1, 1); - add(3913, 1, 1); - add(3914, 1, 0); - add(3915, 1, 0); - add(3916, 2, 0); - add(3917, 1, 0); - add(3918, 1, 0); - add(3919, 0, 1); - add(3920, 1, 1); - add(3921, 1, 0, 0, 1); - add(3922, 1, 0, 0, 1); - add(3923, 1, 0, 0, 1); - add(3924, 1, 1); - add(3925, 1, 1); - add(3926, 1, 1); - // 4000-4100 - add(IADD, "iadd", 2, 1); - add(ISUB, "isub", 2, 1); - add(IMUL, "imul", 2, 1); - add(IDIV, "idiv", 2, 1); - add(RAND_EXCL, "rand_excl", 1, 1); - add(RAND_INCL, "rand_incl", 1, 1); - add(INTERPOLATE, "interpolate", 5, 1); - add(ADD_PERCENT, "add_percent", 2, 1); - add(SET_BIT, "set_bit", 2, 1); - add(CLEAR_BIT, "clear_bit", 2, 1); - add(TEST_BIT, "test_bit", 2, 1); - add(MODULO, "modulo", 2, 1); - add(POW, "pow", 2, 1); - add(INVPOW, "invpow", 2, 1); - add(AND, "and", 2, 1); - add(OR, "or", 2, 1); - add(SCALE, "scale", 3, 1); - // 4100-4200 - add(CONCAT_INT, "concat_int", 1, 0, 1, 1); - add(CONCAT_STRING, "concat_string", 0, 0, 2, 1); - add(4102, 1, 0, 1, 1); - add(TOLOWERCASE, "tolowercase", 0, 0, 1, 1); - add(FORMAT_DATE, "format_date", 1, 0, 0, 1); - add(SWITCH_MALE_OR_FEMALE, "switch_male_or_female", 0, 0, 2, 1); - add(INT_TO_STRING, "int_to_string", 1, 0, 0, 1); - add(STRING_COMPARE, "string_compare", 0, 1, 2, 0); - add(GET_LINE_COUNT, "get_line_count", 2, 1, 1, 0); - add(GET_MAX_LINE_WIDTH, "get_max_line_width", 2, 1, 1, 0); - add(SWITCH_STRING, "switch_string", 1, 0, 2, 1); - add(APPENDTAGS, "appendtags", 0, 0, 1, 1); - add(CONCAT_CHAR, "concat_char", 1, 0, 1, 1); - add(CHAR_IS_PRINTABLE, "char_is_printable", 1, 1); - add(ISALNUM, "isalnum", 1, 1); - add(ISALPHA, "isalpha", 1, 1); - add(ISDIGIT, "isdigit", 1, 1); - add(STRING_LENGTH, "string_length", 0, 1, 1, 0); - add(STRING_SUBSTRING, "string_substring", 2, 0, 1, 1); - add(STRING_REMOVE_HTML, "string_remove_html", 0, 0, 1, 1); - add(STRING_INDEXOF, "string_indexof", 1, 1, 1, 0); - add(STRING_INDEXOF_FROM, "string_indexof_from", 1, 1, 2, 0); - // 4200-4300 - add(GET_ITEM_NAME, "get_item_name", 1, 0, 0, 1); - add(GET_ITEM_GROUND_ACTION, "get_item_ground_action", 2, 0, 0, 1); - add(GET_ITEM_INVENTORY_ACTION, "get_item_inventory_action", 2, 0, 0, 1); - add(GET_ITEM_PRICE, "get_item_price", 1, 1); - add(GET_ITEM_STACKABLE, "get_item_stackable", 1, 1); - add(GET_ITEM_NOTE_1, "get_item_note_1", 1, 1); - add(GET_ITEM_NOTE_2, "get_item_note_2", 1, 1); - add(GET_ITEM_ISMEMBERS, "get_item_ismembers", 1, 1); - add(4208, 1, 1); - add(4209, 1, 1); - add(SEARCH_ITEM, "search_item", 1, 1, 1, 0); - add(NEXT_SEARCH_RESULT, "next_search_result", 0, 1); - add(4212, 0, 0); - // 4300-5100 - add(5000, 0, 1); - add(CHATFILTER_UPDATE, "chatfilter_update", 3, 0); - add(REPORT_PLAYER, "report_player", 2, 0, 1, 0); - add(GET_CHAT_MESSAGE_TYPE, "get_chat_message_type", 2, 2, 0, 3); - add(GET_CHAT_MESSAGE, "get_chat_message", 1, 2, 0, 3); - add(5005, 0, 1); - add(CHATBOX_INPUT, "chatbox_input", 1, 0, 1, 0); - add(PRIVMSG, "privmsg", 0, 0, 2, 0); - add(GET_LOCALPLAYER_NAME, "get_localplayer_name", 0, 0, 0, 1); - add(5016, 0, 1); - add(GET_CHATLINEBUFFER_LENGTH, "get_chatlinebuffer_length", 1, 1); - add(GET_MESSAGENODE_PREV_ID, "get_messagenode_prev_id", 1, 1); - add(GET_MESSAGENODE_NEXT_ID, "get_messagenode_next_id", 1, 1); - add(RUN_COMMAND, "run_command", 0, 0, 1, 0); - add(5021, 0, 0, 1, 0); - add(5022, 0, 0, 0, 1); - // 5100-5400 - add(GET_ISRESIZED, "get_isresized", 0, 1); - add(SET_ISRESIZED, "set_isresized", 1, 0); - add(GET_SCREENTYPE, "get_screentype", 0, 1); - add(SET_SCREENTYPE, "set_screentype", 1, 0); - // 5400-5600 - add(5504, 2, 0); - add(5505, 0, 1); - add(GET_MAPANGLE, "get_mapangle", 0, 1); - add(SET_CAMERA_FOCAL_POINT_HEIGHT, "set_camera_focal_point_height", 1, 0); - add(GET_CAMERA_FOCAL_POINT_HEIGHT, "get_camera_focal_point_height", 0, 1); - // 5600-5700 - add(CANCEL_LOGIN, "cancel_login", 0, 0); - // 5700-6300 - add(6200, 2, 0); - add(SET_ZOOM_DISTANCE, "set_zoom_distance", 2, 0); - add(6202, 4, 0); - add(GET_VIEWPORT_SIZE, "get_viewport_size", 0, 2); - add(GET_ZOOM_DISTANCE, "get_zoom_distance", 0, 2); - add(6205, 0, 2); - // 6300-6600 - add(LOAD_WORLDS, "load_worlds", 0, 1); - add(GET_FIRST_WORLD, "get_first_world", 0, 4, 0, 2); - add(GET_NEXT_WORLD, "get_next_world", 0, 4, 0, 2); - add(GET_WORLD_BY_ID, "get_world_by_id", 1, 4, 0, 2); - add(6507, 4, 0); - add(GET_WORLD_BY_INDEX, "get_world_by_index", 1, 4, 0, 2); - add(6512, 1, 0); - add(GET_IS_MOBILE, "get_is_mobile", 0, 1); - // 6600-6700 - add(6600, 0, 0); - add(GET_MAP_SURFACE_NAME_BY_ID, "get_map_surface_name_by_id", 1, 0, 0, 1); - add(SET_CURRENT_MAP_SURFACE, "set_current_map_surface", 1, 0); - add(GET_CURRENT_MAP_ZOOM, "get_current_map_zoom", 0, 1); - add(SET_CURRENT_MAP_ZOOM, "set_current_map_zoom", 1, 0); - add(6605, 0, 1); - add(SET_MAP_POSITION, "set_map_position", 1, 0); - add(SET_MAP_POSITION_IMMEDIATE, "set_map_position_immediate", 1, 0); - add(SET_MAP_POSITION_2, "set_map_position_2", 1, 0); - add(SET_MAP_POSITION_IMMEDIATE_2, "set_map_position_immediate_2", 1, 0); - add(GET_MAP_POSITION, "get_map_position", 0, 2); - add(GET_MAP_DEFAULT_POSITION_BY_ID, "get_map_default_position_by_id", 1, 1); - add(GET_MAP_DIMENSIONS_BY_ID, "get_map_dimensions_by_id", 1, 2); - add(GET_MAP_BOUNDS_BY_ID, "get_map_bounds_by_id", 1, 4); - add(GET_MAP_INITAL_ZOOM_BY_ID, "get_map_inital_zoom_by_id", 1, 1); - add(6615, 2, 2); - add(GET_CURRENT_MAP_ID, "get_current_map_id", 0, 1); - add(6617, 1, 2); - // 6618 variable - add(6619, 2, 1); - add(6620, 2, 1); - add(MAP_ID_CONTAINS_COORD, "map_id_contains_coord", 2, 1); - add(GET_MAP_DISPLAY_DIMENSIONS, "get_map_display_dimensions", 0, 2); - add(GET_MAP_ID_CONTAINING_COORD, "get_map_id_containing_coord", 1, 1); - add(SET_MAP_ICON_FLASH_COUNT, "set_map_icon_flash_count", 1, 0); - add(RESET_MAP_ICON_FLASH_COUNT, "reset_map_icon_flash_count", 0, 0); - add(SET_MAP_ICON_FLASH_PERIOD, "set_map_icon_flash_period", 1, 0); - add(RESET_MAP_ICON_FLASH_PERIOD, "reset_map_icon_flash_period", 0, 0); - add(SET_MAP_ICON_FLASH_FOREVER, "set_map_icon_flash_forever", 1, 0); - add(FLASH_MAP_ICONS_BY_ID, "flash_map_icons_by_id", 1, 0); - add(FLASH_MAP_ICONS_BY_GROUP, "flash_map_icons_by_group", 1, 0); - add(CLEAR_FLASHING_ICONS, "clear_flashing_icons", 0, 0); - add(SET_MAP_ICONS_DISABLED, "set_map_icons_disabled", 1, 0); - add(SET_MAP_ICONS_ENABLED_BY_ID, "set_map_icons_enabled_by_id", 2, 0); - add(SET_MAP_ICONS_ENABLED_BY_GROUP, "set_map_icons_enabled_by_group", 2, 0); - add(GET_MAP_ICONS_DISABLED, "get_map_icons_disabled", 0, 1); - add(GET_MAP_ICONS_ENABLED_BY_ID, "get_map_icons_enabled_by_id", 1, 1); - add(GET_MAP_ICONS_ENABLED_BY_GROUP, "get_map_icons_enabled_by_group", 1, 1); - add(6638, 2, 1); - add(GET_FIRST_MAP_ICON, "get_first_map_icon", 0, 2); - add(GET_NEXT_MAP_ICON, "get_next_map_icon", 0, 2); - add(GET_MAPICON_NAME_BY_ID, "get_mapicon_name_by_id", 1, 0, 0, 1); - add(GET_MAPICON_FONT_SIZE, "get_mapicon_font_size", 1, 1); - add(GET_MAPICON_GROUP_BY_ID, "get_mapicon_group_by_id", 1, 1); - add(GET_MAPICON_SPRITE_BY_ID, "get_mapicon_sprite_by_id", 1, 1); - add(GET_CURRENT_MAPICON_ID, "get_current_mapicon_id", 0, 1); - add(GET_CURRENT_MAPICON_COORD, "get_current_mapicon_coord", 0, 1); - add(GET_CURRENT_MAPICON_OTHER_COORD, "get_current_mapicon_other_coord", 0, 1); + add(ICONST, "iconst"); + add(GET_VARP, "get_varp"); + add(SET_VARP, "set_varp"); + add(SCONST, "sconst"); + add(JUMP, "jump"); + add(IF_ICMPNE, "if_icmpne"); + add(IF_ICMPEQ, "if_icmpeq"); + add(IF_ICMPLT, "if_icmplt"); + add(IF_ICMPGT, "if_icmpgt"); + add(RETURN, "return"); + add(GET_VARBIT, "get_varbit"); + add(SET_VARBIT, "set_varbit"); + add(IF_ICMPLE, "if_icmple"); + add(IF_ICMPGE, "if_icmpge"); + add(ILOAD, "iload"); + add(ISTORE, "istore"); + add(SLOAD, "sload"); + add(SSTORE, "sstore"); + add(JOIN_STRING, "join_string"); + add(POP_INT, "pop_int"); + add(POP_STRING, "pop_string"); + add(INVOKE, "invoke"); + add(GET_VARC_INT, "get_varc_int"); + add(SET_VARC_INT, "set_varc_int"); + add(DEFINE_ARRAY, "define_array"); + add(GET_ARRAY_INT, "get_array_int"); + add(SET_ARRAY_INT, "set_array_int"); + add(GET_VARC_STRING_OLD, "get_varc_string_old"); + add(SET_VARC_STRING_OLD, "set_varc_string_old"); + add(GET_VARC_STRING, "get_varc_string"); + add(SET_VARC_STRING, "set_varc_string"); + add(SWITCH, "switch"); + add(CC_CREATE, "cc_create"); + add(CC_DELETE, "cc_delete"); + add(CC_DELETEALL, "cc_deleteall"); + add(CC_FIND, "cc_find"); + add(IF_FIND, "if_find"); + add(CC_SETPOSITION, "cc_setposition"); + add(CC_SETSIZE, "cc_setsize"); + add(CC_SETHIDE, "cc_sethide"); + add(CC_SETNOCLICKTHROUGH, "cc_setnoclickthrough"); + add(CC_SETSCROLLPOS, "cc_setscrollpos"); + add(CC_SETCOLOUR, "cc_setcolour"); + add(CC_SETFILL, "cc_setfill"); + add(CC_SETTRANS, "cc_settrans"); + add(CC_SETLINEWID, "cc_setlinewid"); + add(CC_SETGRAPHIC, "cc_setgraphic"); + add(CC_SET2DANGLE, "cc_set2dangle"); + add(CC_SETTILING, "cc_settiling"); + add(CC_SETMODEL, "cc_setmodel"); + add(CC_SETMODELANGLE, "cc_setmodelangle"); + add(CC_SETMODELANIM, "cc_setmodelanim"); + add(CC_SETMODELORTHOG, "cc_setmodelorthog"); + add(CC_SETTEXT, "cc_settext"); + add(CC_SETTEXTFONT, "cc_settextfont"); + add(CC_SETTEXTALIGN, "cc_settextalign"); + add(CC_SETTEXTSHADOW, "cc_settextshadow"); + add(CC_SETOUTLINE, "cc_setoutline"); + add(CC_SETGRAPHICSHADOW, "cc_setgraphicshadow"); + add(CC_SETVFLIP, "cc_setvflip"); + add(CC_SETHFLIP, "cc_sethflip"); + add(CC_SETSCROLLSIZE, "cc_setscrollsize"); + add(CC_RESUME_PAUSEBUTTON, "cc_resume_pausebutton"); + add(CC_SETFILLCOLOUR, "cc_setfillcolour"); + add(CC_SETLINEDIRECTION, "cc_setlinedirection"); + add(CC_SETOBJECT, "cc_setobject"); + add(CC_SETNPCHEAD, "cc_setnpchead"); + add(CC_SETPLAYERHEAD_SELF, "cc_setplayerhead_self"); + add(CC_SETOBJECT_NONUM, "cc_setobject_nonum"); + add(CC_SETOBJECT_ALWAYS_NUM, "cc_setobject_always_num"); + add(CC_SETOP, "cc_setop"); + add(CC_SETDRAGGABLE, "cc_setdraggable"); + add(CC_SETDRAGGABLEBEHAVIOR, "cc_setdraggablebehavior"); + add(CC_SETDRAGDEADZONE, "cc_setdragdeadzone"); + add(CC_SETDRAGDEADTIME, "cc_setdragdeadtime"); + add(CC_SETOPBASE, "cc_setopbase"); + add(CC_SETTARGETVERB, "cc_settargetverb"); + add(CC_CLEAROPS, "cc_clearops"); + add(CC_SETONCLICK, "cc_setonclick"); + add(CC_SETONHOLD, "cc_setonhold"); + add(CC_SETONRELEASE, "cc_setonrelease"); + add(CC_SETONMOUSEOVER, "cc_setonmouseover"); + add(CC_SETONMOUSELEAVE, "cc_setonmouseleave"); + add(CC_SETONDRAG, "cc_setondrag"); + add(CC_SETONTARGETLEAVE, "cc_setontargetleave"); + add(CC_SETONVARTRANSMIT, "cc_setonvartransmit"); + add(CC_SETONTIMER, "cc_setontimer"); + add(CC_SETONOP, "cc_setonop"); + add(CC_SETONDRAGCOMPLETE, "cc_setondragcomplete"); + add(CC_SETONCLICKREPEAT, "cc_setonclickrepeat"); + add(CC_SETONMOUSEREPEAT, "cc_setonmouserepeat"); + add(CC_SETONINVTRANSMIT, "cc_setoninvtransmit"); + add(CC_SETONSTATTRANSMIT, "cc_setonstattransmit"); + add(CC_SETONTARGETENTER, "cc_setontargetenter"); + add(CC_SETONSCROLLWHEEL, "cc_setonscrollwheel"); + add(CC_SETONCHATTRANSMIT, "cc_setonchattransmit"); + add(CC_SETONKEY, "cc_setonkey"); + add(CC_SETONFRIENDTRANSMIT, "cc_setonfriendtransmit"); + add(CC_SETONCLANTRANSMIT, "cc_setonclantransmit"); + add(CC_SETONMISCTRANSMIT, "cc_setonmisctransmit"); + add(CC_SETONDIALOGABORT, "cc_setondialogabort"); + add(CC_SETONSUBCHANGE, "cc_setonsubchange"); + add(CC_SETONSTOCKTRANSMIT, "cc_setonstocktransmit"); + add(CC_SETONRESIZE, "cc_setonresize"); + add(CC_GETX, "cc_getx"); + add(CC_GETY, "cc_gety"); + add(CC_GETWIDTH, "cc_getwidth"); + add(CC_GETHEIGHT, "cc_getheight"); + add(CC_GETHIDE, "cc_gethide"); + add(CC_GETLAYER, "cc_getlayer"); + add(CC_GETSCROLLX, "cc_getscrollx"); + add(CC_GETSCROLLY, "cc_getscrolly"); + add(CC_GETTEXT, "cc_gettext"); + add(CC_GETSCROLLWIDTH, "cc_getscrollwidth"); + add(CC_GETSCROLLHEIGHT, "cc_getscrollheight"); + add(CC_GETMODELZOOM, "cc_getmodelzoom"); + add(CC_GETMODELANGLE_X, "cc_getmodelangle_x"); + add(CC_GETMODELANGLE_Z, "cc_getmodelangle_z"); + add(CC_GETMODELANGLE_Y, "cc_getmodelangle_y"); + add(CC_GETTRANS, "cc_gettrans"); + add(CC_GETCOLOUR, "cc_getcolour"); + add(CC_GETFILLCOLOUR, "cc_getfillcolour"); + add(CC_GETINVOBJECT, "cc_getinvobject"); + add(CC_GETINVCOUNT, "cc_getinvcount"); + add(CC_GETID, "cc_getid"); + add(CC_GETTARGETMASK, "cc_gettargetmask"); + add(CC_GETOP, "cc_getop"); + add(CC_GETOPBASE, "cc_getopbase"); + add(CC_CALLONRESIZE, "cc_callonresize"); + add(IF_SETPOSITION, "if_setposition"); + add(IF_SETSIZE, "if_setsize"); + add(IF_SETHIDE, "if_sethide"); + add(IF_SETNOCLICKTHROUGH, "if_setnoclickthrough"); + add(IF_SETSCROLLPOS, "if_setscrollpos"); + add(IF_SETCOLOUR, "if_setcolour"); + add(IF_SETFILL, "if_setfill"); + add(IF_SETTRANS, "if_settrans"); + add(IF_SETLINEWID, "if_setlinewid"); + add(IF_SETGRAPHIC, "if_setgraphic"); + add(IF_SET2DANGLE, "if_set2dangle"); + add(IF_SETTILING, "if_settiling"); + add(IF_SETMODEL, "if_setmodel"); + add(IF_SETMODELANGLE, "if_setmodelangle"); + add(IF_SETMODELANIM, "if_setmodelanim"); + add(IF_SETMODELORTHOG, "if_setmodelorthog"); + add(IF_SETTEXT, "if_settext"); + add(IF_SETTEXTFONT, "if_settextfont"); + add(IF_SETTEXTALIGN, "if_settextalign"); + add(IF_SETTEXTSHADOW, "if_settextshadow"); + add(IF_SETOUTLINE, "if_setoutline"); + add(IF_SETGRAPHICSHADOW, "if_setgraphicshadow"); + add(IF_SETVFLIP, "if_setvflip"); + add(IF_SETHFLIP, "if_sethflip"); + add(IF_SETSCROLLSIZE, "if_setscrollsize"); + add(IF_RESUME_PAUSEBUTTON, "if_resume_pausebutton"); + add(IF_SETFILLCOLOUR, "if_setfillcolour"); + add(IF_SETLINEDIRECTION, "if_setlinedirection"); + add(IF_SETOBJECT, "if_setobject"); + add(IF_SETNPCHEAD, "if_setnpchead"); + add(IF_SETPLAYERHEAD_SELF, "if_setplayerhead_self"); + add(IF_SETOBJECT_NONUM, "if_setobject_nonum"); + add(IF_SETOBJECT_ALWAYS_NUM, "if_setobject_always_num"); + add(IF_SETOP, "if_setop"); + add(IF_SETDRAGGABLE, "if_setdraggable"); + add(IF_SETDRAGGABLEBEHAVIOR, "if_setdraggablebehavior"); + add(IF_SETDRAGDEADZONE, "if_setdragdeadzone"); + add(IF_SETDRAGDEADTIME, "if_setdragdeadtime"); + add(IF_SETOPBASE, "if_setopbase"); + add(IF_SETTARGETVERB, "if_settargetverb"); + add(IF_CLEAROPS, "if_clearops"); + add(IF_SETOPKEY, "if_setopkey"); + add(IF_SETOPTKEY, "if_setoptkey"); + add(IF_SETOPKEYRATE, "if_setopkeyrate"); + add(IF_SETOPTKEYRATE, "if_setoptkeyrate"); + add(IF_SETOPKEYIGNOREHELD, "if_setopkeyignoreheld"); + add(IF_SETOPTKEYIGNOREHELD, "if_setoptkeyignoreheld"); + add(IF_SETONCLICK, "if_setonclick"); + add(IF_SETONHOLD, "if_setonhold"); + add(IF_SETONRELEASE, "if_setonrelease"); + add(IF_SETONMOUSEOVER, "if_setonmouseover"); + add(IF_SETONMOUSELEAVE, "if_setonmouseleave"); + add(IF_SETONDRAG, "if_setondrag"); + add(IF_SETONTARGETLEAVE, "if_setontargetleave"); + add(IF_SETONVARTRANSMIT, "if_setonvartransmit"); + add(IF_SETONTIMER, "if_setontimer"); + add(IF_SETONOP, "if_setonop"); + add(IF_SETONDRAGCOMPLETE, "if_setondragcomplete"); + add(IF_SETONCLICKREPEAT, "if_setonclickrepeat"); + add(IF_SETONMOUSEREPEAT, "if_setonmouserepeat"); + add(IF_SETONINVTRANSMIT, "if_setoninvtransmit"); + add(IF_SETONSTATTRANSMIT, "if_setonstattransmit"); + add(IF_SETONTARGETENTER, "if_setontargetenter"); + add(IF_SETONSCROLLWHEEL, "if_setonscrollwheel"); + add(IF_SETONCHATTRANSMIT, "if_setonchattransmit"); + add(IF_SETONKEY, "if_setonkey"); + add(IF_SETONFRIENDTRANSMIT, "if_setonfriendtransmit"); + add(IF_SETONCLANTRANSMIT, "if_setonclantransmit"); + add(IF_SETONMISCTRANSMIT, "if_setonmisctransmit"); + add(IF_SETONDIALOGABORT, "if_setondialogabort"); + add(IF_SETONSUBCHANGE, "if_setonsubchange"); + add(IF_SETONSTOCKTRANSMIT, "if_setonstocktransmit"); + add(IF_SETONRESIZE, "if_setonresize"); + add(IF_GETX, "if_getx"); + add(IF_GETY, "if_gety"); + add(IF_GETWIDTH, "if_getwidth"); + add(IF_GETHEIGHT, "if_getheight"); + add(IF_GETHIDE, "if_gethide"); + add(IF_GETLAYER, "if_getlayer"); + add(IF_GETSCROLLX, "if_getscrollx"); + add(IF_GETSCROLLY, "if_getscrolly"); + add(IF_GETTEXT, "if_gettext"); + add(IF_GETSCROLLWIDTH, "if_getscrollwidth"); + add(IF_GETSCROLLHEIGHT, "if_getscrollheight"); + add(IF_GETMODELZOOM, "if_getmodelzoom"); + add(IF_GETMODELANGLE_X, "if_getmodelangle_x"); + add(IF_GETMODELANGLE_Z, "if_getmodelangle_z"); + add(IF_GETMODELANGLE_Y, "if_getmodelangle_y"); + add(IF_GETTRANS, "if_gettrans"); + add(IF_GETCOLOUR, "if_getcolour"); + add(IF_GETFILLCOLOUR, "if_getfillcolour"); + add(IF_GETINVOBJECT, "if_getinvobject"); + add(IF_GETINVCOUNT, "if_getinvcount"); + add(IF_HASSUB, "if_hassub"); + add(IF_GETTOP, "if_gettop"); + add(IF_GETTARGETMASK, "if_gettargetmask"); + add(IF_GETOP, "if_getop"); + add(IF_GETOPBASE, "if_getopbase"); + add(IF_CALLONRESIZE, "if_callonresize"); + add(MES, "mes"); + add(ANIM, "anim"); + add(IF_CLOSE, "if_close"); + add(RESUME_COUNTDIALOG, "resume_countdialog"); + add(RESUME_NAMEDIALOG, "resume_namedialog"); + add(RESUME_STRINGDIALOG, "resume_stringdialog"); + add(OPPLAYER, "opplayer"); + add(IF_DRAGPICKUP, "if_dragpickup"); + add(CC_DRAGPICKUP, "cc_dragpickup"); + add(MOUSECAM, "mousecam"); + add(GETREMOVEROOFS, "getremoveroofs"); + add(SETREMOVEROOFS, "setremoveroofs"); + add(OPENURL, "openurl"); + add(RESUME_OBJDIALOG, "resume_objdialog"); + add(BUG_REPORT, "bug_report"); + add(SETSHIFTCLICKDROP, "setshiftclickdrop"); + add(SETSHOWMOUSEOVERTEXT, "setshowmouseovertext"); + add(RENDERSELF, "renderself"); + add(SETSHOWMOUSECROSS, "setshowmousecross"); + add(SETSHOWLOADINGMESSAGES, "setshowloadingmessages"); + add(SETTAPTODROP, "settaptodrop"); + add(GETTAPTODROP, "gettaptodrop"); + add(GETCANVASSIZE, "getcanvassize"); + add(SETHIDEUSERNAME, "sethideusername"); + add(GETHIDEUSERNAME, "gethideusername"); + add(SETREMEMBERUSERNAME, "setrememberusername"); + add(GETREMEMBERUSERNAME, "getrememberusername"); + add(SOUND_SYNTH, "sound_synth"); + add(SOUND_SONG, "sound_song"); + add(SOUND_JINGLE, "sound_jingle"); + add(CLIENTCLOCK, "clientclock"); + add(INV_GETOBJ, "inv_getobj"); + add(INV_GETNUM, "inv_getnum"); + add(INV_TOTAL, "inv_total"); + add(INV_SIZE, "inv_size"); + add(STAT, "stat"); + add(STAT_BASE, "stat_base"); + add(STAT_XP, "stat_xp"); + add(COORD, "coord"); + add(COORDX, "coordx"); + add(COORDZ, "coordz"); + add(COORDY, "coordy"); + add(MAP_MEMBERS, "map_members"); + add(INVOTHER_GETOBJ, "invother_getobj"); + add(INVOTHER_GETNUM, "invother_getnum"); + add(INVOTHER_TOTAL, "invother_total"); + add(STAFFMODLEVEL, "staffmodlevel"); + add(REBOOTTIMER, "reboottimer"); + add(MAP_WORLD, "map_world"); + add(RUNENERGY_VISIBLE, "runenergy_visible"); + add(RUNWEIGHT_VISIBLE, "runweight_visible"); + add(PLAYERMOD, "playermod"); + add(WORLDFLAGS, "worldflags"); + add(MOVECOORD, "movecoord"); + add(ENUM_STRING, "enum_string"); + add(ENUM, "enum"); + add(ENUM_GETOUTPUTCOUNT, "enum_getoutputcount"); + add(FRIEND_COUNT, "friend_count"); + add(FRIEND_GETNAME, "friend_getname"); + add(FRIEND_GETWORLD, "friend_getworld"); + add(FRIEND_GETRANK, "friend_getrank"); + add(FRIEND_SETRANK, "friend_setrank"); + add(FRIEND_ADD, "friend_add"); + add(FRIEND_DEL, "friend_del"); + add(IGNORE_ADD, "ignore_add"); + add(IGNORE_DEL, "ignore_del"); + add(FRIEND_TEST, "friend_test"); + add(CLAN_GETCHATDISPLAYNAME, "clan_getchatdisplayname"); + add(CLAN_GETCHATCOUNT, "clan_getchatcount"); + add(CLAN_GETCHATUSERNAME, "clan_getchatusername"); + add(CLAN_GETCHATUSERWORLD, "clan_getchatuserworld"); + add(CLAN_GETCHATUSERRANK, "clan_getchatuserrank"); + add(CLAN_GETCHATMINKICK, "clan_getchatminkick"); + add(CLAN_KICKUSER, "clan_kickuser"); + add(CLAN_GETCHATRANK, "clan_getchatrank"); + add(CLAN_JOINCHAT, "clan_joinchat"); + add(CLAN_LEAVECHAT, "clan_leavechat"); + add(IGNORE_COUNT, "ignore_count"); + add(IGNORE_GETNAME, "ignore_getname"); + add(IGNORE_TEST, "ignore_test"); + add(CLAN_ISSELF, "clan_isself"); + add(CLAN_GETCHATOWNERNAME, "clan_getchatownername"); + add(CLAN_ISFRIEND, "clan_isfriend"); + add(CLAN_ISIGNORE, "clan_isignore"); + add(STOCKMARKET_GETOFFERTYPE, "stockmarket_getoffertype"); + add(STOCKMARKET_GETOFFERITEM, "stockmarket_getofferitem"); + add(STOCKMARKET_GETOFFERPRICE, "stockmarket_getofferprice"); + add(STOCKMARKET_GETOFFERCOUNT, "stockmarket_getoffercount"); + add(STOCKMARKET_GETOFFERCOMPLETEDCOUNT, "stockmarket_getoffercompletedcount"); + add(STOCKMARKET_GETOFFERCOMPLETEDGOLD, "stockmarket_getoffercompletedgold"); + add(STOCKMARKET_ISOFFEREMPTY, "stockmarket_isofferempty"); + add(STOCKMARKET_ISOFFERSTABLE, "stockmarket_isofferstable"); + add(STOCKMARKET_ISOFFERFINISHED, "stockmarket_isofferfinished"); + add(STOCKMARKET_ISOFFERADDING, "stockmarket_isofferadding"); + add(TRADINGPOST_SORTBY_NAME, "tradingpost_sortby_name"); + add(TRADINGPOST_SORTBY_PRICE, "tradingpost_sortby_price"); + add(TRADINGPOST_SORTFILTERBY_WORLD, "tradingpost_sortfilterby_world"); + add(TRADINGPOST_SORTBY_AGE, "tradingpost_sortby_age"); + add(TRADINGPOST_SORTBY_COUNT, "tradingpost_sortby_count"); + add(TRADINGPOST_GETTOTALOFFERS, "tradingpost_gettotaloffers"); + add(TRADINGPOST_GETOFFERWORLD, "tradingpost_getofferworld"); + add(TRADINGPOST_GETOFFERNAME, "tradingpost_getoffername"); + add(TRADINGPOST_GETOFFERPREVIOUSNAME, "tradingpost_getofferpreviousname"); + add(TRADINGPOST_GETOFFERAGE, "tradingpost_getofferage"); + add(TRADINGPOST_GETOFFERCOUNT, "tradingpost_getoffercount"); + add(TRADINGPOST_GETOFFERPRICE, "tradingpost_getofferprice"); + add(TRADINGPOST_GETOFFERITEM, "tradingpost_getofferitem"); + add(ADD, "add"); + add(SUB, "sub"); + add(MULTIPLY, "multiply"); + add(DIV, "div"); + add(RANDOM, "random"); + add(RANDOMINC, "randominc"); + add(INTERPOLATE, "interpolate"); + add(ADDPERCENT, "addpercent"); + add(SETBIT, "setbit"); + add(CLEARBIT, "clearbit"); + add(TESTBIT, "testbit"); + add(MOD, "mod"); + add(POW, "pow"); + add(INVPOW, "invpow"); + add(AND, "and"); + add(OR, "or"); + add(SCALE, "scale"); + add(APPEND_NUM, "append_num"); + add(APPEND, "append"); + add(APPEND_SIGNNUM, "append_signnum"); + add(LOWERCASE, "lowercase"); + add(FROMDATE, "fromdate"); + add(TEXT_GENDER, "text_gender"); + add(TOSTRING, "tostring"); + add(COMPARE, "compare"); + add(PARAHEIGHT, "paraheight"); + add(PARAWIDTH, "parawidth"); + add(TEXT_SWITCH, "text_switch"); + add(ESCAPE, "escape"); + add(APPEND_CHAR, "append_char"); + add(CHAR_ISPRINTABLE, "char_isprintable"); + add(CHAR_ISALPHANUMERIC, "char_isalphanumeric"); + add(CHAR_ISALPHA, "char_isalpha"); + add(CHAR_ISNUMERIC, "char_isnumeric"); + add(STRING_LENGTH, "string_length"); + add(SUBSTRING, "substring"); + add(REMOVETAGS, "removetags"); + add(STRING_INDEXOF_CHAR, "string_indexof_char"); + add(STRING_INDEXOF_STRING, "string_indexof_string"); + add(OC_NAME, "oc_name"); + add(OC_OP, "oc_op"); + add(OC_IOP, "oc_iop"); + add(OC_COST, "oc_cost"); + add(OC_STACKABLE, "oc_stackable"); + add(OC_CERT, "oc_cert"); + add(OC_UNCERT, "oc_uncert"); + add(OC_MEMBERS, "oc_members"); + add(OC_PLACEHOLDER, "oc_placeholder"); + add(OC_UNPLACEHOLDER, "oc_unplaceholder"); + add(OC_FIND, "oc_find"); + add(OC_FINDNEXT, "oc_findnext"); + add(OC_FINDRESET, "oc_findreset"); + add(CHAT_GETFILTER_PUBLIC, "chat_getfilter_public"); + add(CHAT_SETFILTER, "chat_setfilter"); + add(CHAT_SENDABUSEREPORT, "chat_sendabusereport"); + add(CHAT_GETHISTORY_BYTYPEANDLINE, "chat_gethistory_bytypeandline"); + add(CHAT_GETHISTORY_BYUID, "chat_gethistory_byuid"); + add(CHAT_GETFILTER_PRIVATE, "chat_getfilter_private"); + add(CHAT_SENDPUBLIC, "chat_sendpublic"); + add(CHAT_SENDPRIVATE, "chat_sendprivate"); + add(CHAT_PLAYERNAME, "chat_playername"); + add(CHAT_GETFILTER_TRADE, "chat_getfilter_trade"); + add(CHAT_GETHISTORYLENGTH, "chat_gethistorylength"); + add(CHAT_GETNEXTUID, "chat_getnextuid"); + add(CHAT_GETPREVUID, "chat_getprevuid"); + add(DOCHEAT, "docheat"); + add(CHAT_SETMESSAGEFILTER, "chat_setmessagefilter"); + add(CHAT_GETMESSAGEFILTER, "chat_getmessagefilter"); + add(GETWINDOWMODE, "getwindowmode"); + add(SETWINDOWMODE, "setwindowmode"); + add(GETDEFAULTWINDOWMODE, "getdefaultwindowmode"); + add(SETDEFAULTWINDOWMODE, "setdefaultwindowmode"); + add(CAM_FORCEANGLE, "cam_forceangle"); + add(CAM_GETANGLE_XA, "cam_getangle_xa"); + add(CAM_GETANGLE_YA, "cam_getangle_ya"); + add(CAM_SETFOLLOWHEIGHT, "cam_setfollowheight"); + add(CAM_GETFOLLOWHEIGHT, "cam_getfollowheight"); + add(LOGOUT, "logout"); + add(VIEWPORT_SETFOV, "viewport_setfov"); + add(VIEWPORT_SETZOOM, "viewport_setzoom"); + add(VIEWPORT_CLAMPFOV, "viewport_clampfov"); + add(VIEWPORT_GETEFFECTIVESIZE, "viewport_geteffectivesize"); + add(VIEWPORT_GETZOOM, "viewport_getzoom"); + add(VIEWPORT_GETFOV, "viewport_getfov"); + add(WORLDLIST_FETCH, "worldlist_fetch"); + add(WORLDLIST_START, "worldlist_start"); + add(WORLDLIST_NEXT, "worldlist_next"); + add(WORLDLIST_SPECIFIC, "worldlist_specific"); + add(WORLDLIST_SORT, "worldlist_sort"); + add(SETFOLLOWEROPSLOWPRIORITY, "setfolloweropslowpriority"); + add(NC_PARAM, "nc_param"); + add(LC_PARAM, "lc_param"); + add(OC_PARAM, "oc_param"); + add(STRUCT_PARAM, "struct_param"); + add(ON_MOBILE, "on_mobile"); + add(CLIENTTYPE, "clienttype"); + add(BATTERYLEVEL, "batterylevel"); + add(BATTERYCHARGING, "batterycharging"); + add(WIFIAVAILABLE, "wifiavailable"); + add(WORLDMAP_GETMAPNAME, "worldmap_getmapname"); + add(WORLDMAP_SETMAP, "worldmap_setmap"); + add(WORLDMAP_GETZOOM, "worldmap_getzoom"); + add(WORLDMAP_SETZOOM, "worldmap_setzoom"); + add(WORLDMAP_ISLOADED, "worldmap_isloaded"); + add(WORLDMAP_JUMPTODISPLAYCOORD, "worldmap_jumptodisplaycoord"); + add(WORLDMAP_JUMPTODISPLAYCOORD_INSTANT, "worldmap_jumptodisplaycoord_instant"); + add(WORLDMAP_JUMPTOSOURCECOORD, "worldmap_jumptosourcecoord"); + add(WORLDMAP_JUMPTOSOURCECOORD_INSTANT, "worldmap_jumptosourcecoord_instant"); + add(WORLDMAP_GETDISPLAYPOSITION, "worldmap_getdisplayposition"); + add(WORLDMAP_GETCONFIGORIGIN, "worldmap_getconfigorigin"); + add(WORLDMAP_GETCONFIGSIZE, "worldmap_getconfigsize"); + add(WORLDMAP_GETCONFIGBOUNDS, "worldmap_getconfigbounds"); + add(WORLDMAP_GETCONFIGZOOM, "worldmap_getconfigzoom"); + add(WORLDMAP_GETCURRENTMAP, "worldmap_getcurrentmap"); + add(WORLDMAP_GETDISPLAYCOORD, "worldmap_getdisplaycoord"); + add(WORLDMAP_COORDINMAP, "worldmap_coordinmap"); + add(WORLDMAP_GETSIZE, "worldmap_getsize"); + add(WORLDMAP_PERPETUALFLASH, "worldmap_perpetualflash"); + add(WORLDMAP_FLASHELEMENT, "worldmap_flashelement"); + add(WORLDMAP_FLASHELEMENTCATEGORY, "worldmap_flashelementcategory"); + add(WORLDMAP_STOPCURRENTFLASHES, "worldmap_stopcurrentflashes"); + add(WORLDMAP_DISABLEELEMENTS, "worldmap_disableelements"); + add(WORLDMAP_DISABLEELEMENT, "worldmap_disableelement"); + add(WORLDMAP_DISABLEELEMENTCATEGORY, "worldmap_disableelementcategory"); + add(WORLDMAP_GETDISABLEELEMENTS, "worldmap_getdisableelements"); + add(WORLDMAP_GETDISABLEELEMENT, "worldmap_getdisableelement"); + add(WORLDMAP_GETDISABLEELEMENTCATEGORY, "worldmap_getdisableelementcategory"); + add(WORLDMAP_LISTELEMENT_START, "worldmap_listelement_start"); + add(WORLDMAP_LISTELEMENT_NEXT, "worldmap_listelement_next"); + add(MEC_TEXT, "mec_text"); + add(MEC_TEXTSIZE, "mec_textsize"); + add(MEC_CATEGORY, "mec_category"); + add(MEC_SPRITE, "mec_sprite"); } - protected void add(int opcode, String name, int ipops, int ipushes, int spops, int spushes) + protected void add(int opcode, String name) { Instruction i = new Instruction(opcode); i.setName(name); - i.setIntStackPops(ipops); - i.setIntStackPushes(ipushes); - i.setStringStackPops(spops); - i.setStringStackPushes(spushes); assert instructions.containsKey(opcode) == false; instructions.put(opcode, i); @@ -554,21 +522,6 @@ public class Instructions } } - protected void add(int opcode, int ipops, int ipushes) - { - add(opcode, null, ipops, ipushes, 0, 0); - } - - protected void add(int opcode, int ipops, int ipushes, int spops, int spushes) - { - add(opcode, null, ipops, ipushes, spops, spushes); - } - - protected void add(int opcode, String name, int ipops, int ipushes) - { - add(opcode, name, ipops, ipushes, 0, 0); - } - public Instruction find(int opcode) { return instructions.get(opcode); diff --git a/cache/src/main/java/net/runelite/cache/script/Opcodes.java b/cache/src/main/java/net/runelite/cache/script/Opcodes.java index 3e67e115df..e69a1ef5ef 100644 --- a/cache/src/main/java/net/runelite/cache/script/Opcodes.java +++ b/cache/src/main/java/net/runelite/cache/script/Opcodes.java @@ -1,5 +1,7 @@ /* * Copyright (c) 2017, Adam + * Copyright (c) 2018-2019, Hunter WB + * Copyright (c) 2019, Abex * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,10 +28,10 @@ package net.runelite.cache.script; public class Opcodes { - public static final int LOAD_INT = 0; + public static final int ICONST = 0; public static final int GET_VARP = 1; - public static final int PUT_VARP = 2; - public static final int LOAD_STRING = 3; + public static final int SET_VARP = 2; + public static final int SCONST = 3; public static final int JUMP = 6; public static final int IF_ICMPNE = 7; public static final int IF_ICMPEQ = 8; @@ -44,374 +46,454 @@ public class Opcodes public static final int ISTORE = 34; public static final int SLOAD = 35; public static final int SSTORE = 36; - public static final int STRING_APPEND = 37; + public static final int JOIN_STRING = 37; public static final int POP_INT = 38; public static final int POP_STRING = 39; public static final int INVOKE = 40; - public static final int GET_VARC = 42; - public static final int PUT_VARC = 43; - public static final int ARRAY_INITIALIZE = 44; - public static final int ARRAY_LOAD = 45; - public static final int ARRAY_STORE = 46; - public static final int GET_VARC_STRING = 47; - public static final int PUT_VARC_STRING = 48; + public static final int GET_VARC_INT = 42; + public static final int SET_VARC_INT = 43; + public static final int DEFINE_ARRAY = 44; + public static final int GET_ARRAY_INT = 45; + public static final int SET_ARRAY_INT = 46; + public static final int GET_VARC_STRING_OLD = 47; + public static final int SET_VARC_STRING_OLD = 48; + public static final int GET_VARC_STRING = 49; + public static final int SET_VARC_STRING = 50; public static final int SWITCH = 60; - public static final int WIDGET_CREATE_CHILD = 100; - public static final int WIDGET_DESTROY_CHILD = 101; - public static final int WIDGET_UNSET_CHILDREN = 102; - public static final int WIDGET_LOAD_CHILD = 200; - public static final int WIDGET_LOAD = 201; - public static final int WIDGET_PUT_POSITION = 1000; - public static final int WIDGET_PUT_SIZE = 1001; - public static final int WIDGET_PUT_HIDDEN = 1003; - public static final int WIDGET_PUT_NO_CLICK_THROUGH = 1005; - public static final int WIDGET_PUT_SCROLL = 1100; - public static final int WIDGET_PUT_TEXTCOLOR = 1101; - public static final int WIDGET_PUT_FILLED = 1102; - public static final int WIDGET_PUT_OPACITY = 1103; - public static final int WIDGET_PUT_LINE_WIDTH = 1104; - public static final int WIDGET_PUT_SPRITEID = 1105; - public static final int WIDGET_PUT_TEXTUREID = 1106; - public static final int WIDGET_PUT_SPRITE_TILING = 1107; - public static final int WIDGET_PUT_MODELID_1 = 1108; - public static final int WIDGET_PUT_3D_ROTATION = 1109; - public static final int WIDGET_PUT_ANIMATION = 1110; - public static final int WIDGET_PUT_TEXT = 1112; - public static final int WIDGET_PUT_FONTID = 1113; - public static final int WIDGET_PUT_TEXT_ALIGNMENT = 1114; - public static final int WIDGET_PUT_TEXT_SHADOWED = 1115; - public static final int WIDGET_PUT_BORDERTHICKNESS = 1116; - public static final int WIDGET_PUT_SPRITE2 = 1117; - public static final int WIDGET_PUT_FLIPPEDVERTICALLY = 1118; - public static final int WIDGET_PUT_FLIPPEDHORIZONALLY = 1119; - public static final int WIDGET_PUT_SCROLLWIDTHHEIGHT = 1120; - public static final int WIDGET_ADVANCE_DIALOGUE = 1121; - public static final int WIDGET_PUT_MODELID_2 = 1201; - public static final int WIDGET_PUT_MODELID_3 = 1202; - public static final int WIDGET_PUT_ACTION = 1300; - public static final int WIDGET_PUT_DRAG_PARENT = 1301; - public static final int WIDGET_PUT_NAME = 1305; - public static final int WIDGET_PUT_SELECTED_ACTION = 1306; - public static final int WIDGET_PUT_ACTIONS_NULL = 1307; - public static final int WIDGET_PUT_MOUSE_PRESS_LISTENER = 1400; - public static final int WIDGET_PUT_DRAGGED_OVER_LISTENER = 1401; - public static final int WIDGET_PUT_MOUSE_RELEASE_LISTENER = 1402; - public static final int WIDGET_PUT_MOUSE_ENTER_LISTENER = 1403; - public static final int WIDGET_PUT_MOUSE_EXIT_LISTENER = 1404; - public static final int WIDGET_PUT_DRAG_START_LISTENER = 1405; - public static final int WIDGET_PUT_USE_WITH_LISTENER = 1406; - public static final int WIDGET_PUT_CONFIG_LISTENER = 1407; - public static final int WIDGET_PUT_RENDER_LISTENER = 1408; - public static final int WIDGET_PUT_OPTION_CLICK_LISTENER = 1409; - public static final int WIDGET_PUT_DRAG_RELEASE_LISTENER = 1410; - public static final int WIDGET_PUT_DRAG_LISTENER = 1411; - public static final int WIDGET_PUT_MOUSE_HOVER_LISTENER = 1412; - public static final int WIDGET_PUT_TABLE_LISTENER = 1414; - public static final int WIDGET_PUT_SKILL_LISTENER = 1415; - public static final int WIDGET_PUT_USE_LISTENER = 1416; - public static final int WIDGET_PUT_SCROLL_LISTENER = 1417; - public static final int WIDGET_PUT_MSG_LISTENER = 1418; - public static final int WIDGET_PUT_KEY_LISTENER = 1419; - public static final int WIDGET_PUT_FRIENDS_LISTENER = 1420; - public static final int WIDGET_PUT_CLAN_LISTENER = 1421; - public static final int WIDGET_PUT_DIALOG_ABORT_LISTENER = 1423; - public static final int WIDGET_PUT_OPENCLOSE_LISTENER = 1424; - public static final int WIDGET_PUT_GE_LISTENER = 1425; - public static final int WIDGET_PUT_RESIZE_LISTENER = 1427; - public static final int WIDGET_GET_RELATIVEX = 1500; - public static final int WIDGET_GET_RELATIVEY = 1501; - public static final int WIDGET_GET_WIDTH = 1502; - public static final int WIDGET_GET_HEIGHT = 1503; - public static final int WIDGET_GET_HIDDEN = 1504; - public static final int WIDGET_GET_PARENTID = 1505; - public static final int WIDGET_GET_SCROLLX = 1600; - public static final int WIDGET_GET_SCROLLY = 1601; - public static final int WIDGET_GET_TEXT = 1602; - public static final int WIDGET_GET_SCROLLWIDTH = 1603; - public static final int WIDGET_GET_SCROLLHEIGHT = 1604; - public static final int WIDGET_GET_MODELZOOM = 1605; - public static final int WIDGET_GET_ROTATIONX = 1606; - public static final int WIDGET_GET_ROTATIONY = 1607; - public static final int WIDGET_GET_ROTATIONZ = 1608; - public static final int WIDGET_GET_OPACITY = 1609; - public static final int WIDGET_GET_TEXTCOLOR = 1611; - public static final int WIDGET_GET_ITEMID = 1700; - public static final int WIDGET_GET_STACKSIZE = 1701; - public static final int WIDGET_GET_INDEX = 1702; - public static final int WIDGET_GET_CONFIG = 1800; - public static final int WIDGET_GET_ACTION = 1801; - public static final int WIDGET_GET_NAME = 1802; - public static final int WIDGET_PUT_POSITION_WIDGET = WIDGET_PUT_POSITION + 1000; - public static final int WIDGET_PUT_SIZE_WIDGET = WIDGET_PUT_SIZE + 1000; - public static final int WIDGET_PUT_HIDDEN_WIDGET = WIDGET_PUT_HIDDEN + 1000; - public static final int WIDGET_PUT_NO_CLICK_THROUGH_WIDGET = WIDGET_PUT_NO_CLICK_THROUGH + 1000; - public static final int WIDGET_PUT_SCROLL_WIDGET = WIDGET_PUT_SCROLL + 1000; - public static final int WIDGET_PUT_TEXTCOLOR_WIDGET = WIDGET_PUT_TEXTCOLOR + 1000; - public static final int WIDGET_PUT_FILLED_WIDGET = WIDGET_PUT_FILLED + 1000; - public static final int WIDGET_PUT_OPACITY_WIDGET = WIDGET_PUT_OPACITY + 1000; - public static final int WIDGET_PUT_LINE_WIDTH_WIDGET = WIDGET_PUT_LINE_WIDTH + 1000; - public static final int WIDGET_PUT_SPRITEID_WIDGET = WIDGET_PUT_SPRITEID + 1000; - public static final int WIDGET_PUT_TEXTUREID_WIDGET = WIDGET_PUT_TEXTUREID + 1000; - public static final int WIDGET_PUT_SPRITE_TILING_WIDGET = WIDGET_PUT_SPRITE_TILING + 1000; - public static final int WIDGET_PUT_MODELID_1_WIDGET = WIDGET_PUT_MODELID_1 + 1000; - public static final int WIDGET_PUT_3D_ROTATION_WIDGET = WIDGET_PUT_3D_ROTATION + 1000; - public static final int WIDGET_PUT_ANIMATION_WIDGET = WIDGET_PUT_ANIMATION + 1000; - public static final int WIDGET_PUT_TEXT_WIDGET = WIDGET_PUT_TEXT + 1000; - public static final int WIDGET_PUT_FONTID_WIDGET = WIDGET_PUT_FONTID + 1000; - public static final int WIDGET_PUT_TEXT_ALIGNMENT_WIDGET = WIDGET_PUT_TEXT_ALIGNMENT + 1000; - public static final int WIDGET_PUT_TEXT_SHADOWED_WIDGET = WIDGET_PUT_TEXT_SHADOWED + 1000; - public static final int WIDGET_PUT_BORDERTHICKNESS_WIDGET = WIDGET_PUT_BORDERTHICKNESS + 1000; - public static final int WIDGET_PUT_SPRITE2_WIDGET = WIDGET_PUT_SPRITE2 + 1000; - public static final int WIDGET_PUT_FLIPPEDVERTICALLY_WIDGET = WIDGET_PUT_FLIPPEDVERTICALLY + 1000; - public static final int WIDGET_PUT_FLIPPEDHORIZONALLY_WIDGET = WIDGET_PUT_FLIPPEDHORIZONALLY + 1000; - public static final int WIDGET_PUT_SCROLLWIDTHHEIGHT_WIDGET = WIDGET_PUT_SCROLLWIDTHHEIGHT + 1000; - public static final int WIDGET_ADVANCE_DIALOGUE_WIDGET = WIDGET_ADVANCE_DIALOGUE + 1000; - public static final int WIDGET_PUT_MODELID_2_WIDGET = WIDGET_PUT_MODELID_2 + 1000; - public static final int WIDGET_PUT_MODELID_3_WIDGET = WIDGET_PUT_MODELID_3 + 1000; - public static final int WIDGET_PUT_ACTION_WIDGET = WIDGET_PUT_ACTION + 1000; - public static final int WIDGET_PUT_DRAG_PARENT_WIDGET = WIDGET_PUT_DRAG_PARENT + 1000; - public static final int WIDGET_PUT_NAME_WIDGET = WIDGET_PUT_NAME + 1000; - public static final int WIDET_PUT_SELECTED_ACTION_WIDGET = WIDGET_PUT_SELECTED_ACTION + 1000; - public static final int WIDGET_PUT_ACTIONS_NULL_WIDGET = WIDGET_PUT_ACTIONS_NULL + 1000; - public static final int WIDGET_PUT_MOUSE_PRESS_LISTENER_WIDGET = WIDGET_PUT_MOUSE_PRESS_LISTENER + 1000; - public static final int WIDGET_PUT_DRAGGED_OVER_LISTENER_WIDGET = WIDGET_PUT_DRAGGED_OVER_LISTENER + 1000; - public static final int WIDGET_PUT_MOUSE_RELEASE_LISTENER_WIDGET = WIDGET_PUT_MOUSE_RELEASE_LISTENER + 1000; - public static final int WIDGET_PUT_MOUSE_ENTER_LISTENER_WIDGET = WIDGET_PUT_MOUSE_ENTER_LISTENER + 1000; - public static final int WIDGET_PUT_MOUSE_EXIT_LISTENER_WIDGET = WIDGET_PUT_MOUSE_EXIT_LISTENER + 1000; - public static final int WIDGET_PUT_DRAG_START_LISTENER_WIDGET = WIDGET_PUT_DRAG_START_LISTENER + 1000; - public static final int WIDGET_PUT_USE_WITH_LISTENER_WIDGET = WIDGET_PUT_USE_WITH_LISTENER + 1000; - public static final int WIDGET_PUT_CONFIG_LISTENER_WIDGET = WIDGET_PUT_CONFIG_LISTENER + 1000; - public static final int WIDGET_PUT_RENDER_LISTENER_WIDGET = WIDGET_PUT_RENDER_LISTENER + 1000; - public static final int WIDGET_PUT_OPTION_CLICK_LISTENER_WIDGET = WIDGET_PUT_OPTION_CLICK_LISTENER + 1000; - public static final int WIDGET_PUT_DRAG_RELEASE_LISTENER_WIDGET = WIDGET_PUT_DRAG_RELEASE_LISTENER + 1000; - public static final int WIDGET_PUT_DRAG_LISTENER_WIDGET = WIDGET_PUT_DRAG_LISTENER + 1000; - public static final int WIDGET_PUT_MOUSE_HOVER_LISTENER_WIDGET = WIDGET_PUT_MOUSE_HOVER_LISTENER + 1000; - public static final int WIDGET_PUT_TABLE_LISTENER_WIDGET = WIDGET_PUT_TABLE_LISTENER + 1000; - public static final int WIDGET_PUT_SKILL_LISTENER_WIDGET = WIDGET_PUT_SKILL_LISTENER + 1000; - public static final int WIDGET_PUT_USE_LISTENER_WIDGET = WIDGET_PUT_USE_LISTENER + 1000; - public static final int WIDGET_PUT_SCROLL_LISTENER_WIDGET = WIDGET_PUT_SCROLL_LISTENER + 1000; - public static final int WIDGET_PUT_MSG_LISTENER_WIDGET = WIDGET_PUT_MSG_LISTENER + 1000; - public static final int WIDGET_PUT_KEY_LISTENER_WIDGET = WIDGET_PUT_KEY_LISTENER + 1000; - public static final int WIDGET_PUT_FRIENDS_LISTENER_WIDGET = WIDGET_PUT_FRIENDS_LISTENER + 1000; - public static final int WIDGET_PUT_CLAN_LISTENER_WIDGET = WIDGET_PUT_CLAN_LISTENER + 1000; - public static final int WIDGET_PUT_DIALOG_ABORT_LISTENER_WIDGET = WIDGET_PUT_DIALOG_ABORT_LISTENER + 1000; - public static final int WIDGET_PUT_OPENCLOSE_LISTENER_WIDGET = WIDGET_PUT_OPENCLOSE_LISTENER + 1000; - public static final int WIDGET_PUT_GE_LISTENER_WIDGET = WIDGET_PUT_GE_LISTENER + 1000; - public static final int WIDGET_PUT_RESIZE_LISTENER_WIDGET = WIDGET_PUT_RESIZE_LISTENER + 1000; - public static final int WIDGET_GET_RELATIVEX_WIDGET = WIDGET_GET_RELATIVEX + 1000; - public static final int WIDGET_GET_RELATIVEY_WIDGET = WIDGET_GET_RELATIVEY + 1000; - public static final int WIDGET_GET_WIDTH_WIDGET = WIDGET_GET_WIDTH + 1000; - public static final int WIDGET_GET_HEIGHT_WIDGET = WIDGET_GET_HEIGHT + 1000; - public static final int WIDGET_GET_HIDDEN_WIDGET = WIDGET_GET_HIDDEN + 1000; - public static final int WIDGET_GET_PARENTID_WIDGET = WIDGET_GET_PARENTID + 1000; - public static final int WIDGET_GET_SCROLLX_WIDGET = WIDGET_GET_SCROLLX + 1000; - public static final int WIDGET_GET_SCROLLY_WIDGET = WIDGET_GET_SCROLLY + 1000; - public static final int WIDGET_GET_TEXT_WIDGET = WIDGET_GET_TEXT + 1000; - public static final int WIDGET_GET_SCROLLWIDTH_WIDGET = WIDGET_GET_SCROLLWIDTH + 1000; - public static final int WIDGET_GET_SCROLLHEIGHT_WIDGET = WIDGET_GET_SCROLLHEIGHT + 1000; - public static final int WIDGET_GET_MODELZOOM_WIDGET = WIDGET_GET_MODELZOOM + 1000; - public static final int WIDGET_GET_ROTATIONX_WIDGET = WIDGET_GET_ROTATIONX + 1000; - public static final int WIDGET_GET_ROTATIONY_WIDGET = WIDGET_GET_ROTATIONY + 1000; - public static final int WIDGET_GET_ROTATIONZ_WIDGET = WIDGET_GET_ROTATIONZ + 1000; - public static final int WIDGET_GET_OPACITY_WIDGET = WIDGET_GET_OPACITY + 1000; - public static final int WIDGET_GET_TEXTCOLOR_WIDGET = WIDGET_GET_TEXTCOLOR + 1000; - public static final int WIDGET_GET_ITEMID_WIDGET = WIDGET_GET_ITEMID + 1000; - public static final int WIDGET_GET_STACKSIZE_WIDGET = WIDGET_GET_STACKSIZE + 1000; - public static final int WIGET_GET_INDEX_WIDGET = WIDGET_GET_INDEX + 1000; - public static final int GET_WIDGET_ROOT = 2706; - public static final int WIDGET_GET_CONFIG_WIGET = WIDGET_GET_CONFIG + 1000; - public static final int WIDGET_GET_ACTION_WIDGET = WIDGET_GET_ACTION + 1000; - public static final int WIDGET_GET_NAME_WIDGET = WIDGET_GET_NAME + 1000; - public static final int SEND_GAME_MESSAGE = 3100; - public static final int PLAYER_ANIMATE = 3101; - public static final int CLOSE_WINDOW = 3103; - public static final int NUMERIC_INPUT = 3104; - public static final int STRING_INPUT_1 = 3105; - public static final int STRING_INPUT_2 = 3106; - public static final int PLAYER_ACTION = 3107; - public static final int SET_TOP_CONTEXT_MENU_ROW = 3108; - public static final int SET_TOP_CONTEXT_MENU_ROW_2 = 3109; - public static final int SET_MOUSE_BUTTON_CONTROLS_CAMERA = 3110; - public static final int GET_HIDEROOFS = 3111; - public static final int SET_HIDEROOFS = 3112; - public static final int OPEN_URL = 3113; - public static final int ITEM_PRICE = 3115; - public static final int SEND_BUG_REPORT = 3116; - public static final int SET_SHIFT_DROP_ENABLED = 3117; - public static final int SET_CONNECTION_TEXT_ENABLED = 3126; - public static final int PLAY_SOUND_EFFECT = 3200; - public static final int GET_GAMECYCLE = 3300; - public static final int GET_ITEMCONTAINER_ITEMID = 3301; - public static final int GET_ITEMCONTAINER_STACKSIZE = 3302; - public static final int GET_ITEMCONTAINER_STACKSIZES_TOTAL = 3303; - public static final int GET_INVENTORY_SIZE = 3304; - public static final int GET_BOOSTEDSKILLLEVELS = 3305; - public static final int GET_REALSKILLLEVELS = 3306; - public static final int GET_SKILLEXPERIENCES = 3307; - public static final int GET_COORDINATES = 3308; - public static final int DIVIDE_BY_16384 = 3309; - public static final int RIGHT_SHIFT_28 = 3310; - public static final int AND_16384 = 3311; - public static final int GET_ISMEMBERS = 3312; - public static final int GET_ITEMCONTAINER_ITEMID_2 = 3313; - public static final int GET_ITEMCONTAINER_STACKSIZE_2 = 3314; - public static final int GET_ITEMCONTAINER_STACKSIZES_TOTAL_2 = 3315; - public static final int GET_RIGHTS = 3316; - public static final int GET_SYSTEM_UPDATE_TIMER = 3317; - public static final int GET_WORLDNUM = 3318; - public static final int GET_ENERGY = 3321; - public static final int GET_WEIGHT = 3322; - public static final int GET_PLAYERMOD = 3323; - public static final int GET_FLAGS = 3324; - public static final int PACK_LOCATION = 3325; - public static final int GET_ENUM_VALUE = 3408; - public static final int GET_FRIENDCOUNT = 3600; - public static final int GET_FRIEND = 3601; - public static final int GET_FRIEND_WORLD = 3602; - public static final int GET_FRIEND_RANK = 3603; - public static final int ADD_FRIEND = 3605; - public static final int REMOVE_FRIEND = 3606; - public static final int ADD_IGNORE = 3607; - public static final int REMOVE_IGNORE = 3608; - public static final int IS_FRIEND = 3609; - public static final int GET_CLANCHAT_OWNER = 3611; - public static final int GET_CLANCHATCOUNT = 3612; - public static final int GET_CLAN_MEMBER_NAME = 3613; - public static final int GET_CLAN_MEMBER_WORLD = 3614; - public static final int GET_CLAN_MEMBER_RANK = 3615; - public static final int CLANCHAT_KICK_RANK = 3616; - public static final int CLANCHAT_KICK_CLANMEMBER = 3617; - public static final int GET_CLANCHAT_RANK = 3618; - public static final int JOIN_CLANCHAT = 3619; - public static final int PART_CLANCHAT = 3620; - public static final int GET_IGNORECOUNT = 3621; - public static final int GET_IGNORE = 3622; - public static final int IS_IGNORE = 3623; - public static final int CLANMEMBER_ISME = 3624; - public static final int GET_CLANCHATOWNER = 3625; - public static final int GET_GRANDEXCHANGE_OFFER_IS_SELLING = 3903; - public static final int GET_GRANDEXCHANGE_OFFER_ITEMID = 3904; - public static final int GET_GRANDEXCHANGE_OFFER_PRICE = 3905; - public static final int GET_GRANDEXCHANGE_OFFER_TOTALQUANTITY = 3906; - public static final int GET_GRANDEXCHANGE_OFFER_QUANTITYSOLD = 3907; - public static final int GET_GRANDEXCHANGE_OFFER_SPENT = 3908; - public static final int GET_GRANDEXCHANGE_OFFER_NOT_STARTED = 3910; - public static final int GET_GRANDEXCHANGE_OFFER_STATUS_2 = 3911; - public static final int GET_GRANDEXCHANGE_OFFER_DONE = 3912; - public static final int IADD = 4000; - public static final int ISUB = 4001; - public static final int IMUL = 4002; - public static final int IDIV = 4003; - public static final int RAND_EXCL = 4004; - public static final int RAND_INCL = 4005; + public static final int CC_CREATE = 100; + public static final int CC_DELETE = 101; + public static final int CC_DELETEALL = 102; + public static final int CC_FIND = 200; + public static final int IF_FIND = 201; + public static final int CC_SETPOSITION = 1000; + public static final int CC_SETSIZE = 1001; + public static final int CC_SETHIDE = 1003; + public static final int CC_SETNOCLICKTHROUGH = 1005; + public static final int CC_SETSCROLLPOS = 1100; + public static final int CC_SETCOLOUR = 1101; + public static final int CC_SETFILL = 1102; + public static final int CC_SETTRANS = 1103; + public static final int CC_SETLINEWID = 1104; + public static final int CC_SETGRAPHIC = 1105; + public static final int CC_SET2DANGLE = 1106; + public static final int CC_SETTILING = 1107; + public static final int CC_SETMODEL = 1108; + public static final int CC_SETMODELANGLE = 1109; + public static final int CC_SETMODELANIM = 1110; + public static final int CC_SETMODELORTHOG = 1111; + public static final int CC_SETTEXT = 1112; + public static final int CC_SETTEXTFONT = 1113; + public static final int CC_SETTEXTALIGN = 1114; + public static final int CC_SETTEXTSHADOW = 1115; + public static final int CC_SETOUTLINE = 1116; + public static final int CC_SETGRAPHICSHADOW = 1117; + public static final int CC_SETVFLIP = 1118; + public static final int CC_SETHFLIP = 1119; + public static final int CC_SETSCROLLSIZE = 1120; + public static final int CC_RESUME_PAUSEBUTTON = 1121; + public static final int CC_SETFILLCOLOUR = 1123; + public static final int CC_SETLINEDIRECTION = 1126; + public static final int CC_SETOBJECT = 1200; + public static final int CC_SETNPCHEAD = 1201; + public static final int CC_SETPLAYERHEAD_SELF = 1202; + public static final int CC_SETOBJECT_NONUM = 1205; + public static final int CC_SETOBJECT_ALWAYS_NUM = 1212; + public static final int CC_SETOP = 1300; + public static final int CC_SETDRAGGABLE = 1301; + public static final int CC_SETDRAGGABLEBEHAVIOR = 1302; + public static final int CC_SETDRAGDEADZONE = 1303; + public static final int CC_SETDRAGDEADTIME = 1304; + public static final int CC_SETOPBASE = 1305; + public static final int CC_SETTARGETVERB = 1306; + public static final int CC_CLEAROPS = 1307; + public static final int CC_SETONCLICK = 1400; + public static final int CC_SETONHOLD = 1401; + public static final int CC_SETONRELEASE = 1402; + public static final int CC_SETONMOUSEOVER = 1403; + public static final int CC_SETONMOUSELEAVE = 1404; + public static final int CC_SETONDRAG = 1405; + public static final int CC_SETONTARGETLEAVE = 1406; + public static final int CC_SETONVARTRANSMIT = 1407; + public static final int CC_SETONTIMER = 1408; + public static final int CC_SETONOP = 1409; + public static final int CC_SETONDRAGCOMPLETE = 1410; + public static final int CC_SETONCLICKREPEAT = 1411; + public static final int CC_SETONMOUSEREPEAT = 1412; + public static final int CC_SETONINVTRANSMIT = 1414; + public static final int CC_SETONSTATTRANSMIT = 1415; + public static final int CC_SETONTARGETENTER = 1416; + public static final int CC_SETONSCROLLWHEEL = 1417; + public static final int CC_SETONCHATTRANSMIT = 1418; + public static final int CC_SETONKEY = 1419; + public static final int CC_SETONFRIENDTRANSMIT = 1420; + public static final int CC_SETONCLANTRANSMIT = 1421; + public static final int CC_SETONMISCTRANSMIT = 1422; + public static final int CC_SETONDIALOGABORT = 1423; + public static final int CC_SETONSUBCHANGE = 1424; + public static final int CC_SETONSTOCKTRANSMIT = 1425; + public static final int CC_SETONRESIZE = 1427; + public static final int CC_GETX = 1500; + public static final int CC_GETY = 1501; + public static final int CC_GETWIDTH = 1502; + public static final int CC_GETHEIGHT = 1503; + public static final int CC_GETHIDE = 1504; + public static final int CC_GETLAYER = 1505; + public static final int CC_GETSCROLLX = 1600; + public static final int CC_GETSCROLLY = 1601; + public static final int CC_GETTEXT = 1602; + public static final int CC_GETSCROLLWIDTH = 1603; + public static final int CC_GETSCROLLHEIGHT = 1604; + public static final int CC_GETMODELZOOM = 1605; + public static final int CC_GETMODELANGLE_X = 1606; + public static final int CC_GETMODELANGLE_Z = 1607; + public static final int CC_GETMODELANGLE_Y = 1608; + public static final int CC_GETTRANS = 1609; + public static final int CC_GETCOLOUR = 1611; + public static final int CC_GETFILLCOLOUR = 1612; + public static final int CC_GETINVOBJECT = 1700; + public static final int CC_GETINVCOUNT = 1701; + public static final int CC_GETID = 1702; + public static final int CC_GETTARGETMASK = 1800; + public static final int CC_GETOP = 1801; + public static final int CC_GETOPBASE = 1802; + public static final int CC_CALLONRESIZE = 1927; + public static final int IF_SETPOSITION = 2000; + public static final int IF_SETSIZE = 2001; + public static final int IF_SETHIDE = 2003; + public static final int IF_SETNOCLICKTHROUGH = 2005; + public static final int IF_SETSCROLLPOS = 2100; + public static final int IF_SETCOLOUR = 2101; + public static final int IF_SETFILL = 2102; + public static final int IF_SETTRANS = 2103; + public static final int IF_SETLINEWID = 2104; + public static final int IF_SETGRAPHIC = 2105; + public static final int IF_SET2DANGLE = 2106; + public static final int IF_SETTILING = 2107; + public static final int IF_SETMODEL = 2108; + public static final int IF_SETMODELANGLE = 2109; + public static final int IF_SETMODELANIM = 2110; + public static final int IF_SETMODELORTHOG = 2111; + public static final int IF_SETTEXT = 2112; + public static final int IF_SETTEXTFONT = 2113; + public static final int IF_SETTEXTALIGN = 2114; + public static final int IF_SETTEXTSHADOW = 2115; + public static final int IF_SETOUTLINE = 2116; + public static final int IF_SETGRAPHICSHADOW = 2117; + public static final int IF_SETVFLIP = 2118; + public static final int IF_SETHFLIP = 2119; + public static final int IF_SETSCROLLSIZE = 2120; + public static final int IF_RESUME_PAUSEBUTTON = 2121; + public static final int IF_SETFILLCOLOUR = 2123; + public static final int IF_SETLINEDIRECTION = 2126; + public static final int IF_SETOBJECT = 2200; + public static final int IF_SETNPCHEAD = 2201; + public static final int IF_SETPLAYERHEAD_SELF = 2202; + public static final int IF_SETOBJECT_NONUM = 2205; + public static final int IF_SETOBJECT_ALWAYS_NUM = 2212; + public static final int IF_SETOP = 2300; + public static final int IF_SETDRAGGABLE = 2301; + public static final int IF_SETDRAGGABLEBEHAVIOR = 2302; + public static final int IF_SETDRAGDEADZONE = 2303; + public static final int IF_SETDRAGDEADTIME = 2304; + public static final int IF_SETOPBASE = 2305; + public static final int IF_SETTARGETVERB = 2306; + public static final int IF_CLEAROPS = 2307; + public static final int IF_SETOPKEY = 2350; + public static final int IF_SETOPTKEY = 2351; + public static final int IF_SETOPKEYRATE = 2352; + public static final int IF_SETOPTKEYRATE = 2353; + public static final int IF_SETOPKEYIGNOREHELD = 2354; + public static final int IF_SETOPTKEYIGNOREHELD = 2355; + public static final int IF_SETONCLICK = 2400; + public static final int IF_SETONHOLD = 2401; + public static final int IF_SETONRELEASE = 2402; + public static final int IF_SETONMOUSEOVER = 2403; + public static final int IF_SETONMOUSELEAVE = 2404; + public static final int IF_SETONDRAG = 2405; + public static final int IF_SETONTARGETLEAVE = 2406; + public static final int IF_SETONVARTRANSMIT = 2407; + public static final int IF_SETONTIMER = 2408; + public static final int IF_SETONOP = 2409; + public static final int IF_SETONDRAGCOMPLETE = 2410; + public static final int IF_SETONCLICKREPEAT = 2411; + public static final int IF_SETONMOUSEREPEAT = 2412; + public static final int IF_SETONINVTRANSMIT = 2414; + public static final int IF_SETONSTATTRANSMIT = 2415; + public static final int IF_SETONTARGETENTER = 2416; + public static final int IF_SETONSCROLLWHEEL = 2417; + public static final int IF_SETONCHATTRANSMIT = 2418; + public static final int IF_SETONKEY = 2419; + public static final int IF_SETONFRIENDTRANSMIT = 2420; + public static final int IF_SETONCLANTRANSMIT = 2421; + public static final int IF_SETONMISCTRANSMIT = 2422; + public static final int IF_SETONDIALOGABORT = 2423; + public static final int IF_SETONSUBCHANGE = 2424; + public static final int IF_SETONSTOCKTRANSMIT = 2425; + public static final int IF_SETONRESIZE = 2427; + public static final int IF_GETX = 2500; + public static final int IF_GETY = 2501; + public static final int IF_GETWIDTH = 2502; + public static final int IF_GETHEIGHT = 2503; + public static final int IF_GETHIDE = 2504; + public static final int IF_GETLAYER = 2505; + public static final int IF_GETSCROLLX = 2600; + public static final int IF_GETSCROLLY = 2601; + public static final int IF_GETTEXT = 2602; + public static final int IF_GETSCROLLWIDTH = 2603; + public static final int IF_GETSCROLLHEIGHT = 2604; + public static final int IF_GETMODELZOOM = 2605; + public static final int IF_GETMODELANGLE_X = 2606; + public static final int IF_GETMODELANGLE_Z = 2607; + public static final int IF_GETMODELANGLE_Y = 2608; + public static final int IF_GETTRANS = 2609; + public static final int IF_GETCOLOUR = 2611; + public static final int IF_GETFILLCOLOUR = 2612; + public static final int IF_GETINVOBJECT = 2700; + public static final int IF_GETINVCOUNT = 2701; + public static final int IF_HASSUB = 2702; + public static final int IF_GETTOP = 2706; + public static final int IF_GETTARGETMASK = 2800; + public static final int IF_GETOP = 2801; + public static final int IF_GETOPBASE = 2802; + public static final int IF_CALLONRESIZE = 2927; + public static final int MES = 3100; + public static final int ANIM = 3101; + public static final int IF_CLOSE = 3103; + public static final int RESUME_COUNTDIALOG = 3104; + public static final int RESUME_NAMEDIALOG = 3105; + public static final int RESUME_STRINGDIALOG = 3106; + public static final int OPPLAYER = 3107; + public static final int IF_DRAGPICKUP = 3108; + public static final int CC_DRAGPICKUP = 3109; + public static final int MOUSECAM = 3110; + public static final int GETREMOVEROOFS = 3111; + public static final int SETREMOVEROOFS = 3112; + public static final int OPENURL = 3113; + public static final int RESUME_OBJDIALOG = 3115; + public static final int BUG_REPORT = 3116; + public static final int SETSHIFTCLICKDROP = 3117; + public static final int SETSHOWMOUSEOVERTEXT = 3118; + public static final int RENDERSELF = 3119; + public static final int SETSHOWMOUSECROSS = 3125; + public static final int SETSHOWLOADINGMESSAGES = 3126; + public static final int SETTAPTODROP = 3127; + public static final int GETTAPTODROP = 3128; + public static final int GETCANVASSIZE = 3132; + public static final int SETHIDEUSERNAME = 3141; + public static final int GETHIDEUSERNAME = 3142; + public static final int SETREMEMBERUSERNAME = 3143; + public static final int GETREMEMBERUSERNAME = 3144; + public static final int SOUND_SYNTH = 3200; + public static final int SOUND_SONG = 3201; + public static final int SOUND_JINGLE = 3202; + public static final int CLIENTCLOCK = 3300; + public static final int INV_GETOBJ = 3301; + public static final int INV_GETNUM = 3302; + public static final int INV_TOTAL = 3303; + public static final int INV_SIZE = 3304; + public static final int STAT = 3305; + public static final int STAT_BASE = 3306; + public static final int STAT_XP = 3307; + public static final int COORD = 3308; + public static final int COORDX = 3309; + public static final int COORDZ = 3310; + public static final int COORDY = 3311; + public static final int MAP_MEMBERS = 3312; + public static final int INVOTHER_GETOBJ = 3313; + public static final int INVOTHER_GETNUM = 3314; + public static final int INVOTHER_TOTAL = 3315; + public static final int STAFFMODLEVEL = 3316; + public static final int REBOOTTIMER = 3317; + public static final int MAP_WORLD = 3318; + public static final int RUNENERGY_VISIBLE = 3321; + public static final int RUNWEIGHT_VISIBLE = 3322; + public static final int PLAYERMOD = 3323; + public static final int WORLDFLAGS = 3324; + public static final int MOVECOORD = 3325; + public static final int ENUM_STRING = 3400; + public static final int ENUM = 3408; + public static final int ENUM_GETOUTPUTCOUNT = 3411; + public static final int FRIEND_COUNT = 3600; + public static final int FRIEND_GETNAME = 3601; + public static final int FRIEND_GETWORLD = 3602; + public static final int FRIEND_GETRANK = 3603; + public static final int FRIEND_SETRANK = 3604; + public static final int FRIEND_ADD = 3605; + public static final int FRIEND_DEL = 3606; + public static final int IGNORE_ADD = 3607; + public static final int IGNORE_DEL = 3608; + public static final int FRIEND_TEST = 3609; + public static final int CLAN_GETCHATDISPLAYNAME = 3611; + public static final int CLAN_GETCHATCOUNT = 3612; + public static final int CLAN_GETCHATUSERNAME = 3613; + public static final int CLAN_GETCHATUSERWORLD = 3614; + public static final int CLAN_GETCHATUSERRANK = 3615; + public static final int CLAN_GETCHATMINKICK = 3616; + public static final int CLAN_KICKUSER = 3617; + public static final int CLAN_GETCHATRANK = 3618; + public static final int CLAN_JOINCHAT = 3619; + public static final int CLAN_LEAVECHAT = 3620; + public static final int IGNORE_COUNT = 3621; + public static final int IGNORE_GETNAME = 3622; + public static final int IGNORE_TEST = 3623; + public static final int CLAN_ISSELF = 3624; + public static final int CLAN_GETCHATOWNERNAME = 3625; + public static final int CLAN_ISFRIEND = 3626; + public static final int CLAN_ISIGNORE = 3627; + public static final int STOCKMARKET_GETOFFERTYPE = 3903; + public static final int STOCKMARKET_GETOFFERITEM = 3904; + public static final int STOCKMARKET_GETOFFERPRICE = 3905; + public static final int STOCKMARKET_GETOFFERCOUNT = 3906; + public static final int STOCKMARKET_GETOFFERCOMPLETEDCOUNT = 3907; + public static final int STOCKMARKET_GETOFFERCOMPLETEDGOLD = 3908; + public static final int STOCKMARKET_ISOFFEREMPTY = 3910; + public static final int STOCKMARKET_ISOFFERSTABLE = 3911; + public static final int STOCKMARKET_ISOFFERFINISHED = 3912; + public static final int STOCKMARKET_ISOFFERADDING = 3913; + public static final int TRADINGPOST_SORTBY_NAME = 3914; + public static final int TRADINGPOST_SORTBY_PRICE = 3915; + public static final int TRADINGPOST_SORTFILTERBY_WORLD = 3916; + public static final int TRADINGPOST_SORTBY_AGE = 3917; + public static final int TRADINGPOST_SORTBY_COUNT = 3918; + public static final int TRADINGPOST_GETTOTALOFFERS = 3919; + public static final int TRADINGPOST_GETOFFERWORLD = 3920; + public static final int TRADINGPOST_GETOFFERNAME = 3921; + public static final int TRADINGPOST_GETOFFERPREVIOUSNAME = 3922; + public static final int TRADINGPOST_GETOFFERAGE = 3923; + public static final int TRADINGPOST_GETOFFERCOUNT = 3924; + public static final int TRADINGPOST_GETOFFERPRICE = 3925; + public static final int TRADINGPOST_GETOFFERITEM = 3926; + public static final int ADD = 4000; + public static final int SUB = 4001; + public static final int MULTIPLY = 4002; + public static final int DIV = 4003; + public static final int RANDOM = 4004; + public static final int RANDOMINC = 4005; public static final int INTERPOLATE = 4006; - public static final int ADD_PERCENT = 4007; - public static final int SET_BIT = 4008; - public static final int CLEAR_BIT = 4009; - public static final int TEST_BIT = 4010; - public static final int MODULO = 4011; + public static final int ADDPERCENT = 4007; + public static final int SETBIT = 4008; + public static final int CLEARBIT = 4009; + public static final int TESTBIT = 4010; + public static final int MOD = 4011; public static final int POW = 4012; public static final int INVPOW = 4013; public static final int AND = 4014; public static final int OR = 4015; public static final int SCALE = 4018; - public static final int CONCAT_INT = 4100; - public static final int CONCAT_STRING = 4101; - public static final int TOLOWERCASE = 4103; - public static final int FORMAT_DATE = 4104; - public static final int SWITCH_MALE_OR_FEMALE = 4105; - public static final int INT_TO_STRING = 4106; - public static final int STRING_COMPARE = 4107; - public static final int GET_LINE_COUNT = 4108; - public static final int GET_MAX_LINE_WIDTH = 4109; - public static final int SWITCH_STRING = 4110; - public static final int APPENDTAGS = 4111; - public static final int CONCAT_CHAR = 4112; - public static final int CHAR_IS_PRINTABLE = 4113; - public static final int ISALNUM = 4114; - public static final int ISALPHA = 4115; - public static final int ISDIGIT = 4116; + public static final int APPEND_NUM = 4100; + public static final int APPEND = 4101; + public static final int APPEND_SIGNNUM = 4102; + public static final int LOWERCASE = 4103; + public static final int FROMDATE = 4104; + public static final int TEXT_GENDER = 4105; + public static final int TOSTRING = 4106; + public static final int COMPARE = 4107; + public static final int PARAHEIGHT = 4108; + public static final int PARAWIDTH = 4109; + public static final int TEXT_SWITCH = 4110; + public static final int ESCAPE = 4111; + public static final int APPEND_CHAR = 4112; + public static final int CHAR_ISPRINTABLE = 4113; + public static final int CHAR_ISALPHANUMERIC = 4114; + public static final int CHAR_ISALPHA = 4115; + public static final int CHAR_ISNUMERIC = 4116; public static final int STRING_LENGTH = 4117; - public static final int STRING_SUBSTRING = 4118; - public static final int STRING_REMOVE_HTML = 4119; - public static final int STRING_INDEXOF = 4120; - public static final int STRING_INDEXOF_FROM = 4121; - public static final int GET_ITEM_NAME = 4200; - public static final int GET_ITEM_GROUND_ACTION = 4201; - public static final int GET_ITEM_INVENTORY_ACTION = 4202; - public static final int GET_ITEM_PRICE = 4203; - public static final int GET_ITEM_STACKABLE = 4204; - public static final int GET_ITEM_NOTE_1 = 4205; - public static final int GET_ITEM_NOTE_2 = 4206; - public static final int GET_ITEM_ISMEMBERS = 4207; - public static final int SEARCH_ITEM = 4210; - public static final int NEXT_SEARCH_RESULT = 4211; - public static final int CHATFILTER_UPDATE = 5001; - public static final int REPORT_PLAYER = 5002; - public static final int GET_CHAT_MESSAGE_TYPE = 5003; - public static final int GET_CHAT_MESSAGE = 5004; - public static final int CHATBOX_INPUT = 5008; - public static final int PRIVMSG = 5009; - public static final int GET_LOCALPLAYER_NAME = 5015; - public static final int GET_CHATLINEBUFFER_LENGTH = 5017; - public static final int GET_MESSAGENODE_PREV_ID = 5018; - public static final int GET_MESSAGENODE_NEXT_ID = 5019; - public static final int RUN_COMMAND = 5020; - public static final int GET_ISRESIZED = 5306; - public static final int SET_ISRESIZED = 5307; - public static final int GET_SCREENTYPE = 5308; - public static final int SET_SCREENTYPE = 5309; - public static final int GET_MAPANGLE = 5506; - public static final int SET_CAMERA_FOCAL_POINT_HEIGHT = 5530; - public static final int GET_CAMERA_FOCAL_POINT_HEIGHT = 5531; - public static final int CANCEL_LOGIN = 5630; - public static final int SET_ZOOM_DISTANCE = 6201; - public static final int GET_VIEWPORT_SIZE = 6203; - public static final int GET_ZOOM_DISTANCE = 6204; - public static final int LOAD_WORLDS = 6500; - public static final int GET_FIRST_WORLD = 6501; - public static final int GET_NEXT_WORLD = 6502; - public static final int GET_WORLD_BY_ID = 6506; - public static final int GET_WORLD_BY_INDEX = 6511; - public static final int GET_IS_MOBILE = 6518; - public static final int GET_MAP_SURFACE_NAME_BY_ID = 6601; - public static final int SET_CURRENT_MAP_SURFACE = 6602; - public static final int GET_CURRENT_MAP_ZOOM = 6603; - public static final int SET_CURRENT_MAP_ZOOM = 6604; - public static final int SET_MAP_POSITION = 6606; - public static final int SET_MAP_POSITION_IMMEDIATE = 6607; - public static final int SET_MAP_POSITION_2 = 6608; - public static final int SET_MAP_POSITION_IMMEDIATE_2 = 6609; - public static final int GET_MAP_POSITION = 6610; - public static final int GET_MAP_DEFAULT_POSITION_BY_ID = 6611; - public static final int GET_MAP_DIMENSIONS_BY_ID = 6612; - public static final int GET_MAP_BOUNDS_BY_ID = 6613; - public static final int GET_MAP_INITAL_ZOOM_BY_ID = 6614; - public static final int GET_CURRENT_MAP_ID = 6616; - public static final int MAP_ID_CONTAINS_COORD = 6621; - public static final int GET_MAP_DISPLAY_DIMENSIONS = 6622; - public static final int GET_MAP_ID_CONTAINING_COORD = 6623; - public static final int SET_MAP_ICON_FLASH_COUNT = 6624; - public static final int RESET_MAP_ICON_FLASH_COUNT = 6625; - public static final int SET_MAP_ICON_FLASH_PERIOD = 6626; - public static final int RESET_MAP_ICON_FLASH_PERIOD = 6627; - public static final int SET_MAP_ICON_FLASH_FOREVER = 6628; - public static final int FLASH_MAP_ICONS_BY_ID = 6629; - public static final int FLASH_MAP_ICONS_BY_GROUP = 6630; - public static final int CLEAR_FLASHING_ICONS = 6631; - public static final int SET_MAP_ICONS_DISABLED = 6632; - public static final int SET_MAP_ICONS_ENABLED_BY_ID = 6633; - public static final int SET_MAP_ICONS_ENABLED_BY_GROUP = 6634; - public static final int GET_MAP_ICONS_DISABLED = 6635; - public static final int GET_MAP_ICONS_ENABLED_BY_ID = 6636; - public static final int GET_MAP_ICONS_ENABLED_BY_GROUP = 6637; - public static final int GET_FIRST_MAP_ICON = 6639; - public static final int GET_NEXT_MAP_ICON = 6640; - public static final int GET_MAPICON_NAME_BY_ID = 6693; - public static final int GET_MAPICON_FONT_SIZE = 6694; - public static final int GET_MAPICON_GROUP_BY_ID = 6695; - public static final int GET_MAPICON_SPRITE_BY_ID = 6696; - public static final int GET_CURRENT_MAPICON_ID = 6697; - public static final int GET_CURRENT_MAPICON_COORD = 6698; - public static final int GET_CURRENT_MAPICON_OTHER_COORD = 6699; + public static final int SUBSTRING = 4118; + public static final int REMOVETAGS = 4119; + public static final int STRING_INDEXOF_CHAR = 4120; + public static final int STRING_INDEXOF_STRING = 4121; + public static final int OC_NAME = 4200; + public static final int OC_OP = 4201; + public static final int OC_IOP = 4202; + public static final int OC_COST = 4203; + public static final int OC_STACKABLE = 4204; + public static final int OC_CERT = 4205; + public static final int OC_UNCERT = 4206; + public static final int OC_MEMBERS = 4207; + public static final int OC_PLACEHOLDER = 4208; + public static final int OC_UNPLACEHOLDER = 4209; + public static final int OC_FIND = 4210; + public static final int OC_FINDNEXT = 4211; + public static final int OC_FINDRESET = 4212; + public static final int CHAT_GETFILTER_PUBLIC = 5000; + public static final int CHAT_SETFILTER = 5001; + public static final int CHAT_SENDABUSEREPORT = 5002; + public static final int CHAT_GETHISTORY_BYTYPEANDLINE = 5003; + public static final int CHAT_GETHISTORY_BYUID = 5004; + public static final int CHAT_GETFILTER_PRIVATE = 5005; + public static final int CHAT_SENDPUBLIC = 5008; + public static final int CHAT_SENDPRIVATE = 5009; + public static final int CHAT_PLAYERNAME = 5015; + public static final int CHAT_GETFILTER_TRADE = 5016; + public static final int CHAT_GETHISTORYLENGTH = 5017; + public static final int CHAT_GETNEXTUID = 5018; + public static final int CHAT_GETPREVUID = 5019; + public static final int DOCHEAT = 5020; + public static final int CHAT_SETMESSAGEFILTER = 5021; + public static final int CHAT_GETMESSAGEFILTER = 5022; + public static final int GETWINDOWMODE = 5306; + public static final int SETWINDOWMODE = 5307; + public static final int GETDEFAULTWINDOWMODE = 5308; + public static final int SETDEFAULTWINDOWMODE = 5309; + public static final int CAM_FORCEANGLE = 5504; + public static final int CAM_GETANGLE_XA = 5505; + public static final int CAM_GETANGLE_YA = 5506; + public static final int CAM_SETFOLLOWHEIGHT = 5530; + public static final int CAM_GETFOLLOWHEIGHT = 5531; + public static final int LOGOUT = 5630; + public static final int VIEWPORT_SETFOV = 6200; + public static final int VIEWPORT_SETZOOM = 6201; + public static final int VIEWPORT_CLAMPFOV = 6202; + public static final int VIEWPORT_GETEFFECTIVESIZE = 6203; + public static final int VIEWPORT_GETZOOM = 6204; + public static final int VIEWPORT_GETFOV = 6205; + public static final int WORLDLIST_FETCH = 6500; + public static final int WORLDLIST_START = 6501; + public static final int WORLDLIST_NEXT = 6502; + public static final int WORLDLIST_SPECIFIC = 6506; + public static final int WORLDLIST_SORT = 6507; + public static final int SETFOLLOWEROPSLOWPRIORITY = 6512; + public static final int NC_PARAM = 6513; + public static final int LC_PARAM = 6514; + public static final int OC_PARAM = 6515; + public static final int STRUCT_PARAM = 6516; + public static final int ON_MOBILE = 6518; + public static final int CLIENTTYPE = 6519; + public static final int BATTERYLEVEL = 6524; + public static final int BATTERYCHARGING = 6525; + public static final int WIFIAVAILABLE = 6526; + public static final int WORLDMAP_GETMAPNAME = 6601; + public static final int WORLDMAP_SETMAP = 6602; + public static final int WORLDMAP_GETZOOM = 6603; + public static final int WORLDMAP_SETZOOM = 6604; + public static final int WORLDMAP_ISLOADED = 6605; + public static final int WORLDMAP_JUMPTODISPLAYCOORD = 6606; + public static final int WORLDMAP_JUMPTODISPLAYCOORD_INSTANT = 6607; + public static final int WORLDMAP_JUMPTOSOURCECOORD = 6608; + public static final int WORLDMAP_JUMPTOSOURCECOORD_INSTANT = 6609; + public static final int WORLDMAP_GETDISPLAYPOSITION = 6610; + public static final int WORLDMAP_GETCONFIGORIGIN = 6611; + public static final int WORLDMAP_GETCONFIGSIZE = 6612; + public static final int WORLDMAP_GETCONFIGBOUNDS = 6613; + public static final int WORLDMAP_GETCONFIGZOOM = 6614; + public static final int WORLDMAP_GETCURRENTMAP = 6616; + public static final int WORLDMAP_GETDISPLAYCOORD = 6617; + public static final int WORLDMAP_COORDINMAP = 6621; + public static final int WORLDMAP_GETSIZE = 6622; + public static final int WORLDMAP_PERPETUALFLASH = 6628; + public static final int WORLDMAP_FLASHELEMENT = 6629; + public static final int WORLDMAP_FLASHELEMENTCATEGORY = 6630; + public static final int WORLDMAP_STOPCURRENTFLASHES = 6631; + public static final int WORLDMAP_DISABLEELEMENTS = 6632; + public static final int WORLDMAP_DISABLEELEMENT = 6633; + public static final int WORLDMAP_DISABLEELEMENTCATEGORY = 6634; + public static final int WORLDMAP_GETDISABLEELEMENTS = 6635; + public static final int WORLDMAP_GETDISABLEELEMENT = 6636; + public static final int WORLDMAP_GETDISABLEELEMENTCATEGORY = 6637; + public static final int WORLDMAP_LISTELEMENT_START = 6639; + public static final int WORLDMAP_LISTELEMENT_NEXT = 6640; + public static final int MEC_TEXT = 6693; + public static final int MEC_TEXTSIZE = 6694; + public static final int MEC_CATEGORY = 6695; + public static final int MEC_SPRITE = 6696; } diff --git a/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java b/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java index a672d3b965..0a6382fec8 100644 --- a/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java +++ b/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java @@ -204,7 +204,7 @@ public class Disassembler switch (opcode) { - case Opcodes.LOAD_INT: + case Opcodes.ICONST: case Opcodes.ILOAD: case Opcodes.SLOAD: case Opcodes.ISTORE: diff --git a/cache/src/test/resources/net/runelite/cache/script/assembler/681.rs2asm b/cache/src/test/resources/net/runelite/cache/script/assembler/681.rs2asm index b70b4c7eee..a5f4222fdb 100644 --- a/cache/src/test/resources/net/runelite/cache/script/assembler/681.rs2asm +++ b/cache/src/test/resources/net/runelite/cache/script/assembler/681.rs2asm @@ -3,28 +3,28 @@ .string_stack_count 0 .int_var_count 2 .string_var_count 1 - get_varc 5 - load_int 14 + get_varc_int 5 + iconst 14 if_icmpeq LABEL4 jump LABEL7 LABEL4: - load_int 1 - put_varc 66 + iconst 1 + set_varc_int 66 return LABEL7: - load_int -1 + iconst -1 istore 0 - load_string "" + sconst "" sstore 0 - get_varc_string 22 + get_varc_string_old 22 string_length istore 1 iload 1 - load_int 0 + iconst 0 if_icmpgt LABEL18 jump LABEL193 LABEL18: - get_varc 5 + get_varc_int 5 switch 1: LABEL21 2: LABEL44 @@ -46,90 +46,90 @@ LABEL21: return jump LABEL192 LABEL23: - get_ignorecount - load_int 0 + ignore_count + iconst 0 if_icmplt LABEL27 jump LABEL30 LABEL27: - load_string "Unable to update ignore list - system busy." - send_game_message + sconst "Unable to update ignore list - system busy." + mes jump LABEL43 LABEL30: - get_varc 5 - load_int 4 + get_varc_int 5 + iconst 4 if_icmpeq LABEL34 jump LABEL37 LABEL34: - get_varc_string 22 - add_ignore + get_varc_string_old 22 + ignore_add jump LABEL43 LABEL37: - get_varc 5 - load_int 5 + get_varc_int 5 + iconst 5 if_icmpeq LABEL41 jump LABEL43 LABEL41: - get_varc_string 22 - remove_ignore + get_varc_string_old 22 + ignore_del LABEL43: jump LABEL192 LABEL44: - get_friendcount - load_int 0 + friend_count + iconst 0 if_icmplt LABEL48 jump LABEL51 LABEL48: - load_string "Unable to complete action - system busy." - send_game_message + sconst "Unable to complete action - system busy." + mes jump LABEL109 LABEL51: - get_varc 5 - load_int 2 + get_varc_int 5 + iconst 2 if_icmpeq LABEL55 jump LABEL58 LABEL55: - get_varc_string 22 - add_friend + get_varc_string_old 22 + friend_add jump LABEL109 LABEL58: - get_varc 5 - load_int 3 + get_varc_int 5 + iconst 3 if_icmpeq LABEL62 jump LABEL65 LABEL62: - get_varc_string 22 - remove_friend + get_varc_string_old 22 + friend_del jump LABEL109 LABEL65: - get_varc 5 - load_int 6 + get_varc_int 5 + iconst 6 if_icmpeq LABEL69 jump LABEL109 LABEL69: - get_varc 203 - load_int 0 + get_varc_int 203 + iconst 0 if_icmpeq LABEL76 - get_varc 203 - load_int -1 + get_varc_int 203 + iconst -1 if_icmpeq LABEL76 jump LABEL82 LABEL76: - load_int 1 - load_int 1 + iconst 1 + iconst 1 invoke 299 - load_string "You must set a name before you can chat." - send_game_message + sconst "You must set a name before you can chat." + mes return LABEL82: - 5005 - load_int 2 + chat_getfilter_private + iconst 2 if_icmpeq LABEL86 jump LABEL97 LABEL86: - 5000 - load_int 1 - 5016 - chatfilter_update + chat_getfilter_public + iconst 1 + chat_getfilter_trade + chat_setfilter invoke 178 invoke 553 istore 0 @@ -139,123 +139,123 @@ LABEL86: invoke 89 LABEL97: get_varbit 4394 - load_int 1 + iconst 1 if_icmpeq LABEL101 jump LABEL104 LABEL101: - get_varc_string 23 - remove_friend + get_varc_string_old 23 + friend_del jump LABEL107 LABEL104: - get_varc_string 23 - get_varc_string 22 - privmsg + get_varc_string_old 23 + get_varc_string_old 22 + chat_sendprivate LABEL107: - get_gamecycle - put_varc 61 + clientclock + set_varc_int 61 LABEL109: jump LABEL192 LABEL110: - get_varc_string 22 + get_varc_string_old 22 invoke 212 - numeric_input + resume_countdialog jump LABEL192 LABEL114: - get_varc_string 22 - string_remove_html - put_varc_string 128 - get_varc_string 22 - string_input_1 + get_varc_string_old 22 + removetags + set_varc_string_old 128 + get_varc_string_old 22 + resume_namedialog jump LABEL192 LABEL120: - get_varc_string 22 - string_input_2 + get_varc_string_old 22 + resume_stringdialog jump LABEL192 LABEL123: - get_varc 203 - load_int 0 + get_varc_int 203 + iconst 0 if_icmpeq LABEL130 - get_varc 203 - load_int -1 + get_varc_int 203 + iconst -1 if_icmpeq LABEL130 jump LABEL136 LABEL130: - load_int 1 - load_int 1 + iconst 1 + iconst 1 invoke 299 - load_string "You must set a name before you can chat." - send_game_message + sconst "You must set a name before you can chat." + mes return LABEL136: - get_varc_string 22 - string_remove_html - put_varc_string 129 - get_varc_string 22 - join_clanchat + get_varc_string_old 22 + removetags + set_varc_string_old 129 + get_varc_string_old 22 + clan_joinchat jump LABEL192 LABEL142: iload 1 - load_int 10 + iconst 10 if_icmpgt LABEL146 jump LABEL152 LABEL146: - get_varc_string 22 - load_int 0 - load_int 9 - string_substring + get_varc_string_old 22 + iconst 0 + iconst 9 + substring sstore 0 jump LABEL154 LABEL152: - get_varc_string 22 + get_varc_string_old 22 sstore 0 LABEL154: sload 0 - tolowercase - 5021 + lowercase + chat_setmessagefilter invoke 553 invoke 84 jump LABEL192 LABEL160: - get_varc 203 - load_int 0 + get_varc_int 203 + iconst 0 if_icmpeq LABEL167 - get_varc 203 - load_int -1 + get_varc_int 203 + iconst -1 if_icmpeq LABEL167 jump LABEL173 LABEL167: - load_int 1 - load_int 1 + iconst 1 + iconst 1 invoke 299 - load_string "You must set a name before you can chat." - send_game_message + sconst "You must set a name before you can chat." + mes return LABEL173: - get_varc_string 22 - load_int 0 - put_varc 62 - put_varc_string 28 + get_varc_string_old 22 + iconst 0 + set_varc_int 62 + set_varc_string_old 28 invoke 95 - load_int 552 - load_int -2147483645 - load_int 1 - load_string "I1" - load_int 10616843 - widget_put_render_listener_widget + iconst 552 + iconst -2147483645 + iconst 1 + sconst "I1" + iconst 10616843 + if_setontimer jump LABEL192 LABEL185: - load_int 0 - load_int 1 + iconst 0 + iconst 1 invoke 299 return jump LABEL192 LABEL190: - get_varc_string 22 + get_varc_string_old 22 invoke 2061 LABEL192: jump LABEL199 LABEL193: - get_varc 5 + get_varc_int 5 switch 16: LABEL198 7: LABEL196 @@ -269,7 +269,7 @@ LABEL196: LABEL198: return LABEL199: - load_int 1 - load_int 1 + iconst 1 + iconst 1 invoke 299 return diff --git a/cache/src/test/resources/net/runelite/cache/script/assembler/91.rs2asm b/cache/src/test/resources/net/runelite/cache/script/assembler/91.rs2asm index 901c7169ad..25a749a77b 100644 --- a/cache/src/test/resources/net/runelite/cache/script/assembler/91.rs2asm +++ b/cache/src/test/resources/net/runelite/cache/script/assembler/91.rs2asm @@ -12,111 +12,111 @@ jump LABEL84 LABEL3: iload 1 - get_varc 175 + get_varc_int 175 if_icmplt LABEL7 jump LABEL9 LABEL7: - load_int 0 + iconst 0 return LABEL9: sload 0 - string_remove_html - is_ignore - load_int 1 + removetags + ignore_test + iconst 1 if_icmpeq LABEL15 jump LABEL17 LABEL15: - load_int 0 + iconst 0 return LABEL17: - load_int 1 + iconst 1 return jump LABEL84 LABEL20: iload 1 - get_varc 175 + get_varc_int 175 if_icmplt LABEL24 jump LABEL26 LABEL24: - load_int 0 + iconst 0 return LABEL26: sload 0 - string_remove_html - is_ignore - load_int 1 + removetags + ignore_test + iconst 1 if_icmpeq LABEL32 jump LABEL34 LABEL32: - load_int 0 + iconst 0 return LABEL34: - 5005 - load_int 0 + chat_getfilter_private + iconst 0 if_icmpeq LABEL38 jump LABEL40 LABEL38: - load_int 1 + iconst 1 return LABEL40: - 5005 - load_int 1 + chat_getfilter_private + iconst 1 if_icmpeq LABEL44 jump LABEL51 LABEL44: sload 0 - is_friend - load_int 1 + friend_test + iconst 1 if_icmpeq LABEL49 jump LABEL51 LABEL49: - load_int 1 + iconst 1 return LABEL51: - load_int 0 + iconst 0 return jump LABEL84 LABEL54: iload 1 - get_varc 175 + get_varc_int 175 if_icmplt LABEL58 jump LABEL60 LABEL58: - load_int 0 + iconst 0 return LABEL60: iload 0 - load_int 5 + iconst 5 if_icmpeq LABEL64 jump LABEL76 LABEL64: get_varbit 1627 - load_int 0 + iconst 0 if_icmpeq LABEL68 jump LABEL76 LABEL68: - get_gamecycle + clientclock iload 1 - isub - load_int 500 + sub + iconst 500 if_icmpge LABEL74 jump LABEL76 LABEL74: - load_int 0 + iconst 0 return LABEL76: - 5005 - load_int 2 + chat_getfilter_private + iconst 2 if_icmpne LABEL80 jump LABEL82 LABEL80: - load_int 1 + iconst 1 return LABEL82: - load_int 0 + iconst 0 return LABEL84: - load_int 0 + iconst 0 return - load_int -1 + iconst -1 return diff --git a/cache/src/test/resources/net/runelite/cache/script/assembler/Unicode.rs2asm b/cache/src/test/resources/net/runelite/cache/script/assembler/Unicode.rs2asm index 7ca51cc723..a1fc0a62e1 100644 --- a/cache/src/test/resources/net/runelite/cache/script/assembler/Unicode.rs2asm +++ b/cache/src/test/resources/net/runelite/cache/script/assembler/Unicode.rs2asm @@ -3,5 +3,5 @@ .string_stack_count 0 .int_var_count 0 .string_var_count 0 - load_string ": " + sconst ": " return diff --git a/checkstyle.xml b/checkstyle.xml index aa3bf946e4..e8669a742c 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -23,8 +23,9 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + diff --git a/http-api/pom.xml b/http-api/pom.xml index 5ab155acba..a9ef3569d7 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT Web API diff --git a/http-api/src/main/java/net/runelite/http/api/feed/FeedClient.java b/http-api/src/main/java/net/runelite/http/api/feed/FeedClient.java index ea1fe18fd6..6b05ad20ba 100644 --- a/http-api/src/main/java/net/runelite/http/api/feed/FeedClient.java +++ b/http-api/src/main/java/net/runelite/http/api/feed/FeedClient.java @@ -55,7 +55,7 @@ public class FeedClient { if (!response.isSuccessful()) { - logger.debug("Error looking up feed: {}", response.message()); + logger.debug("Error looking up feed: {}", response); return null; } diff --git a/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeClient.java b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeClient.java new file mode 100644 index 0000000000..a1b97bc390 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeClient.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.api.ge; + +import com.google.gson.Gson; +import java.io.IOException; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.runelite.http.api.RuneLiteAPI; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +@Slf4j +@AllArgsConstructor +public class GrandExchangeClient +{ + private static final MediaType JSON = MediaType.parse("application/json"); + private static final Gson GSON = RuneLiteAPI.GSON; + + private final UUID uuid; + + public void submit(GrandExchangeTrade grandExchangeTrade) + { + final HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() + .addPathSegment("ge") + .build(); + + Request request = new Request.Builder() + .header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString()) + .post(RequestBody.create(JSON, GSON.toJson(grandExchangeTrade))) + .url(url) + .build(); + + RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback() + { + @Override + public void onFailure(Call call, IOException e) + { + log.debug("unable to submit trade", e); + } + + @Override + public void onResponse(Call call, Response response) + { + log.debug("Submitted trade"); + response.close(); + } + }); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateTotal.java b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java similarity index 71% rename from runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateTotal.java rename to http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java index ad9492981c..b5d0012b16 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateTotal.java +++ b/http-api/src/main/java/net/runelite/http/api/ge/GrandExchangeTrade.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Levi + * Copyright (c) 2019, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,34 +22,17 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.client.plugins.xptracker; +package net.runelite.http.api.ge; +import java.time.Instant; import lombok.Data; @Data -class XpStateTotal +public class GrandExchangeTrade { - private int xpGainedInSession = 0; - private int xpPerHour = 0; - - void reset() - { - xpGainedInSession = 0; - xpPerHour = 0; - } - - void addXpGainedInSession(int skillXpGainedInSession) - { - xpGainedInSession += skillXpGainedInSession; - } - - void addXpPerHour(int skillXpGainedPerHour) - { - xpPerHour += skillXpGainedPerHour; - } - - XpSnapshotTotal snapshot() - { - return new XpSnapshotTotal(xpGainedInSession, xpPerHour); - } + private boolean buy; + private int itemId; + private int quantity; + private int price; + private Instant time; } diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java index 3f3f968d83..a725089de4 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java @@ -106,7 +106,7 @@ public class HiscoreClient case 404: return null; default: - throw new IOException("Error retrieving data from Jagex Hiscores: " + okresponse.message()); + throw new IOException("Error retrieving data from Jagex Hiscores: " + okresponse); } } diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java index 93b138dc7f..17784dd67b 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemClient.java @@ -63,7 +63,7 @@ public class ItemClient { if (!response.isSuccessful()) { - logger.debug("Error looking up item {}: {}", itemId, response.message()); + logger.debug("Error looking up item {}: {}", itemId, response); return null; } @@ -99,7 +99,7 @@ public class ItemClient { if (!response.isSuccessful()) { - logger.debug("Error looking up items {}: {}", Arrays.toString(itemIds), response.message()); + logger.debug("Error looking up items {}: {}", Arrays.toString(itemIds), response); return null; } @@ -130,7 +130,7 @@ public class ItemClient { if (!response.isSuccessful()) { - logger.debug("Error grabbing icon {}: {}", itemId, response.message()); + logger.debug("Error grabbing icon {}: {}", itemId, response); return null; } @@ -160,7 +160,7 @@ public class ItemClient { if (!response.isSuccessful()) { - logger.debug("Error looking up item {}: {}", itemName, response.message()); + logger.debug("Error looking up item {}: {}", itemName, response); return null; } @@ -191,7 +191,7 @@ public class ItemClient { if (!response.isSuccessful()) { - logger.warn("Error looking up prices: {}", response.message()); + logger.warn("Error looking up prices: {}", response); return null; } @@ -204,11 +204,12 @@ public class ItemClient } } - public Map getStats() throws IOException + public Map getStats() throws IOException { HttpUrl.Builder urlBuilder = RuneLiteAPI.getStaticBase().newBuilder() .addPathSegment("item") - .addPathSegment("stats.min.json"); + // TODO: Change this to stats.min.json later after release is undeployed + .addPathSegment("stats.ids.min.json"); HttpUrl url = urlBuilder.build(); @@ -222,12 +223,12 @@ public class ItemClient { if (!response.isSuccessful()) { - logger.warn("Error looking up item stats: {}", response.message()); + logger.warn("Error looking up item stats: {}", response); return null; } InputStream in = response.body().byteStream(); - final Type typeToken = new TypeToken>() + final Type typeToken = new TypeToken>() { }.getType(); return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), typeToken); diff --git a/http-api/src/main/java/net/runelite/http/api/loottracker/LootRecord.java b/http-api/src/main/java/net/runelite/http/api/loottracker/LootRecord.java index fb43a1605a..fc945220f1 100644 --- a/http-api/src/main/java/net/runelite/http/api/loottracker/LootRecord.java +++ b/http-api/src/main/java/net/runelite/http/api/loottracker/LootRecord.java @@ -24,6 +24,7 @@ */ package net.runelite.http.api.loottracker; +import java.time.Instant; import java.util.Collection; import lombok.AllArgsConstructor; import lombok.Data; @@ -37,4 +38,5 @@ public class LootRecord private String eventId; private LootRecordType type; private Collection drops; + private Instant time; } diff --git a/http-api/src/main/java/net/runelite/http/api/loottracker/LootTrackerClient.java b/http-api/src/main/java/net/runelite/http/api/loottracker/LootTrackerClient.java index ac967af886..d250620905 100644 --- a/http-api/src/main/java/net/runelite/http/api/loottracker/LootTrackerClient.java +++ b/http-api/src/main/java/net/runelite/http/api/loottracker/LootTrackerClient.java @@ -90,7 +90,6 @@ public class LootTrackerClient Request request = new Request.Builder() .header(RuneLiteAPI.RUNELITE_AUTH, uuid.toString()) - .get() .url(url) .build(); @@ -98,7 +97,7 @@ public class LootTrackerClient { if (!response.isSuccessful()) { - log.debug("Error looking up loot: {}", response.message()); + log.debug("Error looking up loot: {}", response); return null; } diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/GrandExchangeClient.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java similarity index 91% rename from http-api/src/main/java/net/runelite/http/api/osbuddy/GrandExchangeClient.java rename to http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java index d80a739d29..c01337fdc0 100644 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/GrandExchangeClient.java +++ b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java @@ -35,9 +35,9 @@ import okhttp3.Request; import okhttp3.Response; @Slf4j -public class GrandExchangeClient +public class OSBGrandExchangeClient { - public GrandExchangeResult lookupItem(int itemId) throws IOException + public OSBGrandExchangeResult lookupItem(int itemId) throws IOException { final HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() .addPathSegment("osb") @@ -55,11 +55,11 @@ public class GrandExchangeClient { if (!response.isSuccessful()) { - throw new IOException("Error looking up item id: " + response.message()); + throw new IOException("Error looking up item id: " + response); } final InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), GrandExchangeResult.class); + return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), OSBGrandExchangeResult.class); } catch (JsonParseException ex) { diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/GrandExchangeResult.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java similarity index 97% rename from http-api/src/main/java/net/runelite/http/api/osbuddy/GrandExchangeResult.java rename to http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java index 993ee0d567..13e5f5e8e4 100644 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/GrandExchangeResult.java +++ b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java @@ -28,7 +28,7 @@ import java.time.Instant; import lombok.Data; @Data -public class GrandExchangeResult +public class OSBGrandExchangeResult { private int item_id; private int buy_average; diff --git a/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java b/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java index 1ac8195cce..668e088404 100644 --- a/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java +++ b/http-api/src/main/java/net/runelite/http/api/worlds/WorldClient.java @@ -57,7 +57,7 @@ public class WorldClient { if (!response.isSuccessful()) { - logger.debug("Error looking up worlds: {}", response.message()); + logger.debug("Error looking up worlds: {}", response); return null; } diff --git a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/Join.java b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/Join.java index 1c4cf2f73a..21aed0f653 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/Join.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/Join.java @@ -25,10 +25,12 @@ package net.runelite.http.api.ws.messages.party; import java.util.UUID; +import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.http.api.ws.WebsocketMessage; @Value +@EqualsAndHashCode(callSuper = true) public class Join extends WebsocketMessage { private final UUID partyId; diff --git a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java index 05d27b6790..81abe76827 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java @@ -25,10 +25,12 @@ package net.runelite.http.api.ws.messages.party; import java.util.UUID; +import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.http.api.ws.WebsocketMessage; @Value +@EqualsAndHashCode(callSuper = true) public class UserJoin extends WebsocketMessage { private final UUID memberId; diff --git a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserPart.java b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserPart.java index e3efbe4a9c..e80c6002bd 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserPart.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserPart.java @@ -25,10 +25,12 @@ package net.runelite.http.api.ws.messages.party; import java.util.UUID; +import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.http.api.ws.WebsocketMessage; @Value +@EqualsAndHashCode(callSuper = true) public class UserPart extends WebsocketMessage { private final UUID memberId; diff --git a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserSync.java b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserSync.java index eca9844845..c95038c9fa 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserSync.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserSync.java @@ -24,9 +24,11 @@ */ package net.runelite.http.api.ws.messages.party; +import lombok.EqualsAndHashCode; import lombok.Value; @Value +@EqualsAndHashCode(callSuper = true) public class UserSync extends PartyMemberMessage { } diff --git a/http-service/pom.xml b/http-service/pom.xml index 081195944c..83c3441649 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT Web Service @@ -55,6 +55,10 @@ spring-boot-devtools true + + org.springframework + spring-jdbc + org.mapstruct @@ -78,6 +82,12 @@ ${project.version} + + org.mariadb.jdbc + mariadb-java-client + 2.2.3 + provided + org.sql2o sql2o @@ -112,24 +122,28 @@ + + org.mongodb + mongodb-driver-sync + 3.10.1 + org.springframework.boot spring-boot-starter-test test - - mysql - mysql-connector-java - 5.1.43 - test - com.squareup.okhttp3 mockwebserver 3.7.0 test + + com.h2database + h2 + test + @@ -171,6 +185,56 @@ spring-boot-maven-plugin ${spring.boot.version} + + com.github.kongchen + swagger-maven-plugin + 3.1.8 + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + + + + true + + net.runelite + + + https + + api.runelite.net + /runelite-${project.version} + + ${project.parent.name} HTTP API + ${project.version} + ${project.description} + + https://tldrlegal.com/license/bsd-2-clause-license-(freebsd) + BSD 2-Clause "Simplified" + + + ${basedir}/src/main/templates/template.html.hbs + ${project.build.directory}/swagger-ui + ${project.build.directory}/site/api.html + true + json + + + + + + compile + + generate + + + + diff --git a/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java index 562d93445a..376ef11ec7 100644 --- a/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java +++ b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java @@ -25,13 +25,13 @@ package net.runelite.http.service; import ch.qos.logback.classic.LoggerContext; +import com.google.common.base.Strings; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; import java.io.IOException; import java.time.Instant; import java.util.HashMap; import java.util.Map; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -44,17 +44,23 @@ import okhttp3.Cache; import okhttp3.OkHttpClient; import org.slf4j.ILoggerFactory; import org.slf4j.impl.StaticLoggerBinder; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; +import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; import org.springframework.scheduling.annotation.EnableScheduling; import org.sql2o.Sql2o; import org.sql2o.converters.Converter; import org.sql2o.quirks.NoQuirks; -@SpringBootApplication +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @EnableScheduling @Slf4j public class SpringBootWebApplication extends SpringBootServletInitializer @@ -96,35 +102,86 @@ public class SpringBootWebApplication extends SpringBootServletInitializer }; } - private Context getContext() throws NamingException + @ConfigurationProperties(prefix = "datasource.runelite") + @Bean("dataSourceRuneLite") + public DataSourceProperties dataSourceProperties() { - Context initCtx = new InitialContext(); - return (Context) initCtx.lookup("java:comp/env"); + return new DataSourceProperties(); + } + + @ConfigurationProperties(prefix = "datasource.runelite-cache") + @Bean("dataSourceRuneLiteCache") + public DataSourceProperties dataSourcePropertiesCache() + { + return new DataSourceProperties(); + } + + @ConfigurationProperties(prefix = "datasource.runelite-tracker") + @Bean("dataSourceRuneLiteTracker") + public DataSourceProperties dataSourcePropertiesTracker() + { + return new DataSourceProperties(); + } + + @Bean(value = "runelite", destroyMethod = "") + public DataSource runeliteDataSource(@Qualifier("dataSourceRuneLite") DataSourceProperties dataSourceProperties) + { + return getDataSource(dataSourceProperties); + } + + @Bean(value = "runelite-cache", destroyMethod = "") + public DataSource runeliteCache2DataSource(@Qualifier("dataSourceRuneLiteCache") DataSourceProperties dataSourceProperties) + { + return getDataSource(dataSourceProperties); + } + + @Bean(value = "runelite-tracker", destroyMethod = "") + public DataSource runeliteTrackerDataSource(@Qualifier("dataSourceRuneLiteTracker") DataSourceProperties dataSourceProperties) + { + return getDataSource(dataSourceProperties); } @Bean("Runelite SQL2O") - Sql2o sql2o() throws NamingException + public Sql2o sql2o(@Qualifier("runelite") DataSource dataSource) { - DataSource dataSource = (DataSource) getContext().lookup("jdbc/runelite"); - Map converters = new HashMap<>(); - converters.put(Instant.class, new InstantConverter()); - return new Sql2o(dataSource, new NoQuirks(converters)); + return createSql2oFromDataSource(dataSource); } @Bean("Runelite Cache SQL2O") - Sql2o cacheSql2o() throws NamingException + public Sql2o cacheSql2o(@Qualifier("runelite-cache") DataSource dataSource) { - DataSource dataSource = (DataSource) getContext().lookup("jdbc/runelite-cache2"); - Map converters = new HashMap<>(); - converters.put(Instant.class, new InstantConverter()); - return new Sql2o(dataSource, new NoQuirks(converters)); + return createSql2oFromDataSource(dataSource); } @Bean("Runelite XP Tracker SQL2O") - Sql2o trackerSql2o() throws NamingException + public Sql2o trackerSql2o(@Qualifier("runelite-tracker") DataSource dataSource) { - DataSource dataSource = (DataSource) getContext().lookup("jdbc/runelite-tracker"); - Map converters = new HashMap<>(); + return createSql2oFromDataSource(dataSource); + } + + @Bean + public MongoClient mongoClient(@Value("${mongo.host}") String host) + { + return MongoClients.create(host); + } + + private static DataSource getDataSource(DataSourceProperties dataSourceProperties) + { + if (!Strings.isNullOrEmpty(dataSourceProperties.getJndiName())) + { + // Use JNDI provided datasource, which is already configured with pooling + JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); + return dataSourceLookup.getDataSource(dataSourceProperties.getJndiName()); + } + else + { + return dataSourceProperties.initializeDataSourceBuilder().build(); + } + } + + private static Sql2o createSql2oFromDataSource(final DataSource dataSource) + { + final Map converters = new HashMap<>(); converters.put(Instant.class, new InstantConverter()); return new Sql2o(dataSource, new NoQuirks(converters)); } diff --git a/http-service/src/main/java/net/runelite/http/service/SpringContentNegotiationConfigurer.java b/http-service/src/main/java/net/runelite/http/service/SpringWebMvcConfigurer.java similarity index 67% rename from http-service/src/main/java/net/runelite/http/service/SpringContentNegotiationConfigurer.java rename to http-service/src/main/java/net/runelite/http/service/SpringWebMvcConfigurer.java index ed055d0bdf..704e4f9cb2 100644 --- a/http-service/src/main/java/net/runelite/http/service/SpringContentNegotiationConfigurer.java +++ b/http-service/src/main/java/net/runelite/http/service/SpringWebMvcConfigurer.java @@ -24,22 +24,42 @@ */ package net.runelite.http.service; +import java.util.List; +import net.runelite.http.api.RuneLiteAPI; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -/** - * Configure .js as application/json to trick Cloudflare into caching json responses - */ @Configuration @EnableWebMvc -public class SpringContentNegotiationConfigurer extends WebMvcConfigurerAdapter +public class SpringWebMvcConfigurer extends WebMvcConfigurerAdapter { + /** + * Configure .js as application/json to trick Cloudflare into caching json responses + */ @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.mediaType("js", MediaType.APPLICATION_JSON); } + + /** + * Use GSON instead of Jackson for JSON serialization + * @param converters + */ + @Override + public void extendMessageConverters(List> converters) + { + // Could not figure out a better way to force GSON + converters.removeIf(MappingJackson2HttpMessageConverter.class::isInstance); + + GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter(); + gsonHttpMessageConverter.setGson(RuneLiteAPI.GSON); + converters.add(gsonHttpMessageConverter); + } } diff --git a/http-service/src/main/java/net/runelite/http/service/account/AccountService.java b/http-service/src/main/java/net/runelite/http/service/account/AccountService.java index 3ef3a98659..f9951446aa 100644 --- a/http-service/src/main/java/net/runelite/http/service/account/AccountService.java +++ b/http-service/src/main/java/net/runelite/http/service/account/AccountService.java @@ -33,6 +33,8 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.gson.Gson; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import java.util.concurrent.ExecutionException; import javax.servlet.http.HttpServletRequest; @@ -45,13 +47,12 @@ import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.service.account.beans.SessionEntry; import net.runelite.http.service.account.beans.UserEntry; import net.runelite.http.service.util.redis.RedisPool; -import net.runelite.http.service.ws.SessionManager; -import net.runelite.http.service.ws.WSService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -88,8 +89,7 @@ public class AccountService private static final String SCOPE = "https://www.googleapis.com/auth/userinfo.email"; private static final String USERINFO = "https://www.googleapis.com/oauth2/v2/userinfo"; - private static final String RL_OAUTH_URL = "https://api.runelite.net/oauth/"; - private static final String RL_REDIR = "http://runelite.net/logged-in"; + private static final String RL_REDIR = "https://runelite.net/logged-in"; private final Gson gson = RuneLiteAPI.GSON; private final Gson websocketGson = WebsocketGsonFactory.build(); @@ -97,6 +97,7 @@ public class AccountService private final Sql2o sql2o; private final String oauthClientId; private final String oauthClientSecret; + private final String oauthCallback; private final AuthFilter auth; private final RedisPool jedisPool; @@ -105,6 +106,7 @@ public class AccountService @Qualifier("Runelite SQL2O") Sql2o sql2o, @Value("${oauth.client-id}") String oauthClientId, @Value("${oauth.client-secret}") String oauthClientSecret, + @Value("${oauth.callback}") String oauthCallback, AuthFilter auth, RedisPool jedisPool ) @@ -112,6 +114,7 @@ public class AccountService this.sql2o = sql2o; this.oauthClientId = oauthClientId; this.oauthClientSecret = oauthClientSecret; + this.oauthCallback = oauthCallback; this.auth = auth; this.jedisPool = jedisPool; @@ -135,7 +138,7 @@ public class AccountService } } - @RequestMapping("/login") + @GetMapping("/login") public OAuthResponse login(@RequestParam UUID uuid) { State state = new State(); @@ -146,11 +149,14 @@ public class AccountService .apiKey(oauthClientId) .apiSecret(oauthClientSecret) .scope(SCOPE) - .callback(RL_OAUTH_URL) + .callback(oauthCallback) .state(gson.toJson(state)) .build(GoogleApi20.instance()); - String authorizationUrl = service.getAuthorizationUrl(); + final Map additionalParams = new HashMap<>(); + additionalParams.put("prompt", "select_account"); + + String authorizationUrl = service.getAuthorizationUrl(additionalParams); OAuthResponse lr = new OAuthResponse(); lr.setOauthUrl(authorizationUrl); @@ -159,7 +165,7 @@ public class AccountService return lr; } - @RequestMapping("/callback") + @GetMapping("/callback") public Object callback( HttpServletRequest request, HttpServletResponse response, @@ -182,7 +188,7 @@ public class AccountService .apiKey(oauthClientId) .apiSecret(oauthClientSecret) .scope(SCOPE) - .callback(RL_OAUTH_URL) + .callback(oauthCallback) .state(gson.toJson(state)) .build(GoogleApi20.instance()); @@ -241,19 +247,13 @@ public class AccountService LoginResponse response = new LoginResponse(); response.setUsername(username); - WSService service = SessionManager.findSession(uuid); - if (service != null) - { - service.send(response); - } - try (Jedis jedis = jedisPool.getResource()) { jedis.publish("session." + uuid, websocketGson.toJson(response, WebsocketMessage.class)); } } - @RequestMapping("/logout") + @GetMapping("/logout") public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException { SessionEntry session = auth.handle(request, response); @@ -271,15 +271,9 @@ public class AccountService } } - @RequestMapping("/session-check") + @GetMapping("/session-check") public void sessionCheck(HttpServletRequest request, HttpServletResponse response) throws IOException { auth.handle(request, response); } - - @RequestMapping("/wscount") - public int wscount() - { - return SessionManager.getCount(); - } } diff --git a/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java b/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java index 9e4c0ab0bb..f86f453412 100644 --- a/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java +++ b/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java @@ -62,6 +62,7 @@ import net.runelite.http.service.cache.beans.IndexEntry; import net.runelite.http.service.util.exception.NotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -75,7 +76,7 @@ public class CacheController @Autowired private CacheService cacheService; - @RequestMapping("/") + @GetMapping("/") public List listCaches() { return cacheService.listCaches().stream() @@ -83,7 +84,7 @@ public class CacheController .collect(Collectors.toList()); } - @RequestMapping("{cacheId}") + @GetMapping("{cacheId}") public List listIndexes(@PathVariable int cacheId) { CacheEntry cache = cacheService.findCache(cacheId); @@ -99,7 +100,7 @@ public class CacheController .collect(Collectors.toList()); } - @RequestMapping("{cacheId}/{indexId}") + @GetMapping("{cacheId}/{indexId}") public List listArchives(@PathVariable int cacheId, @PathVariable int indexId) { @@ -122,7 +123,7 @@ public class CacheController .collect(Collectors.toList()); } - @RequestMapping("{cacheId}/{indexId}/{archiveId}") + @GetMapping("{cacheId}/{indexId}/{archiveId}") public CacheArchive getCacheArchive(@PathVariable int cacheId, @PathVariable int indexId, @PathVariable int archiveId) @@ -149,7 +150,7 @@ public class CacheController archiveEntry.getNameHash(), archiveEntry.getRevision()); } - @RequestMapping("{cacheId}/{indexId}/{archiveId}/data") + @GetMapping("{cacheId}/{indexId}/{archiveId}/data") public byte[] getArchiveData( @PathVariable int cacheId, @PathVariable int indexId, @@ -200,7 +201,7 @@ public class CacheController return archiveEntry; } - @RequestMapping("item/{itemId}") + @GetMapping("item/{itemId}") public ItemDefinition getItem(@PathVariable int itemId) throws IOException { ArchiveEntry archiveEntry = findConfig(ConfigType.ITEM); @@ -221,7 +222,7 @@ public class CacheController return itemdef; } - @RequestMapping(path = "item/{itemId}/image", produces = "image/png") + @GetMapping(path = "item/{itemId}/image", produces = "image/png") public ResponseEntity getItemImage( @PathVariable int itemId, @RequestParam(defaultValue = "1") int quantity, @@ -313,7 +314,7 @@ public class CacheController return ResponseEntity.ok(bao.toByteArray()); } - @RequestMapping("object/{objectId}") + @GetMapping("object/{objectId}") public ObjectDefinition getObject( @PathVariable int objectId ) throws IOException @@ -336,7 +337,7 @@ public class CacheController return objectdef; } - @RequestMapping("npc/{npcId}") + @GetMapping("npc/{npcId}") public NpcDefinition getNpc( @PathVariable int npcId ) throws IOException diff --git a/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java b/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java index 882e90c460..e0fca4ac21 100644 --- a/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java +++ b/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java @@ -41,6 +41,7 @@ import java.io.InputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import lombok.extern.slf4j.Slf4j; import net.runelite.cache.ConfigType; @@ -233,6 +234,11 @@ public class CacheService public List getItems() throws IOException { CacheEntry cache = findMostRecent(); + if (cache == null) + { + return Collections.emptyList(); + } + IndexEntry indexEntry = findIndexForCache(cache, IndexType.CONFIGS.getNumber()); ArchiveEntry archiveEntry = findArchiveForIndex(indexEntry, ConfigType.ITEM.getId()); ArchiveFiles archiveFiles = getArchiveFiles(archiveEntry); diff --git a/http-service/src/main/java/net/runelite/http/service/config/ConfigController.java b/http-service/src/main/java/net/runelite/http/service/config/ConfigController.java new file mode 100644 index 0000000000..b14a03659c --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/config/ConfigController.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.config; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import net.runelite.http.api.config.Configuration; +import net.runelite.http.service.account.AuthFilter; +import net.runelite.http.service.account.beans.SessionEntry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import static org.springframework.web.bind.annotation.RequestMethod.DELETE; +import static org.springframework.web.bind.annotation.RequestMethod.PUT; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/config") +public class ConfigController +{ + private final ConfigService configService; + private final AuthFilter authFilter; + + @Autowired + public ConfigController(ConfigService configService, AuthFilter authFilter) + { + this.configService = configService; + this.authFilter = authFilter; + } + + @GetMapping + public Configuration get(HttpServletRequest request, HttpServletResponse response) throws IOException + { + SessionEntry session = authFilter.handle(request, response); + + if (session == null) + { + return null; + } + + return configService.get(session.getUser()); + } + + @RequestMapping(path = "/{key:.+}", method = PUT) + public void setKey( + HttpServletRequest request, + HttpServletResponse response, + @PathVariable String key, + @RequestBody(required = false) String value + ) throws IOException + { + SessionEntry session = authFilter.handle(request, response); + + if (session == null) + { + return; + } + + configService.setKey(session.getUser(), key, value); + } + + @RequestMapping(path = "/{key:.+}", method = DELETE) + public void unsetKey( + HttpServletRequest request, + HttpServletResponse response, + @PathVariable String key + ) throws IOException + { + SessionEntry session = authFilter.handle(request, response); + + if (session == null) + { + return; + } + + configService.unsetKey(session.getUser(), key); + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java b/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java index 102e2f9c7a..de665fc44f 100644 --- a/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java +++ b/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Adam + * Copyright (c) 2017-2019, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,28 +24,36 @@ */ package net.runelite.http.service.config; -import java.io.IOException; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import static com.mongodb.client.model.Filters.eq; +import com.mongodb.client.model.IndexOptions; +import com.mongodb.client.model.Indexes; +import static com.mongodb.client.model.Updates.set; +import static com.mongodb.client.model.Updates.unset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import java.util.Map; +import javax.annotation.Nullable; +import lombok.extern.slf4j.Slf4j; +import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.config.ConfigEntry; import net.runelite.http.api.config.Configuration; -import net.runelite.http.service.account.AuthFilter; -import net.runelite.http.service.account.beans.SessionEntry; +import org.bson.Document; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import static org.springframework.web.bind.annotation.RequestMethod.DELETE; -import static org.springframework.web.bind.annotation.RequestMethod.PUT; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.stereotype.Service; import org.sql2o.Connection; import org.sql2o.Sql2o; import org.sql2o.Sql2oException; -@RestController -@RequestMapping("/config") +@Service +@Slf4j public class ConfigService { private static final String CREATE_CONFIG = "CREATE TABLE IF NOT EXISTS `config` (\n" @@ -59,16 +67,17 @@ public class ConfigService + " ADD CONSTRAINT `user_fk` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;"; private final Sql2o sql2o; - private final AuthFilter auth; + private final Gson GSON = RuneLiteAPI.GSON; + + private final MongoCollection mongoCollection; @Autowired public ConfigService( @Qualifier("Runelite SQL2O") Sql2o sql2o, - AuthFilter auth + MongoClient mongoClient ) { this.sql2o = sql2o; - this.auth = auth; try (Connection con = sql2o.open()) { @@ -85,75 +94,160 @@ public class ConfigService // Ignore, happens when index already exists } } + + MongoDatabase database = mongoClient.getDatabase("config"); + MongoCollection collection = database.getCollection("config"); + this.mongoCollection = collection; + + // Create unique index on _userId + IndexOptions indexOptions = new IndexOptions().unique(true); + collection.createIndex(Indexes.ascending("_userId"), indexOptions); } - @RequestMapping - public Configuration get(HttpServletRequest request, HttpServletResponse response) throws IOException + private Document getConfig(int userId) { - SessionEntry session = auth.handle(request, response); + return mongoCollection.find(eq("_userId", userId)).first(); + } - if (session == null) + public Configuration get(int userId) + { + Map configMap = getConfig(userId); + + if (configMap == null || configMap.isEmpty()) { - return null; + return new Configuration(Collections.emptyList()); } - List config; + List config = new ArrayList<>(); - try (Connection con = sql2o.open()) + for (String group : configMap.keySet()) { - config = con.createQuery("select `key`, value from config where user = :user") - .addParameter("user", session.getUser()) - .executeAndFetch(ConfigEntry.class); + // Reserved keys + if (group.startsWith("_") || group.startsWith("$")) + { + continue; + } + + Map groupMap = (Map) configMap.get(group); + + for (Map.Entry entry : groupMap.entrySet()) + { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof Map || value instanceof Collection) + { + value = GSON.toJson(entry.getValue()); + } + else if (value == null) + { + continue; + } + + ConfigEntry configEntry = new ConfigEntry(); + configEntry.setKey(group + "." + key.replace(':', '.')); + configEntry.setValue(value.toString()); + config.add(configEntry); + } } return new Configuration(config); } - @RequestMapping(path = "/{key:.+}", method = PUT) public void setKey( - HttpServletRequest request, - HttpServletResponse response, - @PathVariable String key, - @RequestBody(required = false) String value - ) throws IOException + int userId, + String key, + @Nullable String value + ) { - SessionEntry session = auth.handle(request, response); - - if (session == null) - { - return; - } - try (Connection con = sql2o.open()) { con.createQuery("insert into config (user, `key`, value) values (:user, :key, :value) on duplicate key update `key` = :key, value = :value") - .addParameter("user", session.getUser()) + .addParameter("user", userId) .addParameter("key", key) .addParameter("value", value != null ? value : "") .executeUpdate(); } - } - @RequestMapping(path = "/{key:.+}", method = DELETE) - public void unsetKey( - HttpServletRequest request, - HttpServletResponse response, - @PathVariable String key - ) throws IOException - { - SessionEntry session = auth.handle(request, response); - - if (session == null) + if (key.startsWith("$") || key.startsWith("_")) { return; } + String[] split = key.split("\\.", 2); + if (split.length != 2) + { + return; + } + + Object jsonValue = parseJsonString(value); + mongoCollection.updateOne(eq("_userId", userId), + set(split[0] + "." + split[1].replace('.', ':'), jsonValue)); + } + + public void unsetKey( + int userId, + String key + ) + { try (Connection con = sql2o.open()) { con.createQuery("delete from config where user = :user and `key` = :key") - .addParameter("user", session.getUser()) + .addParameter("user", userId) .addParameter("key", key) .executeUpdate(); } + + if (key.startsWith("$") || key.startsWith("_")) + { + return; + } + + String[] split = key.split("\\.", 2); + if (split.length != 2) + { + return; + } + + mongoCollection.updateOne(eq("_userId", userId), + unset(split[0] + "." + split[1].replace('.', ':'))); + } + + private static Object parseJsonString(String value) + { + Object jsonValue; + try + { + jsonValue = RuneLiteAPI.GSON.fromJson(value, Object.class); + + if (jsonValue instanceof Double || jsonValue instanceof Float) + { + Number number = (Number) jsonValue; + if (Math.floor(number.doubleValue()) == number.doubleValue() && !Double.isInfinite(number.doubleValue())) + { + // value is an int or long. 'number' might be truncated so parse it from 'value' + try + { + jsonValue = Integer.parseInt(value); + } + catch (NumberFormatException ex) + { + try + { + jsonValue = Long.parseLong(value); + } + catch (NumberFormatException ex2) + { + + } + } + } + } + } + catch (JsonSyntaxException ex) + { + jsonValue = value; + } + return jsonValue; } } diff --git a/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java b/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java index c689172e9b..b7e079497f 100644 --- a/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java +++ b/http-service/src/main/java/net/runelite/http/service/examine/ExamineController.java @@ -30,6 +30,7 @@ import static net.runelite.http.service.examine.ExamineType.OBJECT; import net.runelite.http.service.item.ItemEntry; import net.runelite.http.service.item.ItemService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -50,19 +51,19 @@ public class ExamineController this.itemService = itemService; } - @RequestMapping("/npc/{id}") + @GetMapping("/npc/{id}") public String getNpc(@PathVariable int id) { return examineService.get(NPC, id); } - @RequestMapping("/object/{id}") + @GetMapping("/object/{id}") public String getObject(@PathVariable int id) { return examineService.get(OBJECT, id); } - @RequestMapping("/item/{id}") + @GetMapping("/item/{id}") public String getItem(@PathVariable int id) { // Tradeable item examine info is available from the Jagex item API diff --git a/http-service/src/main/java/net/runelite/http/service/feed/FeedController.java b/http-service/src/main/java/net/runelite/http/service/feed/FeedController.java index 8b55d1b93a..c679cd319f 100644 --- a/http-service/src/main/java/net/runelite/http/service/feed/FeedController.java +++ b/http-service/src/main/java/net/runelite/http/service/feed/FeedController.java @@ -38,6 +38,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.CacheControl; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -71,7 +72,7 @@ public class FeedController } catch (IOException e) { - log.warn(null, e); + log.warn(e.getMessage()); } try @@ -80,7 +81,7 @@ public class FeedController } catch (IOException e) { - log.warn(null, e); + log.warn(e.getMessage()); } try @@ -89,13 +90,13 @@ public class FeedController } catch (IOException e) { - log.warn(null, e); + log.warn(e.getMessage()); } feedResult = new FeedResult(items); } - @RequestMapping + @GetMapping public ResponseEntity getFeed() { if (feedResult == null) diff --git a/http-service/src/main/java/net/runelite/http/service/feed/blog/BlogService.java b/http-service/src/main/java/net/runelite/http/service/feed/blog/BlogService.java index 6b94b609d5..9da6cc171b 100644 --- a/http-service/src/main/java/net/runelite/http/service/feed/blog/BlogService.java +++ b/http-service/src/main/java/net/runelite/http/service/feed/blog/BlogService.java @@ -63,7 +63,7 @@ public class BlogService { if (!response.isSuccessful()) { - throw new IOException("Error getting blog posts: " + response.message()); + throw new IOException("Error getting blog posts: " + response); } try diff --git a/http-service/src/main/java/net/runelite/http/service/feed/osrsnews/OSRSNewsService.java b/http-service/src/main/java/net/runelite/http/service/feed/osrsnews/OSRSNewsService.java index 951e4da551..0ae08bc85c 100644 --- a/http-service/src/main/java/net/runelite/http/service/feed/osrsnews/OSRSNewsService.java +++ b/http-service/src/main/java/net/runelite/http/service/feed/osrsnews/OSRSNewsService.java @@ -50,7 +50,7 @@ import org.xml.sax.SAXException; @Service public class OSRSNewsService { - private static final HttpUrl RSS_URL = HttpUrl.parse("http://services.runescape.com/m=news/latest_news.rss?oldschool=true"); + private static final HttpUrl RSS_URL = HttpUrl.parse("https://services.runescape.com/m=news/latest_news.rss?oldschool=true"); private static final SimpleDateFormat PUB_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy '00:00:00 GMT'", Locale.US); public List getNews() throws IOException @@ -63,7 +63,7 @@ public class OSRSNewsService { if (!response.isSuccessful()) { - throw new IOException("Error getting OSRS news: " + response.message()); + throw new IOException("Error getting OSRS news: " + response); } try diff --git a/http-service/src/main/java/net/runelite/http/service/feed/twitter/TwitterService.java b/http-service/src/main/java/net/runelite/http/service/feed/twitter/TwitterService.java index 230fd2d974..9bb9dc8595 100644 --- a/http-service/src/main/java/net/runelite/http/service/feed/twitter/TwitterService.java +++ b/http-service/src/main/java/net/runelite/http/service/feed/twitter/TwitterService.java @@ -103,9 +103,9 @@ public class TwitterService { return getTweets(true); } - throw new InternalServerErrorException("Could not auth to Twitter after trying once: " + response.message()); + throw new InternalServerErrorException("Could not auth to Twitter after trying once: " + response); default: - throw new IOException("Error getting Twitter list: " + response.message()); + throw new IOException("Error getting Twitter list: " + response); } } @@ -124,7 +124,7 @@ public class TwitterService i.getUser().getProfileImageUrl(), i.getUser().getScreenName(), i.getText().replace("\n\n", " ").replaceAll("\n", " "), - "https://twitter.com/statuses/" + i.getId(), + "https://twitter.com/" + i.getUser().getScreenName() + "/status/" + i.getId(), getTimestampFromSnowflake(i.getId()))); } @@ -146,7 +146,7 @@ public class TwitterService { if (!response.isSuccessful()) { - throw new IOException("Error authing to Twitter: " + response.message()); + throw new IOException("Error authing to Twitter: " + response); } InputStream in = response.body().byteStream(); diff --git a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java new file mode 100644 index 0000000000..94c759b130 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.ge; + +import java.io.IOException; +import java.util.Collection; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import net.runelite.http.api.ge.GrandExchangeTrade; +import net.runelite.http.service.account.AuthFilter; +import net.runelite.http.service.account.beans.SessionEntry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/ge") +public class GrandExchangeController +{ + private final GrandExchangeService grandExchangeService; + private final AuthFilter authFilter; + + @Autowired + public GrandExchangeController(GrandExchangeService grandExchangeService, AuthFilter authFilter) + { + this.grandExchangeService = grandExchangeService; + this.authFilter = authFilter; + } + + @PostMapping + public void submit(HttpServletRequest request, HttpServletResponse response, @RequestBody GrandExchangeTrade grandExchangeTrade) throws IOException + { + SessionEntry session = authFilter.handle(request, response); + + if (session == null) + { + return; + } + + grandExchangeService.add(session.getUser(), grandExchangeTrade); + } + + @GetMapping + public Collection get(HttpServletRequest request, HttpServletResponse response, + @RequestParam(required = false, defaultValue = "1024") int limit, + @RequestParam(required = false, defaultValue = "0") int offset) throws IOException + { + SessionEntry session = authFilter.handle(request, response); + + if (session == null) + { + return null; + } + + return grandExchangeService.get(session.getUser(), limit, offset).stream() + .map(GrandExchangeController::convert) + .collect(Collectors.toList()); + } + + private static GrandExchangeTrade convert(TradeEntry tradeEntry) + { + GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade(); + grandExchangeTrade.setBuy(tradeEntry.getAction() == TradeAction.BUY); + grandExchangeTrade.setItemId(tradeEntry.getItem()); + grandExchangeTrade.setQuantity(tradeEntry.getQuantity()); + grandExchangeTrade.setPrice(tradeEntry.getPrice()); + grandExchangeTrade.setTime(tradeEntry.getTime()); + return grandExchangeTrade; + } + + @DeleteMapping + public void delete(HttpServletRequest request, HttpServletResponse response) throws IOException + { + SessionEntry session = authFilter.handle(request, response); + + if (session == null) + { + return; + } + + grandExchangeService.delete(session.getUser()); + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java new file mode 100644 index 0000000000..6456beb85f --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeService.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.ge; + +import java.util.Collection; +import net.runelite.http.api.ge.GrandExchangeTrade; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.sql2o.Connection; +import org.sql2o.Sql2o; + +@Service +public class GrandExchangeService +{ + private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS `ge_trades` (\n" + + " `id` int(11) NOT NULL AUTO_INCREMENT,\n" + + " `user` int(11) NOT NULL,\n" + + " `action` enum('BUY','SELL') NOT NULL,\n" + + " `item` int(11) NOT NULL,\n" + + " `quantity` int(11) NOT NULL,\n" + + " `price` int(11) NOT NULL,\n" + + " `time` timestamp NOT NULL DEFAULT current_timestamp(),\n" + + " PRIMARY KEY (`id`),\n" + + " KEY `user_time` (`user`, `time`),\n" + + " KEY `time` (`time`),\n" + + " CONSTRAINT `ge_trades_ibfk_1` FOREIGN KEY (`user`) REFERENCES `users` (`id`)\n" + + ") ENGINE=InnoDB;"; + + private final Sql2o sql2o; + + @Autowired + public GrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o) + { + this.sql2o = sql2o; + + // Ensure necessary tables exist + try (Connection con = sql2o.open()) + { + con.createQuery(CREATE_TABLE).executeUpdate(); + } + } + + public void add(int userId, GrandExchangeTrade grandExchangeTrade) + { + try (Connection con = sql2o.open()) + { + con.createQuery("insert into ge_trades (user, action, item, quantity, price) values (:user," + + " :action, :item, :quantity, :price)") + .addParameter("user", userId) + .addParameter("action", grandExchangeTrade.isBuy() ? "BUY" : "SELL") + .addParameter("item", grandExchangeTrade.getItemId()) + .addParameter("quantity", grandExchangeTrade.getQuantity()) + .addParameter("price", grandExchangeTrade.getPrice()) + .executeUpdate(); + } + } + + public Collection get(int userId, int limit, int offset) + { + try (Connection con = sql2o.open()) + { + return con.createQuery("select id, user, action, item, quantity, price, time from ge_trades where user = :user limit :limit offset :offset") + .addParameter("user", userId) + .addParameter("limit", limit) + .addParameter("offset", offset) + .executeAndFetch(TradeEntry.class); + } + } + + public void delete(int userId) + { + try (Connection con = sql2o.open()) + { + con.createQuery("delete from ge_trades where user = :user") + .addParameter("user", userId) + .executeUpdate(); + } + } + + @Scheduled(fixedDelay = 60 * 60 * 1000) + public void expire() + { + try (Connection con = sql2o.open()) + { + con.createQuery("delete from ge_trades where time < current_timestamp - interval 1 month") + .executeUpdate(); + } + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/ge/TradeAction.java b/http-service/src/main/java/net/runelite/http/service/ge/TradeAction.java new file mode 100644 index 0000000000..fcc96d615f --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/ge/TradeAction.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.ge; + +enum TradeAction +{ + BUY, + SELL; +} diff --git a/http-service/src/main/java/net/runelite/http/service/ge/TradeEntry.java b/http-service/src/main/java/net/runelite/http/service/ge/TradeEntry.java new file mode 100644 index 0000000000..bca3869811 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/ge/TradeEntry.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.ge; + +import java.time.Instant; +import lombok.Data; + +@Data +class TradeEntry +{ + private int id; + private int user; + private TradeAction action; + private int item; + private int quantity; + private int price; + private Instant time; +} diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java index d144b7db79..25a89e6a8d 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java +++ b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java @@ -34,6 +34,7 @@ import net.runelite.http.service.util.HiscoreEndpointEditor; import net.runelite.http.service.xp.XpTrackerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -50,7 +51,7 @@ public class HiscoreController @Autowired private XpTrackerService xpTrackerService; - @RequestMapping("/{endpoint}") + @GetMapping("/{endpoint}") public HiscoreResult lookup(@PathVariable HiscoreEndpoint endpoint, @RequestParam String username) throws ExecutionException { HiscoreResult result = hiscoreService.lookupUsername(username, endpoint); @@ -68,7 +69,7 @@ public class HiscoreController return result; } - @RequestMapping("/{endpoint}/{skillName}") + @GetMapping("/{endpoint}/{skillName}") public SingleHiscoreSkillResult singleSkillLookup(@PathVariable HiscoreEndpoint endpoint, @PathVariable String skillName, @RequestParam String username) throws ExecutionException { HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase()); diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemController.java b/http-service/src/main/java/net/runelite/http/service/item/ItemController.java index 9c05889330..9d1ed5710e 100644 --- a/http-service/src/main/java/net/runelite/http/service/item/ItemController.java +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemController.java @@ -40,6 +40,7 @@ import net.runelite.http.api.item.SearchResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.CacheControl; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -78,7 +79,7 @@ public class ItemController .toArray(ItemPrice[]::new), 30, TimeUnit.MINUTES); } - @RequestMapping("/{itemId}") + @GetMapping("/{itemId}") public Item getItem(HttpServletResponse response, @PathVariable int itemId) { ItemEntry item = itemService.getItem(itemId); @@ -91,7 +92,7 @@ public class ItemController return null; } - @RequestMapping(path = "/{itemId}/icon", produces = "image/gif") + @GetMapping(path = "/{itemId}/icon", produces = "image/gif") public ResponseEntity getIcon(@PathVariable int itemId) { ItemEntry item = itemService.getItem(itemId); @@ -104,7 +105,7 @@ public class ItemController return ResponseEntity.notFound().build(); } - @RequestMapping(path = "/{itemId}/icon/large", produces = "image/gif") + @GetMapping(path = "/{itemId}/icon/large", produces = "image/gif") public ResponseEntity getIconLarge(HttpServletResponse response, @PathVariable int itemId) { ItemEntry item = itemService.getItem(itemId); @@ -117,7 +118,7 @@ public class ItemController return ResponseEntity.notFound().build(); } - @RequestMapping("/{itemId}/price") + @GetMapping("/{itemId}/price") public ResponseEntity itemPrice( @PathVariable int itemId, @RequestParam(required = false) Instant time @@ -179,7 +180,7 @@ public class ItemController .body(itemPrice); } - @RequestMapping("/search") + @GetMapping("/search") public SearchResult search(@RequestParam String query) { List result = itemService.search(query); @@ -193,7 +194,7 @@ public class ItemController return searchResult; } - @RequestMapping("/price") + @GetMapping("/price") public ItemPrice[] prices(@RequestParam("id") int[] itemIds) { if (itemIds.length > MAX_BATCH_LOOKUP) @@ -216,7 +217,7 @@ public class ItemController .toArray(ItemPrice[]::new); } - @RequestMapping("/prices") + @GetMapping("/prices") public ResponseEntity prices() { return ResponseEntity.ok() diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java index 2da7a50028..72a0fe85aa 100644 --- a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java @@ -377,7 +377,7 @@ public class ItemService { if (!response.isSuccessful()) { - throw new IOException("Unsuccessful http response: " + response.message()); + throw new IOException("Unsuccessful http response: " + response); } InputStream in = response.body().byteStream(); @@ -401,7 +401,7 @@ public class ItemService { if (!response.isSuccessful()) { - throw new IOException("Unsuccessful http response: " + response.message()); + throw new IOException("Unsuccessful http response: " + response); } return response.body().bytes(); @@ -489,10 +489,16 @@ public class ItemService public void reloadItems() throws IOException { List items = cacheService.getItems(); + if (items.isEmpty()) + { + log.warn("Failed to load any items from cache, item price updating will be disabled"); + } + tradeableItems = items.stream() .filter(item -> item.isTradeable) .mapToInt(item -> item.id) .toArray(); + log.debug("Loaded {} tradeable items", tradeableItems.length); } diff --git a/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerController.java b/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerController.java index 36e0a2333d..2c1bd77140 100644 --- a/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerController.java +++ b/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerController.java @@ -35,6 +35,7 @@ import net.runelite.http.service.account.AuthFilter; import net.runelite.http.service.account.beans.SessionEntry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -65,8 +66,8 @@ public class LootTrackerController response.setStatus(HttpStatusCodes.STATUS_CODE_OK); } - @RequestMapping - public Collection getLootRecords(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "count", defaultValue = "1024") int count) throws IOException + @GetMapping + public Collection getLootRecords(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "count", defaultValue = "1024") int count, @RequestParam(value = "start", defaultValue = "0") int start) throws IOException { SessionEntry e = auth.handle(request, response); if (e == null) @@ -75,7 +76,7 @@ public class LootTrackerController return null; } - return service.get(e.getUser(), count); + return service.get(e.getUser(), count, start); } @DeleteMapping diff --git a/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerService.java b/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerService.java index 386a1d04b0..b999f4eabb 100644 --- a/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerService.java +++ b/http-service/src/main/java/net/runelite/http/service/loottracker/LootTrackerService.java @@ -49,7 +49,7 @@ public class LootTrackerService + " `type` enum('NPC', 'PLAYER', 'EVENT', 'UNKNOWN') NOT NULL,\n" + " `eventId` VARCHAR(255) NOT NULL,\n" + " PRIMARY KEY (id),\n" - + " FOREIGN KEY (accountId) REFERENCES sessions(user) ON DELETE CASCADE,\n" + + " FOREIGN KEY (accountId) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE,\n" + " INDEX idx_acc (accountId, time)," + " INDEX idx_time (time)" + ") ENGINE=InnoDB"; @@ -66,7 +66,7 @@ public class LootTrackerService private static final String INSERT_KILL_QUERY = "INSERT INTO kills (accountId, type, eventId) VALUES (:accountId, :type, :eventId)"; private static final String INSERT_DROP_QUERY = "INSERT INTO drops (killId, itemId, itemQuantity) VALUES (LAST_INSERT_ID(), :itemId, :itemQuantity)"; - private static final String SELECT_LOOT_QUERY = "SELECT killId,time,type,eventId,itemId,itemQuantity FROM kills JOIN drops ON drops.killId = kills.id WHERE accountId = :accountId ORDER BY TIME DESC LIMIT :limit"; + private static final String SELECT_LOOT_QUERY = "SELECT killId,time,type,eventId,itemId,itemQuantity FROM kills JOIN drops ON drops.killId = kills.id WHERE accountId = :accountId ORDER BY TIME DESC LIMIT :limit OFFSET :offset"; private static final String DELETE_LOOT_ACCOUNT = "DELETE FROM kills WHERE accountId = :accountId"; private static final String DELETE_LOOT_ACCOUNT_EVENTID = "DELETE FROM kills WHERE accountId = :accountId AND eventId = :eventId"; @@ -119,7 +119,7 @@ public class LootTrackerService } } - public Collection get(int accountId, int limit) + public Collection get(int accountId, int limit, int offset) { List lootResults; @@ -128,6 +128,7 @@ public class LootTrackerService lootResults = con.createQuery(SELECT_LOOT_QUERY) .addParameter("accountId", accountId) .addParameter("limit", limit) + .addParameter("offset", offset) .executeAndFetch(LootResult.class); } @@ -141,7 +142,7 @@ public class LootTrackerService { if (!gameItems.isEmpty()) { - LootRecord lootRecord = new LootRecord(current.getEventId(), current.getType(), gameItems); + LootRecord lootRecord = new LootRecord(current.getEventId(), current.getType(), gameItems, current.getTime()); lootRecords.add(lootRecord); gameItems = new ArrayList<>(); @@ -156,7 +157,7 @@ public class LootTrackerService if (!gameItems.isEmpty()) { - LootRecord lootRecord = new LootRecord(current.getEventId(), current.getType(), gameItems); + LootRecord lootRecord = new LootRecord(current.getEventId(), current.getType(), gameItems, current.getTime()); lootRecords.add(lootRecord); } diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeController.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java similarity index 90% rename from http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeController.java rename to http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java index 92ba9093e7..eaade27c12 100644 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeController.java +++ b/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeController.java @@ -29,23 +29,24 @@ import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.CacheControl; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/osb/ge") -public class GrandExchangeController +public class OSBGrandExchangeController { - private final GrandExchangeService grandExchangeService; + private final OSBGrandExchangeService grandExchangeService; @Autowired - public GrandExchangeController(GrandExchangeService grandExchangeService) + public OSBGrandExchangeController(OSBGrandExchangeService grandExchangeService) { this.grandExchangeService = grandExchangeService; } - @RequestMapping + @GetMapping public ResponseEntity get(@RequestParam("itemId") int itemId) throws ExecutionException { GrandExchangeEntry grandExchangeEntry = grandExchangeService.get(itemId); diff --git a/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeService.java b/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java similarity index 97% rename from http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeService.java rename to http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java index f7addee899..797d7e76e2 100644 --- a/http-service/src/main/java/net/runelite/http/service/osbuddy/GrandExchangeService.java +++ b/http-service/src/main/java/net/runelite/http/service/osbuddy/OSBGrandExchangeService.java @@ -40,7 +40,7 @@ import org.sql2o.Sql2o; @Service @Slf4j -public class GrandExchangeService +public class OSBGrandExchangeService { private static final String CREATE_GRAND_EXCHANGE_PRICES = "CREATE TABLE IF NOT EXISTS `osb_ge` (\n" + " `item_id` int(11) NOT NULL,\n" @@ -56,7 +56,7 @@ public class GrandExchangeService private final Sql2o sql2o; @Autowired - public GrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o) + public OSBGrandExchangeService(@Qualifier("Runelite SQL2O") Sql2o sql2o) { this.sql2o = sql2o; diff --git a/http-service/src/main/java/net/runelite/http/service/sprite/SpriteController.java b/http-service/src/main/java/net/runelite/http/service/sprite/SpriteController.java index 42b285761e..80d8f738ba 100644 --- a/http-service/src/main/java/net/runelite/http/service/sprite/SpriteController.java +++ b/http-service/src/main/java/net/runelite/http/service/sprite/SpriteController.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -55,7 +56,7 @@ public class SpriteController } }); - @RequestMapping(produces = "image/png") + @GetMapping(produces = "image/png") public ResponseEntity getSprite( @RequestParam int spriteId, @RequestParam(defaultValue = "0") int frameId diff --git a/http-service/src/main/java/net/runelite/http/service/worlds/WorldController.java b/http-service/src/main/java/net/runelite/http/service/worlds/WorldController.java index 7dba1bc1dd..51769e181c 100644 --- a/http-service/src/main/java/net/runelite/http/service/worlds/WorldController.java +++ b/http-service/src/main/java/net/runelite/http/service/worlds/WorldController.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.CacheControl; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -45,7 +46,7 @@ public class WorldController private WorldResult worldResult; - @RequestMapping + @GetMapping public ResponseEntity listWorlds() throws IOException { return ResponseEntity.ok() diff --git a/http-service/src/main/java/net/runelite/http/service/ws/WSService.java b/http-service/src/main/java/net/runelite/http/service/ws/WSService.java deleted file mode 100644 index 05489f2b87..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/ws/WSService.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.http.service.ws; - -import com.google.gson.Gson; -import java.util.UUID; -import javax.websocket.CloseReason; -import javax.websocket.EndpointConfig; -import javax.websocket.OnClose; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpoint; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import net.runelite.http.api.ws.WebsocketGsonFactory; -import net.runelite.http.api.ws.WebsocketMessage; -import net.runelite.http.api.ws.messages.Handshake; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ServerEndpoint("/ws") -public class WSService -{ - private static final Logger logger = LoggerFactory.getLogger(WSService.class); - - private static final Gson gson = WebsocketGsonFactory.build(); - - private Session session; - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private UUID uuid; - - public void send(WebsocketMessage message) - { - String json = gson.toJson(message, WebsocketMessage.class); - - logger.debug("Sending {}", json); - - session.getAsyncRemote().sendText(json); - } - - @OnOpen - public void onOpen(Session session, EndpointConfig config) - { - this.session = session; - logger.debug("New session {}", session); - } - - @OnClose - public void onClose(Session session, CloseReason resaon) - { - SessionManager.remove(this); - logger.debug("Close session {}", session); - } - - @OnError - public void onError(Session session, Throwable ex) - { - SessionManager.remove(this); - logger.debug("Error in session {}", session, ex); - } - - @OnMessage - public void onMessage(Session session, String text) - { - WebsocketMessage message = gson.fromJson(text, WebsocketMessage.class); - logger.debug("Got message: {}", message); - - if (message instanceof Handshake) - { - Handshake hs = (Handshake) message; - SessionManager.changeSessionUID(this, hs.getSession()); - } - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java b/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java index ad72f43c47..068c6e5438 100644 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java +++ b/http-service/src/main/java/net/runelite/http/service/xp/XpMapper.java @@ -38,6 +38,8 @@ public interface XpMapper XpData xpEntityToXpData(XpEntity xpEntity); + @Mapping(target = "time", ignore = true) + @Mapping(source = "attack.experience", target = "attack_xp") @Mapping(source = "defence.experience", target = "defence_xp") @Mapping(source = "strength.experience", target = "strength_xp") diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java index 9710faef20..d247d735a4 100644 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java +++ b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerController.java @@ -28,6 +28,7 @@ import java.time.Instant; import net.runelite.http.api.xp.XpData; import net.runelite.http.service.xp.beans.XpEntity; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -39,13 +40,13 @@ public class XpTrackerController @Autowired private XpTrackerService xpTrackerService; - @RequestMapping("/update") + @GetMapping("/update") public void update(@RequestParam String username) { xpTrackerService.tryUpdate(username); } - @RequestMapping("/get") + @GetMapping("/get") public XpData get(@RequestParam String username, @RequestParam(required = false) Instant time) { if (time == null) diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java index 391d37d1bf..9e8e0a5e06 100644 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java +++ b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java @@ -29,8 +29,8 @@ import com.google.common.hash.Funnels; import java.nio.charset.Charset; import java.time.Duration; import java.time.Instant; +import java.util.ArrayDeque; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ExecutionException; import lombok.extern.slf4j.Slf4j; import net.runelite.http.api.hiscore.HiscoreEndpoint; @@ -50,8 +50,8 @@ import org.sql2o.Sql2o; @Slf4j public class XpTrackerService { - private static final int QUEUE_LIMIT = 100_000; - private static final Duration UPDATE_TIME = Duration.ofMinutes(5); + private static final int QUEUE_LIMIT = 32768; + private static final int BLOOMFILTER_EXPECTED_INSERTIONS = 100_000; @Autowired @Qualifier("Runelite XP Tracker SQL2O") @@ -60,7 +60,7 @@ public class XpTrackerService @Autowired private HiscoreService hiscoreService; - private final Queue usernameUpdateQueue = new ConcurrentLinkedDeque<>(); + private final Queue usernameUpdateQueue = new ArrayDeque<>(); private BloomFilter usernameFilter = createFilter(); public void update(String username) throws ExecutionException @@ -76,13 +76,31 @@ public class XpTrackerService return; } - if (usernameUpdateQueue.size() >= QUEUE_LIMIT) + try (Connection con = sql2o.open()) { - log.warn("Username update queue is full ({})", QUEUE_LIMIT); - return; + PlayerEntity playerEntity = findOrCreatePlayer(con, username); + Duration frequency = updateFrequency(playerEntity); + Instant now = Instant.now(); + Duration timeSinceLastUpdate = Duration.between(playerEntity.getLast_updated(), now); + if (timeSinceLastUpdate.toMillis() < frequency.toMillis()) + { + log.debug("User {} updated too recently", username); + usernameFilter.put(username); + return; + } + + synchronized (usernameUpdateQueue) + { + if (usernameUpdateQueue.size() >= QUEUE_LIMIT) + { + log.warn("Username update queue is full ({})", QUEUE_LIMIT); + return; + } + + usernameUpdateQueue.add(username); + } } - usernameUpdateQueue.add(username); usernameFilter.put(username); } @@ -104,13 +122,6 @@ public class XpTrackerService log.debug("Hiscore for {} already up to date", username); return; } - - Duration difference = Duration.between(currentXp.getTime(), now); - if (difference.compareTo(UPDATE_TIME) <= 0) - { - log.debug("Updated {} too recently", username); - return; - } } con.createQuery("insert into xp (player,attack_xp,defence_xp,strength_xp,hitpoints_xp,ranged_xp,prayer_xp,magic_xp,cooking_xp,woodcutting_xp," @@ -172,6 +183,11 @@ public class XpTrackerService .addParameter("construction_rank", hiscoreResult.getConstruction().getRank()) .addParameter("overall_rank", hiscoreResult.getOverall().getRank()) .executeUpdate(); + + con.createQuery("update player set rank = :rank, last_updated = CURRENT_TIMESTAMP where id = :id") + .addParameter("id", playerEntity.getId()) + .addParameter("rank", hiscoreResult.getOverall().getRank()) + .executeUpdate(); } } @@ -197,6 +213,7 @@ public class XpTrackerService playerEntity.setId(id); playerEntity.setName(username); playerEntity.setTracked_since(now); + playerEntity.setLast_updated(now); return playerEntity; } @@ -220,18 +237,21 @@ public class XpTrackerService @Scheduled(fixedDelay = 1000) public void update() throws ExecutionException { - String next = usernameUpdateQueue.poll(); + String next; + synchronized (usernameUpdateQueue) + { + next = usernameUpdateQueue.poll(); + } if (next == null) { return; } - HiscoreResult hiscoreResult = hiscoreService.lookupUsername(next, HiscoreEndpoint.NORMAL); - update(next, hiscoreResult); + update(next); } - @Scheduled(fixedDelay = 3 * 60 * 60 * 1000) // 3 hours + @Scheduled(fixedDelay = 6 * 60 * 60 * 1000) // 6 hours public void clearFilter() { usernameFilter = createFilter(); @@ -241,14 +261,47 @@ public class XpTrackerService { final BloomFilter filter = BloomFilter.create( Funnels.stringFunnel(Charset.defaultCharset()), - 100_000 + BLOOMFILTER_EXPECTED_INSERTIONS ); - for (String toUpdate : usernameUpdateQueue) + synchronized (usernameUpdateQueue) { - filter.put(toUpdate); + for (String toUpdate : usernameUpdateQueue) + { + filter.put(toUpdate); + } } return filter; } + + /** + * scale how often to check hiscore updates for players based on their rank + * @param playerEntity + * @return + */ + private static Duration updateFrequency(PlayerEntity playerEntity) + { + Integer rank = playerEntity.getRank(); + if (rank == null || rank == -1) + { + return Duration.ofDays(7); + } + else if (rank < 10_000) + { + return Duration.ofHours(6); + } + else if (rank < 50_000) + { + return Duration.ofDays(2); + } + else if (rank < 100_000) + { + return Duration.ofDays(5); + } + else + { + return Duration.ofDays(7); + } + } } diff --git a/http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java b/http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java index d07d1d4640..11bec532d7 100644 --- a/http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java +++ b/http-service/src/main/java/net/runelite/http/service/xp/beans/PlayerEntity.java @@ -33,4 +33,6 @@ public class PlayerEntity private Integer id; private String name; private Instant tracked_since; + private Instant last_updated; + private Integer rank; } diff --git a/http-service/src/main/java/net/runelite/http/service/xtea/XteaController.java b/http-service/src/main/java/net/runelite/http/service/xtea/XteaController.java index 5f06429a80..3868acb8c6 100644 --- a/http-service/src/main/java/net/runelite/http/service/xtea/XteaController.java +++ b/http-service/src/main/java/net/runelite/http/service/xtea/XteaController.java @@ -30,6 +30,7 @@ import net.runelite.http.api.xtea.XteaKey; import net.runelite.http.api.xtea.XteaRequest; import net.runelite.http.service.util.exception.NotFoundException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -49,7 +50,7 @@ public class XteaController xteaService.submit(xteaRequest); } - @RequestMapping + @GetMapping public List get() { return xteaService.get().stream() @@ -57,7 +58,7 @@ public class XteaController .collect(Collectors.toList()); } - @RequestMapping("/{region}") + @GetMapping("/{region}") public XteaKey getRegion(@PathVariable int region) { XteaEntry xteaRegion = xteaService.getRegion(region); diff --git a/http-service/src/main/resources/application-dev.yaml b/http-service/src/main/resources/application-dev.yaml new file mode 100644 index 0000000000..cc2286e9b3 --- /dev/null +++ b/http-service/src/main/resources/application-dev.yaml @@ -0,0 +1,31 @@ +# Enable debug logging +debug: true +logging.level.net.runelite: DEBUG + +# Development data sources +datasource: + runelite: + jndiName: + driverClassName: org.mariadb.jdbc.Driver + type: org.mariadb.jdbc.MariaDbDataSource + url: jdbc:mariadb://localhost:3306/runelite + username: runelite + password: runelite + runelite-cache: + jndiName: + driverClassName: org.mariadb.jdbc.Driver + type: org.mariadb.jdbc.MariaDbDataSource + url: jdbc:mariadb://localhost:3306/cache + username: runelite + password: runelite + runelite-tracker: + jndiName: + driverClassName: org.mariadb.jdbc.Driver + type: org.mariadb.jdbc.MariaDbDataSource + url: jdbc:mariadb://localhost:3306/xptracker + username: runelite + password: runelite + +# Development oauth callback (without proxy) +oauth: + callback: http://localhost:8080/account/callback diff --git a/http-service/src/main/resources/application.yaml b/http-service/src/main/resources/application.yaml new file mode 100644 index 0000000000..9905e61695 --- /dev/null +++ b/http-service/src/main/resources/application.yaml @@ -0,0 +1,41 @@ +datasource: + runelite: + jndiName: java:comp/env/jdbc/runelite + runelite-cache: + jndiName: java:comp/env/jdbc/runelite-cache2 + runelite-tracker: + jndiName: java:comp/env/jdbc/runelite-tracker + +# By default Spring tries to register the datasource as an MXBean, +# so if multiple apis are deployed on one web container with +# shared datasource it tries to register it multiples times and +# fails when starting the 2nd api +spring.jmx.enabled: false + +# Google OAuth client +oauth: + client-id: + client-secret: + callback: https://api.runelite.net/oauth/ + +# Minio client storage for cache +minio: + endpoint: http://localhost:9000 + accesskey: AM54M27O4WZK65N6F8IP + secretkey: /PZCxzmsJzwCHYlogcymuprniGCaaLUOET2n6yMP + bucket: runelite + +# Redis client for temporary data storage +redis: + pool.size: 10 + host: http://localhost:6379 + +mongo: + host: mongodb://localhost:27017 + +# Twitter client for feed +runelite: + twitter: + consumerkey: + secretkey: + listid: 968949795153948673 \ No newline at end of file diff --git a/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql b/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql index ba4c395d62..70f83a30fd 100644 --- a/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql +++ b/http-service/src/main/resources/net/runelite/http/service/xp/schema.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.16 Distrib 10.2.9-MariaDB, for Linux (x86_64) +-- MySQL dump 10.16 Distrib 10.2.18-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: xptracker -- ------------------------------------------------------ --- Server version 10.2.9-MariaDB +-- Server version 10.2.18-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -26,6 +26,8 @@ CREATE TABLE `player` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, `tracked_since` timestamp NOT NULL DEFAULT current_timestamp(), + `last_updated` timestamp NOT NULL DEFAULT current_timestamp(), + `rank` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; @@ -116,7 +118,7 @@ CREATE TABLE `xp` ( `overall_rank` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `player_time` (`player`,`time`), - INDEX `idx_time` (`time`), + KEY `idx_time` (`time`), CONSTRAINT `fk_player` FOREIGN KEY (`player`) REFERENCES `player` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -130,4 +132,4 @@ CREATE TABLE `xp` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-01-20 18:37:09 +-- Dump completed on 2019-02-15 21:01:17 \ No newline at end of file diff --git a/http-service/src/main/templates/markdown.hbs b/http-service/src/main/templates/markdown.hbs new file mode 100644 index 0000000000..1beacd052a --- /dev/null +++ b/http-service/src/main/templates/markdown.hbs @@ -0,0 +1,110 @@ +{{#info}} +# {{title}} +{{join schemes " | "}}://{{host}}{{basePath}} + +{{description}} + +{{#contact}} +[**Contact the developer**](mailto:{{email}}) +{{/contact}} + +**Version** {{version}} + +{{#if termsOfService}} +[**Terms of Service**]({{termsOfService}}) +{{/if}} + +{{/info}} + +{{#if consumes}}__Consumes:__ {{join consumes ", "}}{{/if}} + +{{#if produces}}__Produces:__ {{join produces ", "}}{{/if}} + +{{#if securityDefinitions}} +# Security Definitions +{{> security}} +{{/if}} + +
+Table Of Contents +[toc] +
+ +# APIs + +{{#each paths}} +## {{@key}} +{{#this}} +{{#get}} +### GET +{{> operation}} +{{/get}} + +{{#put}} +### PUT +{{> operation}} +{{/put}} + +{{#post}} +### POST + +{{> operation}} + +{{/post}} + +{{#delete}} +### DELETE +{{> operation}} +{{/delete}} + +{{#option}} +### OPTION +{{> operation}} +{{/option}} + +{{#patch}} +### PATCH +{{> operation}} +{{/patch}} + +{{#head}} +### HEAD +{{> operation}} +{{/head}} + +{{/this}} +{{/each}} + +# Definitions +{{#each definitions}} +## {{@key}} + + + + + + + + + + {{#each this.properties}} + + + + + + + + {{/each}} +
nametyperequireddescriptionexample
{{@key}} + {{#ifeq type "array"}} + {{#items.$ref}} + {{type}}[{{basename items.$ref}}] + {{/items.$ref}} + {{^items.$ref}}{{type}}[{{items.type}}]{{/items.$ref}} + {{else}} + {{#$ref}}{{basename $ref}}{{/$ref}} + {{^$ref}}{{type}}{{#format}} ({{format}}){{/format}}{{/$ref}} + {{/ifeq}} + {{#required}}required{{/required}}{{^required}}optional{{/required}}{{#description}}{{{description}}}{{/description}}{{^description}}-{{/description}}{{example}}
+{{/each}} diff --git a/http-service/src/main/templates/operation.hbs b/http-service/src/main/templates/operation.hbs new file mode 100644 index 0000000000..f7015850b8 --- /dev/null +++ b/http-service/src/main/templates/operation.hbs @@ -0,0 +1,71 @@ +{{#deprecated}}-deprecated-{{/deprecated}} +{{summary}} + +{{description}} + +{{#if externalDocs.url}}{{externalDocs.description}}. [See external documents for more details]({{externalDocs.url}}) +{{/if}} + +{{#if security}} +#### Security +{{/if}} + +{{#security}} +{{#each this}} +* {{@key}} +{{#this}} * {{this}} +{{/this}} +{{/each}} +{{/security}} + +#### Request + +{{#if consumes}}__Content-Type:__ {{join consumes ", "}}{{/if}} + +##### Parameters +{{#if parameters}} + + + + + + + + + +{{/if}} + +{{#parameters}} + + + + + + +{{#ifeq in "body"}} + +{{else}} + {{#ifeq type "array"}} + + {{else}} + + {{/ifeq}} +{{/ifeq}} + +{{/parameters}} +{{#if parameters}} +
NameLocated inRequiredDescriptionDefaultSchema
{{name}}{{in}}{{#if required}}yes{{else}}no{{/if}}{{description}}{{#if pattern}} (**Pattern**: `{{pattern}}`){{/if}} - + {{#ifeq schema.type "array"}}Array[{{basename schema.items.$ref}}]{{/ifeq}} + {{#schema.$ref}}{{basename schema.$ref}} {{/schema.$ref}} + Array[{{items.type}}] ({{collectionFormat}}){{type}} {{#format}}({{format}}){{/format}}
+{{/if}} + + +#### Response + +{{#if produces}}__Content-Type:__ {{join produces ", "}}{{/if}} + +| Status Code | Reason | Response Model | +|-------------|-------------|----------------| +{{#each responses}}| {{@key}} | {{description}} | {{#schema.$ref}}{{basename schema.$ref}}{{/schema.$ref}}{{#ifeq schema.type "array"}}Array[{{basename schema.items.$ref}}]{{/ifeq}}{{^schema}} - {{/schema}}| +{{/each}} diff --git a/http-service/src/main/templates/security.hbs b/http-service/src/main/templates/security.hbs new file mode 100644 index 0000000000..04f86e8380 --- /dev/null +++ b/http-service/src/main/templates/security.hbs @@ -0,0 +1,88 @@ +{{#each securityDefinitions}} +### {{@key}} +{{#this}} +{{#ifeq type "oauth2"}} + + + + + +{{#if description}} + + + + +{{/if}} +{{#if authorizationUrl}} + + + + +{{/if}} +{{#if flow}} + + + + +{{/if}} +{{#if tokenUrl}} + + + + +{{/if}} +{{#if scopes}} + + +{{#each scopes}} + + + + +{{/each}} + +{{/if}} +
type{{type}}
description{{description}}
authorizationUrl{{authorizationUrl}}
flow{{flow}}
tokenUrl{{tokenUrl}}
scopes{{@key}}{{this}}
+{{/ifeq}} +{{#ifeq type "apiKey"}} + + + + + +{{#if description}} + + + + +{{/if}} +{{#if name}} + + + + +{{/if}} +{{#if in}} + + + + +{{/if}} +
type{{type}}
description{{description}}
name{{name}}
in{{in}}
+{{/ifeq}} +{{#ifeq type "basic"}} + + + + + +{{#if description}} + + + + +{{/if}} +
type{{type}}
description{{description}}
+{{/ifeq}} +{{/this}} +{{/each}} \ No newline at end of file diff --git a/http-service/src/main/templates/template.html.hbs b/http-service/src/main/templates/template.html.hbs new file mode 100644 index 0000000000..da587c2cc4 --- /dev/null +++ b/http-service/src/main/templates/template.html.hbs @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + {{info.title}} {{info.version}} + + + + + \ No newline at end of file diff --git a/http-service/src/test/java/net/runelite/http/service/SpringBootWebApplicationTest.java b/http-service/src/test/java/net/runelite/http/service/SpringBootWebApplicationTest.java deleted file mode 100644 index 0503c075d8..0000000000 --- a/http-service/src/test/java/net/runelite/http/service/SpringBootWebApplicationTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.http.service; - -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import javax.naming.NamingException; -import net.runelite.http.service.util.InstantConverter; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.sql2o.Sql2o; -import org.sql2o.converters.Converter; -import org.sql2o.quirks.NoQuirks; - -@SpringBootApplication -@EnableScheduling -public class SpringBootWebApplicationTest -{ - @Bean("Runelite SQL2O") - Sql2o sql2o() - { - Map converters = new HashMap<>(); - converters.put(Instant.class, new InstantConverter()); - return new Sql2o("jdbc:mysql://192.168.1.2/runelite", "runelite", "runelite", new NoQuirks(converters)); - } - - @Bean("Runelite Cache SQL2O") - Sql2o cacheSql2o() throws NamingException - { - Map converters = new HashMap<>(); - converters.put(Instant.class, new InstantConverter()); - return new Sql2o("jdbc:mysql://192.168.1.2/cache", "runelite", "runelite", new NoQuirks(converters)); - } - - @Bean("Runelite XP Tracker SQL2O") - Sql2o xpSql2o() throws NamingException - { - Map converters = new HashMap<>(); - converters.put(Instant.class, new InstantConverter()); - return new Sql2o("jdbc:mysql://192.168.1.2/xptracker", "runelite", "runelite", new NoQuirks(converters)); - } - - @Test - @Ignore - public void test() throws InterruptedException - { - SpringApplication.run(SpringBootWebApplicationTest.class, new String[0]); - for (;;) - { - Thread.sleep(100L); - } - } -} diff --git a/http-service/src/test/java/net/runelite/http/service/config/ConfigControllerTest.java b/http-service/src/test/java/net/runelite/http/service/config/ConfigControllerTest.java new file mode 100644 index 0000000000..b91029bec2 --- /dev/null +++ b/http-service/src/test/java/net/runelite/http/service/config/ConfigControllerTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.config; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import net.runelite.http.service.account.AuthFilter; +import net.runelite.http.service.account.beans.SessionEntry; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(ConfigController.class) +@Slf4j +@ActiveProfiles("test") +public class ConfigControllerTest +{ + @Autowired + private MockMvc mockMvc; + + @MockBean + private ConfigService configService; + + @MockBean + private AuthFilter authFilter; + + @Before + public void before() throws IOException + { + when(authFilter.handle(any(HttpServletRequest.class), any(HttpServletResponse.class))) + .thenReturn(mock(SessionEntry.class)); + } + + @Test + public void testSetKey() throws Exception + { + mockMvc.perform(put("/config/key") + .content("value") + .contentType(MediaType.TEXT_PLAIN)) + .andExpect(status().isOk()); + + verify(configService).setKey(anyInt(), eq("key"), eq("value")); + } +} \ No newline at end of file diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java index 654d0792ee..bdd59b077a 100644 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java +++ b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java @@ -26,7 +26,6 @@ package net.runelite.http.service.hiscore; import java.io.IOException; -import java.util.concurrent.ExecutionException; import net.runelite.http.api.hiscore.HiscoreResult; import okhttp3.HttpUrl; diff --git a/http-service/src/test/java/net/runelite/http/service/loottracker/LootTrackerControllerTest.java b/http-service/src/test/java/net/runelite/http/service/loottracker/LootTrackerControllerTest.java new file mode 100644 index 0000000000..9151838016 --- /dev/null +++ b/http-service/src/test/java/net/runelite/http/service/loottracker/LootTrackerControllerTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.service.loottracker; + +import java.io.IOException; +import java.time.Instant; +import java.util.Collections; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import net.runelite.http.api.RuneLiteAPI; +import net.runelite.http.api.loottracker.GameItem; +import net.runelite.http.api.loottracker.LootRecord; +import net.runelite.http.api.loottracker.LootRecordType; +import net.runelite.http.service.account.AuthFilter; +import net.runelite.http.service.account.beans.SessionEntry; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(LootTrackerController.class) +@Slf4j +@ActiveProfiles("test") +public class LootTrackerControllerTest +{ + @Autowired + private MockMvc mockMvc; + + @MockBean + private LootTrackerService lootTrackerService; + + @MockBean + private AuthFilter authFilter; + + @Before + public void before() throws IOException + { + when(authFilter.handle(any(HttpServletRequest.class), any(HttpServletResponse.class))) + .thenReturn(mock(SessionEntry.class)); + } + + @Test + public void storeLootRecord() throws Exception + { + LootRecord lootRecord = new LootRecord(); + lootRecord.setType(LootRecordType.NPC); + lootRecord.setTime(Instant.now()); + lootRecord.setDrops(Collections.singletonList(new GameItem(4151, 1))); + + String data = RuneLiteAPI.GSON.toJson(lootRecord); + mockMvc.perform(post("/loottracker").content(data).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(lootTrackerService).store(eq(lootRecord), anyInt()); + } +} \ No newline at end of file diff --git a/http-service/src/test/resources/application-test.yaml b/http-service/src/test/resources/application-test.yaml new file mode 100644 index 0000000000..0532963ade --- /dev/null +++ b/http-service/src/test/resources/application-test.yaml @@ -0,0 +1,17 @@ +# Use in-memory database for tests +datasource: + runelite: + jndiName: + driverClassName: org.h2.Driver + type: org.h2.jdbcx.JdbcDataSource + url: jdbc:h2:mem:runelite + runelite-cache: + jndiName: + driverClassName: org.h2.Driver + type: org.h2.jdbcx.JdbcDataSource + url: jdbc:h2:mem:cache + runelite-tracker: + jndiName: + driverClassName: org.h2.Driver + type: org.h2.jdbcx.JdbcDataSource + url: jdbc:h2:mem:xptracker diff --git a/http-service/src/test/resources/application.properties b/http-service/src/test/resources/application.properties deleted file mode 100644 index cb3dcc0507..0000000000 --- a/http-service/src/test/resources/application.properties +++ /dev/null @@ -1,11 +0,0 @@ -oauth.client-id=moo -oauth.client-secret=cow -minio.endpoint=http://10.96.22.171:9000 -minio.accesskey=AM54M27O4WZK65N6F8IP -minio.secretkey=/PZCxzmsJzwCHYlogcymuprniGCaaLUOET2n6yMP -minio.bucket=runelite -runelite.twitter.consumerkey=moo -runelite.twitter.secretkey=cow -runelite.twitter.listid=968949795153948673 -logging.level.net.runelite=DEBUG -spring.jackson.serialization.indent_output=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0c1f89dc1a..c76f91fd68 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT pom RuneLite @@ -43,7 +43,7 @@ true true - 177 + 178 @@ -186,6 +186,10 @@ org.apache.maven.plugins maven-javadoc-plugin 3.0.0-M1 + + + 8 + attach-javadocs @@ -219,6 +223,7 @@ checkstyle.xml ${project.build.sourceDirectory} + true diff --git a/protocol-api/pom.xml b/protocol-api/pom.xml index 551b441ed7..f09edc8cb5 100644 --- a/protocol-api/pom.xml +++ b/protocol-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT protocol-api diff --git a/protocol-api/src/main/java/net/runelite/protocol/api/handshake/LoginHandshakePacket.java b/protocol-api/src/main/java/net/runelite/protocol/api/handshake/LoginHandshakePacket.java index 4a6090504e..16ccb85694 100644 --- a/protocol-api/src/main/java/net/runelite/protocol/api/handshake/LoginHandshakePacket.java +++ b/protocol-api/src/main/java/net/runelite/protocol/api/handshake/LoginHandshakePacket.java @@ -25,8 +25,10 @@ package net.runelite.protocol.api.handshake; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public class LoginHandshakePacket extends HandshakePacket { diff --git a/protocol-api/src/main/java/net/runelite/protocol/api/handshake/UpdateHandshakePacket.java b/protocol-api/src/main/java/net/runelite/protocol/api/handshake/UpdateHandshakePacket.java index 9d1b20c8f2..86b39d41e8 100644 --- a/protocol-api/src/main/java/net/runelite/protocol/api/handshake/UpdateHandshakePacket.java +++ b/protocol-api/src/main/java/net/runelite/protocol/api/handshake/UpdateHandshakePacket.java @@ -26,9 +26,11 @@ package net.runelite.protocol.api.handshake; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @Data +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @AllArgsConstructor public class UpdateHandshakePacket extends HandshakePacket diff --git a/protocol/pom.xml b/protocol/pom.xml index 5255e7bacb..62dfa0997c 100644 --- a/protocol/pom.xml +++ b/protocol/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT protocol diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index 903322a106..2fa7d58969 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT runelite-api diff --git a/runelite-api/src/main/java/net/runelite/api/Actor.java b/runelite-api/src/main/java/net/runelite/api/Actor.java index ce72ceafcb..6357a91ebc 100644 --- a/runelite-api/src/main/java/net/runelite/api/Actor.java +++ b/runelite-api/src/main/java/net/runelite/api/Actor.java @@ -27,6 +27,7 @@ package net.runelite.api; import java.awt.Graphics2D; import java.awt.Polygon; import java.awt.image.BufferedImage; +import javax.annotation.Nullable; import net.runelite.api.annotations.VisibleForDevtools; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldArea; @@ -175,6 +176,7 @@ public interface Actor extends Renderable * @param zOffset the z-axis offset * @return the text drawing location */ + @Nullable Point getCanvasTextLocation(Graphics2D graphics, String text, int zOffset); /** @@ -236,5 +238,12 @@ public interface Actor extends Renderable * * @return the overhead text */ - String getOverhead(); + String getOverheadText(); + + /** + * Sets the overhead text that is displayed above the actor + * + * @param overheadText the overhead text + */ + void setOverheadText(String overheadText); } diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index ee1a50d7ed..45b67c9a33 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -33,6 +33,7 @@ package net.runelite.api; public final class AnimationID { public static final int IDLE = -1; + public static final int HERBLORE_PESTLE_AND_MORTAR = 364; public static final int WOODCUTTING_BRONZE = 879; public static final int WOODCUTTING_IRON = 877; public static final int WOODCUTTING_STEEL = 875; @@ -123,6 +124,7 @@ public final class AnimationID public static final int HERBLORE_POTIONMAKING = 363; //used for both herb and secondary public static final int MAGIC_CHARGING_ORBS = 726; public static final int MAGIC_MAKE_TABLET = 4068; + public static final int MAGIC_ENCHANTING_JEWELRY = 931; public static final int BURYING_BONES = 827; public static final int USING_GILDED_ALTAR = 3705; public static final int LOOKING_INTO = 832; diff --git a/runelite-api/src/main/java/net/runelite/api/ChatLineBuffer.java b/runelite-api/src/main/java/net/runelite/api/ChatLineBuffer.java index 22a15743f3..a1f8a7e056 100644 --- a/runelite-api/src/main/java/net/runelite/api/ChatLineBuffer.java +++ b/runelite-api/src/main/java/net/runelite/api/ChatLineBuffer.java @@ -44,4 +44,11 @@ public interface ChatLineBuffer * @return the length */ int getLength(); + + /** + * Removes a message node + * + * @param node the {@link MessageNode} to remove + */ + void removeMessageNode(MessageNode node); } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index ca51dc74a9..2b7d3aa844 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -634,20 +634,10 @@ public interface Client extends GameEngine int[] getVarps(); /** - * Gets an array of all integer client variables. - * - * @return local variables + * Gets an array of all client variables. */ @VisibleForDevtools - int[] getIntVarcs(); - - /** - * Gets an array of all string client variables. - * - * @return local variables - */ - @VisibleForDevtools - String[] getStrVarcs(); + Map getVarcMap(); /** * Gets the value corresponding to the passed player variable. @@ -782,6 +772,13 @@ public interface Client extends GameEngine */ int getSkillExperience(Skill skill); + /** + * Get the total experience of the player + * + * @return + */ + long getOverallExperience(); + /** * Gets the game drawing mode. * @@ -1055,6 +1052,20 @@ public interface Client extends GameEngine */ ClanMember[] getClanMembers(); + /** + * Gets the clan owner of the currently joined clan chat + * + * @return + */ + String getClanOwner(); + + /** + * Gets the clan chat name of the currently joined clan chat + * + * @return + */ + String getClanChatName(); + /** * Gets an array of players in the friends list. * @@ -1569,4 +1580,16 @@ public interface Client extends GameEngine int getRasterizer3D_clipMidY2(); void checkClickbox(Model model, int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y, int z, long hash); + + /** + * Sets if a widget is in target mode + */ + void setSpellSelected(boolean selected); + + /** + * Returns client item composition cache + */ + NodeCache getItemCompositionCache(); + + EnumComposition getEnum(int id); } diff --git a/runelite-api/src/main/java/net/runelite/api/DecorativeObject.java b/runelite-api/src/main/java/net/runelite/api/DecorativeObject.java index c2bbd14cf3..145531fa5d 100644 --- a/runelite-api/src/main/java/net/runelite/api/DecorativeObject.java +++ b/runelite-api/src/main/java/net/runelite/api/DecorativeObject.java @@ -38,6 +38,7 @@ public interface DecorativeObject extends TileObject * @see net.runelite.api.model.Jarvis */ Polygon getConvexHull(); + Polygon getConvexHull2(); Renderable getRenderable(); Renderable getRenderable2(); diff --git a/runelite-api/src/main/java/net/runelite/api/EnumComposition.java b/runelite-api/src/main/java/net/runelite/api/EnumComposition.java new file mode 100644 index 0000000000..00f8c30814 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/EnumComposition.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +public interface EnumComposition +{ + int[] getKeys(); + + int[] getIntVals(); + + String[] getStringVals(); + + int getIntValue(int key); + + String getStringValue(int key); +} diff --git a/runelite-api/src/main/java/net/runelite/api/EnumID.java b/runelite-api/src/main/java/net/runelite/api/EnumID.java new file mode 100644 index 0000000000..0b2d477a84 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/EnumID.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, Shaun Dreclin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +/** + * Utility class used for mapping enum IDs. + *

+ * Note: This class is not complete and may be missing mapped IDs. + */ +public final class EnumID +{ + public static final int MUSIC_TRACK_NAMES = 812; + public static final int MUSIC_TRACK_IDS = 819; +} diff --git a/runelite-api/src/main/java/net/runelite/api/GraphicID.java b/runelite-api/src/main/java/net/runelite/api/GraphicID.java index 913cb9d881..b1d2c3d00f 100644 --- a/runelite-api/src/main/java/net/runelite/api/GraphicID.java +++ b/runelite-api/src/main/java/net/runelite/api/GraphicID.java @@ -26,6 +26,7 @@ package net.runelite.api; public class GraphicID { + public static final int SPLASH = 85; public static final int TELEPORT = 111; public static final int GREY_BUBBLE_TELEPORT = 86; public static final int ENTANGLE = 179; diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index d8ce5fc04a..f272260eec 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -6494,7 +6494,7 @@ public final class ItemID public static final int ZAMORAK_CHAPS = 10372; public static final int ZAMORAK_COIF = 10374; public static final int GUTHIX_BRACERS = 10376; - public static final int GUTHIX_DRAGONHIDE = 10378; + public static final int GUTHIX_DHIDE = 10378; public static final int GUTHIX_CHAPS = 10380; public static final int GUTHIX_COIF = 10382; public static final int SARADOMIN_BRACERS = 10384; @@ -6801,7 +6801,7 @@ public final class ItemID public static final int GUTHIX_ROBE_TOP_10788 = 10788; public static final int ZAMORAK_DHIDE_10790 = 10790; public static final int SARADOMIN_DHIDE_10792 = 10792; - public static final int GUTHIX_DRAGONHIDE_10794 = 10794; + public static final int GUTHIX_DRAGONHIDE = 10794; public static final int ROBIN_HOOD_HAT_10796 = 10796; public static final int RUNE_PLATEBODY_G_10798 = 10798; public static final int RUNE_PLATEBODY_T_10800 = 10800; @@ -10637,5 +10637,17 @@ public final class ItemID public static final int ALCHEMICAL_HYDRA_HEAD = 23081; public static final int ANTIQUE_LAMP_23082 = 23082; public static final int BRIMSTONE_KEY = 23083; + public static final int ORNATE_GLOVES = 23091; + public static final int ORNATE_BOOTS = 23093; + public static final int ORNATE_LEGS = 23095; + public static final int ORNATE_TOP = 23097; + public static final int ORNATE_CAPE = 23099; + public static final int ORNATE_HELM = 23101; + public static final int BIRTHDAY_CAKE = 23108; + public static final int MYSTIC_SET_LIGHT = 23110; + public static final int MYSTIC_SET_BLUE = 23113; + public static final int MYSTIC_SET_DARK = 23116; + public static final int MYSTIC_SET_DUSK = 23119; + public static final int OILY_PEARL_FISHING_ROD = 23122; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NPCComposition.java b/runelite-api/src/main/java/net/runelite/api/NPCComposition.java index 2a3a26343d..0386ba954f 100644 --- a/runelite-api/src/main/java/net/runelite/api/NPCComposition.java +++ b/runelite-api/src/main/java/net/runelite/api/NPCComposition.java @@ -63,14 +63,14 @@ public interface NPCComposition * * @return the mini-map visible state */ - boolean isMinimapVisable(); + boolean isMinimapVisible(); /** * Gets whether the NPC is visible. * * @return the visible state */ - boolean isVisable(); + boolean isVisible(); /** * Gets the ID of the NPC. diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java index 4222a45a62..3a5363de22 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -1033,8 +1033,6 @@ public final class NpcID public static final int ANGRY_BEAR = 1060; public static final int ANGRY_UNICORN = 1061; public static final int ANGRY_GIANT_RAT = 1062; - public static final int ANGRY_GIANT_RAT_1063 = 1063; - public static final int ANGRY_GIANT_RAT_1064 = 1064; public static final int ANGRY_GOBLIN = 1065; public static final int FEAR_REAPER = 1066; public static final int CONFUSION_BEAST = 1067; @@ -2685,7 +2683,7 @@ public final class NpcID public static final int BAT = 2827; public static final int DRYAD = 2828; public static final int FAIRY_2829 = 2829; - public static final int LEPRECHAUN = 2830; + public static final int MYSTERIOUS_OLD_MAN = 2830; public static final int LIZARD_MAN = 2831; public static final int ORC = 2832; public static final int TROLL_2833 = 2833; @@ -6186,7 +6184,7 @@ public final class NpcID public static final int EVIL_CHICKEN_6739 = 6739; public static final int SHADE_6740 = 6740; public static final int ZOMBIE_6741 = 6741; - public static final int MYSTERIOUS_OLD_MAN = 6742; + public static final int MYSTERIOUS_OLD_MAN_6742 = 6742; public static final int SERGEANT_DAMIEN_6743 = 6743; public static final int FLIPPA_6744 = 6744; public static final int LEO = 6745; @@ -6209,6 +6207,7 @@ public final class NpcID public static final int SPAWN_6768 = 6768; public static final int OSTEN = 6769; public static final int ARCIS = 6770; + public static final int DREW = 6771; public static final int LOVADA = 6772; public static final int DOOMSAYER = 6773; public static final int DOOMSAYER_6774 = 6774; @@ -6218,6 +6217,7 @@ public final class NpcID public static final int MAZE_GUARDIAN_6779 = 6779; public static final int PILIAR = 6780; public static final int SHAYDA = 6781; + public static final int FISHING_SPOT_6784 = 6784; public static final int HOSA = 6785; public static final int HELLRAT_BEHEMOTH = 6793; public static final int MONKEY_ARCHER_6794 = 6794; @@ -7838,5 +7838,6 @@ public final class NpcID public static final int VEOS_8630 = 8630; public static final int SEAMAN_MORRIS = 8631; public static final int ALCHEMICAL_HYDRA_8634 = 8634; + public static final int DODGY_GEEZER = 8644; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index 8c4072cbe3..32141ef820 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -12267,5 +12267,26 @@ public final class NullItemID public static final int NULL_23088 = 23088; public static final int NULL_23089 = 23089; public static final int NULL_23090 = 23090; + public static final int NULL_23092 = 23092; + public static final int NULL_23094 = 23094; + public static final int NULL_23096 = 23096; + public static final int NULL_23098 = 23098; + public static final int NULL_23100 = 23100; + public static final int NULL_23102 = 23102; + public static final int NULL_23103 = 23103; + public static final int NULL_23104 = 23104; + public static final int NULL_23105 = 23105; + public static final int NULL_23106 = 23106; + public static final int NULL_23107 = 23107; + public static final int NULL_23109 = 23109; + public static final int NULL_23111 = 23111; + public static final int NULL_23112 = 23112; + public static final int NULL_23114 = 23114; + public static final int NULL_23115 = 23115; + public static final int NULL_23117 = 23117; + public static final int NULL_23118 = 23118; + public static final int NULL_23120 = 23120; + public static final int NULL_23121 = 23121; + public static final int NULL_23123 = 23123; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index 5371b0fdc2..c44dee1a9a 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -1184,6 +1184,7 @@ public final class NullObjectID public static final int NULL_2566 = 2566; public static final int NULL_2567 = 2567; public static final int NULL_2568 = 2568; + public static final int NULL_2630 = 2630; public static final int NULL_2637 = 2637; public static final int NULL_2638 = 2638; public static final int NULL_2639 = 2639; @@ -4639,6 +4640,7 @@ public final class NullObjectID public static final int NULL_11016 = 11016; public static final int NULL_11026 = 11026; public static final int NULL_11027 = 11027; + public static final int NULL_11040 = 11040; public static final int NULL_11045 = 11045; public static final int NULL_11046 = 11046; public static final int NULL_11047 = 11047; @@ -6203,6 +6205,7 @@ public final class NullObjectID public static final int NULL_14425 = 14425; public static final int NULL_14426 = 14426; public static final int NULL_14427 = 14427; + public static final int NULL_14428 = 14428; public static final int NULL_14429 = 14429; public static final int NULL_14430 = 14430; public static final int NULL_14432 = 14432; @@ -9329,6 +9332,7 @@ public final class NullObjectID public static final int NULL_20869 = 20869; public static final int NULL_20874 = 20874; public static final int NULL_20875 = 20875; + public static final int NULL_20877 = 20877; public static final int NULL_20879 = 20879; public static final int NULL_20880 = 20880; public static final int NULL_20881 = 20881; @@ -11438,7 +11442,6 @@ public final class NullObjectID public static final int NULL_24552 = 24552; public static final int NULL_24553 = 24553; public static final int NULL_24554 = 24554; - public static final int NULL_24558 = 24558; public static final int NULL_24570 = 24570; public static final int NULL_24604 = 24604; public static final int NULL_24623 = 24623; @@ -12310,6 +12313,8 @@ public final class NullObjectID public static final int NULL_26195 = 26195; public static final int NULL_26196 = 26196; public static final int NULL_26197 = 26197; + public static final int NULL_26200 = 26200; + public static final int NULL_26204 = 26204; public static final int NULL_26208 = 26208; public static final int NULL_26209 = 26209; public static final int NULL_26245 = 26245; @@ -16101,5 +16106,13 @@ public final class NullObjectID public static final int NULL_34651 = 34651; public static final int NULL_34652 = 34652; public static final int NULL_34662 = 34662; + public static final int NULL_34678 = 34678; + public static final int NULL_34679 = 34679; + public static final int NULL_34680 = 34680; + public static final int NULL_34707 = 34707; + public static final int NULL_34708 = 34708; + public static final int NULL_34709 = 34709; + public static final int NULL_34710 = 34710; + public static final int NULL_34711 = 34711; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java index 6679539d8f..f4c746ca3b 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -1452,7 +1452,6 @@ public final class ObjectID public static final int DOOR_2627 = 2627; public static final int DOOR_2628 = 2628; public static final int WALL_2629 = 2629; - public static final int FISHING_SPOT_2630 = 2630; public static final int DOOR_2631 = 2631; public static final int CHEST_2632 = 2632; public static final int CHEST_2633 = 2633; @@ -6405,7 +6404,6 @@ public final class ObjectID public static final int WALL_11037 = 11037; public static final int WALL_11038 = 11038; public static final int WALL_11039 = 11039; - public static final int RUBBLE_11040 = 11040; public static final int LADDER_11041 = 11041; public static final int LADDER_11042 = 11042; public static final int STONE_LADDER = 11043; @@ -8228,7 +8226,6 @@ public final class ObjectID public static final int MYSTERIOUS_RUINS_14413 = 14413; public static final int MYSTERIOUS_RUINS_14414 = 14414; public static final int STUDY_DESK_14415 = 14415; - public static final int FISHING_SPOT_14428 = 14428; public static final int RIFT_14431 = 14431; public static final int GAS_BUBBLE = 14434; public static final int CAVE_ENTRANCE_14436 = 14436; @@ -11551,7 +11548,6 @@ public final class ObjectID public static final int COMPOST_BIN_20872 = 20872; public static final int CAGE_20873 = 20873; public static final int DUNGEON_ENTRANCE_20876 = 20876; - public static final int DUNGEON_ENTRANCE_20877 = 20877; public static final int EXIT_20878 = 20878; public static final int LOG_BALANCE_20882 = 20882; public static final int LOG_BALANCE_20884 = 20884; @@ -13122,8 +13118,9 @@ public final class ObjectID public static final int DISPLAY_CASE_24551 = 24551; public static final int SPECIMEN_TABLE_24555 = 24555; public static final int SPECIMEN_TABLE_24556 = 24556; - public static final int ROCKS_24557 = 24557; - public static final int DIG_SITE_SPECIMEN_ROCKS = 24559; + public static final int DIG_SITE_SPECIMEN_ROCKS = 24557; + public static final int DIG_SITE_SPECIMEN_ROCKS_24558 = 24558; + public static final int DIG_SITE_SPECIMEN_ROCKS_24559 = 24559; public static final int GATE_24560 = 24560; public static final int GATE_24561 = 24561; public static final int GAP_24562 = 24562; @@ -13892,14 +13889,11 @@ public final class ObjectID public static final int CHEST_26193 = 26193; public static final int LEVER_26194 = 26194; public static final int BIRTHDAY_CAKE = 26198; - public static final int BIRTHDAY_CAKE_26199 = 26199; - public static final int BIRTHDAY_CAKE_26200 = 26200; + public static final int GRINDER = 26199; public static final int TABLE_26201 = 26201; public static final int TABLE_26202 = 26202; public static final int TABLE_26203 = 26203; - public static final int PRESENT = 26204; - public static final int PRESENT_26205 = 26205; - public static final int TABLE_26206 = 26206; + public static final int DOOR_26205 = 26205; public static final int LARGE_DOOR_26207 = 26207; public static final int WOODEN_BENCH_26210 = 26210; public static final int OAK_BENCH_26211 = 26211; @@ -17884,12 +17878,12 @@ public final class ObjectID public static final int POTATO_CACTUS_33746 = 33746; public static final int POTATO_CACTUS_33747 = 33747; public static final int POTATO_CACTUS_33748 = 33748; - public static final int DISEASED_POATO_CACTUS = 33749; - public static final int DISEASED_POATO_CACTUS_33750 = 33750; - public static final int DISEASED_POATO_CACTUS_33751 = 33751; - public static final int DISEASED_POATO_CACTUS_33752 = 33752; - public static final int DISEASED_POATO_CACTUS_33753 = 33753; - public static final int DISEASED_POATO_CACTUS_33754 = 33754; + public static final int DISEASED_POTATO_CACTUS = 33749; + public static final int DISEASED_POTATO_CACTUS_33750 = 33750; + public static final int DISEASED_POTATO_CACTUS_33751 = 33751; + public static final int DISEASED_POTATO_CACTUS_33752 = 33752; + public static final int DISEASED_POTATO_CACTUS_33753 = 33753; + public static final int DISEASED_POTATO_CACTUS_33754 = 33754; public static final int DEAD_POTATO_CACTUS = 33755; public static final int DEAD_POTATO_CACTUS_33756 = 33756; public static final int DEAD_POTATO_CACTUS_33757 = 33757; @@ -18545,10 +18539,31 @@ public final class ObjectID public static final int ALCHEMICAL_TOPIARY = 34654; public static final int MYSTERIOUS_PIPE = 34655; public static final int CHEMICAL_WASTE_PIPE = 34656; - public static final int GANGPLANK_34657 = 34657; - public static final int GANGPLANK_34658 = 34658; public static final int THE_SHEARED_RAM = 34659; public static final int BRIMSTONE_CHEST = 34660; public static final int BRIMSTONE_CHEST_34661 = 34661; + public static final int RUBBLE_34663 = 34663; + public static final int RUBBLE_34664 = 34664; + public static final int RUBBLE_34665 = 34665; + public static final int RUBBLE_34666 = 34666; + public static final int GANGPLANK_34667 = 34667; + public static final int GANGPLANK_34668 = 34668; + public static final int GANGPLANK_34669 = 34669; + public static final int GANGPLANK_34670 = 34670; + public static final int GANGPLANK_34671 = 34671; + public static final int GANGPLANK_34672 = 34672; + public static final int VERZIK_VITUR_DISPLAY = 34677; + public static final int MAKING_FRIENDS_WITH_MY_ARM_DISPLAY = 34681; + public static final int FIRE_34682 = 34682; + public static final int MAGIC_MIRROR = 34683; + public static final int ALCHEMICAL_HYDRA_DISPLAY_34684 = 34684; + public static final int ATTAS_PLANT_DISPLAY = 34685; + public static final int LEATHER_SHIELDS = 34686; + public static final int BRYOPHYTA_DISPLAY = 34687; + public static final int BANNER_34688 = 34688; + public static final int BLOOMING_HESPORI_SPROUT = 34705; + public static final int SHRIVELLED_PLANT = 34706; + public static final int TWISTED_BUSH = 34712; + public static final int DUNGEON_ENTRANCE_34713 = 34713; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/Perspective.java b/runelite-api/src/main/java/net/runelite/api/Perspective.java index 99116b7714..a0e2297ab9 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -379,7 +379,7 @@ public class Perspective @Nullable String text, int zOffset) { - if (text == null || "".equals(text)) + if (text == null) { return null; } diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java index 778b271036..68abc5e0f7 100644 --- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java +++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java @@ -45,6 +45,29 @@ public final class ScriptID */ public static final int CHATBOX_INPUT = 96; + /** + * Rebuilds the chatbox + */ + public static final int BUILD_CHATBOX = 216; + + /** + * Opens the Private Message chat interface + * + * Jagex refers to this script as {@code meslayer_mode6} + *

    + *
  • String Player to send private message to
  • + *
+ */ + public static final int OPEN_PRIVATE_MESSAGE_INTERFACE = 107; + + /** + * Rebuilds the text input widget inside the chat interface + *
    + *
  • String Message Prefix. Only used inside the GE search interfaces + *
+ */ + public static final int CHAT_TEXT_INPUT_REBUILD = 222; + /** * Layouts the bank widgets * @@ -93,15 +116,6 @@ public final class ScriptID */ public static final int DIARY_QUEST_UPDATE_LINECOUNT = 2523; - /** - * Initializes the chatbox input to use RuneLite callbacks - *
    - *
  • String Prompt text
  • - *
  • String Default value
  • - *
- */ - public static final int RUNELITE_CHATBOX_INPUT_INIT = 10001; - /** * Does nothing * diff --git a/runelite-api/src/main/java/net/runelite/api/SpriteID.java b/runelite-api/src/main/java/net/runelite/api/SpriteID.java index 2c4ac4f878..e707854c12 100644 --- a/runelite-api/src/main/java/net/runelite/api/SpriteID.java +++ b/runelite-api/src/main/java/net/runelite/api/SpriteID.java @@ -1172,7 +1172,7 @@ public final class SpriteID public static final int MINIMAP_ORB_XP_ACTIVATED = 1197; public static final int MINIMAP_ORB_XP_HOVERED = 1198; public static final int MINIMAP_ORB_XP_ACTIVATED_HOVERED = 1199; - public static final int UNKNOWN_BLACK_BLOBS = 1200; + public static final int MINIMAP_CLICK_MASK = 1200; public static final int OPTIONS_ZOOM_SLIDER_THUMB = 1201; public static final int EMOTE_SIT_UP = 1202; public static final int EMOTE_STAR_JUMP = 1203; diff --git a/runelite-api/src/main/java/net/runelite/api/VarClientStr.java b/runelite-api/src/main/java/net/runelite/api/VarClientStr.java index b3bf1b09b6..9667c56e74 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarClientStr.java +++ b/runelite-api/src/main/java/net/runelite/api/VarClientStr.java @@ -34,9 +34,10 @@ import lombok.Getter; @Getter public enum VarClientStr { - CHATBOX_TYPED_TEXT(1), - INPUT_TEXT(22), - RECENT_CLAN_CHAT(129); + CHATBOX_TYPED_TEXT(335), + INPUT_TEXT(359), + PRIVATE_MESSAGE_TARGET(360), + RECENT_CLAN_CHAT(362); private final int index; } diff --git a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java index c358d95da8..62489df3f0 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java +++ b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java @@ -37,6 +37,10 @@ public enum VarPlayer ATTACK_STYLE(43), QUEST_POINTS(101), IS_POISONED(102), + /** + * Seems to start at 50(10 splash) and goes down by 1 every 30 seconds + */ + DISEASE_VALUE(456), BANK_TAB(115), @@ -49,6 +53,14 @@ public enum VarPlayer NMZ_REWARD_POINTS(1060), + /** + * -1 : Poison immune + * Normal poison damage is ceil( this / 5.0f ) + * If this is greater than or equal to 1000000, the player is envenomed. + * Venom damage is (this - 999997) * 2 + */ + POISON(102), + /** * 0 : not started * greater than 0 : in progress @@ -56,6 +68,11 @@ public enum VarPlayer */ THRONE_OF_MISCELLANIA(359), + /** + * Item currently active in the creation of a buy or sell offer + */ + CURRENT_GE_ITEM(1151), + /** * Experience tracker goal start. */ @@ -122,7 +139,30 @@ public enum VarPlayer * Slayer unlock bitfields */ SLAYER_UNLOCK_1(1076), - SLAYER_UNLOCK_2(1344); + SLAYER_UNLOCK_2(1344), + + /** + * Music track unlock bitfields + */ + MUSIC_TRACKS_UNLOCKED_1(20), + MUSIC_TRACKS_UNLOCKED_2(21), + MUSIC_TRACKS_UNLOCKED_3(22), + MUSIC_TRACKS_UNLOCKED_4(23), + MUSIC_TRACKS_UNLOCKED_5(24), + MUSIC_TRACKS_UNLOCKED_6(25), + MUSIC_TRACKS_UNLOCKED_7(298), + MUSIC_TRACKS_UNLOCKED_8(311), + MUSIC_TRACKS_UNLOCKED_9(346), + MUSIC_TRACKS_UNLOCKED_10(414), + MUSIC_TRACKS_UNLOCKED_11(464), + MUSIC_TRACKS_UNLOCKED_12(598), + MUSIC_TRACKS_UNLOCKED_13(662), + MUSIC_TRACKS_UNLOCKED_14(721), + MUSIC_TRACKS_UNLOCKED_15(906), + MUSIC_TRACKS_UNLOCKED_16(1009), + MUSIC_TRACKS_UNLOCKED_17(1338), + MUSIC_TRACKS_UNLOCKED_18(1681), + MUSIC_TRACKS_UNLOCKED_19(2065); private final int id; } diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index f3ce1e6e12..ca053bd207 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -468,7 +468,14 @@ public enum Varbits BANK_TAB_SIX_COUNT(4176), BANK_TAB_SEVEN_COUNT(4177), BANK_TAB_EIGHT_COUNT(4178), - BANK_TAB_NINE_COUNT(4179); + BANK_TAB_NINE_COUNT(4179), + + /** + * Type of GE offer currently being created + * 0 = buy + * 1 = sell + */ + GE_OFFER_CREATION_TYPE(4397); /** * The raw varbit ID. diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java index ea96884f72..9abb3aeac8 100644 --- a/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java +++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java @@ -114,8 +114,7 @@ public class WorldArea return Integer.MAX_VALUE; } - Point distances = getAxisDistances(other); - return Math.max(distances.getX(), distances.getY()); + return distanceTo2D(other); } /** @@ -129,6 +128,29 @@ public class WorldArea return distanceTo(new WorldArea(other, 1, 1)); } + /** + * Computes the shortest distance to another area while ignoring the plane. + * + * @param other the passed area + * @return the distance + */ + public int distanceTo2D(WorldArea other) + { + Point distances = getAxisDistances(other); + return Math.max(distances.getX(), distances.getY()); + } + + /** + * Computes the shortest distance to a world coordinate. + * + * @param other the passed coordinate + * @return the distance + */ + public int distanceTo2D(WorldPoint other) + { + return distanceTo2D(new WorldArea(other, 1, 1)); + } + /** * Checks whether this area is within melee distance of another. *

diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java index 3f164c1845..bbacd1914a 100644 --- a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java +++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java @@ -25,6 +25,10 @@ */ package net.runelite.api.coords; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import lombok.Value; import net.runelite.api.Client; import static net.runelite.api.Constants.CHUNK_SIZE; @@ -150,7 +154,8 @@ public class WorldPoint } /** - * Gets the coordinate of the tile that contains the passed local point. + * Gets the coordinate of the tile that contains the passed local point, + * accounting for instances. * * @param client the client * @param localPoint the local coordinate @@ -190,6 +195,46 @@ public class WorldPoint } } + /** + * Get occurrences of a tile on the scene, accounting for instances. There may be + * more than one if the same template chunk occurs more than once on the scene. + * @param client + * @param worldPoint + * @return + */ + public static Collection toLocalInstance(Client client, WorldPoint worldPoint) + { + if (!client.isInInstancedRegion()) + { + return Collections.singleton(worldPoint); + } + + // find instance chunks using the template point. there might be more than one. + List worldPoints = new ArrayList<>(); + final int z = worldPoint.getPlane(); + int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks(); + for (int x = 0; x < instanceTemplateChunks[z].length; ++x) + { + for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y) + { + int chunkData = instanceTemplateChunks[z][x][y]; + int rotation = chunkData >> 1 & 0x3; + int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE; + int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE; + if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE + && worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE) + { + WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)), + client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)), + worldPoint.getPlane()); + p = rotate(p, rotation); + worldPoints.add(p); + } + } + } + return worldPoints; + } + /** * Rotate the coordinates in the chunk according to chunk rotation * @@ -281,4 +326,36 @@ public class WorldPoint { return ((x >> 6) << 8) | (y >> 6); } + + /** + * Converts the passed region ID and coordinates to a world coordinate + */ + public static WorldPoint fromRegion(int regionId, int regionX, int regionY, int plane) + { + return new WorldPoint( + ((regionId >>> 8) << 6) + regionX, + ((regionId & 0xff) << 6) + regionY, + plane); + } + + /** + * Gets the X-axis coordinate of the region coordinate + */ + public int getRegionX() + { + return getRegionOffset(x); + } + + /** + * Gets the Y-axis coordinate of the region coordinate + */ + public int getRegionY() + { + return getRegionOffset(y); + } + + private static int getRegionOffset(final int position) + { + return position & 0x3f; + } } diff --git a/runelite-api/src/main/java/net/runelite/api/events/ChatMessage.java b/runelite-api/src/main/java/net/runelite/api/events/ChatMessage.java index 9b5e12b6fd..0f5182e22b 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/ChatMessage.java +++ b/runelite-api/src/main/java/net/runelite/api/events/ChatMessage.java @@ -26,7 +26,9 @@ package net.runelite.api.events; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import net.runelite.api.ChatMessageType; +import net.runelite.api.MessageNode; /** * An event where a new chat message is received. @@ -38,8 +40,13 @@ import net.runelite.api.ChatMessageType; */ @Data @AllArgsConstructor +@NoArgsConstructor public class ChatMessage { + /** + * The underlying MessageNode for the message. + */ + private MessageNode messageNode; /** * The type of message received. */ @@ -59,4 +66,8 @@ public class ChatMessage * current name of the clan chat the client is in. */ private String sender; + /** + * Timestamp of the message. + */ + private int timestamp; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpSnapshotTotal.java b/runelite-api/src/main/java/net/runelite/api/events/ClanMemberJoined.java similarity index 84% rename from runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpSnapshotTotal.java rename to runelite-api/src/main/java/net/runelite/api/events/ClanMemberJoined.java index 72fcdd93d5..ff2a373c4b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpSnapshotTotal.java +++ b/runelite-api/src/main/java/net/runelite/api/events/ClanMemberJoined.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Levi + * Copyright (c) 2018, trimbe * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,18 +22,16 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.client.plugins.xptracker; +package net.runelite.api.events; import lombok.Value; +import net.runelite.api.ClanMember; @Value -class XpSnapshotTotal +public class ClanMemberJoined { - private final int xpGainedInSession; - private final int xpPerHour; - - static XpSnapshotTotal zero() - { - return new XpSnapshotTotal(0, 0); - } + /** + * The ClanMember that joined + */ + private ClanMember member; } diff --git a/runelite-api/src/main/java/net/runelite/api/events/ClanMemberLeft.java b/runelite-api/src/main/java/net/runelite/api/events/ClanMemberLeft.java new file mode 100644 index 0000000000..24bc58f960 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/ClanMemberLeft.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api.events; + +import lombok.Value; +import net.runelite.api.ClanMember; + +@Value +public class ClanMemberLeft +{ + /** + * The ClanMember that left + */ + private ClanMember member; +} diff --git a/runelite-api/src/main/java/net/runelite/api/events/OverheadTextChanged.java b/runelite-api/src/main/java/net/runelite/api/events/OverheadTextChanged.java new file mode 100644 index 0000000000..a366eb297a --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/OverheadTextChanged.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, Magic fTail + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api.events; + +import lombok.Value; +import net.runelite.api.Actor; + +/** + * Event fired when an actors overhead text is changed. + */ +@Value +public class OverheadTextChanged +{ + private final Actor actor; + + private final String overheadText; +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/events/SetMessage.java b/runelite-api/src/main/java/net/runelite/api/events/SetMessage.java deleted file mode 100644 index 0dde863bcc..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/SetMessage.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.runelite.api.events; - -import lombok.Data; -import net.runelite.api.ChatMessageType; -import net.runelite.api.MessageNode; - -/** - * An event where a {@link MessageNode} has had its message set. - *

- * Called whenever a message is received in the chat box. - *

- * Editing the {@link #messageNode} properties will reflect the change when - * the message in the chat is rendered. The original values of the message - * are held by the other fields of this event. - */ -@Data -public class SetMessage -{ - /** - * The updated message node. - */ - private MessageNode messageNode; - /** - * The set message type. - */ - private ChatMessageType type; - /** - * The name of the player that sent the message. - */ - private String name; - /** - * The sender of the message (ie. clan name). - */ - private String sender; - /** - * The new message value. - */ - private String value; - /** - * Timestamp of the message. - */ - private int timestamp; -} diff --git a/runelite-api/src/main/java/net/runelite/api/events/VarbitChanged.java b/runelite-api/src/main/java/net/runelite/api/events/VarbitChanged.java index 5a6d6adc2d..9680e54ac4 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/VarbitChanged.java +++ b/runelite-api/src/main/java/net/runelite/api/events/VarbitChanged.java @@ -29,9 +29,14 @@ package net.runelite.api.events; import lombok.Data; /** - * An event where a varbit has changed. + * An event when a varbit or varplayer has changed. */ @Data public class VarbitChanged { + /** + * Index in the varp array that was changed. + * For varplayer, this is the varplayer id. + */ + private int index = -1; } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/geometry/Geometry.java b/runelite-api/src/main/java/net/runelite/api/geometry/Geometry.java new file mode 100644 index 0000000000..39efa74afa --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/geometry/Geometry.java @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2018, Woox + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api.geometry; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.util.LinkedList; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Consumer; + +public class Geometry +{ + /** + * Find the point where two lines intersect. + * + * @param x1 X coordinate of the first endpoint of the first line. + * @param y1 Y coordinate of the first endpoint of the first line. + * @param x2 X coordinate of the second endpoint of the first line. + * @param y2 Y coordinate of the second endpoint of the first line. + * @param x3 X coordinate of the first endpoint of the second line. + * @param y3 Y coordinate of the first endpoint of the second line. + * @param x4 X coordinate of the second endpoint of the second line. + * @param y4 Y coordinate of the second endpoint of the second line. + * @return The intersection point of the lines, or null if the lines don't intersect. + */ + public static Point2D.Float lineIntersectionPoint( + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) + { + // https://stackoverflow.com/a/1968345 + + float p1x = x2 - x1; + float p1y = y2 - y1; + float p2x = x4 - x3; + float p2y = y4 - y3; + + float s = (-p1y * (x1 - x3) + p1x * (y1 - y3)) / (-p2x * p1y + p1x * p2y); + float t = ( p2x * (y1 - y3) - p2y * (x1 - x3)) / (-p2x * p1y + p1x * p2y); + + if (s >= 0 && s <= 1 && t >= 0 && t <= 1) + { + float x = x1 + (t * p1x); + float y = y1 + (t * p1y); + return new Point2D.Float(x, y); + } + + // No intersection + return null; + } + + /** + * Find the intersection points between a Shape and a line. + * + * @param shape The shape. + * @param x1 X coordinate of the first endpoint of the line. + * @param y1 Y coordinate of the first endpoint of the line. + * @param x2 X coordinate of the second endpoint of the line. + * @param y2 Y coordinate of the second endpoint of the line. + * @return A list with the intersection points. + */ + public static List intersectionPoints(Shape shape, float x1, float y1, float x2, float y2) + { + List intersections = new LinkedList<>(); + + PathIterator it = shape.getPathIterator(new AffineTransform()); + float[] coords = new float[2]; + float[] prevCoords = new float[2]; + float[] start = new float[2]; + while (!it.isDone()) + { + int type = it.currentSegment(coords); + if (type == PathIterator.SEG_MOVETO) + { + start[0] = coords[0]; + start[1] = coords[1]; + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + else if (type == PathIterator.SEG_LINETO) + { + Point2D.Float intersection = lineIntersectionPoint( + prevCoords[0], prevCoords[1], coords[0], coords[1], x1, y1, x2, y2); + if (intersection != null) + { + intersections.add(intersection); + } + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + else if (type == PathIterator.SEG_CLOSE) + { + Point2D.Float intersection = lineIntersectionPoint( + coords[0], coords[1], start[0], start[1], x1, y1, x2, y2); + if (intersection != null) + { + intersections.add(intersection); + } + } + it.next(); + } + + return intersections; + } + + /** + * Transforms the points in a path according to a method. + * + * @param it The iterator of the path to change the points on. + * @param method The method to use to transform the points. Takes a float[2] array with x and y coordinates as parameter. + * @return The transformed path. + */ + public static GeneralPath transformPath(PathIterator it, Consumer method) + { + GeneralPath path = new GeneralPath(); + float[] coords = new float[2]; + while (!it.isDone()) + { + int type = it.currentSegment(coords); + if (type == PathIterator.SEG_MOVETO) + { + method.accept(coords); + path.moveTo(coords[0], coords[1]); + } + else if (type == PathIterator.SEG_LINETO) + { + method.accept(coords); + path.lineTo(coords[0], coords[1]); + } + else if (type == PathIterator.SEG_CLOSE) + { + path.closePath(); + } + it.next(); + } + + return path; + } + + /** + * Transforms the points in a path according to a method. + * + * @param path The path to change the points on. + * @param method The method to use to transform the points. Takes a float[2] array with x and y coordinates as parameter. + * @return The transformed path. + */ + public static GeneralPath transformPath(GeneralPath path, Consumer method) + { + return transformPath(path.getPathIterator(new AffineTransform()), method); + } + + /** + * Splits a line into smaller segments and appends the segments to a path. + * + * @param path The path to append lines to. + * @param segmentLength The desired length to use for the segmented lines. + * @param x1 X coordinate of the first endpoint of the line. + * @param y1 Y coordinate of the first endpoint of the line. + * @param x2 X coordinate of the second endpoint of the line. + * @param y2 Y coordinate of the second endpoint of the line. + */ + private static void appendSegmentLines(GeneralPath path, float segmentLength, + float x1, float y1, float x2, float y2) + { + float x = x1; + float y = y1; + float angle = (float)Math.atan2(y2 - y1, x2 - x1); + float dx = (float)Math.cos(angle) * segmentLength; + float dy = (float)Math.sin(angle) * segmentLength; + float length = (float)Math.hypot(x2 - x1, y2 - y1); + int steps = (int)((length - 1e-4) / segmentLength); + for (int i = 0; i < steps; i++) + { + x += dx; + y += dy; + path.lineTo(x, y); + } + } + + /** + * Splits a path into smaller segments. + * For example, calling this on a path with a line of length 6, with desired + * segment length of 2, would split the path into 3 consecutive lines of length 2. + * + * @param it The iterator of the path to modify. + * @param segmentLength The desired length to use for the segments. + * @return The modified path. + */ + public static GeneralPath splitIntoSegments(PathIterator it, float segmentLength) + { + GeneralPath newPath = new GeneralPath(); + float[] prevCoords = new float[2]; + float[] coords = new float[2]; + float[] startCoords = new float[2]; + while (!it.isDone()) + { + int type = it.currentSegment(coords); + if (type == PathIterator.SEG_MOVETO) + { + startCoords[0] = coords[0]; + startCoords[1] = coords[1]; + newPath.moveTo(coords[0], coords[1]); + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + else if (type == PathIterator.SEG_LINETO) + { + appendSegmentLines(newPath, segmentLength, prevCoords[0], prevCoords[1], coords[0], coords[1]); + newPath.lineTo(coords[0], coords[1]); + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + else if (type == PathIterator.SEG_CLOSE) + { + appendSegmentLines(newPath, segmentLength, coords[0], coords[1], startCoords[0], startCoords[1]); + newPath.closePath(); + } + it.next(); + } + + return newPath; + } + + /** + * Splits a path into smaller segments. + * For example, calling this on a path with a line of length 6, with desired + * segment length of 2, would split the path into 3 consecutive lines of length 2. + * + * @param path The path to modify. + * @param segmentLength The desired length to use for the segments. + * @return The modified path. + */ + public static GeneralPath splitIntoSegments(GeneralPath path, float segmentLength) + { + return splitIntoSegments(path.getPathIterator(new AffineTransform()), segmentLength); + } + + /** + * Removes lines from a path according to a method. + * + * @param it The iterator of the path to filter. + * @param method The method to use to decide which lines to remove. Takes two float[2] arrays with x and y coordinates of the endpoints of the line. Lines for which the predicate returns false are removed. + * @return The filtered path. + */ + public static GeneralPath filterPath(PathIterator it, BiPredicate method) + { + GeneralPath newPath = new GeneralPath(); + float[] prevCoords = new float[2]; + float[] coords = new float[2]; + float[] start = new float[2]; + boolean shouldMoveNext = false; + while (!it.isDone()) + { + int type = it.currentSegment(coords); + if (type == PathIterator.SEG_MOVETO) + { + start[0] = coords[0]; + start[1] = coords[1]; + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + shouldMoveNext = true; + } + else if (type == PathIterator.SEG_LINETO) + { + if (method.test(prevCoords, coords)) + { + if (shouldMoveNext) + { + newPath.moveTo(prevCoords[0], prevCoords[1]); + shouldMoveNext = false; + } + newPath.lineTo(coords[0], coords[1]); + } + else + { + shouldMoveNext = true; + } + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + else if (type == PathIterator.SEG_CLOSE) + { + if (shouldMoveNext) + { + newPath.moveTo(prevCoords[0], prevCoords[1]); + } + if (method.test(prevCoords, start)) + { + newPath.lineTo(start[0], start[1]); + } + shouldMoveNext = false; + } + it.next(); + } + + return newPath; + } + + /** + * Removes lines from a path according to a method. + * + * @param path The path to filter. + * @param method The method to use to decide which lines to remove. Takes two float[2] arrays with x and y coordinates of the endpoints of the line. Lines for which the predicate returns false are removed. + * @return The filtered path. + */ + public static GeneralPath filterPath(GeneralPath path, BiPredicate method) + { + return filterPath(path.getPathIterator(new AffineTransform()), method); + } + + /** + * Removes lines from a path that lie outside the clipping area and cuts + * lines intersecting with the clipping area so the resulting lines + * lie within the clipping area. + * + * @param it The iterator of the path to clip. + * @param shape The clipping area to clip with. + * @return The clipped path. + */ + public static GeneralPath clipPath(PathIterator it, Shape shape) + { + GeneralPath newPath = new GeneralPath(); + float[] prevCoords = new float[2]; + float[] coords = new float[2]; + float[] start = new float[2]; + float[] nextMove = new float[2]; + boolean shouldMove = false; + boolean wasInside = false; + while (!it.isDone()) + { + int type = it.currentSegment(coords); + if (type == PathIterator.SEG_MOVETO) + { + start[0] = coords[0]; + start[1] = coords[1]; + wasInside = shape.contains(coords[0], coords[1]); + if (wasInside) + { + nextMove[0] = coords[0]; + nextMove[1] = coords[1]; + shouldMove = true; + } + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + else if (type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE) + { + if (type == PathIterator.SEG_CLOSE) + { + coords[0] = start[0]; + coords[1] = start[1]; + } + + List intersections = intersectionPoints(shape, prevCoords[0], prevCoords[1], coords[0], coords[1]); + intersections.sort((a, b) -> + { + double diff = a.distance(prevCoords[0], prevCoords[1]) - b.distance(prevCoords[0], prevCoords[1]); + if (diff < 0) + { + return -1; + } + if (diff > 0) + { + return 1; + } + return 0; + }); + + for (Point2D.Float intersection : intersections) + { + if (wasInside) + { + if (shouldMove) + { + newPath.moveTo(nextMove[0], nextMove[1]); + shouldMove = false; + } + newPath.lineTo(intersection.getX(), intersection.getY()); + } + else + { + nextMove[0] = intersection.x; + nextMove[1] = intersection.y; + shouldMove = true; + } + wasInside = !wasInside; + prevCoords[0] = intersection.x; + prevCoords[1] = intersection.y; + } + + wasInside = shape.contains(coords[0], coords[1]); + if (wasInside) + { + if (shouldMove) + { + newPath.moveTo(nextMove[0], nextMove[1]); + shouldMove = false; + } + newPath.lineTo(coords[0], coords[1]); + } + else + { + nextMove[0] = coords[0]; + nextMove[1] = coords[1]; + shouldMove = true; + } + + prevCoords[0] = coords[0]; + prevCoords[1] = coords[1]; + } + it.next(); + } + return newPath; + } + + /** + * Removes lines from a path that lie outside the clipping area and cuts + * lines intersecting with the clipping area so the resulting lines + * lie within the clipping area. + * + * @param path The path to clip. + * @param shape The clipping area to clip with. + * @return The clipped path. + */ + public static GeneralPath clipPath(GeneralPath path, Shape shape) + { + return clipPath(path.getPathIterator(new AffineTransform()), shape); + } +} diff --git a/runelite-api/src/main/java/net/runelite/api/vars/InputType.java b/runelite-api/src/main/java/net/runelite/api/vars/InputType.java index db1301b281..c94ccd79ef 100644 --- a/runelite-api/src/main/java/net/runelite/api/vars/InputType.java +++ b/runelite-api/src/main/java/net/runelite/api/vars/InputType.java @@ -38,6 +38,7 @@ public enum InputType RUNELITE_CHATBOX_PANEL(-3), RUNELITE(-2), NONE(0), + PRIVATE_MESSAGE(6), SEARCH(11); private final int type; diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java index 3aa6e23f13..ed4277a2a3 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java @@ -79,6 +79,7 @@ public interface Widget /** * Gets the current click configuration of the widget. + * @see WidgetConfig * * @see WidgetConfig */ @@ -551,6 +552,13 @@ public interface Widget */ void setOnMouseOverListener(Object... args); + /** + * Sets a script to be ran every frame when the mouse is in the widget bounds + * + * @param args A ScriptID, then the args for the script + */ + void setOnMouseRepeatListener(Object... args); + /** * Sets a script to be ran when the mouse leaves the widget bounds * @@ -565,6 +573,20 @@ public interface Widget */ void setOnTimerListener(Object... args); + /** + * Sets a script to be ran when the target mode has been activated for this widget + * + * @param args A ScriptID, then the args for the script + */ + void setOnTargetEnterListener(Object... args); + + /** + * Sets a script to be ran when the target mode has been deactivated for this widget + * + * @param args A ScriptID, then the args for the script + */ + void setOnTargetLeaveListener(Object... args); + /** * If this widget has any listeners on it */ @@ -769,4 +791,34 @@ public interface Widget * Sets if the rectangle is filled or just stroked */ void setFilled(boolean filled); + + /** + * Verb for spell targets + */ + String getTargetVerb(); + + /** + * Verb for spell targets + */ + void setTargetVerb(String targetVerb); + + /** + * Can widgets under this widgets be clicked in this widgets bounding box + */ + boolean getNoClickThrough(); + + /** + * Can widgets under this widgets be clicked in this widgets bounding box + */ + void setNoClickThrough(boolean noClickThrough); + + /** + * Can widgets under this widgets be scrolled in this widgets bounding box + */ + boolean getNoScrollThrough(); + + /** + * Can widgets under this widgets be scrolled in this widgets bounding box + */ + void setNoScrollThrough(boolean noScrollThrough); } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetConfig.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetConfig.java index 0b8f6a587d..31829b5417 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetConfig.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetConfig.java @@ -24,6 +24,8 @@ */ package net.runelite.api.widgets; +import net.runelite.api.MenuAction; + /** * Utility class used for defining options to be used on the click mask * of a {@link Widget}. @@ -36,12 +38,61 @@ public class WidgetConfig * Enables displaying a ninth option on a menu. */ public static final int SHOW_MENU_OPTION_NINE = 1 << 9; + + /** + * Can this widget be used on a item on the floor + */ + public static final int USE_GROUND_ITEM = 1 << 11; + + /** + * Can this widget be used on a NPC + */ + public static final int USE_NPC = 2 << 11; + + /** + * Can this widget be used on a game object + */ + public static final int USE_OBJECT = 4 << 11; + + /** + * Can this widget be used on a player + */ + public static final int USE_PLAYER = 8 << 11; + + /** + * Can this widget be used on a item in your inventory + */ + public static final int USE_ITEM = 16 << 11; + + /** + * Can this widget be used on a widget with the WIDGET_USE_TARGET flag + */ + public static final int USE_WIDGET = 32 << 11; + /** * Controls whether or not a widget can have another dragged onto it. */ public static final int DRAG_ON = 1 << 17; + /** * Controls whether or not a widget can be dragged around. */ public static final int DRAG = 1 << 20; + + /** + * Can widgets with USE_WIDGET be used on this widget + */ + public static final int WIDGET_USE_TARGET = 1 << 21; + + /** + * Is the widget an (inventory?) item + */ + public static final int ITEM = 1 << 30; + + /** + * Add a USE option + * + * @see MenuAction#ITEM_USE + */ + public static final int ITEM_USE_OP = 1 << 31; } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index bb9d8b6000..e6a73dc211 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -125,6 +125,8 @@ public class WidgetID public static final int SKOTIZO_GROUP_ID = 308; public static final int ENTERING_HOUSE_GROUP_ID = 71; public static final int FULLSCREEN_MAP_GROUP_ID = 165; + public static final int QUESTLIST_GROUP_ID = 399; + public static final int SKILLS_GROUP_ID = 320; static class WorldMap { @@ -133,7 +135,7 @@ public class WidgetID static final int SEARCH = 24; static final int SURFACE_SELECTOR = 32; static final int TOOLTIP = 38; - static final int OPTION = 42; + static final int OPTION = 43; } static class SlayerRewards @@ -292,6 +294,7 @@ public class WidgetID static final int TOGGLE_RUN_ORB = 22; // Has the "Toggle run" name static final int RUN_ORB_TEXT = 23; static final int SPEC_ORB = 28; + static final int WORLDMAP_ORB = 41; } static class LoginClickToPlayScreen @@ -347,6 +350,7 @@ public class WidgetID static final int ROOT_INTERFACE_CONTAINER = 62; static final int BANK_CONTAINER = 64; static final int INTERFACE_CONTAINER = 65; + static final int INVENTORY_CONTAINER = 69; } static class ResizableViewport @@ -380,6 +384,7 @@ public class WidgetID static final int PRAYER_ICON = 63; static final int MAGIC_ICON = 64; static final int INTERFACE_CONTAINER = 65; + static final int INVENTORY_CONTAINER = 71; } static class ResizableViewportBottomLine @@ -412,6 +417,7 @@ public class WidgetID static final int MUSIC_TAB = 40; static final int MUSIC_ICON = 46; static final int MAGIC_ICON = 63; + static final int INVENTORY_CONTAINER = 71; } static class Chatbox @@ -513,6 +519,7 @@ public class WidgetID static final int SPELL_BOX = 25; static final int SPELL_ICON = 27; static final int SPELL_TEXT = 28; + static final int AUTO_RETALIATE = 29; } static class VolcanicMine @@ -566,7 +573,7 @@ public class WidgetID static class Raids { - static final int POINTS_INFOBOX = 3; + static final int POINTS_INFOBOX = 6; } static class ExperienceDrop @@ -685,7 +692,7 @@ public class WidgetID static class Minigames { - static final int TELEPORT_BUTTON = 31; + static final int TELEPORT_BUTTON = 26; } static class StandardSpellBook @@ -710,16 +717,11 @@ public class WidgetID static class Pvp { - static final int BOUNTY_HUNTER_INFO = 6; - static final int KILLDEATH_RATIO = 9; - static final int BOUNTY_HUNTER_STATS = 28; - static final int PVP_WIDGET_CONTAINER = 54; - static final int SKULL_CONTAINER = 55; - static final int SKULL = 56; - static final int SAFE_ZONE = 57; - static final int ATTACK_RANGE = 59; - static final int WILDERNESS_LEVEL = 60; // this can also be the Deadman Mode "Protection" text - static final int DEADMAN_PROTECTION_TIME = 61; + static final int BOUNTY_HUNTER_INFO = 19; + static final int KILLDEATH_RATIO = 15; + static final int SKULL_CONTAINER = 62; + static final int SAFE_ZONE = 64; + static final int WILDERNESS_LEVEL = 67; // this can also be the Deadman Mode "Protection" text } static class KourendFavour @@ -746,4 +748,11 @@ public class WidgetID { static final int ROOT = 25; } + + static class QuestList + { + static final int FREE_CONTAINER = 6; + static final int MEMBERS_CONTAINER = 7; + static final int MINIQUEST_CONTAINER = 8; + } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index ef02681690..fb9b005bb5 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -76,8 +76,6 @@ public enum WidgetInfo EMOTE_WINDOW(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_WINDOW), EMOTE_CONTAINER(WidgetID.EMOTES_GROUP_ID, WidgetID.Emotes.EMOTE_CONTAINER), - DIARY_LIST(WidgetID.DIARY_GROUP_ID, 10), - DIARY_QUEST_WIDGET_TITLE(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TITLE), DIARY_QUEST_WIDGET_TEXT(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TEXT), @@ -159,6 +157,7 @@ public enum WidgetInfo MINIMAP_RUN_ORB_TEXT(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.RUN_ORB_TEXT), MINIMAP_HEALTH_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.HEALTH_ORB), MINIMAP_SPEC_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.SPEC_ORB), + MINIMAP_WORLDMAP_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), LOGIN_CLICK_TO_PLAY_SCREEN(WidgetID.LOGIN_CLICK_TO_PLAY_GROUP_ID, 0), LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY(WidgetID.LOGIN_CLICK_TO_PLAY_GROUP_ID, WidgetID.LoginClickToPlayScreen.MESSAGE_OF_THE_DAY), @@ -167,6 +166,7 @@ public enum WidgetInfo FIXED_VIEWPORT_ROOT_INTERFACE_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.ROOT_INTERFACE_CONTAINER), FIXED_VIEWPORT_BANK_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.BANK_CONTAINER), FIXED_VIEWPORT_INTERFACE_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.INTERFACE_CONTAINER), + FIXED_VIEWPORT_INVENTORY_CONTAINER(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.INVENTORY_CONTAINER), FIXED_VIEWPORT_COMBAT_TAB(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.COMBAT_TAB), FIXED_VIEWPORT_STATS_TAB(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.STATS_TAB), FIXED_VIEWPORT_QUESTS_TAB(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.QUESTS_TAB), @@ -257,7 +257,9 @@ public enum WidgetInfo RESIZABLE_VIEWPORT_BOTTOM_LINE_OPTIONS_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.SETTINGS_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_EMOTES_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.EMOTE_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_MUSIC_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.MUSIC_ICON), + RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.INVENTORY_CONTAINER), RESIZABLE_VIEWPORT_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER), + RESIZABLE_VIEWPORT_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INVENTORY_CONTAINER), RESIZABLE_VIEWPORT_BOTTOM_LINE_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER), PRAYER_THICK_SKIN(WidgetID.PRAYER_GROUP_ID, WidgetID.Prayer.THICK_SKIN), @@ -305,6 +307,7 @@ public enum WidgetInfo COMBAT_SPELL_BOX(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPELL_BOX), COMBAT_SPELL_ICON(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPELL_ICON), COMBAT_SPELL_TEXT(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPELL_TEXT), + COMBAT_AUTO_RETALIATE(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.AUTO_RETALIATE), DIALOG_OPTION(WidgetID.DIALOG_OPTION_GROUP_ID, 0), @@ -441,19 +444,12 @@ public enum WidgetInfo SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.LUNAR_HOME_TELEPORT), SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT), - PVP_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.PVP_WIDGET_CONTAINER), PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER), - PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), - PVP_WILDERNESS_LEVEL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), - PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO), - PVP_BOUNTY_HUNTER_STATS(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_STATS), - PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO), - PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE), - PVP_WORLD_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), - DEADMAN_PROTECTION_TEXT(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_LEVEL), - DEADMAN_PROTECTION_TIME(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.DEADMAN_PROTECTION_TIME), + PVP_WILDERNESS_LEVEL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_LEVEL), + PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO), + PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO), KOUREND_FAVOUR_OVERLAY(WidgetID.KOUREND_FAVOUR_GROUP_ID, WidgetID.KourendFavour.KOUREND_FAVOUR_OVERLAY), ZEAH_MESS_HALL_COOKING_DISPLAY(WidgetID.ZEAH_MESS_HALL_GROUP_ID, WidgetID.Zeah.MESS_HALL_COOKING_DISPLAY), @@ -462,7 +458,11 @@ public enum WidgetInfo SKOTIZO_CONTAINER(WidgetID.SKOTIZO_GROUP_ID, WidgetID.Skotizo.CONTAINER), - FULLSCREEN_MAP_ROOT(WidgetID.FULLSCREEN_MAP_GROUP_ID, WidgetID.FullScreenMap.ROOT); + FULLSCREEN_MAP_ROOT(WidgetID.FULLSCREEN_MAP_GROUP_ID, WidgetID.FullScreenMap.ROOT), + + QUESTLIST_FREE_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.FREE_CONTAINER), + QUESTLIST_MEMBERS_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MEMBERS_CONTAINER), + QUESTLIST_MINIQUEST_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MINIQUEST_CONTAINER); private final int groupId; private final int childId; diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetType.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetType.java index da76a7580f..9d140c3cd0 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetType.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetType.java @@ -27,9 +27,12 @@ package net.runelite.api.widgets; public final class WidgetType { public static final int LAYER = 0; + public static final int INVENTORY = 2; public static final int RECTANGLE = 3; public static final int TEXT = 4; public static final int GRAPHIC = 5; public static final int MODEL = 6; + public static final int TEXT_INVENTORY = 7; + public static final int IF1_TOOLTIP = 8; public static final int LINE = 9; } diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 6306dc3763..9198253015 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT client diff --git a/runelite-client/src/main/java/net/runelite/client/Notifier.java b/runelite-client/src/main/java/net/runelite/client/Notifier.java index 491c397202..b48a2f6e71 100644 --- a/runelite-client/src/main/java/net/runelite/client/Notifier.java +++ b/runelite-client/src/main/java/net/runelite/client/Notifier.java @@ -154,13 +154,13 @@ public class Notifier public void processFlash(final Graphics2D graphics) { - if (flashStart == null) + if (flashStart == null || client.getGameCycle() % 40 >= 20) { return; } - - if (client.getGameCycle() % 40 >= 20) + else if (client.getGameState() != GameState.LOGGED_IN) { + flashStart = null; return; } diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index b7fae34e2c..ecdda28103 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -183,9 +183,9 @@ public class RuneLite System.exit(0); } - final boolean developerMode = options.has("developer-mode"); + final boolean developerMode = options.has("developer-mode") && RuneLiteProperties.getLauncherVersion() == null; - if (developerMode && RuneLiteProperties.getLauncherVersion() == null) + if (developerMode) { boolean assertions = false; assert assertions = true; diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java index 63f6b9b479..6ef8c82e73 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java @@ -36,8 +36,8 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.events.SessionClose; -import net.runelite.api.events.SessionOpen; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.client.RuneLite; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; @@ -155,7 +155,7 @@ public class SessionManager private void closeSession() { - wsClient.close(); + wsClient.changeSession(null); if (accountSession == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 4cb368ace7..08cd4ea3fe 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -186,8 +186,8 @@ public class Hooks implements Callbacks * When the world map opens it loads about ~100mb of data into memory, which * represents about half of the total memory allocated by the client. * This gets cached and never released, which causes GC pressure which can affect - * performance. This method reinitailzies the world map cache, which allows the - * data to be garbage collecged, and causes the map data from disk each time + * performance. This method reinitializes the world map cache, which allows the + * data to be garbage collected, and causes the map data from disk each time * is it opened. */ private void checkWorldMap() diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommand.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommand.java index fb2de339a3..6b4fb9eec2 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommand.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommand.java @@ -28,7 +28,7 @@ import java.util.function.BiConsumer; import java.util.function.BiPredicate; import lombok.AllArgsConstructor; import lombok.Getter; -import net.runelite.api.events.SetMessage; +import net.runelite.api.events.ChatMessage; import net.runelite.client.events.ChatInput; @AllArgsConstructor @@ -37,6 +37,6 @@ class ChatCommand { private final String name; private boolean async; - private final BiConsumer execute; + private final BiConsumer execute; private final BiPredicate input; } diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java index 4d062d5c91..415afd8d80 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java @@ -34,7 +34,7 @@ import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.api.events.SetMessage; +import net.runelite.api.events.ChatMessage; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; @@ -59,22 +59,22 @@ public class ChatCommandManager implements ChatboxInputListener commandManager.register(this); } - public void registerCommand(String command, BiConsumer execute) + public void registerCommand(String command, BiConsumer execute) { registerCommand(command, execute, null); } - public void registerCommand(String command, BiConsumer execute, BiPredicate input) + public void registerCommand(String command, BiConsumer execute, BiPredicate input) { commands.put(command.toLowerCase(), new ChatCommand(command, false, execute, input)); } - public void registerCommandAsync(String command, BiConsumer execute) + public void registerCommandAsync(String command, BiConsumer execute) { registerCommandAsync(command, execute, null); } - public void registerCommandAsync(String command, BiConsumer execute, BiPredicate input) + public void registerCommandAsync(String command, BiConsumer execute, BiPredicate input) { commands.put(command.toLowerCase(), new ChatCommand(command, true, execute, input)); } @@ -85,14 +85,14 @@ public class ChatCommandManager implements ChatboxInputListener } @Subscribe - public void onSetMessage(SetMessage setMessage) + public void onChatMessage(ChatMessage chatMessage) { if (client.getGameState() != GameState.LOGGED_IN) { return; } - switch (setMessage.getType()) + switch (chatMessage.getType()) { case PUBLIC: case PUBLIC_MOD: @@ -104,7 +104,7 @@ public class ChatCommandManager implements ChatboxInputListener return; } - String message = setMessage.getValue(); + String message = chatMessage.getMessage(); String command = extractCommand(message); if (command == null) @@ -120,11 +120,11 @@ public class ChatCommandManager implements ChatboxInputListener if (chatCommand.isAsync()) { - scheduledExecutorService.execute(() -> chatCommand.getExecute().accept(setMessage, message)); + scheduledExecutorService.execute(() -> chatCommand.getExecute().accept(chatMessage, message)); } else { - chatCommand.getExecute().accept(setMessage, message); + chatCommand.getExecute().accept(chatMessage, message); } } diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java index b563773915..0dc2d7de1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java @@ -42,10 +42,10 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.MessageNode; import net.runelite.api.Varbits; +import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ResizeableChanged; import net.runelite.api.events.ScriptCallbackEvent; -import net.runelite.api.events.SetMessage; import net.runelite.api.events.VarbitChanged; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ChatColorConfig; @@ -103,10 +103,10 @@ public class ChatMessageManager } @Subscribe - public void onSetMessage(SetMessage setMessage) + public void onChatMessage(ChatMessage chatMessage) { - MessageNode messageNode = setMessage.getMessageNode(); - ChatMessageType chatMessageType = setMessage.getType(); + MessageNode messageNode = chatMessage.getMessageNode(); + ChatMessageType chatMessageType = chatMessage.getType(); boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1; Color usernameColor = null; @@ -125,7 +125,7 @@ public class ChatMessageManager case PUBLIC: case PUBLIC_MOD: { - boolean isFriend = client.isFriended(setMessage.getName(), true) && !client.getLocalPlayer().getName().equals(setMessage.getName()); + boolean isFriend = client.isFriended(chatMessage.getName(), true) && !client.getLocalPlayer().getName().equals(chatMessage.getName()); if (isFriend) { @@ -149,7 +149,7 @@ public class ChatMessageManager messageNode.setName(ColorUtil.wrapWithColorTag(messageNode.getName(), usernameColor)); } - String sender = setMessage.getSender(); + String sender = chatMessage.getSender(); if (senderColor != null && !Strings.isNullOrEmpty(sender)) { messageNode.setSender(ColorUtil.wrapWithColorTag(sender, senderColor)); diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 2cde4900ad..87f63d3826 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -43,8 +43,12 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.nio.channels.FileLock; import java.nio.charset.Charset; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.Duration; import java.time.Instant; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -56,6 +60,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ConfigChanged; import net.runelite.client.RuneLite; import net.runelite.client.account.AccountSession; @@ -70,6 +75,7 @@ import net.runelite.http.api.config.Configuration; public class ConfigManager { private static final String SETTINGS_FILE_NAME = "settings.properties"; + private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); @Inject EventBus eventBus; @@ -95,6 +101,9 @@ public class ConfigManager public final void switchSession(AccountSession session) { + // Ensure existing config is saved + sendConfig(); + if (session == null) { this.session = null; @@ -111,12 +120,17 @@ public class ConfigManager load(); // load profile specific config } + private File getLocalPropertiesFile() + { + return new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME); + } + private File getPropertiesFile() { // Sessions that aren't logged in have no username if (session == null || session.getUsername() == null) { - return new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME); + return getLocalPropertiesFile(); } else { @@ -146,7 +160,7 @@ public class ConfigManager return; } - if (configuration.getConfig().isEmpty()) + if (configuration.getConfig() == null || configuration.getConfig().isEmpty()) { log.debug("No configuration from client, using saved configuration on disk"); loadFromFile(); @@ -158,7 +172,13 @@ public class ConfigManager for (ConfigEntry entry : configuration.getConfig()) { log.debug("Loading configuration value from client {}: {}", entry.getKey(), entry.getValue()); - final String[] split = entry.getKey().split("\\."); + final String[] split = entry.getKey().split("\\.", 2); + + if (split.length != 2) + { + continue; + } + final String groupName = split[0]; final String key = split[1]; final String value = entry.getValue(); @@ -174,7 +194,7 @@ public class ConfigManager try { - saveToFile(); + saveToFile(propertiesFile); log.debug("Updated configuration on disk with the latest version"); } @@ -184,6 +204,75 @@ public class ConfigManager } } + private synchronized void syncPropertiesFromFile(File propertiesFile) + { + final Properties properties = new Properties(); + try (FileInputStream in = new FileInputStream(propertiesFile)) + { + properties.load(new InputStreamReader(in, Charset.forName("UTF-8"))); + } + catch (Exception e) + { + log.debug("Malformed properties, skipping update"); + return; + } + + final Map copy = (Map) ImmutableMap.copyOf(this.properties); + copy.forEach((groupAndKey, value) -> + { + if (!properties.containsKey(groupAndKey)) + { + final String[] split = groupAndKey.split("\\.", 2); + if (split.length != 2) + { + return; + } + + final String groupName = split[0]; + final String key = split[1]; + unsetConfiguration(groupName, key); + } + }); + + properties.forEach((objGroupAndKey, objValue) -> + { + final String groupAndKey = String.valueOf(objGroupAndKey); + final String[] split = groupAndKey.split("\\.", 2); + if (split.length != 2) + { + return; + } + + final String groupName = split[0]; + final String key = split[1]; + final String value = String.valueOf(objValue); + setConfiguration(groupName, key, value); + }); + } + + public void importLocal() + { + if (session == null) + { + // No session, no import + return; + } + + final File file = new File(propertiesFile.getParent(), propertiesFile.getName() + "." + TIME_FORMAT.format(new Date())); + + try + { + saveToFile(file); + } + catch (IOException e) + { + log.warn("Backup failed, skipping import", e); + return; + } + + syncPropertiesFromFile(getLocalPropertiesFile()); + } + private synchronized void loadFromFile() { properties.clear(); @@ -231,7 +320,7 @@ public class ConfigManager } } - private synchronized void saveToFile() throws IOException + private void saveToFile(final File propertiesFile) throws IOException { propertiesFile.getParentFile().mkdirs(); @@ -294,8 +383,6 @@ public class ConfigManager public void setConfiguration(String groupName, String key, String value) { - log.debug("Setting configuration value for {}.{} to {}", groupName, key, value); - String oldValue = (String) properties.setProperty(groupName + "." + key, value); if (Objects.equals(oldValue, value)) @@ -303,24 +390,13 @@ public class ConfigManager return; } + log.debug("Setting configuration value for {}.{} to {}", groupName, key, value); + synchronized (pendingChanges) { pendingChanges.put(groupName + "." + key, value); } - Runnable task = () -> - { - try - { - saveToFile(); - } - catch (IOException ex) - { - log.warn("unable to save configuration file", ex); - } - }; - executor.execute(task); - ConfigChanged configChanged = new ConfigChanged(); configChanged.setGroup(groupName); configChanged.setKey(key); @@ -337,8 +413,6 @@ public class ConfigManager public void unsetConfiguration(String groupName, String key) { - log.debug("Unsetting configuration value for {}.{}", groupName, key); - String oldValue = (String) properties.remove(groupName + "." + key); if (oldValue == null) @@ -346,24 +420,13 @@ public class ConfigManager return; } + log.debug("Unsetting configuration value for {}.{}", groupName, key); + synchronized (pendingChanges) { pendingChanges.put(groupName + "." + key, null); } - Runnable task = () -> - { - try - { - saveToFile(); - } - catch (IOException ex) - { - log.warn("unable to save configuration file", ex); - } - }; - executor.execute(task); - ConfigChanged configChanged = new ConfigChanged(); configChanged.setGroup(groupName); configChanged.setKey(key); @@ -527,6 +590,18 @@ public class ConfigManager } return new Keybind(code, mods); } + if (type == WorldPoint.class) + { + String[] splitStr = str.split(":"); + int x = Integer.parseInt(splitStr[0]); + int y = Integer.parseInt(splitStr[1]); + int plane = Integer.parseInt(splitStr[2]); + return new WorldPoint(x, y, plane); + } + if (type == Duration.class) + { + return Duration.ofMillis(Long.parseLong(str)); + } return str; } @@ -564,11 +639,21 @@ public class ConfigManager Keybind k = (Keybind) object; return k.getKeyCode() + ":" + k.getModifiers(); } + if (object instanceof WorldPoint) + { + WorldPoint wp = (WorldPoint) object; + return wp.getX() + ":" + wp.getY() + ":" + wp.getPlane(); + } + if (object instanceof Duration) + { + return Long.toString(((Duration) object).toMillis()); + } return object.toString(); } public void sendConfig() { + boolean changed; synchronized (pendingChanges) { if (client != null) @@ -588,7 +673,20 @@ public class ConfigManager } } } + changed = !pendingChanges.isEmpty(); pendingChanges.clear(); } + + if (changed) + { + try + { + saveToFile(propertiesFile); + } + catch (IOException ex) + { + log.warn("unable to save configuration file", ex); + } + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java b/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java index 0c2739b8a2..091c479ac6 100644 --- a/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java +++ b/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java @@ -78,7 +78,7 @@ public class DiscordService implements AutoCloseable discordRPC = DiscordRPC.INSTANCE; discordEventHandlers = new DiscordEventHandlers(); } - catch (UnsatisfiedLinkError e) + catch (Error e) { log.warn("Failed to load Discord library, Discord support will be disabled."); } @@ -150,9 +150,12 @@ public class DiscordService implements AutoCloseable ? "default" : discordPresence.getLargeImageKey(); discordRichPresence.largeImageText = discordPresence.getLargeImageText(); - discordRichPresence.smallImageKey = Strings.isNullOrEmpty(discordPresence.getSmallImageKey()) - ? "default" - : discordPresence.getSmallImageKey(); + + if (!Strings.isNullOrEmpty(discordPresence.getSmallImageKey())) + { + discordRichPresence.smallImageKey = discordPresence.getSmallImageKey(); + } + discordRichPresence.smallImageText = discordPresence.getSmallImageText(); discordRichPresence.partyId = discordPresence.getPartyId(); discordRichPresence.partySize = discordPresence.getPartySize(); diff --git a/runelite-client/src/main/java/net/runelite/client/events/ChatboxInput.java b/runelite-client/src/main/java/net/runelite/client/events/ChatboxInput.java index 6388c8b433..cad7d38077 100644 --- a/runelite-client/src/main/java/net/runelite/client/events/ChatboxInput.java +++ b/runelite-client/src/main/java/net/runelite/client/events/ChatboxInput.java @@ -25,8 +25,10 @@ package net.runelite.client.events; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public abstract class ChatboxInput extends ChatInput { private final String value; diff --git a/runelite-client/src/main/java/net/runelite/client/events/PrivateMessageInput.java b/runelite-client/src/main/java/net/runelite/client/events/PrivateMessageInput.java index fc31fae7f1..80a189f273 100644 --- a/runelite-client/src/main/java/net/runelite/client/events/PrivateMessageInput.java +++ b/runelite-client/src/main/java/net/runelite/client/events/PrivateMessageInput.java @@ -25,8 +25,10 @@ package net.runelite.client.events; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public abstract class PrivateMessageInput extends ChatInput { private final String target; diff --git a/runelite-api/src/main/java/net/runelite/api/events/SessionClose.java b/runelite-client/src/main/java/net/runelite/client/events/SessionClose.java similarity index 97% rename from runelite-api/src/main/java/net/runelite/api/events/SessionClose.java rename to runelite-client/src/main/java/net/runelite/client/events/SessionClose.java index 7075607291..e8a2f227cb 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/SessionClose.java +++ b/runelite-client/src/main/java/net/runelite/client/events/SessionClose.java @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.api.events; +package net.runelite.client.events; import lombok.Data; diff --git a/runelite-api/src/main/java/net/runelite/api/events/SessionOpen.java b/runelite-client/src/main/java/net/runelite/client/events/SessionOpen.java similarity index 97% rename from runelite-api/src/main/java/net/runelite/api/events/SessionOpen.java rename to runelite-client/src/main/java/net/runelite/client/events/SessionOpen.java index 7ff930470b..971ba7cb2e 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/SessionOpen.java +++ b/runelite-client/src/main/java/net/runelite/client/events/SessionOpen.java @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.api.events; +package net.runelite.client.events; import lombok.Data; diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java new file mode 100644 index 0000000000..6261f1aabe --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2018, SomeoneWithAnInternetConnection + * Copyright (c) 2019, MrGroggle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.game; + +import lombok.Getter; +import static net.runelite.api.NullObjectID.*; +import static net.runelite.api.ObjectID.*; +import net.runelite.api.coords.WorldPoint; + +@Getter +public enum AgilityShortcut +{ + GENERIC_SHORTCUT(1, "Shortcut", null, + // Trollheim + ROCKS_3790, ROCKS_3791, + // Fremennik Slayer Cave + STEPS_29993, + // Fossil Island + LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM, + // Brimhaven dungeon + CREVICE_30198, + // Lumbridge + STILE_12982, + // Gu'Tanoth Bridge + GAP, GAP_2831, + // Lumbridge Swamp Caves + STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673, + // Morytania Pirate Ship + ROCK_16115, + // Lumber Yard + BROKEN_FENCE_2618, + // McGrubor's Wood + LOOSE_RAILING, + // Underwater Area Fossil Island + TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962, + // Tree Gnome Village + LOOSE_RAILING_2186, + // Burgh de Rott + LOW_FENCE, + // Taverley + STILE, + // Asgarnian Ice Dungeon + STEPS, + // Fossil Island Wyvern Cave + STAIRS_31485), + BRIMHAVEN_DUNGEON_MEDIUM_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2698, 9491, 0), PIPE_21727), + BRIMHAVEN_DUNGEON_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2655, 9573, 0), PIPE_21728), + BRIMHAVEN_DUNGEON_STEPPING_STONES_RETURN(1, "Pipe Squeeze", null, STEPPING_STONE_21739), + BRIMHAVEN_DUNGEON_LOG_BALANCE_RETURN(1, "Log Balance", null, LOG_BALANCE_20884), + AGILITY_PYRAMID_ROCKS_WEST(1, "Rocks", null, CLIMBING_ROCKS_11948), + CAIRN_ISLE_CLIMBING_ROCKS(1, "Rocks", null, CLIMBING_ROCKS), + KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG ), + FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222 ), + RIVER_LUM_GRAPPLE_WEST(8, "Grapple Broken Raft", new WorldPoint(3245, 3179, 0), BROKEN_RAFT), + RIVER_LUM_GRAPPLE_EAST(8, "Grapple Broken Raft", new WorldPoint(3258, 3179, 0), BROKEN_RAFT), + CORSAIR_COVE_ROCKS(10, "Rocks", new WorldPoint(2545, 2871, 0), ROCKS_31757), + KARAMJA_MOSS_GIANT_SWING(10, "Rope", null, ROPESWING_23568, ROPESWING_23569), + FALADOR_GRAPPLE_WALL(11, "Grapple Wall", new WorldPoint(3031, 3391, 0), WALL_17049, WALL_17050), + BRIMHAVEN_DUNGEON_STEPPING_STONES(12, "Stepping Stones", null, STEPPING_STONE_21738), + VARROCK_SOUTH_FENCE(13, "Fence", new WorldPoint(3239, 3334, 0), FENCE_16518), + GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP), + CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809), + EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566), + TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 + YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, WALL_17047), + YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056), + COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274), + GRAND_EXCHANGE_UNDERWALL_TUNNEL(21, "Underwall Tunnel", new WorldPoint(3139, 3515, 0), UNDERWALL_TUNNEL_16529, UNDERWALL_TUNNEL_16530), + BRIMHAVEN_DUNGEON_PIPE(22, "Pipe Squeeze", new WorldPoint(2654, 9569, 0), PIPE_21728), + OBSERVATORY_SCALE_CLIFF(23, "Grapple Rocks", new WorldPoint(2447, 3155, 0), NULL_31849), + EAGLES_PEAK_ROCK_CLIMB(25, "Rock Climb", new WorldPoint(2320, 3499, 0), ROCKS_19849), + FALADOR_UNDERWALL_TUNNEL(26, "Underwall Tunnel", new WorldPoint(2947, 3313, 0), UNDERWALL_TUNNEL, UNDERWALL_TUNNEL_16528), + MOUNT_KARUULM_LOWER(29, "Rocks", new WorldPoint(1324, 3782, 0), ROCKS_34397), + CORSAIR_COVE_RESOURCE_ROCKS(30, "Rocks", new WorldPoint(2486, 2898, 0), ROCKS_31758, ROCKS_31759), + SOUTHEAST_KARAJMA_STEPPING_STONES(30, "Stepping Stones", new WorldPoint(2924, 2946, 0), STEPPING_STONES, STEPPING_STONES_23646, STEPPING_STONES_23647), + BRIMHAVEN_DUNGEON_LOG_BALANCE(30, "Log Balance", null, LOG_BALANCE_20882), + AGILITY_PYRAMID_ROCKS_EAST(30, "Rocks", null, CLIMBING_ROCKS_11949), + DRAYNOR_MANOR_STEPPING_STONES(31, "Stepping Stones", new WorldPoint(3150, 3362, 0), STEPPING_STONE_16533), + CATHERBY_CLIFFSIDE_GRAPPLE(32, "Grapple Rock", new WorldPoint(2868, 3429, 0), ROCKS_17042), + CAIRN_ISLE_ROCKS(32, "Rocks", null, ROCKS_2231), + ARDOUGNE_LOG_BALANCE(33, "Log Balance", new WorldPoint(2602, 3336, 0), LOG_BALANCE_16546, LOG_BALANCE_16547, LOG_BALANCE_16548), + BRIMHAVEN_DUNGEON_MEDIUM_PIPE(34, "Pipe Squeeze", null, new WorldPoint(2698, 9501, 0), PIPE_21727), + CATHERBY_OBELISK_GRAPPLE(36, "Grapple Rock", new WorldPoint(2841, 3434, 0), CROSSBOW_TREE_17062), + GNOME_STRONGHOLD_ROCKS(37, "Rocks", new WorldPoint(2485, 3515, 0), ROCKS_16534, ROCKS_16535), + AL_KHARID_MINING_PITCLIFF_SCRAMBLE(38, "Rocks", new WorldPoint(3305, 3315, 0), ROCKS_16549, ROCKS_16550), + YANILLE_WALL_GRAPPLE(39, "Grapple Wall", new WorldPoint(2552, 3072, 0), CASTLE_WALL), + NEITIZNOT_BRIDGE_REPAIR(40, "Bridge Repair - Quest", new WorldPoint(2315, 3828, 0), ROPE_BRIDGE_21306, ROPE_BRIDGE_21307), + KOUREND_LAKE_JUMP_EAST(40, "Stepping Stones", new WorldPoint(1612, 3570, 0), STEPPING_STONE_29729, STEPPING_STONE_29730), + KOUREND_LAKE_JUMP_WEST(40, "Stepping Stones", new WorldPoint(1604, 3572, 0), STEPPING_STONE_29729, STEPPING_STONE_29730), + YANILLE_DUNGEON_BALANCE(40, "Balancing Ledge", null, BALANCING_LEDGE_23548), + TROLLHEIM_EASY_CLIFF_SCRAMBLE(41, "Rocks", new WorldPoint(2869, 3670, 0), ROCKS_16521), + DWARVEN_MINE_NARROW_CREVICE(42, "Narrow Crevice", new WorldPoint(3034, 9806, 0), CREVICE_16543), + DRAYNOR_UNDERWALL_TUNNEL(42, "Underwall Tunnel", new WorldPoint(3068, 3261, 0), UNDERWALL_TUNNEL_19032, UNDERWALL_TUNNEL_19036), + TROLLHEIM_MEDIUM_CLIFF_SCRAMBLE_NORTH(43, "Rocks", new WorldPoint(2886, 3684, 0), ROCKS_3803, ROCKS_3804, ROCKS_16522), + TROLLHEIM_MEDIUM_CLIFF_SCRAMBLE_SOUTH(43, "Rocks", new WorldPoint(2876, 3666, 0), ROCKS_3803, ROCKS_3804, ROCKS_16522), + TROLLHEIM_ADVANCED_CLIFF_SCRAMBLE(44, "Rocks", new WorldPoint(2907, 3686, 0), ROCKS_16523, ROCKS_3748), + KOUREND_RIVER_STEPPING_STONES(45, "Stepping Stones", new WorldPoint(1721, 3509, 0), STEPPING_STONE_29728), + TIRANNWN_LOG_BALANCE(45, "Log Balance", null, LOG_BALANCE_3933, LOG_BALANCE_3931, LOG_BALANCE_3930, LOG_BALANCE_3929, LOG_BALANCE_3932), + COSMIC_ALTAR_MEDIUM_WALKWAY(46, "Narrow Walkway", new WorldPoint(2399, 4403, 0), JUTTING_WALL_17002), + DEEP_WILDERNESS_DUNGEON_CREVICE_NORTH(46, "Narrow Crevice", new WorldPoint(3047, 10335, 0), CREVICE_19043), + DEEP_WILDERNESS_DUNGEON_CREVICE_SOUTH(46, "Narrow Crevice", new WorldPoint(3045, 10327, 0), CREVICE_19043), + TROLLHEIM_HARD_CLIFF_SCRAMBLE(47, "Rocks", new WorldPoint(2902, 3680, 0), ROCKS_16524), + FREMENNIK_LOG_BALANCE(48, "Log Balance", new WorldPoint(2721, 3591, 0), LOG_BALANCE_16540, LOG_BALANCE_16541, LOG_BALANCE_16542), + YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140), + ARCEUUS_ESSENCE_MINE_BOULDER(49, "Boulder", new WorldPoint(1774, 3888, 0), BOULDER_27990), + MORYTANIA_STEPPING_STONE(50, "Stepping Stone", new WorldPoint(3418, 3326, 0), STEPPING_STONE_13504), + VARROCK_SEWERS_PIPE_SQUEEZE(51, "Pipe Squeeze", new WorldPoint(3152, 9905, 0), OBSTACLE_PIPE_16511), + ARCEUUS_ESSENCE_MINE_EAST_SCRAMBLE(52, "Rock Climb", new WorldPoint(1770, 3851, 0), ROCKS_27987, ROCKS_27988), + KARAMJA_VOLCANO_GRAPPLE_NORTH(53, "Grapple Rock", new WorldPoint(2873, 3143, 0), STRONG_TREE_17074), + KARAMJA_VOLCANO_GRAPPLE_SOUTH(53, "Grapple Rock", new WorldPoint(2874, 3128, 0), STRONG_TREE_17074), + MOTHERLODE_MINE_WALL_EAST(54, "Wall", new WorldPoint(3124, 9703, 0), DARK_TUNNEL_10047), + MOTHERLODE_MINE_WALL_WEST(54, "Wall", new WorldPoint(3118, 9702, 0), DARK_TUNNEL_10047), + MISCELLANIA_DOCK_STEPPING_STONE(55, "Stepping Stone", new WorldPoint(2572, 3862, 0), STEPPING_STONE_11768), + ISAFDAR_FOREST_OBSTACLES(56, "Trap", null, DENSE_FOREST_3938, DENSE_FOREST_3939, DENSE_FOREST_3998, DENSE_FOREST_3999, DENSE_FOREST, LEAVES, LEAVES_3924, LEAVES_3925, STICKS, TRIPWIRE), + RELEKKA_EAST_FENCE(57, "Fence", new WorldPoint(2688, 3697, 0), BROKEN_FENCE), + YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567), + PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null , WEATHERED_WALL, WEATHERED_WALL_16526), + ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515), + WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406), + WILDERNESS_GWD_CLIMB_WEST(60, "Rocks", new WorldPoint(2928, 3760, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406), + MOS_LEHARMLESS_STEPPING_STONE(60, "Stepping Stone", new WorldPoint(3710, 2970, 0), STEPPING_STONE_19042), + WINTERTODT_GAP(60, "Gap", new WorldPoint(1629, 4023, 0), GAP_29326), + UNGAEL_ICE(60, "Ice Chunks", null, NULL_25337, NULL_29868, NULL_29869, NULL_29870, ICE_CHUNKS_31822, NULL_31823, ICE_CHUNKS_31990), + SLAYER_TOWER_MEDIUM_CHAIN_FIRST(61, "Spiked Chain (Floor 1)", new WorldPoint(3421, 3550, 0), SPIKEY_CHAIN), + SLAYER_TOWER_MEDIUM_CHAIN_SECOND(61, "Spiked Chain (Floor 2)", new WorldPoint(3420, 3551, 0), SPIKEY_CHAIN_16538), + SLAYER_DUNGEON_CREVICE(62, "Narrow Crevice", new WorldPoint(2729, 10008, 0), CREVICE_16539), + MOUNT_KARUULM_UPPER(62, "Rocks", new WorldPoint(1322, 3791, 0), ROCKS_34396), + TAVERLEY_DUNGEON_RAILING(63, "Loose Railing", new WorldPoint(2935, 9811, 0), LOOSE_RAILING_28849), + TROLLHEIM_WILDERNESS_ROCKS_EAST(64, "Rocks", new WorldPoint(2945, 3678, 0), ROCKS_16545), + TROLLHEIM_WILDERNESS_ROCKS_WEST(64, "Rocks", new WorldPoint(2917, 3672, 0), ROCKS_16545), + FOSSIL_ISLAND_VOLCANO(64, "Rope", new WorldPoint(3780, 3822, 0), ROPE_ANCHOR, ROPE_ANCHOR_30917), + MORYTANIA_TEMPLE(65, "Loose Railing", new WorldPoint(3422, 3476, 0), ROCKS_16998, ROCKS_16999, ORNATE_RAILING, ORNATE_RAILING_17000), + REVENANT_CAVES_GREEN_DRAGONS(65, "Jump", new WorldPoint(3220, 10086, 0), PILLAR_31561), + COSMIC_ALTAR_ADVANCED_WALKWAY(66, "Narrow Walkway", new WorldPoint(2408, 4401, 0), JUTTING_WALL_17002), + LUMBRIDGE_DESERT_STEPPING_STONE(66, "Stepping Stone", new WorldPoint(3210, 3135, 0), STEPPING_STONE_16513), + HEROES_GUILD_TUNNEL_EAST(67, "Crevice", new WorldPoint(2898, 9901, 0), CREVICE_9739, CREVICE_9740), + HEROES_GUILD_TUNNEL_WEST(67, "Crevice", new WorldPoint(2913, 9895, 0), CREVICE_9739, CREVICE_9740), + YANILLE_DUNGEON_RUBBLE_CLIMB(67, "Pile of Rubble", null, PILE_OF_RUBBLE_23563, PILE_OF_RUBBLE_23564), + ELVEN_OVERPASS_MEDIUM_CLIFF(68, "Rocks", new WorldPoint(2337, 3288, 0), ROCKS_16514, ROCKS_16515), + WEISS_OBSTACLES(68, "Shortcut", null, LITTLE_BOULDER, ROCKSLIDE_33184, ROCKSLIDE_33185, NULL_33327, NULL_33328, LEDGE_33190, ROCKSLIDE_33191, FALLEN_TREE_33192), + ARCEUUS_ESSENSE_NORTH(69, "Rock Climb", new WorldPoint(1759, 3873, 0), ROCKS_27984, ROCKS_27985), + TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509), + TAVERLEY_DUNGEON_ROCKS_NORTH(70, "Rocks", new WorldPoint(2887, 9823, 0), ROCKS, ROCKS_14106), + TAVERLEY_DUNGEON_ROCKS_SOUTH(70, "Rocks", new WorldPoint(2887, 9631, 0), ROCKS, ROCKS_14106), + FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole" , new WorldPoint(3713, 3827, 0), HOLE_31481, HOLE_31482), + FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole" , new WorldPoint(3715, 3817, 0), HOLE_31481, HOLE_31482), + AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW), + GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371), + GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375), + SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN ), + SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538), + STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175), + TROLL_STRONGHOLD_WALL_CLIMB(73, "Rocks", new WorldPoint(2841, 3694, 0), ROCKS_16464), + ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985 ), + LAVA_DRAGON_ISLE_JUMP(74, "Stepping Stone", new WorldPoint(3200, 3807, 0), STEPPING_STONE_14918), + REVENANT_CAVES_DEMONS_JUMP(75, "Jump", new WorldPoint(3199, 10135, 0), PILLAR_31561), + REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561), + REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561), + ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663), + SHILO_VILLAGE_STEPPING_STONES( 77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466), + KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886), + TAVERLEY_DUNGEON_SPIKED_BLADES(80, "Strange Floor", new WorldPoint(2877, 9813, 0), STRANGE_FLOOR), + SLAYER_DUNGEON_CHASM_JUMP(81, "Spiked Blades", new WorldPoint(2770, 10003, 0), STRANGE_FLOOR_16544), + LAVA_MAZE_NORTH_JUMP(82, "Stepping Stone", new WorldPoint(3092, 3880, 0), STEPPING_STONE_14917), + BRIMHAVEN_DUNGEON_EAST_STEPPING_STONES_NORTH(83, "Stepping Stones", new WorldPoint(2685, 9547, 0), STEPPING_STONE_19040), + BRIMHAVEN_DUNGEON_EAST_STEPPING_STONES_SOUTH(83, "Stepping Stones", new WorldPoint(2693, 9529, 0), STEPPING_STONE_19040), + ELVEN_ADVANCED_CLIFF_SCRAMBLE(85, "Rocks", new WorldPoint(2337, 3253, 0), ROCKS_16514, ROCKS_16514), + KALPHITE_WALL(86, "Crevice", new WorldPoint(3214, 9508, 0), CREVICE_16465), + BRIMHAVEN_DUNGEON_VINE_EAST(87, "Vine", new WorldPoint(2672, 9582, 0), VINE_26880, VINE_26882), + BRIMHAVEN_DUNGEON_VINE_WEST(87, "Vine", new WorldPoint(2606, 9584, 0), VINE_26880, VINE_26882), + MOUNT_KARUULM_PIPE_SOUTH(88, "Pipe", new WorldPoint(1316, 10214, 0), MYSTERIOUS_PIPE), + MOUNT_KARUULM_PIPE_NORTH(88, "Pipe", new WorldPoint(1346, 10231, 0), MYSTERIOUS_PIPE), + REVENANT_CAVES_CHAMBER_JUMP(89, "Jump", new WorldPoint(3240, 10144, 0), PILLAR_31561); + + /** + * The agility level required to pass the shortcut + */ + @Getter + private final int level; + /** + * Brief description of the shortcut (e.g. 'Rocks', 'Stepping Stones', 'Jump') + */ + @Getter + private final String description; + /** + * The location of the Shortcut icon on the world map (null if there is no icon) + */ + @Getter + private final WorldPoint worldMapLocation; + /** + * An optional location in case the location of the shortcut icon is either + * null or isn't close enough to the obstacle + */ + @Getter + private final WorldPoint worldLocation; + /** + * Array of obstacles, null objects, decorations etc. that this shortcut uses. + * Typically an ObjectID/NullObjectID + */ + @Getter + private final int[] obstacleIds; + + AgilityShortcut(int level, String description, WorldPoint mapLocation, WorldPoint worldLocation, int... obstacleIds) + { + this.level = level; + this.description = description; + this.worldMapLocation = mapLocation; + this.worldLocation = worldLocation; + this.obstacleIds = obstacleIds; + } + + AgilityShortcut(int level, String description, WorldPoint location, int... obstacleIds) + { + this(level, description, location, location, obstacleIds); + } + + public String getTooltip() + { + return description + " - Level " + level; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/ChatboxInputManager.java b/runelite-client/src/main/java/net/runelite/client/game/ChatboxInputManager.java deleted file mode 100644 index ec8905e380..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/game/ChatboxInputManager.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2018 Abex - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.game; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import java.util.function.Consumer; -import lombok.Getter; -import net.runelite.api.Client; -import net.runelite.api.ScriptID; -import net.runelite.api.events.ScriptCallbackEvent; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; - -@Singleton -public class ChatboxInputManager -{ - public static final int NO_LIMIT = Integer.MAX_VALUE; - private final Client client; - private final ClientThread clientThread; - - private Consumer done; - private Consumer changed; - private int characterLimit = NO_LIMIT; - - @Getter - private boolean open = false; - - @Inject - public ChatboxInputManager(Client client, ClientThread clientThread, EventBus eventBus) - { - this.client = client; - this.clientThread = clientThread; - eventBus.register(this); - } - - /** - * Opens a RuneScape-style chatbox input - * - * @param text Text to show at the top of the window - * @param defaul Default text in the editable field - * @param done Callback when the text box has been exited, called with "" on esc - */ - public void openInputWindow(String text, String defaul, Consumer done) - { - openInputWindow(text, defaul, NO_LIMIT, done); - } - - public void openInputWindow(String text, String defaul, int characterLimit, Consumer done) - { - openInputWindow(text, defaul, characterLimit, null, done); - } - - public void openInputWindow(String text, String defaul, int characterLimit, Consumer changed, Consumer done) - { - this.done = done; - this.changed = changed; - this.characterLimit = characterLimit; - this.open = true; - clientThread.invoke(() -> client.runScript( - ScriptID.RUNELITE_CHATBOX_INPUT_INIT, - text, - defaul - )); - } - - /** - * Closes the RuneScape-style chatbox input - */ - public void closeInputWindow() - { - if (!this.open) - { - return; - } - this.open = false; - clientThread.invoke(() -> client.runScript( - ScriptID.RESET_CHATBOX_INPUT, - 1, - 1 - )); - } - - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent ev) - { - // This replaces script 74 and most of 112 - if ("chatboxInputHandler".equals(ev.getEventName())) - { - int intStackSize = client.getIntStackSize(); - int stringStackSize = client.getStringStackSize(); - int typedKey = client.getIntStack()[--intStackSize]; - String str = client.getStringStack()[--stringStackSize]; - boolean isDone = false; - - switch (typedKey) - { - case 27: // Escape - str = ""; - // fallthrough - case '\n': - this.open = false; - isDone = true; - break; - case '\b': - if (!str.isEmpty()) - { - str = str.substring(0, str.length() - 1); - } - break; - default: - // If we wanted to do numbers only, we could add a limit here - if (typedKey >= 32 && (str.length() < characterLimit)) - { - str += Character.toString((char) typedKey); - } - } - - if (changed != null) - { - changed.accept(str); - } - - if (isDone && done != null) - { - done.accept(str); - } - - client.getStringStack()[stringStackSize++] = str; - client.getIntStack()[intStackSize++] = isDone ? 1 : 0; - client.setIntStackSize(intStackSize); - client.setStringStackSize(stringStackSize); - } - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index ad06024a7d..0f21a5b434 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -84,7 +84,7 @@ public class ItemManager private final ItemClient itemClient = new ItemClient(); private Map itemPrices = Collections.emptyMap(); - private Map itemStats = Collections.emptyMap(); + private Map itemStats = Collections.emptyMap(); private final LoadingCache itemImages; private final LoadingCache itemCompositions; private final LoadingCache itemOutlines; @@ -226,7 +226,7 @@ public class ItemManager { try { - final Map stats = itemClient.getStats(); + final Map stats = itemClient.getStats(); if (stats != null) { itemStats = ImmutableMap.copyOf(stats); @@ -256,6 +256,15 @@ public class ItemManager itemCompositions.put(event.getItemComposition().getId(), event.getItemComposition()); } + /** + * Invalidates internal item manager item composition cache (but not client item composition cache) + * @see Client#getItemCompositionCache() + */ + public void invalidateItemCompositionCache() + { + itemCompositions.invalidateAll(); + } + /** * Look up an item's price * @@ -298,16 +307,16 @@ public class ItemManager * @return item stats */ @Nullable - public ItemStats getItemStats(int itemId) + public ItemStats getItemStats(int itemId, boolean allowNote) { ItemComposition itemComposition = getItemComposition(itemId); - if (itemComposition == null || itemComposition.getName() == null) + if (itemComposition == null || itemComposition.getName() == null || (!allowNote && itemComposition.getNote() != -1)) { return null; } - return itemStats.get(itemComposition.getName()); + return itemStats.get(canonicalize(itemId)); } /** diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java index 5eda167c17..f866d199ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemMapping.java @@ -195,7 +195,7 @@ public enum ItemMapping BLACK_MASK, BLACK_MASK_I, BLACK_MASK_1, BLACK_MASK_1_I, BLACK_MASK_2, BLACK_MASK_2_I, BLACK_MASK_3, BLACK_MASK_3_I, BLACK_MASK_4, BLACK_MASK_4_I, BLACK_MASK_5, BLACK_MASK_5_I, BLACK_MASK_6, BLACK_MASK_6_I, BLACK_MASK_7, BLACK_MASK_7_I, BLACK_MASK_8, BLACK_MASK_8_I, BLACK_MASK_9, BLACK_MASK_9_I, BLACK_MASK_10_I, SLAYER_HELMET, SLAYER_HELMET_I, BLACK_SLAYER_HELMET, BLACK_SLAYER_HELMET_I, PURPLE_SLAYER_HELMET, PURPLE_SLAYER_HELMET_I, RED_SLAYER_HELMET, RED_SLAYER_HELMET_I, - GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I), + GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I), // Pharaoh's Sceptres ITEM_PHARAOHS_SCEPTRE_1(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_1), diff --git a/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java b/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java index f0df8286cd..f177377818 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java @@ -28,6 +28,7 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.inject.Inject; import java.awt.image.BufferedImage; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import javax.annotation.Nullable; @@ -36,11 +37,14 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.SwingUtilities; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.SpritePixels; import net.runelite.client.callback.ClientThread; +import net.runelite.client.util.ImageUtil; +@Slf4j @Singleton public class SpriteManager { @@ -127,4 +131,36 @@ public class SpriteManager }); }); } + + public void addSpriteOverrides(SpriteOverride[] add) + { + if (add.length <= 0) + { + return; + } + + clientThread.invokeLater(() -> + { + Map overrides = client.getSpriteOverrides(); + Class owner = add[0].getClass(); + for (SpriteOverride o : add) + { + BufferedImage image = ImageUtil.getResourceStreamFromClass(owner, o.getFileName()); + SpritePixels sp = ImageUtil.getImageSpritePixels(image, client); + overrides.put(o.getSpriteId(), sp); + } + }); + } + + public void removeSpriteOverrides(SpriteOverride[] remove) + { + clientThread.invokeLater(() -> + { + Map overrides = client.getSpriteOverrides(); + for (SpriteOverride o : remove) + { + overrides.remove(o.getSpriteId()); + } + }); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java b/runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java new file mode 100644 index 0000000000..a4f894d5c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/SpriteOverride.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.game; + +import net.runelite.api.SpriteID; + +public interface SpriteOverride +{ + /** + * An ID for a sprite. Negative numbers are used by RuneLite specific sprites + * + * @see SpriteID + */ + int getSpriteId(); + + /** + * The file name for the resource to be loaded, relative to the implementing class + */ + String getFileName(); +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java index 35e42a617e..ff23bb2cda 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java @@ -93,6 +93,10 @@ public class ChatboxPanelManager 0, 1 ); + if (currentInput != null) + { + killCurrentPanel(); + } } private void unsafeOpenInput(ChatboxInput input) @@ -113,6 +117,11 @@ public class ChatboxPanelManager mouseManager.registerMouseWheelListener((MouseWheelListener) input); } + if (currentInput != null) + { + killCurrentPanel(); + } + currentInput = input; client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType()); client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true); diff --git a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextInput.java b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextInput.java index e340027d1a..e59e47059d 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextInput.java +++ b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextInput.java @@ -24,7 +24,10 @@ */ package net.runelite.client.game.chatbox; +import com.google.common.base.Strings; +import com.google.common.primitives.Ints; import com.google.inject.Inject; +import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; @@ -33,21 +36,25 @@ import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.function.Consumer; import java.util.function.IntPredicate; import java.util.function.Predicate; import java.util.function.ToIntFunction; +import java.util.regex.Pattern; import javax.swing.SwingUtilities; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.FontTypeFace; import net.runelite.api.FontID; -import net.runelite.api.widgets.WidgetType; +import net.runelite.api.FontTypeFace; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetSizeMode; import net.runelite.api.widgets.WidgetTextAlignment; +import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; import net.runelite.client.input.KeyListener; import net.runelite.client.input.MouseListener; @@ -57,6 +64,7 @@ import net.runelite.client.util.Text; public class ChatboxTextInput extends ChatboxInput implements KeyListener, MouseListener { private static final int CURSOR_FLASH_RATE_MILLIS = 1000; + private static final Pattern BREAK_MATCHER = Pattern.compile("[^a-zA-Z0-9']"); private final ChatboxPanelManager chatboxPanelManager; private final ClientThread clientThread; @@ -66,13 +74,24 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse return i -> i >= 32 && i < 127; } + @AllArgsConstructor + private static class Line + { + private final int start; + private final int end; + private final String text; + } + @Getter private String prompt; + @Getter + private int lines; + private StringBuffer value = new StringBuffer(); @Getter - private int cursor = 0; + private int cursorStart = 0; @Getter private int cursorEnd = 0; @@ -95,12 +114,14 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse @Getter private int fontID = FontID.QUILL_8; - // This is a lambda so I can have atomic updates for it's captures - private ToIntFunction getCharOffset = null; - private Predicate isInBounds = null; - + @Getter private boolean built = false; + // These are lambdas for atomic updates + private Predicate isInBounds = null; + private ToIntFunction getLineOffset = null; + private ToIntFunction getPointCharOffset = null; + @Inject protected ChatboxTextInput(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread) { @@ -108,6 +129,16 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse this.clientThread = clientThread; } + public ChatboxTextInput lines(int lines) + { + this.lines = lines; + if (built) + { + clientThread.invoke(this::update); + } + return this; + } + public ChatboxTextInput prompt(String prompt) { this.prompt = prompt; @@ -157,7 +188,7 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse end = v; } - this.cursor = start; + this.cursorStart = start; this.cursorEnd = end; if (built) @@ -209,7 +240,6 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse protected void update() { - this.built = true; Widget container = chatboxPanelManager.getContainerWidget(); container.deleteAllChildren(); @@ -232,103 +262,209 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse protected void buildEdit(int x, int y, int w, int h) { + final List editLines = new ArrayList<>(); + Widget container = chatboxPanelManager.getContainerWidget(); - String lt = Text.escapeJagex(value.substring(0, this.cursor)); - String mt = Text.escapeJagex(value.substring(this.cursor, this.cursorEnd)); - String rt = Text.escapeJagex(value.substring(this.cursorEnd)); - - Widget leftText = container.createChild(-1, WidgetType.TEXT); - Widget cursor = container.createChild(-1, WidgetType.RECTANGLE); - Widget middleText = container.createChild(-1, WidgetType.TEXT); - Widget rightText = container.createChild(-1, WidgetType.TEXT); - - leftText.setFontId(fontID); - FontTypeFace font = leftText.getFont(); + final Widget cursor = container.createChild(-1, WidgetType.RECTANGLE); + long start = System.currentTimeMillis(); + cursor.setOnTimerListener((JavaScriptCallback) ev -> + { + boolean on = (System.currentTimeMillis() - start) % CURSOR_FLASH_RATE_MILLIS > (CURSOR_FLASH_RATE_MILLIS / 2); + cursor.setOpacity(on ? 255 : 0); + }); + cursor.setTextColor(0xFFFFFF); + cursor.setHasListener(true); + cursor.setFilled(true); + cursor.setFontId(fontID); + FontTypeFace font = cursor.getFont(); if (h <= 0) { h = font.getBaseline(); } - int ltw = font.getTextWidth(lt); - int mtw = font.getTextWidth(mt); - int rtw = font.getTextWidth(rt); + final int oy = y; + final int ox = x; + final int oh = h; - int fullWidth = ltw + mtw + rtw; - - int ox = x; - if (w > 0) + int breakIndex = -1; + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < value.length(); i++) { - x += (w - fullWidth) / 2; - } - - int ltx = x; - int mtx = ltx + ltw; - int rtx = mtx + mtw; - - leftText.setText(lt); - leftText.setOriginalX(ltx); - leftText.setOriginalY(y); - leftText.setOriginalWidth(ltw); - leftText.setOriginalHeight(h); - leftText.revalidate(); - - if (!mt.isEmpty()) - { - cursor.setTextColor(0x113399); - } - else - { - cursor.setTextColor(0xFFFFFF); - long start = System.currentTimeMillis(); - cursor.setOnTimerListener((JavaScriptCallback) ev -> + int count = i - sb.length(); + final String c = value.charAt(i) + ""; + sb.append(c); + if (BREAK_MATCHER.matcher(c).matches()) { - boolean on = (System.currentTimeMillis() - start) % CURSOR_FLASH_RATE_MILLIS > (CURSOR_FLASH_RATE_MILLIS / 2); - cursor.setOpacity(on ? 255 : 0); - }); - cursor.setHasListener(true); + breakIndex = sb.length(); + } + + if (i == value.length() - 1) + { + Line line = new Line(count, count + sb.length() - 1, sb.toString()); + editLines.add(line); + break; + } + + if (font.getTextWidth(sb.toString() + value.charAt(i + 1)) < w) + { + continue; + } + + if (editLines.size() < this.lines - 1 || this.lines == 0) + { + if (breakIndex > 1) + { + String str = sb.substring(0, breakIndex); + Line line = new Line(count, count + str.length() - 1, str); + editLines.add(line); + + sb.replace(0, breakIndex, ""); + breakIndex = -1; + continue; + } + + Line line = new Line(count, count + sb.length() - 1, sb.toString()); + editLines.add(line); + sb.replace(0, sb.length(), ""); + } } - cursor.setFilled(true); - cursor.setOriginalX(mtx - 1); - cursor.setOriginalY(y); - cursor.setOriginalWidth(2 + mtw); - cursor.setOriginalHeight(h); - cursor.revalidate(); - middleText.setText(mt); - middleText.setFontId(fontID); - middleText.setOriginalX(mtx); - middleText.setOriginalY(y); - middleText.setOriginalWidth(mtw); - middleText.setOriginalHeight(h); - middleText.setTextColor(0xFFFFFF); - middleText.revalidate(); + Rectangle bounds = new Rectangle(container.getCanvasLocation().getX() + container.getWidth(), y, 0, editLines.size() * oh); + for (int i = 0; i < editLines.size() || i == 0; i++) + { + final Line line = editLines.size() > 0 ? editLines.get(i) : new Line(0, 0, ""); + final String text = line.text; + final int len = text.length(); - rightText.setText(rt); - rightText.setFontId(fontID); - rightText.setOriginalX(rtx); - rightText.setOriginalY(y); - rightText.setOriginalWidth(rtw); - rightText.setOriginalHeight(h); - rightText.revalidate(); + String lt = Text.escapeJagex(text); + String mt = ""; + String rt = ""; + + final boolean isStartLine = cursorOnLine(cursorStart, line.start, line.end) + || (cursorOnLine(cursorStart, line.start, line.end + 1) && i == editLines.size() - 1); + + final boolean isEndLine = cursorOnLine(cursorEnd, line.start, line.end); + + if (isStartLine || isEndLine || (cursorEnd > line.end && cursorStart < line.start)) + { + final int cIdx = Ints.constrainToRange(cursorStart - line.start, 0, len); + final int ceIdx = Ints.constrainToRange(cursorEnd - line.start, 0, len); + + lt = Text.escapeJagex(text.substring(0, cIdx)); + mt = Text.escapeJagex(text.substring(cIdx, ceIdx)); + rt = Text.escapeJagex(text.substring(ceIdx)); + } + + final int ltw = font.getTextWidth(lt); + final int mtw = font.getTextWidth(mt); + final int rtw = font.getTextWidth(rt); + final int fullWidth = ltw + mtw + rtw; + + int ltx = ox; + if (w > 0) + { + ltx += (w - fullWidth) / 2; + } + + final int mtx = ltx + ltw; + final int rtx = mtx + mtw; + + if (ltx < bounds.x) + { + bounds.setLocation(ltx, bounds.y); + } + + if (fullWidth > bounds.width) + { + bounds.setSize(fullWidth, bounds.height); + } + + if (editLines.size() == 0 || isStartLine) + { + cursor.setOriginalX(mtx - 1); + cursor.setOriginalY(y); + cursor.setOriginalWidth(2); + cursor.setOriginalHeight(h); + cursor.revalidate(); + } + + if (!Strings.isNullOrEmpty(lt)) + { + final Widget leftText = container.createChild(-1, WidgetType.TEXT); + leftText.setFontId(fontID); + leftText.setText(lt); + leftText.setOriginalX(ltx); + leftText.setOriginalY(y); + leftText.setOriginalWidth(ltw); + leftText.setOriginalHeight(h); + leftText.revalidate(); + } + + if (!Strings.isNullOrEmpty(mt)) + { + final Widget background = container.createChild(-1, WidgetType.RECTANGLE); + background.setTextColor(0x113399); + background.setFilled(true); + background.setOriginalX(mtx - 1); + background.setOriginalY(y); + background.setOriginalWidth(2 + mtw); + background.setOriginalHeight(h); + background.revalidate(); + + final Widget middleText = container.createChild(-1, WidgetType.TEXT); + middleText.setText(mt); + middleText.setFontId(fontID); + middleText.setOriginalX(mtx); + middleText.setOriginalY(y); + middleText.setOriginalWidth(mtw); + middleText.setOriginalHeight(h); + middleText.setTextColor(0xFFFFFF); + middleText.revalidate(); + } + + if (!Strings.isNullOrEmpty(rt)) + { + final Widget rightText = container.createChild(-1, WidgetType.TEXT); + rightText.setText(rt); + rightText.setFontId(fontID); + rightText.setOriginalX(rtx); + rightText.setOriginalY(y); + rightText.setOriginalWidth(rtw); + rightText.setOriginalHeight(h); + rightText.revalidate(); + } + + y += h; + } net.runelite.api.Point ccl = container.getCanvasLocation(); - int canvasX = ltx + ccl.getX(); - Rectangle bounds = new Rectangle(ccl.getX() + ox, ccl.getY() + y, w > 0 ? w : fullWidth, h); - String tsValue = value.toString(); - isInBounds = ev -> bounds.contains(ev.getPoint()); - getCharOffset = ev -> + isInBounds = ev -> bounds.contains(new Point(ev.getX() - ccl.getX(), ev.getY() - ccl.getY())); + getPointCharOffset = p -> { - if (fullWidth <= 0) + if (bounds.width <= 0) { return 0; } - int cx = ev.getX() - canvasX; + int cx = p.x - ccl.getX() - ox; + int cy = p.y - ccl.getY() - oy; - int charIndex = (tsValue.length() * cx) / fullWidth; + int currentLine = Ints.constrainToRange(cy / oh, 0, editLines.size() - 1); + + final Line line = editLines.get(currentLine); + final String tsValue = line.text; + int charIndex = tsValue.length(); + int fullWidth = font.getTextWidth(tsValue); + + int tx = ox; + if (w > 0) + { + tx += (w - fullWidth) / 2; + } + cx -= tx; // `i` is used to track max execution time incase there is a font with ligature width data that causes this to fail for (int i = tsValue.length(); i >= 0 && charIndex >= 0 && charIndex <= tsValue.length(); i--) @@ -353,22 +489,72 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse break; } - if (charIndex < 0) + charIndex = Ints.constrainToRange(charIndex, 0, tsValue.length()); + return line.start + charIndex; + }; + + getLineOffset = code -> + { + if (editLines.size() < 2) { - charIndex = 0; - } - if (charIndex > tsValue.length()) - { - charIndex = tsValue.length(); + return cursorStart; } - return charIndex; + int currentLine = -1; + for (int i = 0; i < editLines.size(); i++) + { + Line l = editLines.get(i); + if (cursorOnLine(cursorStart, l.start, l.end) + || (cursorOnLine(cursorStart, l.start, l.end + 1) && i == editLines.size() - 1)) + { + currentLine = i; + break; + } + } + + if (currentLine == -1 + || (code == KeyEvent.VK_UP && currentLine == 0) + || (code == KeyEvent.VK_DOWN && currentLine == editLines.size() - 1)) + { + return cursorStart; + } + + final Line line = editLines.get(currentLine); + final int direction = code == KeyEvent.VK_UP ? -1 : 1; + final Point dest = new Point(cursor.getCanvasLocation().getX(), cursor.getCanvasLocation().getY() + (direction * oh)); + final int charOffset = getPointCharOffset.applyAsInt(dest); + + // Place cursor on right line if whitespace keep it on the same line or skip a line + final Line nextLine = editLines.get(currentLine + direction); + if ((direction == -1 && charOffset >= line.start) + || (direction == 1 && (charOffset > nextLine.end && (currentLine + direction != editLines.size() - 1)))) + { + return nextLine.end; + } + + return charOffset; }; } + private boolean cursorOnLine(final int cursor, final int start, final int end) + { + return (cursor >= start) && (cursor <= end); + } + + private int getCharOffset(MouseEvent ev) + { + if (getPointCharOffset == null) + { + return 0; + } + + return getPointCharOffset.applyAsInt(ev.getPoint()); + } + @Override protected void open() { + this.built = true; update(); } @@ -398,12 +584,12 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse char c = e.getKeyChar(); if (charValidator.test(c)) { - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { - value.delete(cursor, cursorEnd); + value.delete(cursorStart, cursorEnd); } - value.insert(cursor, c); - cursorAt(cursor + 1); + value.insert(cursorStart, c); + cursorAt(cursorStart + 1); if (onChanged != null) { onChanged.accept(getValue()); @@ -421,13 +607,13 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse { case KeyEvent.VK_X: case KeyEvent.VK_C: - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { - String s = value.substring(cursor, cursorEnd); + String s = value.substring(cursorStart, cursorEnd); if (code == KeyEvent.VK_X) { - value.delete(cursor, cursorEnd); - cursorAt(cursor); + value.delete(cursorStart, cursorEnd); + cursorAt(cursorStart); } Toolkit.getDefaultToolkit() .getSystemClipboard() @@ -441,20 +627,20 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse .getSystemClipboard() .getData(DataFlavor.stringFlavor) .toString(); - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { - value.delete(cursor, cursorEnd); + value.delete(cursorStart, cursorEnd); } for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if (charValidator.test(ch)) { - value.insert(cursor, ch); - cursor++; + value.insert(cursorStart, ch); + cursorStart++; } } - cursorAt(cursor); + cursorAt(cursorStart); if (onChanged != null) { onChanged.accept(getValue()); @@ -468,13 +654,13 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse } return; } - int newPos = cursor; + int newPos = cursorStart; if (ev.isShiftDown()) { if (selectionEnd == -1 || selectionStart == -1) { - selectionStart = cursor; - selectionEnd = cursor; + selectionStart = cursorStart; + selectionEnd = cursorStart; } newPos = selectionEnd; } @@ -486,20 +672,20 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse switch (code) { case KeyEvent.VK_DELETE: - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { - value.delete(cursor, cursorEnd); - cursorAt(cursor); + value.delete(cursorStart, cursorEnd); + cursorAt(cursorStart); if (onChanged != null) { onChanged.accept(getValue()); } return; } - if (cursor < value.length()) + if (cursorStart < value.length()) { - value.deleteCharAt(cursor); - cursorAt(cursor); + value.deleteCharAt(cursorStart); + cursorAt(cursorStart); if (onChanged != null) { onChanged.accept(getValue()); @@ -507,20 +693,20 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse } return; case KeyEvent.VK_BACK_SPACE: - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { - value.delete(cursor, cursorEnd); - cursorAt(cursor); + value.delete(cursorStart, cursorEnd); + cursorAt(cursorStart); if (onChanged != null) { onChanged.accept(getValue()); } return; } - if (cursor > 0) + if (cursorStart > 0) { - value.deleteCharAt(cursor - 1); - cursorAt(cursor - 1); + value.deleteCharAt(cursorStart - 1); + cursorAt(cursorStart - 1); if (onChanged != null) { onChanged.accept(getValue()); @@ -535,6 +721,14 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse ev.consume(); newPos++; break; + case KeyEvent.VK_UP: + ev.consume(); + newPos = getLineOffset.applyAsInt(code); + break; + case KeyEvent.VK_DOWN: + ev.consume(); + newPos = getLineOffset.applyAsInt(code); + break; case KeyEvent.VK_HOME: ev.consume(); newPos = 0; @@ -553,9 +747,9 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse return; case KeyEvent.VK_ESCAPE: ev.consume(); - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { - cursorAt(cursor); + cursorAt(cursorStart); return; } chatboxPanelManager.close(); @@ -602,16 +796,16 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse } if (isInBounds == null || !isInBounds.test(mouseEvent)) { - if (cursor != cursorEnd) + if (cursorStart != cursorEnd) { selectionStart = -1; selectionEnd = -1; - cursorAt(getCharOffset.applyAsInt(mouseEvent)); + cursorAt(getCharOffset(mouseEvent)); } return mouseEvent; } - int nco = getCharOffset.applyAsInt(mouseEvent); + int nco = getCharOffset(mouseEvent); if (mouseEvent.isShiftDown() && selectionEnd != -1) { @@ -653,7 +847,7 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse return mouseEvent; } - int nco = getCharOffset.applyAsInt(mouseEvent); + int nco = getCharOffset(mouseEvent); if (selectionStart != -1) { selectionEnd = nco; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index caa116835e..73d6bf32e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -57,8 +57,8 @@ import javax.inject.Singleton; import javax.swing.SwingUtilities; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.events.SessionClose; -import net.runelite.api.events.SessionOpen; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.client.RuneLite; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java index 0bef99bac0..55ab81fbe3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java @@ -29,11 +29,11 @@ import java.util.concurrent.ScheduledExecutorService; import javax.inject.Inject; import javax.swing.JOptionPane; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.events.SessionClose; -import net.runelite.api.events.SessionOpen; import net.runelite.client.account.AccountSession; import net.runelite.client.account.SessionManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; @@ -113,10 +113,10 @@ public class AccountPlugin extends Plugin private void logoutClick() { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null, - "Are you sure you want to logout from RuneLite?", "Logout Confirmation", - JOptionPane.YES_NO_OPTION)) + "Are you sure you want to logout from RuneLite?", "Logout Confirmation", + JOptionPane.YES_NO_OPTION)) { - sessionManager.logout(); + executor.execute(sessionManager::logout); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java index 7873c2c923..85adb4db7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java @@ -40,8 +40,10 @@ public class ArdougneDiaryRequirement extends GenericDiaryRequirement new QuestRequirement(Quest.RUNE_MYSTERIES)); add("Steal a cake from the Ardougne market stalls.", new SkillRequirement(Skill.THIEVING, 5)); - add("Enter the Combat Training Camp north of W. Ardougne", + add("Enter the Combat Training Camp north of W. Ardougne.", new QuestRequirement(Quest.BIOHAZARD)); + add("Go out fishing on the Fishing Trawler.", + new SkillRequirement(Skill.FISHING, 15)); // MEDIUM add("Enter the Unicorn pen in Ardougne zoo using Fairy rings.", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java index 3111b0d6e1..30f7843199 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java @@ -94,6 +94,8 @@ public class FaladorDiaryRequirement extends GenericDiaryRequirement new SkillRequirement(Skill.AGILITY, 50)); add("Enter the mining guild wearing full prospector.", new SkillRequirement(Skill.MINING, 60)); + add("Kill the Blue Dragon under the Heroes' Guild.", + new QuestRequirement(Quest.HEROES_QUEST)); add("Crack a wall safe within Rogues Den.", new SkillRequirement(Skill.THIEVING, 50)); add("Recharge your prayer in the Port Sarim church while wearing full Proselyte.", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java index 130432035b..46c708efbb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java @@ -50,9 +50,9 @@ public class FremennikDiaryRequirement extends GenericDiaryRequirement add("Steal from the Keldagrim crafting or baker's stall.", new SkillRequirement(Skill.THIEVING, 5), new QuestRequirement(Quest.THE_GIANT_DWARF, true)); - add("Enter the Troll Stronghold", + add("Enter the Troll Stronghold.", new QuestRequirement(Quest.DEATH_PLATEAU), - new QuestRequirement(Quest.TROLL_STRONGHOLD)); + new QuestRequirement(Quest.TROLL_STRONGHOLD, true)); add("Chop and burn some oak logs in the Fremennik Province.", new SkillRequirement(Skill.WOODCUTTING, 15), new SkillRequirement(Skill.FIREMAKING, 15)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KandarinDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KandarinDiaryRequirement.java index 0b775a0dba..ef9df50ce2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KandarinDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KandarinDiaryRequirement.java @@ -40,7 +40,7 @@ public class KandarinDiaryRequirement extends GenericDiaryRequirement new SkillRequirement(Skill.FISHING, 16)); add("Plant some Jute seeds in the patch north of McGrubor's Wood.", new SkillRequirement(Skill.FARMING, 13)); - add("Defeat on of each elemental in the workshop.", + add("Defeat one of each elemental in the workshop.", new QuestRequirement(Quest.ELEMENTAL_WORKSHOP_I, true)); add("Cross the Coal truck log shortcut.", new SkillRequirement(Skill.AGILITY, 20)); @@ -96,6 +96,9 @@ public class KandarinDiaryRequirement extends GenericDiaryRequirement new SkillRequirement(Skill.MAGIC, 56)); add("Burn some Maple logs with a bow in Seers' Village.", new SkillRequirement(Skill.FIREMAKING, 65)); + add("Kill a Shadow Hound in the Shadow dungeon.", + new SkillRequirement(Skill.THIEVING, 53), + new QuestRequirement(Quest.DESERT_TREASURE, true)); add("Purchase and equip a granite body from Barbarian Assault.", new SkillRequirement(Skill.STRENGTH, 50), new SkillRequirement(Skill.DEFENCE, 50)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java index 951ce3a48b..182b288a3b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java @@ -128,7 +128,6 @@ public class KourendDiaryRequirement extends GenericDiaryRequirement new SkillRequirement(Skill.MAGIC, 90), new SkillRequirement(Skill.MINING, 38), new SkillRequirement(Skill.CRAFTING, 38), - new QuestRequirement(Quest.MONKEY_MADNESS_I), new FavourRequirement(Favour.ARCEUUS, 100)); add("Create your own Battlestaff from scratch within the Farming Guild.", new SkillRequirement(Skill.FARMING, 85), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/MorytaniaDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/MorytaniaDiaryRequirement.java index 9b9a861779..826b1a8410 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/MorytaniaDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/MorytaniaDiaryRequirement.java @@ -48,6 +48,8 @@ public class MorytaniaDiaryRequirement extends GenericDiaryRequirement new SkillRequirement(Skill.SLAYER, 15)); add("Place a Scarecrow in the Morytania flower patch.", new SkillRequirement(Skill.FARMING, 23)); + add("Kill a werewolf in its human form using the Wolfbane Dagger.", + new QuestRequirement(Quest.PRIEST_IN_PERIL)); add("Restore your prayer points at the nature altar.", new QuestRequirement(Quest.NATURE_SPIRIT)); @@ -74,7 +76,7 @@ public class MorytaniaDiaryRequirement extends GenericDiaryRequirement add("Use an ectophial to return to Port Phasmatys.", new QuestRequirement(Quest.GHOSTS_AHOY)); add("Mix a Guthix Balance potion while in Morytania.", - new SkillRequirement(Skill.HERBLORE, 36), + new SkillRequirement(Skill.HERBLORE, 22), new QuestRequirement(Quest.IN_AID_OF_THE_MYREQUE, true)); // HARD diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java index be612338e8..ee67f45132 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java @@ -88,7 +88,7 @@ public class WesternDiaryRequirement extends GenericDiaryRequirement // HARD add("Kill an Elf with a Crystal bow.", new SkillRequirement(Skill.RANGED, 70), - new SkillRequirement(Skill.AGILITY, 50), + new SkillRequirement(Skill.AGILITY, 56), new QuestRequirement(Quest.ROVING_ELVES)); add("Catch and cook a Monkfish in Piscatoris.", new SkillRequirement(Skill.FISHING, 62), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java index bc6e953f6d..e9c205f64f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java @@ -36,6 +36,7 @@ import net.runelite.api.Client; import net.runelite.api.Point; import net.runelite.api.Tile; import net.runelite.api.coords.LocalPoint; +import net.runelite.client.game.AgilityShortcut; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; @@ -44,6 +45,7 @@ import net.runelite.client.ui.overlay.OverlayUtil; class AgilityOverlay extends Overlay { private static final int MAX_DISTANCE = 2350; + private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE; private final Client client; private final AgilityPlugin plugin; @@ -66,14 +68,15 @@ class AgilityOverlay extends Overlay LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation(); Point mousePosition = client.getMouseCanvasPosition(); final List marksOfGrace = plugin.getMarksOfGrace(); - plugin.getObstacles().forEach((object, tile) -> + plugin.getObstacles().forEach((object, obstacle) -> { - if (Obstacles.SHORTCUT_OBSTACLE_IDS.contains(object.getId()) && !config.highlightShortcuts() || + if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() || Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay()) { return; } + Tile tile = obstacle.getTile(); if (tile.getPlane() == client.getPlane() && object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) { @@ -87,11 +90,11 @@ class AgilityOverlay extends Overlay } return; } - Area objectClickbox = object.getClickbox(); if (objectClickbox != null) { - Color configColor = config.getOverlayColor(); + AgilityShortcut agilityShortcut = obstacle.getShortcut(); + Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? config.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR; if (config.highlightMarks() && !marksOfGrace.isEmpty()) { configColor = config.getMarkColor(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java index cd60c6b940..c895a07980 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java @@ -38,10 +38,12 @@ import net.runelite.api.Item; import net.runelite.api.ItemID; import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET; import net.runelite.api.Player; +import net.runelite.api.Skill; import static net.runelite.api.Skill.AGILITY; import net.runelite.api.Tile; import net.runelite.api.TileObject; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.DecorativeObjectChanged; import net.runelite.api.events.DecorativeObjectDespawned; @@ -63,6 +65,7 @@ import net.runelite.api.events.WallObjectSpawned; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.AgilityShortcut; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -80,7 +83,7 @@ public class AgilityPlugin extends Plugin private static final int AGILITY_ARENA_REGION_ID = 11157; @Getter - private final Map obstacles = new HashMap<>(); + private final Map obstacles = new HashMap<>(); @Getter private final List marksOfGrace = new ArrayList<>(); @@ -115,6 +118,9 @@ public class AgilityPlugin extends Plugin private int lastAgilityXp; private WorldPoint lastArenaTicketPosition; + @Getter + private int agilityLevel; + @Provides AgilityConfig getConfig(ConfigManager configManager) { @@ -126,6 +132,7 @@ public class AgilityPlugin extends Plugin { overlayManager.add(agilityOverlay); overlayManager.add(lapCounterOverlay); + agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY); } @Override @@ -136,6 +143,7 @@ public class AgilityPlugin extends Plugin marksOfGrace.clear(); obstacles.clear(); session = null; + agilityLevel = 0; } @Subscribe @@ -208,6 +216,17 @@ public class AgilityPlugin extends Plugin } } + + @Subscribe + public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged) + { + Skill skill = boostedLevelChanged.getSkill(); + if (skill == AGILITY) + { + agilityLevel = client.getBoostedSkillLevel(skill); + } + } + @Subscribe public void onItemSpawned(ItemSpawned itemSpawned) { @@ -366,11 +385,40 @@ public class AgilityPlugin extends Plugin } if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) || - Obstacles.SHORTCUT_OBSTACLE_IDS.contains(newObject.getId()) || (Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId()) && Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID()))) { - obstacles.put(newObject, tile); + obstacles.put(newObject, new Obstacle(tile, null)); + } + + if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(newObject.getId())) + { + AgilityShortcut closestShortcut = null; + int distance = -1; + + // Find the closest shortcut to this object + for (AgilityShortcut shortcut : Obstacles.SHORTCUT_OBSTACLE_IDS.get(newObject.getId())) + { + if (shortcut.getWorldLocation() == null) + { + closestShortcut = shortcut; + break; + } + else + { + int newDistance = shortcut.getWorldLocation().distanceTo2D(newObject.getWorldLocation()); + if (closestShortcut == null || newDistance < distance) + { + closestShortcut = shortcut; + distance = newDistance; + } + } + } + + if (closestShortcut != null) + { + obstacles.put(newObject, new Obstacle(tile, closestShortcut)); + } } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacle.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacle.java new file mode 100644 index 0000000000..6038de468b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacle.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019, MrGroggle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.agility; + +import javax.annotation.Nullable; +import lombok.AllArgsConstructor; +import lombok.Value; +import net.runelite.api.Tile; +import net.runelite.client.game.AgilityShortcut; + +@Value +@AllArgsConstructor +class Obstacle +{ + private final Tile tile; + @Nullable + private final AgilityShortcut shortcut; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java index 43a96bd151..92df605a36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java @@ -25,11 +25,27 @@ package net.runelite.client.plugins.agility; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Multimap; import java.util.List; import java.util.Set; -import static net.runelite.api.NullObjectID.*; +import static net.runelite.api.NullObjectID.NULL_10872; +import static net.runelite.api.NullObjectID.NULL_10873; +import static net.runelite.api.NullObjectID.NULL_12945; +import static net.runelite.api.NullObjectID.NULL_18083; +import static net.runelite.api.NullObjectID.NULL_18116; +import static net.runelite.api.NullObjectID.NULL_18122; +import static net.runelite.api.NullObjectID.NULL_18124; +import static net.runelite.api.NullObjectID.NULL_18129; +import static net.runelite.api.NullObjectID.NULL_18130; +import static net.runelite.api.NullObjectID.NULL_18132; +import static net.runelite.api.NullObjectID.NULL_18133; +import static net.runelite.api.NullObjectID.NULL_18135; +import static net.runelite.api.NullObjectID.NULL_18136; +import static net.runelite.api.NullObjectID.NULL_3550; import static net.runelite.api.ObjectID.*; +import net.runelite.client.game.AgilityShortcut; class Obstacles { @@ -62,7 +78,7 @@ class Obstacles STEPPING_STONE_15412, TROPICAL_TREE_15414, MONKEYBARS_15417, SKULL_SLOPE_15483, ROPE_15487, TROPICAL_TREE_16062, // Falador ROUGH_WALL_10833, TIGHTROPE_10834, HAND_HOLDS_10836, GAP_11161, GAP_11360, TIGHTROPE_11361, - TIGHTROPE_11364, GAP_11365, LEDGE_11366, LEDGE_11367, LEDGE_11368, LEDGE_11370, EDGE_11371, + TIGHTROPE_11364, GAP_11365, LEDGE_11366, LEDGE_11367, LEDGE_11369, LEDGE_11370, EDGE_11371, // Wilderness OBSTACLE_PIPE_23137, ROPESWING_23132, STEPPING_STONE_23556, LOG_BALANCE_23542, ROCKS_23640, // Seers @@ -91,144 +107,7 @@ class Obstacles ZIP_LINE_11645, ZIP_LINE_11646 ); - static final Set SHORTCUT_OBSTACLE_IDS = ImmutableSet.of( - // Grand Exchange - UNDERWALL_TUNNEL_16529, UNDERWALL_TUNNEL_16530, - // South Varrock - STEPPING_STONE_16533, FENCE_16518, ROCKS_16549, ROCKS_16550, - // Falador - WALL_17049, WALL_17050, CRUMBLING_WALL_24222, UNDERWALL_TUNNEL, UNDERWALL_TUNNEL_16528, CREVICE_16543, - // Draynor - UNDERWALL_TUNNEL_19032, UNDERWALL_TUNNEL_19036, - // South Lumbridge - BROKEN_RAFT, STEPPING_STONE_16513, - // Trollheim - ROCKS_3790, ROCKS_3791, ROCKS_3803, ROCKS_3804, ROCKS_16523, ROCKS_16524, ROCKS_3748, ROCKS_16545, ROCKS_16521, - ROCKS_16522, ROCKS_16464, - // North Camelot - LOG_BALANCE_16540, LOG_BALANCE_16541, LOG_BALANCE_16542, - // Rellekka - BROKEN_FENCE, - // Ardougne - LOG_BALANCE_16546, LOG_BALANCE_16547, LOG_BALANCE_16548, - // Yanille - CASTLE_WALL, HOLE_16520, WALL_17047, - // Observatory - NULL_31849, - // Gnome Stronghold - ROCKS_16534, ROCKS_16535, - // Karamja Volcano - STRONG_TREE_17074, - // Shilo Village - STEPPING_STONE_16466, - // Vine east of Shilo Village - NULL_26884, NULL_26886, - // Stepping stones east of Shilo Village - STEPPING_STONES, STEPPING_STONES_23646, STEPPING_STONES_23647, - // Middle of Karamja - A_WOODEN_LOG, - // Slayer Tower - SPIKEY_CHAIN, SPIKEY_CHAIN_16538, - // Fremennik Slayer Cave - STRANGE_FLOOR_16544, CREVICE_16539, STEPS_29993, - // Wilderness - STEPPING_STONE_14918, STEPPING_STONE_14917, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406, - // Godwars - ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, - // Seers' Village Coal Mine - LOG_BALANCE_23274, - // Arceuus Essence Mine - ROCKS_27984, ROCKS_27985, BOULDER_27990, ROCKS_27987, ROCKS_27988, - // Wintertodt - GAP_29326, - // Gnome Stronghold Slayer Underground - TUNNEL_30174, TUNNEL_30175, - // Taverley Underground - OBSTACLE_PIPE_16509, STRANGE_FLOOR, ROCKS, ROCKS_14106, LOOSE_RAILING_28849, - // Heroes Guild - CREVICE_9739, CREVICE_9740, - // Fossil Island - HOLE_31481, HOLE_31482, LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, ROPE_ANCHOR, ROPE_ANCHOR_30917, - RUBBER_CAP_MUSHROOM, - ROCKS_31757, ROCKS_31758, ROCKS_31759, PILLAR_31809, - // West Brimhaven - ROPESWING_23568, ROPESWING_23569, - // Brimhaven Dungeon - VINE_26880, VINE_26882, PIPE_21728, STEPPING_STONE_19040, PIPE_21727, LOG_BALANCE_20882, LOG_BALANCE_20884, - STEPPING_STONE_21738, STEPPING_STONE_21739, TIGHTGAP, - // Lumbridge - STILE_12982, - // Edgeville Dungeon - MONKEYBARS_23566, OBSTACLE_PIPE_16511, - // Miscellania - STEPPING_STONE_11768, - // Kalphite - CREVICE_16465, - // Eagles' Peak - ROCKS_19849, - // Catherby - CROSSBOW_TREE_17062, ROCKS_17042, - // McGrubor's Woods - LOOSE_RAILING, - // Cairn Isle - ROCKS_2231, - // South Kourend - STEPPING_STONE_29728, STEPPING_STONE_29729, STEPPING_STONE_29730, - // Cosmic Temple - JUTTING_WALL_17002, - // Arandar - ROCKS_16514, ROCKS_16515, LOG_BALANCE_3933, - // South River Salve - STEPPING_STONE_13504, - DARK_TUNNEL_10047, - // Ectofuntus - WEATHERED_WALL, WEATHERED_WALL_16526, - // Mos Le'Harmless - STEPPING_STONE_19042, - // North River Salve - ROCKS_16998, ROCKS_16999, ORNATE_RAILING, ORNATE_RAILING_17000, - // West Zul-Andra - STEPPING_STONE_10663, - // Yanille Agility Dungeon - BALANCING_LEDGE_23548, OBSTACLE_PIPE_23140, MONKEYBARS_23567, PILE_OF_RUBBLE_23563, PILE_OF_RUBBLE_23564, - // High Level Wilderness Dungeon - CREVICE_19043, - // Revenant Caves - PILLAR_31561, - // Elf Camp Isafdar Tirranwn - LOG_BALANCE_3931, LOG_BALANCE_3930, LOG_BALANCE_3929, LOG_BALANCE_3932, DENSE_FOREST_3938, DENSE_FOREST_3939, - DENSE_FOREST_3998, DENSE_FOREST_3999, DENSE_FOREST, LEAVES, LEAVES_3924, LEAVES_3925, STICKS, TRIPWIRE, - // Gu'Tanoth bridge - GAP, GAP_2831, - // Lumbridge Swamp Caves - STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673, - // Morytania Pirate Ship - ROCK_16115, - // Agility Pyramid Entrance - CLIMBING_ROCKS_11948, CLIMBING_ROCKS_11949, - // Lumber Yard - BROKEN_FENCE_2618, - // Ungael and Vorkath crater - NULL_25337, NULL_29868, NULL_29869, NULL_29870, ICE_CHUNKS_31822, NULL_31823, ICE_CHUNKS_31990, - // Underwater Area Fossil Island - TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962, - // Tree Gnome Village - LOOSE_RAILING_2186, - // Weiss - LITTLE_BOULDER, ROCKSLIDE_33184, ROCKSLIDE_33185, NULL_33327, NULL_33328, LEDGE_33190, ROCKSLIDE_33191, FALLEN_TREE_33192, - // Al-Kharid - BROKEN_WALL_33344, BIG_WINDOW, - // Burgh de Rott - LOW_FENCE, - // Taverley - STILE, - // Asgarnian Ice Dungeon - STEPS, - // Fossil Island Wyvern Cave - STAIRS_31485, - // Mount Karuulm - ROCKS_34397, ROCKS_34396 - ); + static final Multimap SHORTCUT_OBSTACLE_IDS; static final Set TRAP_OBSTACLE_IDS = ImmutableSet.of( // Agility pyramid @@ -236,4 +115,17 @@ class Obstacles ); static final List TRAP_OBSTACLE_REGIONS = ImmutableList.of(12105, 13356); + + static + { + final ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); + for (final AgilityShortcut item : AgilityShortcut.values()) + { + for (int obstacle : item.getObstacleIds()) + { + builder.put(obstacle, item); + } + } + SHORTCUT_OBSTACLE_IDS = builder.build(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesConfig.java index 111fb9dc85..c3715481d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesConfig.java @@ -97,11 +97,22 @@ public interface AttackStylesConfig extends Config return false; } + @ConfigItem( + keyName = "hideAutoRetaliate", + name = "Hide auto retaliate", + description = "Hide auto retaliate from the combat options tab", + position = 7 + ) + default boolean hideAutoRetaliate() + { + return false; + } + @ConfigItem( keyName = "removeWarnedStyles", name = "Remove warned styles", description = "Remove warned styles from the combat options tab", - position = 7 + position = 8 ) default boolean removeWarnedStyles() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java index 4b6de0ea1d..db7a9ed751 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java @@ -126,6 +126,7 @@ public class AttackStylesPlugin extends Plugin overlayManager.remove(overlay); hideWarnedStyles(false); processWidgets(); + hideWidget(client.getWidget(WidgetInfo.COMBAT_AUTO_RETALIATE), false); } public AttackStyle getAttackStyle() @@ -174,6 +175,7 @@ public class AttackStylesPlugin extends Plugin hideWidget(client.getWidget(widgetKey), widgetsToHide.get(equippedWeaponType, widgetKey)); } } + hideWidget(client.getWidget(WidgetInfo.COMBAT_AUTO_RETALIATE), config.hideAutoRetaliate()); } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 620cc586be..6a3a7f3416 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -60,6 +60,7 @@ import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; @@ -125,6 +126,9 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis @Inject private KeyManager keyManager; + @Inject + private SpriteManager spriteManager; + private boolean shiftPressed = false; @Provides @@ -139,7 +143,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis keyManager.registerKeyListener(this); mouseManager.registerMouseWheelListener(this); clientThread.invokeLater(tabInterface::init); - client.getSpriteOverrides().putAll(TabSprites.toMap(client)); + spriteManager.addSpriteOverrides(TabSprites.values()); } @Override @@ -148,11 +152,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis keyManager.unregisterKeyListener(this); mouseManager.unregisterMouseWheelListener(this); clientThread.invokeLater(tabInterface::destroy); - - for (TabSprites value : TabSprites.values()) - { - client.getSpriteOverrides().remove(value.getSpriteId()); - } + spriteManager.removeSpriteOverrides(TabSprites.values()); shiftPressed = false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/TagManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/TagManager.java index c20974758d..c1d5ff8c11 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/TagManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/TagManager.java @@ -167,6 +167,20 @@ public class TagManager } } + public void renameTag(String oldTag, String newTag) + { + List items = getItemsForTag(Text.standardize(oldTag)); + items.forEach(id -> + { + Collection tags = getTags(id, id < 0); + + tags.remove(Text.standardize(oldTag)); + tags.add(Text.standardize(newTag)); + + setTags(id, tags, id < 0); + }); + } + private int getItemId(int itemId, boolean variation) { itemId = Math.abs(itemId); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java index afa8f6e276..51e179b143 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java @@ -39,5 +39,6 @@ class MenuIndexes static final int CHANGE_ICON = 3; static final int DELETE_TAB = 4; static final int EXPORT_TAB = 5; + static final int RENAME_TAB = 6; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 148b965043..e0b1af23eb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -64,7 +64,6 @@ import net.runelite.api.SpriteID; import net.runelite.api.VarClientInt; import net.runelite.api.VarClientStr; import net.runelite.api.Varbits; -import net.runelite.api.widgets.WidgetType; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.vars.InputType; @@ -73,15 +72,14 @@ import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetConfig; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetSizeMode; +import net.runelite.api.widgets.WidgetType; import net.runelite.client.Notifier; import net.runelite.client.callback.ClientThread; -import net.runelite.client.config.ConfigManager; import net.runelite.client.game.ItemManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.plugins.banktags.BankTagsConfig; import net.runelite.client.plugins.banktags.BankTagsPlugin; -import static net.runelite.client.plugins.banktags.BankTagsPlugin.CONFIG_GROUP; -import static net.runelite.client.plugins.banktags.BankTagsPlugin.ICON_SEARCH; import static net.runelite.client.plugins.banktags.BankTagsPlugin.TAG_SEARCH; import static net.runelite.client.plugins.banktags.BankTagsPlugin.VAR_TAG_SUFFIX; import net.runelite.client.plugins.banktags.TagManager; @@ -102,6 +100,7 @@ public class TabInterface private static final String EXPORT_TAB = "Export tag tab"; private static final String IMPORT_TAB = "Import tag tab"; private static final String VIEW_TAB = "View tag tab"; + private static final String RENAME_TAB = "Rename tag tab"; private static final String CHANGE_ICON = "Change icon"; private static final String REMOVE_TAG = "Remove-tag"; private static final String TAG_GEAR = "Tag-equipment"; @@ -111,11 +110,12 @@ public class TabInterface private static final int BUTTON_HEIGHT = 20; private static final int MARGIN = 1; private static final int SCROLL_TICK = 500; + private static final int INCINERATOR_WIDTH = 48; + private static final int INCINERATOR_HEIGHT = 39; private final Client client; private final ClientThread clientThread; private final ItemManager itemManager; - private final ConfigManager configManager; private final TagManager tagManager; private final TabManager tabManager; private final ChatboxPanelManager chatboxPanelManager; @@ -130,6 +130,8 @@ public class TabInterface private int currentTabIndex; private TagTab iconToSet = null; private Instant startScroll = Instant.now(); + private String rememberedSearch; + private boolean waitSearchTick; @Getter private Widget upButton; @@ -148,7 +150,6 @@ public class TabInterface final Client client, final ClientThread clientThread, final ItemManager itemManager, - final ConfigManager configManager, final TagManager tagManager, final TabManager tabManager, final ChatboxPanelManager chatboxPanelManager, @@ -159,7 +160,6 @@ public class TabInterface this.client = client; this.clientThread = clientThread; this.itemManager = itemManager; - this.configManager = configManager; this.tagManager = tagManager; this.tabManager = tabManager; this.chatboxPanelManager = chatboxPanelManager; @@ -211,7 +211,7 @@ public class TabInterface if (config.rememberTab() && !Strings.isNullOrEmpty(config.tab())) { - openTag(TAG_SEARCH + config.tab()); + openTag(config.tab()); } } @@ -239,7 +239,7 @@ public class TabInterface tagManager.addTag(item, activeTab.getTag(), false); } - openTag(TAG_SEARCH + activeTab.getTag()); + openTag(activeTab.getTag()); } return; @@ -292,7 +292,7 @@ public class TabInterface final Iterator dataIter = Text.fromCSV(dataString).iterator(); final String name = dataIter.next(); final String icon = dataIter.next(); - configManager.setConfiguration(CONFIG_GROUP, ICON_SEARCH + name, icon); + tabManager.setIcon(name, icon); while (dataIter.hasNext()) { @@ -306,7 +306,7 @@ public class TabInterface if (activeTab != null && name.equals(activeTab.getTag())) { - openTag(TAG_SEARCH + activeTab.getTag()); + openTag(activeTab.getTag()); } notifier.notify("Tag tab " + name + " has been imported from your clipboard!"); @@ -336,7 +336,7 @@ public class TabInterface } else { - openTag(TAG_SEARCH + Text.removeTags(clicked.getName())); + openTag(Text.removeTags(clicked.getName())); } client.playSoundEffect(SoundEffectID.UI_BOOP); @@ -373,6 +373,10 @@ public class TabInterface Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); notifier.notify("Tag tab " + tagTab.getTag() + " has been copied to your clipboard!"); break; + case Tab.RENAME_TAB: + String renameTarget = Text.standardize(event.getOpbase()); + renameTab(renameTarget); + break; } } @@ -382,6 +386,8 @@ public class TabInterface currentTabIndex = 0; maxTabs = 0; parent = null; + waitSearchTick = false; + rememberedSearch = ""; if (upButton != null) { @@ -398,6 +404,8 @@ public class TabInterface if (isHidden()) { parent = null; + waitSearchTick = false; + rememberedSearch = ""; // If bank window was just hidden, update last active tab position if (currentTabIndex != config.position()) @@ -462,6 +470,20 @@ public class TabInterface activateTab(null); } + if (!waitSearchTick + && activeTab == null + && !Strings.isNullOrEmpty(rememberedSearch) + && client.getVar(VarClientInt.INPUT_TYPE) == InputType.NONE.getType()) + { + bankSearch.reset(true); + bankSearch.search(InputType.NONE, rememberedSearch, true); + rememberedSearch = ""; + } + else if (waitSearchTick) + { + waitSearchTick = false; + } + updateBounds(); scrollTab(0); } @@ -542,6 +564,15 @@ public class TabInterface return; } + if (event.getWidgetId() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + && event.getMenuAction() == MenuAction.EXAMINE_ITEM_BANK_EQ + && event.getMenuOption().equalsIgnoreCase("withdraw-x")) + { + waitSearchTick = true; + rememberedSearch = client.getVar(VarClientStr.INPUT_TEXT); + bankSearch.search(InputType.NONE, rememberedSearch, true); + } + if (iconToSet != null) { if (event.getMenuOption().startsWith(CHANGE_ICON + " (")) @@ -550,7 +581,7 @@ public class TabInterface int itemId = itemManager.canonicalize(item.getId()); iconToSet.setIconItemId(itemId); iconToSet.getIcon().setItemId(itemId); - configManager.setConfiguration(CONFIG_GROUP, ICON_SEARCH + iconToSet.getTag(), itemId + ""); + tabManager.setIcon(iconToSet.getTag(), itemId + ""); event.consume(); } @@ -597,7 +628,7 @@ public class TabInterface { if (activeTab != null && tags.contains(activeTab.getTag())) { - openTag(TAG_SEARCH + activeTab.getTag()); + openTag(activeTab.getTag()); } } @@ -683,6 +714,7 @@ public class TabInterface btn.setAction(2, CHANGE_ICON); btn.setAction(3, REMOVE_TAB); btn.setAction(4, EXPORT_TAB); + btn.setAction(5, RENAME_TAB); btn.setOnOpListener((JavaScriptCallback) this::handleTagTab); tagTab.setBackground(btn); } @@ -712,13 +744,66 @@ public class TabInterface } tabManager.remove(tag); - configManager.unsetConfiguration(CONFIG_GROUP, ICON_SEARCH + tag); tabManager.save(); updateBounds(); scrollTab(0); } + private void renameTab(String oldTag) + { + chatboxPanelManager.openTextInput("Enter new tag name for tag \"" + oldTag + "\":") + .onDone((newTag) -> clientThread.invoke(() -> + { + if (!Strings.isNullOrEmpty(newTag) && !newTag.equalsIgnoreCase(oldTag)) + { + if (tabManager.find(newTag) == null) + { + TagTab tagTab = tabManager.find(oldTag); + tagTab.setTag(newTag); + + final String coloredName = ColorUtil.wrapWithColorTag(newTag, HILIGHT_COLOR); + tagTab.getIcon().setName(coloredName); + tagTab.getBackground().setName(coloredName); + + tabManager.removeIcon(oldTag); + tabManager.setIcon(newTag, tagTab.getIconItemId() + ""); + + tabManager.save(); + tagManager.renameTag(oldTag, newTag); + + if (activeTab != null && activeTab.equals(tagTab)) + { + openTag(newTag); + } + } + else + { + chatboxPanelManager.openTextMenuInput("The specified bank tag already exists.") + .option("1. Merge into existing tag \"" + newTag + "\".", () -> + clientThread.invoke(() -> + { + tagManager.renameTag(oldTag, newTag); + final String activeTag = activeTab != null ? activeTab.getTag() : ""; + deleteTab(oldTag); + + if (activeTag.equals(oldTag)) + { + openTag(newTag); + } + }) + ) + .option("2. Choose a different name.", () -> + clientThread.invoke(() -> + renameTab(oldTag)) + ) + .build(); + } + } + })) + .build(); + } + private void scrollTick(int direction) { // This ensures that dragging on scroll buttons do not scrolls too fast @@ -805,17 +890,18 @@ public class TabInterface if (incinerator != null && !incinerator.isHidden()) { - // This is the required way to move incinerator, don't change it! - incinerator.setOriginalHeight(39); - incinerator.setOriginalWidth(48); - incinerator.setRelativeY(itemContainer.getHeight()); - incinerator.revalidate(); + incinerator.setOriginalHeight(INCINERATOR_HEIGHT); + incinerator.setOriginalWidth(INCINERATOR_WIDTH); + incinerator.setOriginalY(INCINERATOR_HEIGHT); Widget child = incinerator.getDynamicChildren()[0]; - child.setHeight(39); - child.setWidth(48); + child.setOriginalHeight(INCINERATOR_HEIGHT); + child.setOriginalWidth(INCINERATOR_WIDTH); + child.setWidthMode(WidgetSizeMode.ABSOLUTE); + child.setHeightMode(WidgetSizeMode.ABSOLUTE); child.setType(WidgetType.GRAPHIC); child.setSpriteId(TabSprites.INCINERATOR.getSpriteId()); + incinerator.revalidate(); bounds.setSize(TAB_WIDTH + MARGIN * 2, height - incinerator.getHeight()); } @@ -900,7 +986,6 @@ public class TabInterface private void updateWidget(Widget t, int y) { t.setOriginalY(y); - t.setRelativeY(y); t.setHidden(y < (bounds.y + BUTTON_HEIGHT + MARGIN) || y > (bounds.y + bounds.height - TAB_HEIGHT - MARGIN - BUTTON_HEIGHT)); t.revalidate(); } @@ -913,10 +998,10 @@ public class TabInterface return itemManager.getItemComposition(item.getId()); } - private void openTag(String tag) + private void openTag(final String tag) { - bankSearch.search(InputType.SEARCH, tag, true); - activateTab(tabManager.find(tag.substring(TAG_SEARCH.length()))); + bankSearch.search(InputType.SEARCH, TAG_SEARCH + tag, true); + activateTab(tabManager.find(tag)); // When tab is selected with search window open, the search window closes but the search button // stays highlighted, this solves that issue diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java index 3f1430dd7c..e1995a5095 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java @@ -115,6 +115,7 @@ class TabManager { tagTab.setHidden(true); tabs.remove(tagTab); + removeIcon(tag); } } @@ -124,6 +125,16 @@ class TabManager configManager.setConfiguration(CONFIG_GROUP, TAG_TABS_CONFIG, tags); } + void removeIcon(final String tag) + { + configManager.unsetConfiguration(CONFIG_GROUP, ICON_SEARCH + Text.standardize(tag)); + } + + void setIcon(final String tag, final String icon) + { + configManager.setConfiguration(CONFIG_GROUP, ICON_SEARCH + Text.standardize(tag), icon); + } + int size() { return tabs.size(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java index e7706679b0..20f9d0dfb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabSprites.java @@ -25,17 +25,12 @@ */ package net.runelite.client.plugins.banktags.tabs; -import java.awt.image.BufferedImage; -import java.util.HashMap; -import java.util.Map; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.SpritePixels; -import net.runelite.client.util.ImageUtil; +import lombok.RequiredArgsConstructor; +import net.runelite.client.game.SpriteOverride; -@Slf4j -public enum TabSprites +@RequiredArgsConstructor +public enum TabSprites implements SpriteOverride { INCINERATOR(-200, "incinerator.png"), TAB_BACKGROUND(-201, "tag-tab.png"), @@ -46,23 +41,7 @@ public enum TabSprites @Getter private final int spriteId; - private final BufferedImage image; - TabSprites(final int spriteId, final String imageName) - { - this.spriteId = spriteId; - this.image = ImageUtil.getResourceStreamFromClass(this.getClass(), imageName); - } - - public static Map toMap(Client client) - { - final Map map = new HashMap<>(); - - for (TabSprites value : values()) - { - map.put(value.spriteId, ImageUtil.getImageSpritePixels(value.image, client)); - } - - return map; - } + @Getter + private final String fileName; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java index d3d417f465..004e5f45ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java @@ -33,7 +33,7 @@ import net.runelite.api.widgets.Widget; @EqualsAndHashCode(of = "tag") class TagTab { - private final String tag; + private String tag; private int iconItemId; private Widget background; private Widget icon; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java index dfd175cae7..1c480719ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsOverlay.java @@ -77,7 +77,7 @@ class BarrowsOverlay extends Overlay { final NPCComposition composition = npc.getComposition(); - if (composition != null && !composition.isMinimapVisable()) + if (composition != null && !composition.isMinimapVisible()) { continue; } @@ -90,10 +90,16 @@ class BarrowsOverlay extends Overlay } // Player dots - graphics.setColor(npcColor); + graphics.setColor(playerColor); final List players = client.getPlayers(); for (Player player : players) { + if (player == local) + { + // Skip local player as we draw square for it later + continue; + } + net.runelite.api.Point minimapLocation = player.getMinimapLocation(); if (minimapLocation != null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java index 014f7cda98..42c1853a2f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java @@ -49,7 +49,9 @@ import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; @@ -128,6 +130,19 @@ public class BarrowsPlugin extends Plugin overlayManager.remove(brotherOverlay); walls.clear(); ladders.clear(); + + // Restore widgets + final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL); + if (potential != null) + { + potential.setHidden(false); + } + + final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS); + if (barrowsBrothers != null) + { + barrowsBrothers.setHidden(false); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsOverlay.java index a02ee25e94..bebfcee730 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsOverlay.java @@ -137,7 +137,7 @@ class BoostsOverlay extends Overlay return new Color(238, 51, 51); } - return boost < config.boostThreshold() ? Color.YELLOW : Color.GREEN; + return boost <= config.boostThreshold() ? Color.YELLOW : Color.GREEN; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonCounter.java index 2db9d6f3e0..bd13e194be 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonCounter.java @@ -26,15 +26,15 @@ package net.runelite.client.plugins.cannon; import java.awt.Color; import java.awt.image.BufferedImage; -import net.runelite.client.ui.overlay.infobox.Counter; +import net.runelite.client.ui.overlay.infobox.InfoBox; -public class CannonCounter extends Counter +public class CannonCounter extends InfoBox { private final CannonPlugin plugin; - public CannonCounter(BufferedImage img, CannonPlugin plugin) + CannonCounter(BufferedImage img, CannonPlugin plugin) { - super(img, plugin, String.valueOf(plugin.getCballsLeft())); + super(img, plugin); this.plugin = plugin; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java index 2087e31844..47f1adbec4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java @@ -75,7 +75,8 @@ public class CerberusPlugin extends Plugin @Subscribe public void onGameStateChanged(GameStateChanged event) { - if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING) + GameState gameState = event.getGameState(); + if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING || gameState == GameState.CONNECTION_LOST) { ghosts.clear(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index a927782809..e7e22cdae3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -43,7 +43,6 @@ import net.runelite.api.MessageNode; import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; -import net.runelite.api.events.SetMessage; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.vars.AccountType; @@ -300,7 +299,7 @@ public class ChatCommandsPlugin extends Plugin Widget boss = bossChildren[i]; Widget kill = killsChildren[i]; - String bossName = boss.getText(); + String bossName = boss.getText().replace(":", ""); int kc = Integer.parseInt(kill.getText().replace(",", "")); if (kc != getKc(bossName)) { @@ -360,14 +359,19 @@ public class ChatCommandsPlugin extends Plugin return true; } - private void killCountLookup(SetMessage setMessage, String message) + private void killCountLookup(ChatMessage chatMessage, String message) { if (!config.killcount()) { return; } - ChatMessageType type = setMessage.getType(); + if (message.length() <= KILLCOUNT_COMMAND_STRING.length()) + { + return; + } + + ChatMessageType type = chatMessage.getType(); String search = message.substring(KILLCOUNT_COMMAND_STRING.length() + 1); final String player; @@ -377,7 +381,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(setMessage.getName()); + player = sanitize(chatMessage.getName()); } search = longBossName(search); @@ -403,20 +407,20 @@ public class ChatCommandsPlugin extends Plugin .build(); log.debug("Setting response {}", response); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); } - private void questPointsLookup(SetMessage setMessage, String message) + private void questPointsLookup(ChatMessage chatMessage, String message) { if (!config.qp()) { return; } - ChatMessageType type = setMessage.getType(); + ChatMessageType type = chatMessage.getType(); final String player; if (type.equals(ChatMessageType.PRIVATE_MESSAGE_SENT)) @@ -425,7 +429,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(setMessage.getName()); + player = sanitize(chatMessage.getName()); } int qp; @@ -447,7 +451,7 @@ public class ChatCommandsPlugin extends Plugin .build(); log.debug("Setting response {}", response); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); @@ -477,14 +481,19 @@ public class ChatCommandsPlugin extends Plugin return true; } - private void personalBestLookup(SetMessage setMessage, String message) + private void personalBestLookup(ChatMessage chatMessage, String message) { if (!config.pb()) { return; } - ChatMessageType type = setMessage.getType(); + if (message.length() <= PB_COMMAND.length()) + { + return; + } + + ChatMessageType type = chatMessage.getType(); String search = message.substring(PB_COMMAND.length() + 1); final String player; @@ -494,7 +503,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(setMessage.getName()); + player = sanitize(chatMessage.getName()); } search = longBossName(search); @@ -523,7 +532,7 @@ public class ChatCommandsPlugin extends Plugin .build(); log.debug("Setting response {}", response); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); @@ -565,17 +574,22 @@ public class ChatCommandsPlugin extends Plugin * Looks up the item price and changes the original message to the * response. * - * @param setMessage The chat message containing the command. + * @param chatMessage The chat message containing the command. * @param message The chat message */ - private void itemPriceLookup(SetMessage setMessage, String message) + private void itemPriceLookup(ChatMessage chatMessage, String message) { if (!config.price()) { return; } - MessageNode messageNode = setMessage.getMessageNode(); + if (message.length() <= PRICE_COMMAND_STRING.length()) + { + return; + } + + MessageNode messageNode = chatMessage.getMessageNode(); String search = message.substring(PRICE_COMMAND_STRING.length() + 1); List results = itemManager.search(search); @@ -621,10 +635,10 @@ public class ChatCommandsPlugin extends Plugin * Looks up the player skill and changes the original message to the * response. * - * @param setMessage The chat message containing the command. + * @param chatMessage The chat message containing the command. * @param message The chat message */ - private void playerSkillLookup(SetMessage setMessage, String message) + private void playerSkillLookup(ChatMessage chatMessage, String message) { if (!config.lvl()) { @@ -638,6 +652,11 @@ public class ChatCommandsPlugin extends Plugin } else { + if (message.length() <= LEVEL_COMMAND_STRING.length()) + { + return; + } + search = message.substring(LEVEL_COMMAND_STRING.length() + 1); } @@ -652,7 +671,7 @@ public class ChatCommandsPlugin extends Plugin return; } - final HiscoreLookup lookup = getCorrectLookupFor(setMessage); + final HiscoreLookup lookup = getCorrectLookupFor(chatMessage); try { @@ -682,7 +701,7 @@ public class ChatCommandsPlugin extends Plugin .build(); log.debug("Setting response {}", response); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); @@ -693,14 +712,14 @@ public class ChatCommandsPlugin extends Plugin } } - private void combatLevelLookup(SetMessage setMessage, String message) + private void combatLevelLookup(ChatMessage chatMessage, String message) { if (!config.lvl()) { return; } - ChatMessageType type = setMessage.getType(); + ChatMessageType type = chatMessage.getType(); String player; if (type == ChatMessageType.PRIVATE_MESSAGE_SENT) @@ -709,7 +728,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(setMessage.getName()); + player = sanitize(chatMessage.getName()); } try @@ -767,7 +786,7 @@ public class ChatCommandsPlugin extends Plugin .build(); log.debug("Setting response {}", response); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); @@ -778,7 +797,7 @@ public class ChatCommandsPlugin extends Plugin } } - private void clueLookup(SetMessage setMessage, String message) + private void clueLookup(ChatMessage chatMessage, String message) { if (!config.clue()) { @@ -799,7 +818,7 @@ public class ChatCommandsPlugin extends Plugin try { final Skill hiscoreSkill; - final HiscoreLookup lookup = getCorrectLookupFor(setMessage); + final HiscoreLookup lookup = getCorrectLookupFor(chatMessage); final HiscoreResult result = hiscoreClient.lookup(lookup.getName(), lookup.getEndpoint()); if (result == null) @@ -858,7 +877,7 @@ public class ChatCommandsPlugin extends Plugin String response = chatMessageBuilder.build(); log.debug("Setting response {}", response); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); @@ -872,22 +891,22 @@ public class ChatCommandsPlugin extends Plugin /** * Gets correct lookup data for message * - * @param setMessage chat message + * @param chatMessage chat message * @return hiscore lookup data */ - private HiscoreLookup getCorrectLookupFor(final SetMessage setMessage) + private HiscoreLookup getCorrectLookupFor(final ChatMessage chatMessage) { final String player; final HiscoreEndpoint ironmanStatus; - if (setMessage.getType().equals(ChatMessageType.PRIVATE_MESSAGE_SENT)) + if (chatMessage.getType().equals(ChatMessageType.PRIVATE_MESSAGE_SENT)) { player = client.getLocalPlayer().getName(); ironmanStatus = hiscoreEndpoint; } else { - player = sanitize(setMessage.getName()); + player = sanitize(chatMessage.getName()); if (player.equals(client.getLocalPlayer().getName())) { @@ -897,7 +916,7 @@ public class ChatCommandsPlugin extends Plugin else { // Get ironman status from their icon in chat - ironmanStatus = getHiscoreEndpointByName(setMessage.getName()); + ironmanStatus = getHiscoreEndpointByName(chatMessage.getName()); } } @@ -1090,6 +1109,7 @@ public class ChatCommandsPlugin extends Plugin case "barrows": return "Barrows Chests"; + // cox case "cox": case "xeric": case "chambers": @@ -1097,6 +1117,15 @@ public class ChatCommandsPlugin extends Plugin case "raids": return "Chambers of Xeric"; + // cox cm + case "cox cm": + case "xeric cm": + case "chambers cm": + case "olm cm": + case "raids cm": + return "Chambers of Xeric Challenge Mode"; + + // tob case "tob": case "theatre": case "verzik": diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java new file mode 100644 index 0000000000..abc1747b4a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterConfig.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018, Magic fTail + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.chatfilter; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("chatfilter") +public interface ChatFilterConfig extends Config +{ + @ConfigItem( + keyName = "filterType", + name = "Filter type", + description = "Configures how the messages are filtered", + position = 1 + ) + default ChatFilterType filterType() + { + return ChatFilterType.CENSOR_WORDS; + } + + @ConfigItem( + keyName = "filteredWords", + name = "Filtered Words", + description = "List of filtered words, separated by commas", + position = 2 + ) + default String filteredWords() + { + return ""; + } + + @ConfigItem( + keyName = "filteredRegex", + name = "Filtered Regex", + description = "List of regular expressions to filter, one per line", + position = 3 + ) + default String filteredRegex() + { + return ""; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java new file mode 100644 index 0000000000..355ed29b28 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2018, Magic fTail + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.chatfilter; + +import com.google.common.base.Splitter; +import com.google.inject.Provides; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import javax.inject.Inject; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.Player; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.OverheadTextChanged; +import net.runelite.api.events.ScriptCallbackEvent; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.Text; +import org.apache.commons.lang3.StringUtils; + +@PluginDescriptor( + name = "Chat Filter", + description = "Censor user configurable words or patterns from chat", + enabledByDefault = false +) +public class ChatFilterPlugin extends Plugin +{ + private static final Splitter NEWLINE_SPLITTER = Splitter + .on("\n") + .omitEmptyStrings() + .trimResults(); + + private static final String CENSOR_MESSAGE = "Hey, everyone, I just tried to say something very silly!"; + + private final JagexPrintableCharMatcher jagexPrintableCharMatcher = new JagexPrintableCharMatcher(); + private final List filteredPatterns = new ArrayList<>(); + + @Inject + private Client client; + + @Inject + private ChatFilterConfig config; + + @Provides + ChatFilterConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(ChatFilterConfig.class); + } + + @Override + protected void startUp() throws Exception + { + updateFilteredPatterns(); + } + + @Override + protected void shutDown() throws Exception + { + filteredPatterns.clear(); + } + + @Subscribe + public void onScriptCallbackEvent(ScriptCallbackEvent event) + { + if (!"chatFilterCheck".equals(event.getEventName())) + { + return; + } + + int[] intStack = client.getIntStack(); + int intStackSize = client.getIntStackSize(); + ChatMessageType chatMessageType = ChatMessageType.of(intStack[intStackSize - 1]); + + // Only filter public chat and private messages + switch (chatMessageType) + { + case PUBLIC: + case PUBLIC_MOD: + case AUTOCHAT: + case PRIVATE_MESSAGE_RECEIVED: + case PRIVATE_MESSAGE_RECEIVED_MOD: + case CLANCHAT: + break; + default: + return; + } + + String[] stringStack = client.getStringStack(); + int stringStackSize = client.getStringStackSize(); + + String message = stringStack[stringStackSize - 1]; + String censoredMessage = censorMessage(message); + + if (censoredMessage == null) + { + // Block the message + intStack[intStackSize - 2] = 0; + } + else + { + // Replace the message + stringStack[stringStackSize - 1] = censoredMessage; + } + } + + @Subscribe + public void onOverheadTextChanged(OverheadTextChanged event) + { + if (!(event.getActor() instanceof Player)) + { + return; + } + + String message = censorMessage(event.getOverheadText()); + + if (message == null) + { + message = " "; + } + + event.getActor().setOverheadText(message); + } + + String censorMessage(final String message) + { + String strippedMessage = jagexPrintableCharMatcher.retainFrom(message) + .replace('\u00A0', ' '); + boolean filtered = false; + for (Pattern pattern : filteredPatterns) + { + Matcher m = pattern.matcher(strippedMessage); + + StringBuffer sb = new StringBuffer(); + + while (m.find()) + { + switch (config.filterType()) + { + case CENSOR_WORDS: + m.appendReplacement(sb, StringUtils.repeat("*", m.group(0).length())); + filtered = true; + break; + case CENSOR_MESSAGE: + return CENSOR_MESSAGE; + case REMOVE_MESSAGE: + return null; + } + } + m.appendTail(sb); + + strippedMessage = sb.toString(); + } + + return filtered ? strippedMessage : message; + } + + void updateFilteredPatterns() + { + filteredPatterns.clear(); + + Text.fromCSV(config.filteredWords()).stream() + .map(s -> Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE)) + .forEach(filteredPatterns::add); + + NEWLINE_SPLITTER.splitToList(config.filteredRegex()).stream() + .map(s -> + { + try + { + return Pattern.compile(s, Pattern.CASE_INSENSITIVE); + } + catch (PatternSyntaxException ex) + { + return null; + } + }) + .filter(Objects::nonNull) + .forEach(filteredPatterns::add); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!"chatfilter".equals(event.getGroup())) + { + return; + } + + updateFilteredPatterns(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java new file mode 100644 index 0000000000..cf52fa969f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Magic fTail + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.chatfilter; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum ChatFilterType +{ + CENSOR_WORDS("Censor words"), + CENSOR_MESSAGE("Censor message"), + REMOVE_MESSAGE("Remove message"); + + private final String name; + + @Override + public String toString() + { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/JagexPrintableCharMatcher.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/JagexPrintableCharMatcher.java new file mode 100644 index 0000000000..53b76cbc19 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/JagexPrintableCharMatcher.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.chatfilter; + +import com.google.common.base.CharMatcher; + +class JagexPrintableCharMatcher extends CharMatcher +{ + @Override + public boolean matches(char c) + { + // Characters which are printable + return (c >= 32 && c <= 126) + || c == 128 + || (c >= 161 && c <= 255); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java new file mode 100644 index 0000000000..e30629c742 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018, TheStonedTurtle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.chathistory; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("chathistory") +public interface ChatHistoryConfig extends Config +{ + @ConfigItem( + keyName = "retainChatHistory", + name = "Retain Chat History", + description = "Retains chat history when logging in/out or world hopping", + position = 0 + ) + default boolean retainChatHistory() + { + return true; + } + + @ConfigItem( + keyName = "pmTargetCycling", + name = "PM Target Cycling", + description = "Pressing Tab while sending a PM will cycle the target username based on PM history", + position = 1 + ) + default boolean pmTargetCycling() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index 4f2ae79818..43919214ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -25,47 +25,74 @@ package net.runelite.client.plugins.chathistory; import com.google.common.collect.EvictingQueue; -import com.google.common.collect.Sets; +import com.google.inject.Provides; +import java.awt.event.KeyEvent; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Iterator; import java.util.Queue; -import java.util.Set; import javax.inject.Inject; import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.ScriptID; +import net.runelite.api.VarClientInt; +import net.runelite.api.VarClientStr; +import net.runelite.api.events.ChatMessage; import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.SetMessage; +import net.runelite.api.vars.InputType; +import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.Text; @PluginDescriptor( name = "Chat History", - description = "Retain your chat history when logging in/out or world hopping" + description = "Retain your chat history when logging in/out or world hopping", + tags = {"chat", "history", "retain", "cycle", "pm"} ) -public class ChatHistoryPlugin extends Plugin +public class ChatHistoryPlugin extends Plugin implements KeyListener { private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape."; private static final String CLEAR_HISTORY = "Clear history"; private static final String CLEAR_PRIVATE = "Private:"; - private static final Set ALLOWED_HISTORY = Sets.newHashSet( - ChatMessageType.PUBLIC, - ChatMessageType.PUBLIC_MOD, - ChatMessageType.CLANCHAT, - ChatMessageType.PRIVATE_MESSAGE_RECEIVED, - ChatMessageType.PRIVATE_MESSAGE_SENT, - ChatMessageType.PRIVATE_MESSAGE_RECEIVED_MOD, - ChatMessageType.GAME - ); + private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB; private Queue messageQueue; + private Deque friends; + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private ChatHistoryConfig config; + + @Inject + private KeyManager keyManager; @Inject private ChatMessageManager chatMessageManager; + + @Provides + ChatHistoryConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ChatHistoryConfig.class); + } @Override protected void startUp() { messageQueue = EvictingQueue.create(100); + friends = new ArrayDeque<>(5); + keyManager.registerKeyListener(this); } @Override @@ -73,15 +100,23 @@ public class ChatHistoryPlugin extends Plugin { messageQueue.clear(); messageQueue = null; + friends.clear(); + friends = null; + keyManager.unregisterKeyListener(this); } @Subscribe - public void onSetMessage(SetMessage message) + public void onChatMessage(ChatMessage chatMessage) { // Start sending old messages right after the welcome message, as that is most reliable source // of information that chat history was reset - if (message.getValue().equals(WELCOME_MESSAGE)) + if (chatMessage.getMessage().equals(WELCOME_MESSAGE)) { + if (!config.retainChatHistory()) + { + return; + } + QueuedMessage queuedMessage; while ((queuedMessage = messageQueue.poll()) != null) @@ -92,21 +127,33 @@ public class ChatHistoryPlugin extends Plugin return; } - if (ALLOWED_HISTORY.contains(message.getType())) + switch (chatMessage.getType()) { - final QueuedMessage queuedMessage = QueuedMessage.builder() - .type(message.getType()) - .name(message.getName()) - .sender(message.getSender()) - .value(nbsp(message.getValue())) - .runeLiteFormattedMessage(nbsp(message.getMessageNode().getRuneLiteFormatMessage())) - .timestamp(message.getTimestamp()) - .build(); + case PRIVATE_MESSAGE_SENT: + case PRIVATE_MESSAGE_RECEIVED: + case PRIVATE_MESSAGE_RECEIVED_MOD: + final String name = Text.removeTags(chatMessage.getName()); + // Remove to ensure uniqueness & its place in history + friends.remove(name); + friends.add(name); + // intentional fall-through + case PUBLIC: + case PUBLIC_MOD: + case CLANCHAT: + case GAME: + final QueuedMessage queuedMessage = QueuedMessage.builder() + .type(chatMessage.getType()) + .name(chatMessage.getName()) + .sender(chatMessage.getSender()) + .value(nbsp(chatMessage.getMessage())) + .runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage())) + .timestamp(chatMessage.getTimestamp()) + .build(); - if (!messageQueue.contains(queuedMessage)) - { - messageQueue.offer(queuedMessage); - } + if (!messageQueue.contains(queuedMessage)) + { + messageQueue.offer(queuedMessage); + } } } @@ -143,4 +190,64 @@ public class ChatHistoryPlugin extends Plugin return null; } + + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() != CYCLE_HOTKEY || !config.pmTargetCycling()) + { + return; + } + + if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.PRIVATE_MESSAGE.getType()) + { + return; + } + + clientThread.invoke(() -> + { + final String target = findPreviousFriend(); + if (target == null) + { + return; + } + + final String currentMessage = client.getVar(VarClientStr.INPUT_TEXT); + + client.runScript(ScriptID.OPEN_PRIVATE_MESSAGE_INTERFACE, target); + + client.setVar(VarClientStr.INPUT_TEXT, currentMessage); + client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, ""); + }); + } + + @Override + public void keyTyped(KeyEvent e) + { + } + + @Override + public void keyReleased(KeyEvent e) + { + } + + private String findPreviousFriend() + { + final String currentTarget = client.getVar(VarClientStr.PRIVATE_MESSAGE_TARGET); + if (currentTarget == null || friends.isEmpty()) + { + return null; + } + + for (Iterator it = friends.descendingIterator(); it.hasNext(); ) + { + String friend = it.next(); + if (friend.equals(currentTarget)) + { + return it.hasNext() ? it.next() : friends.getLast(); + } + } + + return friends.getLast(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java index fd148c1e90..0bfd952e01 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java @@ -35,9 +35,9 @@ import java.util.stream.Collectors; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MessageNode; +import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.SetMessage; import net.runelite.client.Notifier; import net.runelite.client.RuneLiteProperties; import net.runelite.client.chat.ChatColorType; @@ -124,29 +124,29 @@ public class ChatNotificationsPlugin extends Plugin } @Subscribe - public void onSetMessage(SetMessage event) + public void onChatMessage(ChatMessage chatMessage) { - MessageNode messageNode = event.getMessageNode(); + MessageNode messageNode = chatMessage.getMessageNode(); String nodeValue = Text.removeTags(messageNode.getValue()); boolean update = false; - switch (event.getType()) + switch (chatMessage.getType()) { case TRADE: - if (event.getValue().contains("wishes to trade with you.") && config.notifyOnTrade()) + if (chatMessage.getMessage().contains("wishes to trade with you.") && config.notifyOnTrade()) { - notifier.notify(event.getValue()); + notifier.notify(chatMessage.getMessage()); } break; case DUEL: - if (event.getValue().contains("wishes to duel with you.") && config.notifyOnDuel()) + if (chatMessage.getMessage().contains("wishes to duel with you.") && config.notifyOnDuel()) { - notifier.notify(event.getValue()); + notifier.notify(chatMessage.getMessage()); } break; case GAME: // Don't notify for notification messages - if (event.getName().equals(runeLiteProperties.getTitle())) + if (chatMessage.getName().equals(runeLiteProperties.getTitle())) { return; } @@ -170,7 +170,7 @@ public class ChatNotificationsPlugin extends Plugin if (config.notifyOnOwnName()) { - sendNotification(event); + sendNotification(chatMessage); } } } @@ -196,7 +196,7 @@ public class ChatNotificationsPlugin extends Plugin if (config.notifyOnHighlight()) { - sendNotification(event); + sendNotification(chatMessage); } } } @@ -208,7 +208,7 @@ public class ChatNotificationsPlugin extends Plugin } } - private void sendNotification(SetMessage message) + private void sendNotification(ChatMessage message) { String name = Text.removeTags(message.getName()); String sender = message.getSender(); @@ -224,7 +224,7 @@ public class ChatNotificationsPlugin extends Plugin stringBuilder.append(name).append(": "); } - stringBuilder.append(Text.removeTags(message.getValue())); + stringBuilder.append(Text.removeTags(message.getMessage())); String notification = stringBuilder.toString(); notifier.notify(notification); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanActivityType.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanActivityType.java new file mode 100644 index 0000000000..86cc5e60a5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanActivityType.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.clanchat; + +enum ClanActivityType +{ + JOINED, + LEFT +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java index 9b70ce0fca..5fdd7996be 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.clanchat; +import net.runelite.api.ClanMemberRank; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -31,17 +32,39 @@ import net.runelite.client.config.ConfigItem; @ConfigGroup("clanchat") public interface ClanChatConfig extends Config { + @ConfigItem( + keyName = "clanChatIcons", + name = "Clan Chat Icons", + description = "Show clan chat icons next to clan members.", + position = 1 + ) + default boolean clanChatIcons() + { + return true; + } + @ConfigItem( keyName = "recentChats", name = "Recent Chats", description = "Show recent clan chats.", - position = 1 + position = 2 ) default boolean recentChats() { return true; } + @ConfigItem( + keyName = "clanCounter", + name = "Clan Members Counter", + description = "Show the amount of clan members near you.", + position = 3 + ) + default boolean showClanCounter() + { + return false; + } + @ConfigItem( keyName = "chatsData", name = "", @@ -59,4 +82,48 @@ public interface ClanChatConfig extends Config description = "" ) void chatsData(String str); + + @ConfigItem( + keyName = "showJoinLeave", + name = "Show Join/Leave", + description = "Adds a temporary message notifying when a member joins or leaves.", + position = 4 + ) + default boolean showJoinLeave() + { + return false; + } + + @ConfigItem( + keyName = "joinLeaveRank", + name = "Join/Leave rank", + description = "Only show join/leave messages for members at or above this rank.", + position = 5 + ) + default ClanMemberRank joinLeaveRank() + { + return ClanMemberRank.UNRANKED; + } + + @ConfigItem( + keyName = "privateMessageIcons", + name = "Private Message Icons", + description = "Add clan chat rank icons to private messages received from clan mates.", + position = 6 + ) + default boolean privateMessageIcons() + { + return false; + } + + @ConfigItem( + keyName = "publicChatIcons", + name = "Public Chat Icons", + description = "Add clan chat rank icons to public chat messages from clan mates.", + position = 7 + ) + default boolean publicChatIcons() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatIndicator.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatIndicator.java new file mode 100644 index 0000000000..e8f7542d7d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatIndicator.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Sebastiaan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.clanchat; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import net.runelite.client.ui.overlay.infobox.Counter; + +class ClanChatIndicator extends Counter +{ + private final ClanChatPlugin plugin; + + ClanChatIndicator(BufferedImage image, ClanChatPlugin plugin) + { + super(image, plugin, plugin.getClanAmount()); + this.plugin = plugin; + } + + @Override + public int getCount() + { + return plugin.getClanAmount(); + } + + @Override + public String getTooltip() + { + return plugin.getClanAmount() + " clan member(s) near you"; + } + + @Override + public Color getTextColor() + { + return Color.WHITE; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java index b5ee817198..73859e0271 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java @@ -1,5 +1,7 @@ /* * Copyright (c) 2017, Devin French + * Copyright (c) 2019, Adam + * Copyright (c) 2018, trimbe * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,26 +29,55 @@ package net.runelite.client.plugins.clanchat; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.inject.Provides; +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.inject.Inject; +import net.runelite.api.ChatLineBuffer; import net.runelite.api.ChatMessageType; +import net.runelite.api.ClanMember; import net.runelite.api.ClanMemberRank; import net.runelite.api.Client; import net.runelite.api.GameState; +import net.runelite.api.MessageNode; +import net.runelite.api.Player; +import net.runelite.api.ScriptID; +import net.runelite.api.SpriteID; import net.runelite.api.VarClientStr; -import net.runelite.api.widgets.WidgetType; +import net.runelite.api.Varbits; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ClanChanged; +import net.runelite.api.events.ClanMemberJoined; +import net.runelite.api.events.ClanMemberLeft; import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; -import net.runelite.api.events.SetMessage; +import net.runelite.api.events.PlayerDespawned; +import net.runelite.api.events.PlayerSpawned; import net.runelite.api.events.VarClientStrChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetType; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ClanManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND; +import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND; +import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_OPAQUE_BACKGROUND; +import static net.runelite.client.ui.JagexColors.CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.ColorUtil; import net.runelite.client.util.Text; @PluginDescriptor( @@ -59,6 +90,8 @@ public class ClanChatPlugin extends Plugin private static final int MAX_CHATS = 10; private static final String CLAN_CHAT_TITLE = "Clan Chat"; private static final String RECENT_TITLE = "Recent Clan Chats"; + private static final int JOIN_LEAVE_DURATION = 20; + private static final int MESSAGE_DELAY = 10; @Inject private Client client; @@ -69,7 +102,24 @@ public class ClanChatPlugin extends Plugin @Inject private ClanChatConfig config; + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private SpriteManager spriteManager; + + @Inject + private ClientThread clientThread; + private List chats = new ArrayList<>(); + private List clanMembers = new ArrayList<>(); + private ClanChatIndicator clanMemberCounter; + /** + * queue of temporary messages added to the client + */ + private final Deque clanJoinMessages = new ArrayDeque<>(); + private Map activityBuffer = new HashMap<>(); + private int clanJoinedTick; @Provides ClanChatConfig getConfig(ConfigManager configManager) @@ -86,15 +136,118 @@ public class ClanChatPlugin extends Plugin @Override public void shutDown() { + clanMembers.clear(); + removeClanCounter(); resetClanChats(); } @Subscribe public void onConfigChanged(ConfigChanged configChanged) { - if (configChanged.getGroup().equals("clanchat") && !config.recentChats()) + if (configChanged.getGroup().equals("clanchat")) { - resetClanChats(); + if (!config.recentChats()) + { + resetClanChats(); + } + + if (config.showClanCounter()) + { + clientThread.invoke(this::addClanCounter); + } + else + { + removeClanCounter(); + } + } + } + + @Subscribe + public void onClanMemberJoined(ClanMemberJoined event) + { + final ClanMember member = event.getMember(); + + if (member.getWorld() == client.getWorld()) + { + final String memberName = Text.toJagexName(member.getUsername()); + + for (final Player player : client.getPlayers()) + { + if (player != null && memberName.equals(Text.toJagexName(player.getName()))) + { + clanMembers.add(player); + addClanCounter(); + break; + } + } + } + + // clan members getting initialized isn't relevant + if (clanJoinedTick == client.getTickCount()) + { + return; + } + + if (!config.showJoinLeave() || + member.getRank().getValue() < config.joinLeaveRank().getValue()) + { + return; + } + + // attempt to filter out world hopping joins + if (!activityBuffer.containsKey(member.getUsername())) + { + ClanMemberActivity joinActivity = new ClanMemberActivity(ClanActivityType.JOINED, + member, client.getTickCount()); + activityBuffer.put(member.getUsername(), joinActivity); + } + else + { + activityBuffer.remove(member.getUsername()); + } + } + + @Subscribe + public void onClanMemberLeft(ClanMemberLeft event) + { + final ClanMember member = event.getMember(); + + if (member.getWorld() == client.getWorld()) + { + final String memberName = Text.toJagexName(member.getUsername()); + final Iterator each = clanMembers.iterator(); + + while (each.hasNext()) + { + if (memberName.equals(Text.toJagexName(each.next().getName()))) + { + each.remove(); + + if (clanMembers.isEmpty()) + { + removeClanCounter(); + } + + break; + } + } + } + + if (!config.showJoinLeave() || + member.getRank().getValue() < config.joinLeaveRank().getValue()) + { + return; + } + + if (!activityBuffer.containsKey(member.getUsername())) + { + ClanMemberActivity leaveActivity = new ClanMemberActivity(ClanActivityType.LEFT, + member, client.getTickCount()); + activityBuffer.put(member.getUsername(), leaveActivity); + } + else + { + activityBuffer.remove(member.getUsername()); } } @@ -122,6 +275,112 @@ public class ClanChatPlugin extends Plugin loadClanChats(); } } + + if (!config.showJoinLeave()) + { + return; + } + + timeoutClanMessages(); + + addClanActivityMessages(); + } + + private void timeoutClanMessages() + { + if (clanJoinMessages.isEmpty()) + { + return; + } + + boolean removed = false; + + for (Iterator it = clanJoinMessages.iterator(); it.hasNext(); ) + { + ClanJoinMessage clanJoinMessage = it.next(); + MessageNode messageNode = clanJoinMessage.getMessageNode(); + final int createdTick = clanJoinMessage.getTick(); + + if (client.getTickCount() > createdTick + JOIN_LEAVE_DURATION) + { + it.remove(); + + // If this message has been reused since, it will get a different id + if (clanJoinMessage.getGetMessageId() == messageNode.getId()) + { + ChatLineBuffer ccInfoBuffer = client.getChatLineMap().get(ChatMessageType.CLANCHAT_INFO.getType()); + if (ccInfoBuffer != null) + { + ccInfoBuffer.removeMessageNode(messageNode); + removed = true; + } + } + } + else + { + // Everything else in the deque is newer + break; + } + } + + if (removed) + { + clientThread.invoke(() -> client.runScript(ScriptID.BUILD_CHATBOX)); + } + } + + private void addClanActivityMessages() + { + Iterator activityIt = activityBuffer.values().iterator(); + + while (activityIt.hasNext()) + { + ClanMemberActivity activity = activityIt.next(); + + if (activity.getTick() < client.getTickCount() - MESSAGE_DELAY) + { + activityIt.remove(); + addActivityMessage(activity.getMember(), activity.getActivityType()); + } + } + } + + private void addActivityMessage(ClanMember member, ClanActivityType activityType) + { + final String activityMessage = activityType == ClanActivityType.JOINED ? " has joined." : " has left."; + final ClanMemberRank rank = member.getRank(); + String rankTag = ""; + Color textColor = CHAT_CLAN_TEXT_OPAQUE_BACKGROUND; + Color channelColor = CHAT_CLAN_NAME_OPAQUE_BACKGROUND; + + if (client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1) + { + textColor = CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND; + channelColor = CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND; + } + + if (config.clanChatIcons() && rank != null && rank != ClanMemberRank.UNRANKED) + { + int iconNumber = clanManager.getIconNumber(rank); + rankTag = " "; + } + + ChatMessageBuilder message = new ChatMessageBuilder(); + String messageString = message + .append("[") + .append(ColorUtil.wrapWithColorTag(client.getClanChatName(), channelColor) + rankTag) + .append("] ") + .append(ColorUtil.wrapWithColorTag(member.getUsername() + activityMessage, textColor)) + .build(); + + client.addChatMessage(ChatMessageType.CLANCHAT_INFO, "", messageString, ""); + + final ChatLineBuffer chatLineBuffer = client.getChatLineMap().get(ChatMessageType.CLANCHAT_INFO.getType()); + final MessageNode[] lines = chatLineBuffer.getLines(); + final MessageNode line = lines[0]; + + ClanJoinMessage clanJoinMessage = new ClanJoinMessage(line, line.getId(), client.getTickCount()); + clanJoinMessages.addLast(clanJoinMessage); } @Subscribe @@ -134,28 +393,119 @@ public class ClanChatPlugin extends Plugin } @Subscribe - public void onSetMessage(SetMessage setMessage) + public void onChatMessage(ChatMessage chatMessage) { if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) { return; } - if (setMessage.getType() == ChatMessageType.CLANCHAT && client.getClanChatCount() > 0) + if (client.getClanChatCount() <= 0) { - insertClanRankIcon(setMessage); + return; + } + + switch (chatMessage.getType()) + { + case PRIVATE_MESSAGE_RECEIVED: + case PRIVATE_MESSAGE_RECEIVED_MOD: + if (!config.privateMessageIcons()) + { + return; + } + break; + case PUBLIC: + case PUBLIC_MOD: + if (!config.publicChatIcons()) + { + return; + } + break; + case CLANCHAT: + if (!config.clanChatIcons()) + { + return; + } + break; + default: + return; + } + + insertClanRankIcon(chatMessage); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged state) + { + GameState gameState = state.getGameState(); + + if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.CONNECTION_LOST || gameState == GameState.HOPPING) + { + clanMembers.clear(); + removeClanCounter(); + + clanJoinMessages.clear(); } } - private void insertClanRankIcon(final SetMessage message) + @Subscribe + public void onPlayerSpawned(PlayerSpawned event) + { + if (event.getPlayer().isClanMember()) + { + clanMembers.add(event.getPlayer()); + addClanCounter(); + } + } + + @Subscribe + public void onPlayerDespawned(PlayerDespawned event) + { + if (clanMembers.remove(event.getPlayer()) && clanMembers.isEmpty()) + { + removeClanCounter(); + } + } + + @Subscribe + public void onClanChanged(ClanChanged event) + { + if (event.isJoined()) + { + clanJoinedTick = client.getTickCount(); + } + else + { + clanMembers.clear(); + removeClanCounter(); + } + + activityBuffer.clear(); + } + + int getClanAmount() + { + return clanMembers.size(); + } + + private void insertClanRankIcon(final ChatMessage message) { final ClanMemberRank rank = clanManager.getRank(message.getName()); if (rank != null && rank != ClanMemberRank.UNRANKED) { int iconNumber = clanManager.getIconNumber(rank); - message.getMessageNode() - .setSender(message.getMessageNode().getSender() + " "); + final String img = ""; + if (message.getType() == ChatMessageType.CLANCHAT) + { + message.getMessageNode() + .setSender(message.getMessageNode().getSender() + " " + img); + } + else + { + message.getMessageNode() + .setName(img + message.getMessageNode().getName()); + } client.refreshChat(); } } @@ -223,4 +573,22 @@ public class ClanChatPlugin extends Plugin config.chatsData(Text.toCSV(chats)); } + + private void removeClanCounter() + { + infoBoxManager.removeInfoBox(clanMemberCounter); + clanMemberCounter = null; + } + + private void addClanCounter() + { + if (!config.showClanCounter() || clanMemberCounter != null || clanMembers.isEmpty()) + { + return; + } + + final BufferedImage image = spriteManager.getSprite(SpriteID.TAB_CLAN_CHAT, 0); + clanMemberCounter = new ClanChatIndicator(image, this); + infoBoxManager.addInfoBox(clanMemberCounter); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanJoinMessage.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanJoinMessage.java new file mode 100644 index 0000000000..8ac0b0069b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanJoinMessage.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.clanchat; + +import lombok.Value; +import net.runelite.api.MessageNode; + +@Value +class ClanJoinMessage +{ + private final MessageNode messageNode; + private final int getMessageId; + private final int tick; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanMemberActivity.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanMemberActivity.java new file mode 100644 index 0000000000..1cea036a95 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanMemberActivity.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.clanchat; + +import lombok.AllArgsConstructor; +import lombok.Value; +import net.runelite.api.ClanMember; + +@Value +@AllArgsConstructor +class ClanMemberActivity +{ + private ClanActivityType activityType; + private ClanMember member; + private Integer tick; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java index 4c4d0adcd2..61b83c4c11 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java @@ -49,7 +49,7 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc { private static final Set CLUES = ImmutableSet.of( new AnagramClue("A BAKER", "Baraek", new WorldPoint(3217, 3434, 0), "Varrock square", "5"), - new AnagramClue("A BASIC ANTI POT", "Captain Tobias", new WorldPoint(3026, 3216, 0), "Port Sarim", "7"), + new AnagramClue("A BASIC ANTI POT", "Captain Tobias", new WorldPoint(3026, 3216, 0), "Port Sarim", "6"), new AnagramClue("A HEART", "Aretha", new WorldPoint(1814, 3851, 0), "Soul altar", "2"), new AnagramClue("A ZEN SHE", "Zenesha", new WorldPoint(2652, 3295, 0), "Platebody Southern Ardougne centre square"), new AnagramClue("ACE MATCH ELM", "Cam The Camel", new WorldPoint(3300, 3231, 0), "North of the glider in Al Kharid"), @@ -257,4 +257,4 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc { return new int[] {objectId}; } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java index 654f31e977..f352115c1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.cluescrolls.clues; +import com.google.common.collect.ImmutableMap; import java.awt.Color; import java.awt.Graphics2D; import lombok.AllArgsConstructor; @@ -43,6 +44,154 @@ import net.runelite.client.ui.overlay.components.TitleComponent; @AllArgsConstructor public class CoordinateClue extends ClueScroll implements TextClueScroll, LocationClueScroll { + private static final ImmutableMap CLUES = new ImmutableMap.Builder() + // Medium + .put(new WorldPoint(2479, 3158, 0), "South of fruit tree patch, west of Tree Gnome Village.") + .put(new WorldPoint(2887, 3154, 0), "West of Banana plantation on Karamja.") + .put(new WorldPoint(2743, 3151, 0), "Entrance of Brimhaven dungeon.") + .put(new WorldPoint(3184, 3150, 0), "South of Lumbridge Swamp.") + .put(new WorldPoint(3217, 3177, 0), "East of Lumbridge Swamp.") + .put(new WorldPoint(3007, 3144, 0), "Near the entrance to the Asgarnian Ice Dungeon, south of Port Sarim (AIQ).") + .put(new WorldPoint(2896, 3119, 0), "Near Karambwan fishing spot (DKP).") + .put(new WorldPoint(2697, 3207, 0), "Centre of Moss Giant Island, west of Brimhaven.") + .put(new WorldPoint(2679, 3110, 0), "North of Hazelmere's house (CLS).") + .put(new WorldPoint(3510, 3074, 0), "East of Uzer (DLQ).") + .put(new WorldPoint(3160, 3251, 0), "West of trapdoor leading to H.A.M Hideout.") + .put(new WorldPoint(2643, 3252, 0), "South of Ardougne Zoo, North of Tower of Life (DJP).") + .put(new WorldPoint(2322, 3061, 0), "South-west of Castle wars (BKP).") + .put(new WorldPoint(2875, 3046, 0), "North of nature altar, north of Shilo Village (CKR).") + .put(new WorldPoint(2849, 3033, 0), "West of nature altar, north of Shilo Village (CKR).") + .put(new WorldPoint(2848, 3296, 0), "North of Crandor island.") + .put(new WorldPoint(2583, 2990, 0), "Feldip Hills, south-east of Gu'Thanoth (AKS).") + .put(new WorldPoint(3179, 3344, 0), "South of the Champions' Guild, opposite side of the River Lum.") + .put(new WorldPoint(2383, 3370, 0), "South-west of Tree Gnome Stronghold.") + .put(new WorldPoint(3312, 3375, 0), "North-west of Exam Centre, on the hill.") + .put(new WorldPoint(3121, 3384, 0), "North-east of Draynor Manor, near River Lum.") + .put(new WorldPoint(3430, 3388, 0), "West of Mort Myre Swamp.") + .put(new WorldPoint(2920, 3403, 0), "South-east of Taverley, near Lady of the Lake.") + .put(new WorldPoint(2594, 2899, 0), "South-east of Feldip Hills, by the crimson swifts (AKS).") + .put(new WorldPoint(2387, 3435, 0), "West of Tree Gnome Stronghold, near the pen containing terrorbirds.") + .put(new WorldPoint(2512, 3467, 0), "Baxtorian Falls (Bring rope).") + .put(new WorldPoint(2381, 3468, 0), "West of Tree Gnome Stronghold, north of the pen with terrorbirds.") + .put(new WorldPoint(3005, 3475, 0), "Ice Mountain, west of Edgeville.") + .put(new WorldPoint(2585, 3505, 0), "By the shore line north of the Coal Trucks.") + .put(new WorldPoint(3443, 3515, 0), "South of Slayer Tower.") + .put(new WorldPoint(2416, 3516, 0), "Tree Gnome Stronghold, west of Grand Tree, near swamp.") + .put(new WorldPoint(3429, 3523, 0), "South of Slayer Tower.") + .put(new WorldPoint(2363, 3531, 0), "North-east of Eagles' Peak.") + .put(new WorldPoint(2919, 3535, 0), "East of Burthorpe pub.") + .put(new WorldPoint(3548, 3560, 0), "Inside Fenkenstrain's Castle.") + .put(new WorldPoint(1456, 3620, 0), "Graveyard west of Shayzien House.") + .put(new WorldPoint(2735, 3638, 0), "East of Rellekka, north-west of Golden Apple Tree (AJR).") + .put(new WorldPoint(2681, 3653, 0), "Rellekka, in the garden of the south-east house.") + .put(new WorldPoint(2537, 3881, 0), "Miscellania.") + // Hard + .put(new WorldPoint(2209, 3161, 0), "North-east of Tyras Camp.") + .put(new WorldPoint(2181, 3206, 0), "South of Elf Camp.") + .put(new WorldPoint(3081, 3209, 0), "Small Island (CLP).") + .put(new WorldPoint(3374, 3250, 0), "Duel Arena combat area.") + .put(new WorldPoint(2699, 3251, 0), "Little island (AIR).") + .put(new WorldPoint(3546, 3251, 0), "North-east of Burgh de Rott.") + .put(new WorldPoint(3544, 3256, 0), "North-east of Burgh de Rott.") + .put(new WorldPoint(2841, 3267, 0), "Crandor island.") + .put(new WorldPoint(3168, 3041, 0), "Bedabin Camp.") + .put(new WorldPoint(2542, 3031, 0), "Gu'Tanoth.") + .put(new WorldPoint(2581, 3030, 0), "Gu'Tanoth island, enter cave north-west of Feldip Hills (AKS).") + .put(new WorldPoint(2961, 3024, 0), "Ship yard (DKP).") + .put(new WorldPoint(2339, 3311, 0), "East of Tirannwn on Arandar mountain pass.") + .put(new WorldPoint(3440, 3341, 0), "Nature Spirit's grotto.") + .put(new WorldPoint(2763, 2974, 0), "Cairn Isle, west of Shilo Village.") + .put(new WorldPoint(3138, 2969, 0), "West of Bandit Camp.") + .put(new WorldPoint(2924, 2963, 0), "On the southern part of eastern Karamja.") + .put(new WorldPoint(2838, 2914, 0), "Kharazi Jungle, near water pool.") + .put(new WorldPoint(3441, 3419, 0), "Mort Myre Swamp.") + .put(new WorldPoint(2950, 2902, 0), "South-east of Kharazi Jungle.") + .put(new WorldPoint(2775, 2891, 0), "South-west of Kharazi Jungle.") + .put(new WorldPoint(3113, 3602, 0), "Wilderness. North of Edgeville (level 11).") + .put(new WorldPoint(2892, 3675, 0), "On the summit of Trollheim.") + .put(new WorldPoint(3168, 3677, 0), "Wilderness. Graveyard of Shadows.") + .put(new WorldPoint(2853, 3690, 0), "Entrance to the troll Stronghold.") + .put(new WorldPoint(3305, 3692, 0), "Wilderness. West of eastern green dragon.") + .put(new WorldPoint(3055, 3696, 0), "Wilderness. Bandit Camp.") + .put(new WorldPoint(3302, 3696, 0), "Wilderness. West of eastern green dragon.") + .put(new WorldPoint(1479, 3696, 0), "Lizardman Canyon.") + .put(new WorldPoint(2712, 3732, 0), "North-east of Rellekka.") + .put(new WorldPoint(2970, 3749, 0), "Wilderness. Forgotten Cemetery.") + .put(new WorldPoint(3094, 3764, 0), "Wilderness. Mining site north of Bandit Camp.") + .put(new WorldPoint(3311, 3769, 0), "Wilderness. North of Venenatis.") + .put(new WorldPoint(1460, 3782, 0), "Lovakengj, near burning man.") + .put(new WorldPoint(3244, 3792, 0), "Wilderness. South-east of Lava Dragon Isle by some Chaos Dwarves.") + .put(new WorldPoint(3140, 3804, 0), "Wilderness. North of Ruins.") + .put(new WorldPoint(2946, 3819, 0), "Wilderness. Chaos Temple (level 38).") + .put(new WorldPoint(3771, 3825, 0), "Fossil Island. East of Museum Camp.") + .put(new WorldPoint(3013, 3846, 0), "Wilderness. West of Lava Maze, before KBD's lair.") + .put(new WorldPoint(3058, 3884, 0), "Wilderness. Near runite ore north of Lava Maze.") + .put(new WorldPoint(3290, 3889, 0), "Wilderness. Demonic Ruins.") + .put(new WorldPoint(3770, 3897, 0), "Small Island north of Fossil Island.") + .put(new WorldPoint(2505, 3899, 0), "Small Island north-east of Miscellania (AJS).") + .put(new WorldPoint(3285, 3942, 0), "Wilderness. Rogues' Castle.") + .put(new WorldPoint(3159, 3959, 0), "Wilderness. North of Deserted Keep, west of Resource Area.") + .put(new WorldPoint(3039, 3960, 0), "Wilderness. Pirates' Hideout.") + .put(new WorldPoint(2987, 3963, 0), "Wilderness. West of Wilderness Agility Course.") + .put(new WorldPoint(3189, 3963, 0), "Wilderness. North of Resource Area, near magic axe hut.") + // Elite + .put(new WorldPoint(2357, 3151, 0), "Lletya.") + .put(new WorldPoint(3587, 3180, 0), "Meiyerditch.") + .put(new WorldPoint(2820, 3078, 0), "Tai Bwo Wannai. Hardwood Grove.") + .put(new WorldPoint(3811, 3060, 0), "Small island north-east of Mos Le'Harmless.") + .put(new WorldPoint(2180, 3282, 0), "North of Elf Camp.") + .put(new WorldPoint(2870, 2997, 0), "North-east of Shilo Village.") + .put(new WorldPoint(3302, 2988, 0), "On top of a cliff to the west of Pollnivneach.") + .put(new WorldPoint(2511, 2980, 0), "Just south of Gu'Tanoth, west of gnome glider.") + .put(new WorldPoint(2732, 3372, 0), "Legends' Guild.") + .put(new WorldPoint(3573, 3425, 0), "North of Dessous's tomb from Desert Treasure.") + .put(new WorldPoint(3828, 2848, 0), "East of Harmony Island.") + .put(new WorldPoint(3225, 2838, 0), "South of Desert Treasure pyramid.") + .put(new WorldPoint(1773, 3510, 0), "Between magic trees South of Tithe Farm.") + .put(new WorldPoint(3822, 3562, 0), "North-east of Dragontooth Island.") + .put(new WorldPoint(3603, 3564, 0), "North of the wrecked ship, outside of Port Phasmatys.") + .put(new WorldPoint(2936, 2721, 0), "Eastern shore of Crash Island.") + .put(new WorldPoint(2697, 2705, 0), "South-west of Ape Atoll.") + .put(new WorldPoint(2778, 3678, 0), "Mountain Camp.") + .put(new WorldPoint(2827, 3740, 0), "West of the entrance to the Ice Path, where the Troll child resides.") + .put(new WorldPoint(2359, 3799, 0), "Neitiznot.") + .put(new WorldPoint(2194, 3807, 0), "Pirates' Cove.") + .put(new WorldPoint(2700, 3808, 0), "Northwestern part of the Trollweiss and Rellekka Hunter area (DKS).") + .put(new WorldPoint(3215, 3835, 0), "Wilderness. Lava Dragon Isle.") + .put(new WorldPoint(3369, 3894, 0), "Wilderness. Fountain of Rune.") + .put(new WorldPoint(2065, 3923, 0), "Outside the western wall on Lunar Isle.") + .put(new WorldPoint(3188, 3933, 0), "Wilderness. Resource Area.") + .put(new WorldPoint(2997, 3953, 0), "Wilderness. Inside Agility Training Area.") + .put(new WorldPoint(3380, 3963, 0), "Wilderness. North of Volcano.") + // Master + .put(new WorldPoint(2178, 3209, 0), "South of Elf Camp.") + .put(new WorldPoint(2155, 3100, 0), "South of Port Tyras (BJS).") + .put(new WorldPoint(2217, 3092, 0), "Poison Waste island (DLR).") + .put(new WorldPoint(3830, 3060, 0), "Small island located north-east of Mos Le'Harmless.") + .put(new WorldPoint(2834, 3271, 0), "Crandor island.") + .put(new WorldPoint(2732, 3284, 0), "Witchaven.") + .put(new WorldPoint(3622, 3320, 0), "Meiyerditch. Outside mine.") + .put(new WorldPoint(2303, 3328, 0), "East of Prifddinas.") + .put(new WorldPoint(3570, 3405, 0), "North of Dessous's tomb from Desert Treasure.") + .put(new WorldPoint(2840, 3423, 0), "Water Obelisk Island.") + .put(new WorldPoint(3604, 3564, 0), "North of the wrecked ship, outside of Port Phasmatys (ALQ).") + .put(new WorldPoint(3085, 3569, 0), "Wilderness. Obelisk of Air.") + .put(new WorldPoint(2934, 2727, 0), "Eastern shore of Crash Island.") + .put(new WorldPoint(1451, 3695, 0), "West side of Lizardman Canyon with Lizardman shaman.") + .put(new WorldPoint(2538, 3739, 0), "Waterbirth Island.") + .put(new WorldPoint(1248, 3751, 0), "Farming Guild.") + .put(new WorldPoint(1698, 3792, 0), "Arceuus church.") + .put(new WorldPoint(2951, 3820, 0), "Wilderness. Chaos Temple (level 38).") + .put(new WorldPoint(2202, 3825, 0), "Pirates' Cove, between Lunar Isle and Rellekka.") + .put(new WorldPoint(1761, 3853, 0), "Arceuus essence mine.") + .put(new WorldPoint(2090, 3863, 0), "South of Lunar Isle, west of Astral altar.") + .put(new WorldPoint(1442, 3878, 0), "Sulphur Mine.") + .put(new WorldPoint(3380, 3929, 0), "Wilderness. Near Volcano.") + .put(new WorldPoint(3188, 3939, 0), "Wilderness. Resource Area.") + .put(new WorldPoint(3304, 3941, 0), "Wilderness. East of Rogues' Castle.") + .put(new WorldPoint(2994, 3961, 0), "Wilderness. Inside Agility Training Area.") + .build(); + private String text; private WorldPoint location; private static final ItemRequirement HAS_SPADE = new SingleItemRequirement(ItemID.SPADE); @@ -52,8 +201,18 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati { panelComponent.getChildren().add(TitleComponent.builder().text("Coordinate Clue").build()); + String solution = CLUES.get(location); + + if (solution != null) + { + panelComponent.getChildren().add(LineComponent.builder() + .left(solution) + .build()); + panelComponent.getChildren().add(LineComponent.builder().build()); + } + panelComponent.getChildren().add(LineComponent.builder() - .left("Click the clue scroll along the edge of your world map to see where you should dig.") + .left("Click the clue scroll on your world map to see dig location.") .build()); if (plugin.getInventoryItems() != null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index 200a223aa3..20f0b16d9d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -300,8 +300,9 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Does one really need a fire to stay warm here?", new WorldPoint(3816, 3810, 0), "Dig next to the fire near the Volcanic Mine entrance."), new CrypticClue("Search the open crate found in a small farmhouse in Hosidius. Cabbages grow outside.", CRATE_27533, new WorldPoint(1687, 3628, 0), "The house is east of the Mess in Great Kourend."), new CrypticClue("Dig under Ithoi's cabin.", new WorldPoint(2529, 2838, 0), "Dig under Ithoi's cabin in the Corsair Cove."), - new CrypticClue("Search the drawers, upstairs in the bank to the East of Varrock.", new WorldPoint(3250, 3420, 1), "Search the drawers upstairs in Varrock east bank"), - new CrypticClue("Speak to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Located upstairs in the house to the north of fairy ring CLS. Answer: 6859") + new CrypticClue("Search the drawers, upstairs in the bank to the East of Varrock.", DRAWERS_7194, new WorldPoint(3250, 3420, 1), "Search the drawers upstairs in Varrock east bank."), + new CrypticClue("Speak to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Located upstairs in the house to the north of fairy ring CLS. Answer: 6859"), + new CrypticClue("The effects of this fire are magnified.", new WorldPoint(1179, 3626, 0), "Dig by the fire beside Ket'sal K'uk in the westernmost part of the Kebos Swamp. ") ); private String text; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java index 30a33d7e50..80b97e6c24 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -76,7 +76,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu new EmoteClue("Show your anger towards the Statue of Saradomin in Ellamaria's garden. Beware of double agents! Equip a zamorak godsword.", BY_THE_BEAR_CAGE_IN_VARROCK_PALACE_GARDENS, new WorldPoint(3230, 3478, 0), ANGRY, item(ZAMORAK_GODSWORD)), new EmoteClue("Show your anger at the Wise old man. Beware of double agents! Equip an abyssal whip, a legend's cape and some spined chaps.", BEHIND_MISS_SCHISM_IN_DRAYNOR_VILLAGE, new WorldPoint(3088, 3254, 0), ANGRY, any("Abyssal whip", item(ABYSSAL_WHIP), item(VOLCANIC_ABYSSAL_WHIP), item(FROZEN_ABYSSAL_WHIP)), item(CAPE_OF_LEGENDS), item(SPINED_CHAPS)), new EmoteClue("Beckon in the Digsite, near the eastern winch. Bow before you talk to me. Equip a green gnome hat, snakeskin boots and an iron pickaxe.", DIGSITE, new WorldPoint(3370, 3425, 0), BECKON, BOW, item(GREEN_HAT), item(SNAKESKIN_BOOTS), item(IRON_PICKAXE)), - new EmoteClue("Beckon in Tai Bwo Wannai. Clap before you talk to me. Equip green dragonhide chaps, a ring of dueling and a mithril medium helmet.", SOUTH_OF_THE_SHRINE_IN_TAI_BWO_WANNAI_VILLAGE, new WorldPoint(2784, 3065, 0), BECKON, CLAP, item(GREEN_DHIDE_CHAPS), any("Ring of dueling", item(RING_OF_DUELING1), item(RING_OF_DUELING2), item(RING_OF_DUELING3), item(RING_OF_DUELING4), item(RING_OF_DUELING5), item(RING_OF_DUELING6), item(RING_OF_DUELING7), item(RING_OF_DUELING8)), item(MITHRIL_MED_HELM)), + new EmoteClue("Beckon in Tai Bwo Wannai. Clap before you talk to me. Equip green dragonhide chaps, a ring of dueling and a mithril medium helmet.", SOUTH_OF_THE_SHRINE_IN_TAI_BWO_WANNAI_VILLAGE, new WorldPoint(2803, 3073, 0), BECKON, CLAP, item(GREEN_DHIDE_CHAPS), any("Ring of dueling", item(RING_OF_DUELING1), item(RING_OF_DUELING2), item(RING_OF_DUELING3), item(RING_OF_DUELING4), item(RING_OF_DUELING5), item(RING_OF_DUELING6), item(RING_OF_DUELING7), item(RING_OF_DUELING8)), item(MITHRIL_MED_HELM)), new EmoteClue("Beckon in the combat ring of Shayzien. Show your anger before you talk to me. Equip an adamant platebody, adamant full helm and adamant platelegs.", WEST_OF_THE_SHAYZIEN_COMBAT_RING, new WorldPoint(1545, 3594, 0), BECKON, ANGRY, item(ADAMANT_PLATELEGS), item(ADAMANT_PLATEBODY), item(ADAMANT_FULL_HELM)), new EmoteClue("Bow near Lord Iorwerth. Beware of double agents! Equip a new imbued crystal bow.", TENT_IN_LORD_IORWERTHS_ENCAMPMENT, new WorldPoint(2205, 3252, 0), BOW, any("Imbued crystal bow", item(NEW_CRYSTAL_BOW_I), item(CRYSTAL_BOW_FULL_I), item(CRYSTAL_BOW_910_I), item(CRYSTAL_BOW_810_I), item(CRYSTAL_BOW_710_I), item(CRYSTAL_BOW_610_I), item(CRYSTAL_BOW_510_I), item(CRYSTAL_BOW_410_I), item(CRYSTAL_BOW_310_I), item(CRYSTAL_BOW_210_I), item(CRYSTAL_BOW_110_I))), new EmoteClue("Bow outside the entrance to the Legends' Guild. Equip iron platelegs, an emerald amulet and an oak longbow.", OUTSIDE_THE_LEGENDS_GUILD_GATES, new WorldPoint(2729, 3349, 0), BOW, item(IRON_PLATELEGS), item(OAK_LONGBOW), item(EMERALD_AMULET)), @@ -133,8 +133,8 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu new EmoteClue("Panic by the pilot on White Wolf Mountain. Beware of double agents! Equip mithril platelegs, a ring of life and a rune axe.", GNOME_GLIDER_ON_WHITE_WOLF_MOUNTAIN, new WorldPoint(2847, 3499, 0), PANIC, item(MITHRIL_PLATELEGS), item(RING_OF_LIFE), item(RUNE_AXE)), new EmoteClue("Panic by the big egg where no one dare goes and the ground is burnt. Beware of double agents! Equip a dragon med helm, a TokTz-Ket-Xil, a brine sabre, rune platebody and an uncharged amulet of glory.", SOUTHEAST_CORNER_OF_LAVA_DRAGON_ISLE, new WorldPoint(3227, 3831, 0), PANIC, item(DRAGON_MED_HELM), item(TOKTZKETXIL), item(BRINE_SABRE), item(RUNE_PLATEBODY), item(AMULET_OF_GLORY)), new EmoteClue("Panic at the area flowers meet snow. Equip Blue D'hide vambs, a dragon spear and a rune plateskirt.", HALFWAY_DOWN_TROLLWEISS_MOUNTAIN, new WorldPoint(2776, 3781, 0), PANIC, item(BLUE_DHIDE_VAMB), item(DRAGON_SPEAR), item(RUNE_PLATESKIRT), item(SLED_4084)), - new EmoteClue("Do a push up at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), PUSH_UP, item(DRAGON_BATTLEAXE), item(DRAGON_DEFENDER), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I))), - new EmoteClue("Blow a raspberry at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), RASPBERRY, item(DRAGON_BATTLEAXE), item(DRAGON_DEFENDER), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I))), + new EmoteClue("Do a push up at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), PUSH_UP, item(DRAGON_BATTLEAXE), item(DRAGON_DEFENDER), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I), item(HYDRA_SLAYER_HELMET), item(HYDRA_SLAYER_HELMET_I))), + new EmoteClue("Blow a raspberry at the bank of the Warrior's guild. Beware of double agents! Equip a dragon battleaxe, a dragon defender and a slayer helm of any kind.", WARRIORS_GUILD_BANK_29047, new WorldPoint(2843, 3543, 0), RASPBERRY, item(DRAGON_BATTLEAXE), item(DRAGON_DEFENDER), any("Any slayer helmet", item(SLAYER_HELMET), item(BLACK_SLAYER_HELMET), item(GREEN_SLAYER_HELMET), item(PURPLE_SLAYER_HELMET), item(RED_SLAYER_HELMET), item(TURQUOISE_SLAYER_HELMET), item(SLAYER_HELMET_I), item(BLACK_SLAYER_HELMET_I), item(GREEN_SLAYER_HELMET_I), item(PURPLE_SLAYER_HELMET_I), item(RED_SLAYER_HELMET_I), item(TURQUOISE_SLAYER_HELMET_I), item(HYDRA_SLAYER_HELMET), item(HYDRA_SLAYER_HELMET_I))), new EmoteClue("Blow a raspberry at the monkey cage in Ardougne Zoo. Equip a studded leather body, bronze platelegs and a normal staff with no orb.", NEAR_THE_PARROTS_IN_ARDOUGNE_ZOO, new WorldPoint(2607, 3282, 0), RASPBERRY, item(STUDDED_BODY), item(BRONZE_PLATELEGS), item(STAFF)), new EmoteClue("Blow raspberries outside the entrance to Keep Le Faye. Equip a coif, an iron platebody and leather gloves.", OUTSIDE_KEEP_LE_FAYE, new WorldPoint(2757, 3401, 0), RASPBERRY, item(COIF), item(IRON_PLATEBODY), item(LEATHER_GLOVES)), new EmoteClue("Blow a raspberry in the Fishing Guild bank. Beware of double agents! Equip an elemental shield, blue dragonhide chaps and a rune warhammer.", FISHING_GUILD_BANK, new WorldPoint(2588, 3419, 0), RASPBERRY, item(ELEMENTAL_SHIELD), item(BLUE_DHIDE_CHAPS), item(RUNE_WARHAMMER)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index 4f7253da7d..17fe16453b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -170,7 +170,6 @@ public enum HotColdLocation ZEAH_MESS_HALL(new WorldPoint(1658, 3621, 0), ZEAH, "East of Mess hall."), ZEAH_WATSONS_HOUSE(new WorldPoint(1653, 3573, 0), ZEAH, "East of Watson's house."), ZEAH_VANNAHS_FARM_STORE(new WorldPoint(1806, 3521, 0), ZEAH, "North of Vannah's Farm Store, between the chicken coop and willow trees."), - ZEAH_FARMING_GUILD_SW(new WorldPoint(1227, 3712, 0), ZEAH, "South-west of the Farming Guild."), ZEAH_FARMING_GUILD_W(new WorldPoint(1209, 3737, 0), ZEAH, "West of the Farming Guild."), ZEAH_DAIRY_COW(new WorldPoint(1320, 3718, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), ZEAH_CRIMSON_SWIFTS(new WorldPoint(1186, 3583, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts."); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelConfig.java index cf910192f2..cc82bcea65 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelConfig.java @@ -40,4 +40,14 @@ public interface CombatLevelConfig extends Config { return true; } + + @ConfigItem( + keyName = "wildernessAttackLevelRange", + name = "Show level range in wilderness", + description = "Displays a PVP-world-like attack level range in the wilderness" + ) + default boolean wildernessAttackLevelRange() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java index a72e0bf2df..bbde15c2e0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Devin French + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,14 +27,20 @@ package net.runelite.client.plugins.combatlevel; import com.google.inject.Provides; import java.text.DecimalFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.Experience; import net.runelite.api.GameState; import net.runelite.api.Skill; +import net.runelite.api.WorldType; +import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; @@ -42,15 +49,31 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( name = "Combat Level", - description = "Show a more accurate combat level in Combat Options panel" + description = "Show a more accurate combat level in Combat Options panel and other combat level functions", + tags = {"wilderness", "attack", "range"} ) public class CombatLevelPlugin extends Plugin { - private final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###"); + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###"); + private static final String CONFIG_GROUP = "combatlevel"; + private static final String ATTACK_RANGE_CONFIG_KEY = "wildernessAttackLevelRange"; + private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+)$"); + private static final int SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y = 6; + private static final int WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y = 3; + private static final int MIN_COMBAT_LEVEL = 3; + + private int originalWildernessLevelTextPosition = -1; + private int originalSkullContainerPosition = -1; @Inject private Client client; + @Inject + private ClientThread clientThread; + + @Inject + private CombatLevelConfig config; + @Inject private CombatLevelOverlay overlay; @@ -67,6 +90,11 @@ public class CombatLevelPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); + + if (config.wildernessAttackLevelRange()) + { + appendAttackLevelRangeText(); + } } @Override @@ -84,6 +112,8 @@ public class CombatLevelPlugin extends Plugin combatLevelWidget.setText(widgetText.substring(0, widgetText.indexOf("."))); } } + + shutDownAttackLevelRange(); } @Subscribe @@ -112,4 +142,103 @@ public class CombatLevelPlugin extends Plugin combatLevelWidget.setText("Combat Lvl: " + DECIMAL_FORMAT.format(combatLevelPrecise)); } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!CONFIG_GROUP.equals(event.getGroup()) || !ATTACK_RANGE_CONFIG_KEY.equals(event.getKey())) + { + return; + } + + if (config.wildernessAttackLevelRange()) + { + appendAttackLevelRangeText(); + } + else + { + shutDownAttackLevelRange(); + } + } + + @Subscribe + public void onScriptCallbackEvent(ScriptCallbackEvent event) + { + if (config.wildernessAttackLevelRange() + && "wildernessWidgetTextSet".equals(event.getEventName())) + { + appendAttackLevelRangeText(); + } + } + + private void appendAttackLevelRangeText() + { + final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL); + if (wildernessLevelWidget == null) + { + return; + } + + final String wildernessLevelText = wildernessLevelWidget.getText(); + final Matcher m = WILDERNESS_LEVEL_PATTERN.matcher(wildernessLevelText); + if (!m.matches() + || WorldType.isPvpWorld(client.getWorldType())) + { + return; + } + + final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER); + if (originalWildernessLevelTextPosition == -1) + { + originalWildernessLevelTextPosition = wildernessLevelWidget.getOriginalY(); + } + if (originalSkullContainerPosition == -1) + { + originalSkullContainerPosition = skullContainer.getRelativeY(); + } + + final int wildernessLevel = Integer.parseInt(m.group(1)); + final int combatLevel = client.getLocalPlayer().getCombatLevel(); + + wildernessLevelWidget.setText(wildernessLevelText + "
" + combatAttackRange(combatLevel, wildernessLevel)); + wildernessLevelWidget.setOriginalY(WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y); + skullContainer.setOriginalY(SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y); + + clientThread.invoke(wildernessLevelWidget::revalidate); + clientThread.invoke(skullContainer::revalidate); + } + + private void shutDownAttackLevelRange() + { + if (WorldType.isPvpWorld(client.getWorldType())) + { + return; + } + + final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL); + if (wildernessLevelWidget != null) + { + String wildernessLevelText = wildernessLevelWidget.getText(); + if (wildernessLevelText.contains("
")) + { + wildernessLevelWidget.setText(wildernessLevelText.substring(0, wildernessLevelText.indexOf("
"))); + } + wildernessLevelWidget.setOriginalY(originalWildernessLevelTextPosition); + clientThread.invoke(wildernessLevelWidget::revalidate); + } + originalWildernessLevelTextPosition = -1; + + final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER); + if (skullContainer != null) + { + skullContainer.setOriginalY(originalSkullContainerPosition); + clientThread.invoke(skullContainer::revalidate); + } + originalSkullContainerPosition = -1; + } + + private static String combatAttackRange(final int combatLevel, final int wildernessLevel) + { + return Math.max(MIN_COMBAT_LEVEL, combatLevel - wildernessLevel) + "-" + Math.min(Experience.MAX_COMBAT_LEVEL, combatLevel + wildernessLevel); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java index af0a5a8b62..7e25f3ad31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingOverlay.java @@ -78,7 +78,6 @@ class CookingOverlay extends Overlay return null; } - panelComponent.setPreferredSize(new Dimension(145, 0)); panelComponent.getChildren().clear(); if (isCooking() || Duration.between(session.getLastCookingAction(), Instant.now()).getSeconds() < COOK_TIMEOUT) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java index e44df4796a..04d6a460a3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, Infinitay - * Copyright (c) 2018, Shaun Dreclin + * Copyright (c) 2018-2019, Shaun Dreclin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -86,10 +86,15 @@ public class DailyTasksPlugin extends Plugin } @Override - protected void shutDown() throws Exception + public void startUp() + { + loggingIn = true; + } + + @Override + public void shutDown() { lastReset = 0L; - loggingIn = false; } @Subscribe @@ -108,7 +113,6 @@ public class DailyTasksPlugin extends Plugin boolean dailyReset = !loggingIn && currentTime - lastReset > ONE_DAY; if ((dailyReset || loggingIn) - && client.getGameState() == GameState.LOGGED_IN && client.getVar(VarClientInt.MEMBERSHIP_STATUS) == 1) { // Round down to the nearest day diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java index 636d9b923b..d68791d289 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java @@ -31,7 +31,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.SessionOpen; +import net.runelite.client.events.SessionOpen; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; @@ -43,7 +43,8 @@ import net.runelite.http.api.worlds.WorldResult; @PluginDescriptor( name = "Default World", - description = "Enable a default world to be selected when launching the client" + description = "Enable a default world to be selected when launching the client", + tags = {"home"} ) @Slf4j public class DefaultWorldPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index 0b9be07b7e..fd96de011c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -347,6 +347,12 @@ class DevToolsOverlay extends Overlay { graphics.drawPolygon(p); } + + p = decorObject.getConvexHull2(); + if (p != null) + { + graphics.drawPolygon(p); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index 5aae397d0f..3730a878b9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -238,7 +238,9 @@ public class DevToolsPlugin extends Plugin int value = Integer.parseInt(args[1]); client.setVarpValue(client.getVarps(), varp, value); client.addChatMessage(ChatMessageType.SERVER, "", "Set VarPlayer " + varp + " to " + value, null); - eventBus.post(new VarbitChanged()); // fake event + VarbitChanged varbitChanged = new VarbitChanged(); + varbitChanged.setIndex(varp); + eventBus.post(varbitChanged); // fake event break; } case "getvarb": diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java index dc6a6f6461..ef8454b712 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java @@ -32,6 +32,8 @@ import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import javax.swing.BorderFactory; import javax.swing.JButton; @@ -95,8 +97,7 @@ class VarInspector extends JFrame private int[] oldVarps2 = null; private int numVarbits = 10000; - private int[] oldIntVarcs = null; - private String[] oldStrVarcs = null; + private Map varcs = null; @Inject VarInspector(Client client, EventBus eventBus, DevToolsPlugin plugin) @@ -279,9 +280,9 @@ class VarInspector extends JFrame public void onVarClientIntChanged(VarClientIntChanged e) { int idx = e.getIndex(); - int neew = client.getIntVarcs()[idx]; - int old = oldIntVarcs[idx]; - oldIntVarcs[idx] = neew; + int neew = (Integer) client.getVarcMap().getOrDefault(idx, 0); + int old = (Integer) varcs.getOrDefault(idx, 0); + varcs.put(idx, neew); if (old != neew) { @@ -302,9 +303,9 @@ class VarInspector extends JFrame public void onVarClientStrChanged(VarClientStrChanged e) { int idx = e.getIndex(); - String neew = client.getStrVarcs()[idx]; - String old = oldStrVarcs[idx]; - oldStrVarcs[idx] = neew; + String neew = (String) client.getVarcMap().getOrDefault(idx, ""); + String old = (String) varcs.getOrDefault(idx, ""); + varcs.put(idx, neew); if (!Objects.equals(old, neew)) { @@ -343,14 +344,11 @@ class VarInspector extends JFrame { oldVarps = new int[client.getVarps().length]; oldVarps2 = new int[client.getVarps().length]; - oldIntVarcs = new int[client.getIntVarcs().length]; - oldStrVarcs = new String[client.getStrVarcs().length]; } System.arraycopy(client.getVarps(), 0, oldVarps, 0, oldVarps.length); System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length); - System.arraycopy(client.getIntVarcs(), 0, oldIntVarcs, 0, oldIntVarcs.length); - System.arraycopy(client.getStrVarcs(), 0, oldStrVarcs, 0, oldStrVarcs.length); + varcs = new HashMap<>(client.getVarcMap()); eventBus.register(this); setVisible(true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java index 79bb99bc5a..acd8851c0b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInfoTableModel.java @@ -183,6 +183,9 @@ public class WidgetInfoTableModel extends AbstractTableModel out.add(new WidgetField<>("ScrollHeight", Widget::getScrollHeight, Widget::setScrollHeight, Integer.class)); out.add(new WidgetField<>("DragDeadZone", Widget::getDragDeadZone, Widget::setDragDeadZone, Integer.class)); out.add(new WidgetField<>("DragDeadTime", Widget::getDragDeadTime, Widget::setDragDeadTime, Integer.class)); + out.add(new WidgetField<>("NoClickThrough", Widget::getNoClickThrough, Widget::setNoClickThrough, Boolean.class)); + out.add(new WidgetField<>("NoScrollThrough", Widget::getNoScrollThrough, Widget::setNoScrollThrough, Boolean.class)); + out.add(new WidgetField<>("TargetVerb", Widget::getTargetVerb, Widget::setTargetVerb, String.class)); return out; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java index 06e0369535..9598b7eff5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java @@ -130,6 +130,7 @@ public class DiscordPlugin extends Plugin clientToolbar.addNavigation(discordButton); checkForGameStateUpdate(); + checkForAreaUpdate(); if (discordService.getCurrentUser() != null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java index 625aed1f08..0b57424f85 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java @@ -34,6 +34,7 @@ import java.util.Optional; import java.util.UUID; import javax.inject.Inject; import lombok.Data; +import net.runelite.client.RuneLiteProperties; import net.runelite.client.discord.DiscordPresence; import net.runelite.client.discord.DiscordService; import net.runelite.client.ws.PartyService; @@ -57,14 +58,16 @@ class DiscordState private final DiscordService discordService; private final DiscordConfig config; private PartyService party; + private final RuneLiteProperties properties; private DiscordPresence lastPresence; @Inject - private DiscordState(final DiscordService discordService, final DiscordConfig config, final PartyService party) + private DiscordState(final DiscordService discordService, final DiscordConfig config, final PartyService party, final RuneLiteProperties properties) { this.discordService = discordService; this.config = config; this.party = party; + this.properties = properties; } /** @@ -90,6 +93,7 @@ class DiscordState final DiscordPresence.DiscordPresenceBuilder presenceBuilder = DiscordPresence.builder() .state(lastPresence.getState()) .details(lastPresence.getDetails()) + .largeImageText(lastPresence.getLargeImageText()) .startTimestamp(lastPresence.getStartTimestamp()) .smallImageKey(lastPresence.getSmallImageKey()) .partyMax(lastPresence.getPartyMax()) @@ -168,11 +172,15 @@ class DiscordState } } + // Replace snapshot with + to make tooltip shorter (so it will span only 1 line) + final String versionShortHand = properties.getVersion().replace("-SNAPSHOT", "+"); + final DiscordPresence.DiscordPresenceBuilder presenceBuilder = DiscordPresence.builder() .state(MoreObjects.firstNonNull(state, "")) .details(MoreObjects.firstNonNull(details, "")) + .largeImageText(properties.getTitle() + " v" + versionShortHand) .startTimestamp(event.getStart()) - .smallImageKey(MoreObjects.firstNonNull(imageKey, "default")) + .smallImageKey(imageKey) .partyMax(PARTY_MAX) .partySize(party.getMembers().size()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java index b358a7d01e..360d58652e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java @@ -24,10 +24,12 @@ */ package net.runelite.client.plugins.discord; +import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.http.api.ws.messages.party.PartyMemberMessage; @Value +@EqualsAndHashCode(callSuper = true) class DiscordUserInfo extends PartyMemberMessage { private final String userId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java index 07977334e4..8da48d7cdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java @@ -147,7 +147,8 @@ public class FishingPlugin extends Plugin @Subscribe public void onGameStateChanged(GameStateChanged gameStateChanged) { - if (gameStateChanged.getGameState() == GameState.LOADING) + GameState gameState = gameStateChanged.getGameState(); + if (gameState == GameState.CONNECTION_LOST || gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING) { fishingSpots.clear(); minnowSpots.clear(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java index beb56a171f..75cc26163c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java @@ -167,7 +167,7 @@ public class FriendNotesPlugin extends Plugin if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) { // Friends have color tags - setHoveredFriend(Text.removeTags(event.getTarget())); + setHoveredFriend(Text.toJagexName(Text.removeTags(event.getTarget()))); // Build "Add Note" or "Edit Note" menu entry final MenuEntry addNote = new MenuEntry(); @@ -197,13 +197,13 @@ public class FriendNotesPlugin extends Plugin return; } - //Friends have color tags - final String sanitizedTarget = Text.removeTags(event.getMenuTarget()); - // Handle clicks on "Add Note" or "Edit Note" if (event.getMenuOption().equals(ADD_NOTE) || event.getMenuOption().equals(EDIT_NOTE)) { event.consume(); + + //Friends have color tags + final String sanitizedTarget = Text.toJagexName(Text.removeTags(event.getMenuTarget())); final String note = getFriendNote(sanitizedTarget); // Open the new chatbox input dialog @@ -234,7 +234,16 @@ public class FriendNotesPlugin extends Plugin { // Migrate a friend's note to their new display name final Friend friend = (Friend) nameable; - migrateFriendNote(friend.getName(), friend.getPrevName()); + String name = friend.getName(); + String prevName = friend.getPrevName(); + + if (prevName != null) + { + migrateFriendNote( + Text.toJagexName(name), + Text.toJagexName(prevName) + ); + } } } @@ -242,7 +251,7 @@ public class FriendNotesPlugin extends Plugin public void onRemovedFriend(RemovedFriend event) { // Delete a friend's note if they are removed - final String displayName = event.getName(); + final String displayName = Text.toJagexName(event.getName()); log.debug("Remove friend: '{}'", displayName); setFriendNote(displayName, null); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index a7871f95da..7c0054ac66 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -37,7 +37,9 @@ import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLProfile; import java.awt.Canvas; import java.awt.Dimension; +import java.awt.Graphics2D; import java.awt.Image; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.nio.ByteBuffer; @@ -46,6 +48,7 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.function.Function; import javax.inject.Inject; +import jogamp.nativewindow.SurfaceScaleUtils; import jogamp.nativewindow.jawt.x11.X11JAWTWindow; import jogamp.newt.awt.NewtFactoryAWT; import lombok.extern.slf4j.Slf4j; @@ -71,18 +74,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; -import static net.runelite.client.plugins.gpu.GLUtil.glDeleteBuffer; -import static net.runelite.client.plugins.gpu.GLUtil.glDeleteFrameBuffer; -import static net.runelite.client.plugins.gpu.GLUtil.glDeleteRenderbuffers; -import static net.runelite.client.plugins.gpu.GLUtil.glDeleteTexture; -import static net.runelite.client.plugins.gpu.GLUtil.glDeleteVertexArrays; -import static net.runelite.client.plugins.gpu.GLUtil.glGenBuffers; -import static net.runelite.client.plugins.gpu.GLUtil.glGetInteger; -import static net.runelite.client.plugins.gpu.GLUtil.glGenFrameBuffer; -import static net.runelite.client.plugins.gpu.GLUtil.glGenRenderbuffer; -import static net.runelite.client.plugins.gpu.GLUtil.glGenTexture; -import static net.runelite.client.plugins.gpu.GLUtil.glGenVertexArrays; -import static net.runelite.client.plugins.gpu.GLUtil.inputStreamToString; +import static net.runelite.client.plugins.gpu.GLUtil.*; import net.runelite.client.plugins.gpu.config.AntiAliasingMode; import net.runelite.client.plugins.gpu.template.Template; import net.runelite.client.ui.DrawManager; @@ -1021,7 +1013,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks renderWidthOff = (int) Math.floor(scaleFactorX * (renderWidthOff )) - padding; } - gl.glViewport(renderWidthOff, renderCanvasHeight - renderViewportHeight - renderHeightOff, renderViewportWidth, renderViewportHeight); + glDpiAwareViewport(renderWidthOff, renderCanvasHeight - renderViewportHeight - renderHeightOff, renderViewportWidth, renderViewportHeight); gl.glUseProgram(glProgram); @@ -1151,16 +1143,14 @@ public class GpuPlugin extends Plugin implements DrawCallbacks gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, width, height, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, interfaceBuffer); } - gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); - if (client.isStretchedEnabled()) { Dimension dim = client.getStretchedDimensions(); - gl.glViewport(0, 0, dim.width, dim.height); + glDpiAwareViewport(0, 0, dim.width, dim.height); } else { - gl.glViewport(0, 0, canvasWidth, canvasHeight); + glDpiAwareViewport(0, 0, canvasWidth, canvasHeight); } // Use the texture bound in the first pass @@ -1455,4 +1445,18 @@ public class GpuPlugin extends Plugin implements DrawCallbacks } } + private int getScaledValue(final double scale, final int value) + { + return SurfaceScaleUtils.scale(value, (float) scale); + } + + private void glDpiAwareViewport(final int x, final int y, final int width, final int height) + { + final AffineTransform t = ((Graphics2D) canvas.getGraphics()).getTransform(); + gl.glViewport( + getScaledValue(t.getScaleX(), x), + getScaledValue(t.getScaleY(), y), + getScaledValue(t.getScaleX(), width), + getScaledValue(t.getScaleY(), height)); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java index 1c28371c56..445f6c60d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java @@ -300,7 +300,7 @@ class SceneUploader int vertexCx = localX + Perspective.LOCAL_TILE_SIZE; int vertexCy = localY; int vertexCz = seHeight; - final int c2 = nwColor; + final int c2 = seColor; // 1,1 int vertexAx = localX + Perspective.LOCAL_TILE_SIZE; @@ -312,7 +312,7 @@ class SceneUploader int vertexBx = localX; int vertexBy = localY + Perspective.LOCAL_TILE_SIZE; int vertexBz = nwHeight; - final int c4 = seColor; + final int c4 = nwColor; vertexBuffer.put(vertexAx, vertexAz, vertexAy, c3); vertexBuffer.put(vertexBx, vertexBz, vertexBy, c4); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index cd4f3f050e..5c81aca1b4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -1,5 +1,5 @@ /* - * + * Copyright (c) 2019, Adam * Copyright (c) 2017, Robbie * Copyright (c) 2018, SomeoneWithAnInternetConnection * All rights reserved. @@ -46,6 +46,7 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.GrandExchangeOffer; +import net.runelite.api.GrandExchangeOfferState; import net.runelite.api.ItemComposition; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; @@ -56,11 +57,15 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.GrandExchangeOfferChanged; import net.runelite.api.events.MenuEntryAdded; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; +import net.runelite.client.account.AccountSession; +import net.runelite.client.account.SessionManager; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; @@ -73,8 +78,10 @@ import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.StackFormatter; import net.runelite.client.util.Text; -import net.runelite.http.api.osbuddy.GrandExchangeClient; -import net.runelite.http.api.osbuddy.GrandExchangeResult; +import net.runelite.http.api.ge.GrandExchangeClient; +import net.runelite.http.api.ge.GrandExchangeTrade; +import net.runelite.http.api.osbuddy.OSBGrandExchangeClient; +import net.runelite.http.api.osbuddy.OSBGrandExchangeResult; @PluginDescriptor( name = "Grand Exchange", @@ -86,7 +93,7 @@ public class GrandExchangePlugin extends Plugin { private static final int OFFER_CONTAINER_ITEM = 21; private static final int OFFER_DEFAULT_ITEM_ID = 6512; - private static final GrandExchangeClient CLIENT = new GrandExchangeClient(); + private static final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient(); private static final String OSB_GE_TEXT = "
OSBuddy Actively traded price: "; private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; @@ -134,10 +141,38 @@ public class GrandExchangePlugin extends Plugin @Inject private ScheduledExecutorService executorService; + @Inject + private SessionManager sessionManager; + + @Inject + private ConfigManager configManager; + private Widget grandExchangeText; private Widget grandExchangeItem; private Map itemGELimits; + private GrandExchangeClient grandExchangeClient; + + private SavedOffer getOffer(int slot) + { + String offer = configManager.getConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot)); + if (offer == null) + { + return null; + } + return GSON.fromJson(offer, SavedOffer.class); + } + + private void setOffer(int slot, SavedOffer offer) + { + configManager.setConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot), GSON.toJson(offer)); + } + + private void deleteOffer(int slot) + { + configManager.unsetConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot)); + } + @Provides GrandExchangeConfig provideConfig(ConfigManager configManager) { @@ -167,6 +202,12 @@ public class GrandExchangePlugin extends Plugin mouseManager.registerMouseListener(inputListener); keyManager.registerKeyListener(inputListener); } + + AccountSession accountSession = sessionManager.getAccountSession(); + if (accountSession != null) + { + grandExchangeClient = new GrandExchangeClient(accountSession.getUuid()); + } } @Override @@ -178,6 +219,27 @@ public class GrandExchangePlugin extends Plugin grandExchangeText = null; grandExchangeItem = null; itemGELimits = null; + grandExchangeClient = null; + } + + @Subscribe + public void onSessionOpen(SessionOpen sessionOpen) + { + AccountSession accountSession = sessionManager.getAccountSession(); + if (accountSession.getUuid() != null) + { + grandExchangeClient = new GrandExchangeClient(accountSession.getUuid()); + } + else + { + grandExchangeClient = null; + } + } + + @Subscribe + public void onSessionClose(SessionClose sessionClose) + { + grandExchangeClient = null; } @Subscribe @@ -204,11 +266,79 @@ public class GrandExchangePlugin extends Plugin @Subscribe public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent) { - GrandExchangeOffer offer = offerEvent.getOffer(); + final int slot = offerEvent.getSlot(); + final GrandExchangeOffer offer = offerEvent.getOffer(); + ItemComposition offerItem = itemManager.getItemComposition(offer.getItemId()); boolean shouldStack = offerItem.isStackable() || offer.getTotalQuantity() > 1; BufferedImage itemImage = itemManager.getImage(offer.getItemId(), offer.getTotalQuantity(), shouldStack); - SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offerEvent.getOffer(), offerEvent.getSlot())); + SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offer, slot)); + + submitTrades(slot, offer); + + updateConfig(slot, offer); + } + + private void submitTrades(int slot, GrandExchangeOffer offer) + { + if (grandExchangeClient == null) + { + return; + } + + // Only interested in offers which are fully bought/sold + if (offer.getState() != GrandExchangeOfferState.BOUGHT && offer.getState() != GrandExchangeOfferState.SOLD) + { + return; + } + + SavedOffer savedOffer = getOffer(slot); + if (!shouldUpdate(savedOffer, offer)) + { + return; + } + + // getPrice() is the price of the offer, not necessarily what the item bought at + int priceEach = offer.getSpent() / offer.getTotalQuantity(); + + GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade(); + grandExchangeTrade.setBuy(offer.getState() == GrandExchangeOfferState.BOUGHT); + grandExchangeTrade.setItemId(offer.getItemId()); + grandExchangeTrade.setQuantity(offer.getTotalQuantity()); + grandExchangeTrade.setPrice(priceEach); + + log.debug("Submitting trade: {}", grandExchangeTrade); + grandExchangeClient.submit(grandExchangeTrade); + } + + private void updateConfig(int slot, GrandExchangeOffer offer) + { + if (offer.getState() == GrandExchangeOfferState.EMPTY) + { + deleteOffer(slot); + } + else + { + SavedOffer savedOffer = new SavedOffer(); + savedOffer.setItemId(offer.getItemId()); + savedOffer.setQuantitySold(offer.getQuantitySold()); + savedOffer.setTotalQuantity(offer.getTotalQuantity()); + savedOffer.setPrice(offer.getPrice()); + savedOffer.setSpent(offer.getSpent()); + savedOffer.setState(offer.getState()); + setOffer(slot, savedOffer); + } + } + + private boolean shouldUpdate(SavedOffer savedOffer, GrandExchangeOffer grandExchangeOffer) + { + if (savedOffer == null) + { + return false; + } + + // Only update offer if state has changed + return savedOffer.getState() != grandExchangeOffer.getState(); } @Subscribe @@ -346,7 +476,7 @@ public class GrandExchangePlugin extends Plugin try { - final GrandExchangeResult result = CLIENT.lookupItem(itemId); + final OSBGrandExchangeResult result = CLIENT.lookupItem(itemId); final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(result.getOverall_average()); geText.setText(text); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/SavedOffer.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/SavedOffer.java new file mode 100644 index 0000000000..58a4055fed --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/SavedOffer.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.grandexchange; + +import lombok.Data; +import net.runelite.api.GrandExchangeOfferState; + +@Data +class SavedOffer +{ + private int itemId; + private int quantitySold; + private int totalQuantity; + private int price; + private int spent; + private GrandExchangeOfferState state; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/ColorTileMarker.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/ColorTileMarker.java new file mode 100644 index 0000000000..6a6a30a065 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/ColorTileMarker.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.groundmarkers; + +import java.awt.Color; +import lombok.Value; +import net.runelite.api.coords.WorldPoint; + +/** + * Used to denote marked tiles and their colors. + * Note: This is not used for serialization of ground markers; see {@link GroundMarkerPoint} + */ +@Value +class ColorTileMarker +{ + private WorldPoint worldPoint; + private Color color; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java index d77f3ab9f5..ba8cb98e14 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java @@ -23,7 +23,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - package net.runelite.client.plugins.groundmarkers; import java.awt.Color; @@ -45,4 +44,14 @@ public interface GroundMarkerConfig extends Config { return Color.YELLOW; } + + @ConfigItem( + keyName = "rememberTileColors", + name = "Remember color per tile", + description = "Color tiles using the color from time of placement" + ) + default boolean rememberTileColors() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java index 3b87dd1802..a097d47d29 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java @@ -64,4 +64,4 @@ public class GroundMarkerInputListener implements KeyListener plugin.setHotKeyPressed(false); } } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java index ccd6fd7483..768d90b51b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java @@ -25,10 +25,11 @@ */ package net.runelite.client.plugins.groundmarkers; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; -import java.util.List; +import java.util.Collection; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.Perspective; @@ -42,6 +43,8 @@ import net.runelite.client.ui.overlay.OverlayUtil; public class GroundMarkerOverlay extends Overlay { + private static final int MAX_DRAW_DISTANCE = 32; + private final Client client; private final GroundMarkerConfig config; private final GroundMarkerPlugin plugin; @@ -60,25 +63,33 @@ public class GroundMarkerOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - List points = plugin.getPoints(); - for (WorldPoint point : points) + final Collection points = plugin.getPoints(); + for (final ColorTileMarker point : points) { - if (point.getPlane() != client.getPlane()) + WorldPoint worldPoint = point.getWorldPoint(); + if (worldPoint.getPlane() != client.getPlane()) { continue; } - drawTile(graphics, point); + Color tileColor = point.getColor(); + if (tileColor == null || !config.rememberTileColors()) + { + // If this is an old tile which has no color, or rememberTileColors is off, use marker color + tileColor = config.markerColor(); + } + + drawTile(graphics, worldPoint, tileColor); } return null; } - private void drawTile(Graphics2D graphics, WorldPoint point) + private void drawTile(Graphics2D graphics, WorldPoint point, Color color) { WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); - if (point.distanceTo(playerLocation) >= 32) + if (point.distanceTo(playerLocation) >= MAX_DRAW_DISTANCE) { return; } @@ -95,6 +106,6 @@ public class GroundMarkerOverlay extends Overlay return; } - OverlayUtil.renderPolygon(graphics, poly, config.markerColor()); + OverlayUtil.renderPolygon(graphics, poly, color); } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index 12ceda382a..40e7ff72cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -34,13 +34,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import static net.runelite.api.Constants.CHUNK_SIZE; import net.runelite.api.GameState; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; @@ -69,19 +69,23 @@ public class GroundMarkerPlugin extends Plugin private static final String CONFIG_GROUP = "groundMarker"; private static final String MARK = "Mark tile"; private static final String WALK_HERE = "Walk here"; + private static final String REGION_PREFIX = "region_"; - private static final Gson gson = new Gson(); + private static final Gson GSON = new Gson(); @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) private boolean hotKeyPressed; @Getter(AccessLevel.PACKAGE) - private final List points = new ArrayList<>(); + private final List points = new ArrayList<>(); @Inject private Client client; + @Inject + private GroundMarkerConfig config; + @Inject private GroundMarkerInputListener inputListener; @@ -101,24 +105,25 @@ public class GroundMarkerPlugin extends Plugin { if (points == null || points.isEmpty()) { - configManager.unsetConfiguration(CONFIG_GROUP, "region_" + regionId); + configManager.unsetConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId); return; } - String json = gson.toJson(points); - configManager.setConfiguration(CONFIG_GROUP, "region_" + regionId, json); + String json = GSON.toJson(points); + configManager.setConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId, json); } private Collection getPoints(int regionId) { - String json = configManager.getConfiguration(CONFIG_GROUP, "region_" + regionId); + String json = configManager.getConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId); if (Strings.isNullOrEmpty(json)) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } - return gson.fromJson(json, new TypeToken>() - { - }.getType()); + + // CHECKSTYLE:OFF + return GSON.fromJson(json, new TypeToken>(){}.getType()); + // CHECKSTYLE:ON } @Provides @@ -132,110 +137,46 @@ public class GroundMarkerPlugin extends Plugin points.clear(); int[] regions = client.getMapRegions(); + + if (regions == null) + { + return; + } + for (int regionId : regions) { // load points for region log.debug("Loading points for region {}", regionId); Collection regionPoints = getPoints(regionId); - Collection worldPoints = translateToWorld(regionPoints); - points.addAll(worldPoints); + Collection colorTileMarkers = translateToColorTileMarker(regionPoints); + points.addAll(colorTileMarkers); } } /** - * Translate a collection of ground marker points to world points, accounting for instances + * Translate a collection of ground marker points to color tile markers, accounting for instances * - * @param points - * @return + * @param points {@link GroundMarkerPoint}s to be converted to {@link ColorTileMarker}s + * @return A collection of color tile markers, converted from the passed ground marker points, accounting for local + * instance points. See {@link WorldPoint#toLocalInstance(Client, WorldPoint)} */ - private Collection translateToWorld(Collection points) + private Collection translateToColorTileMarker(Collection points) { if (points.isEmpty()) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } - List worldPoints = new ArrayList<>(); - for (GroundMarkerPoint point : points) - { - int regionId = point.getRegionId(); - int regionX = point.getRegionX(); - int regionY = point.getRegionY(); - int z = point.getZ(); - - // world point of the tile marker - WorldPoint worldPoint = new WorldPoint( - ((regionId >>> 8) << 6) + regionX, - ((regionId & 0xff) << 6) + regionY, - z - ); - - if (!client.isInInstancedRegion()) + return points.stream() + .map(point -> new ColorTileMarker( + WorldPoint.fromRegion(point.getRegionId(), point.getRegionX(), point.getRegionY(), point.getZ()), + point.getColor())) + .flatMap(colorTile -> { - worldPoints.add(worldPoint); - continue; - } - - // find instance chunks using the template point. there might be more than one. - int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks(); - for (int x = 0; x < instanceTemplateChunks[z].length; ++x) - { - for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y) - { - int chunkData = instanceTemplateChunks[z][x][y]; - int rotation = chunkData >> 1 & 0x3; - int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE; - int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE; - if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE - && worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE) - { - WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)), - client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)), - worldPoint.getPlane()); - p = rotate(p, rotation); - worldPoints.add(p); - } - } - } - } - return worldPoints; - } - - /** - * Rotate the chunk containing the given point to rotation 0 - * - * @param point point - * @param rotation rotation - * @return world point - */ - private static WorldPoint rotateInverse(WorldPoint point, int rotation) - { - return rotate(point, 4 - rotation); - } - - /** - * Rotate the coordinates in the chunk according to chunk rotation - * - * @param point point - * @param rotation rotation - * @return world point - */ - private static WorldPoint rotate(WorldPoint point, int rotation) - { - int chunkX = point.getX() & ~(CHUNK_SIZE - 1); - int chunkY = point.getY() & ~(CHUNK_SIZE - 1); - int x = point.getX() & (CHUNK_SIZE - 1); - int y = point.getY() & (CHUNK_SIZE - 1); - switch (rotation) - { - case 1: - return new WorldPoint(chunkX + y, chunkY + (CHUNK_SIZE - 1 - x), point.getPlane()); - case 2: - return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - x), chunkY + (CHUNK_SIZE - 1 - y), point.getPlane()); - case 3: - return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - y), chunkY + x, point.getPlane()); - } - return point; + final Collection localWorldPoints = WorldPoint.toLocalInstance(client, colorTile.getWorldPoint()); + return localWorldPoints.stream().map(wp -> new ColorTileMarker(wp, colorTile.getColor())); + }) + .collect(Collectors.toList()); } @Subscribe @@ -298,6 +239,7 @@ public class GroundMarkerPlugin extends Plugin { overlayManager.add(overlay); keyManager.registerKeyListener(inputListener); + loadPoints(); } @Override @@ -305,10 +247,10 @@ public class GroundMarkerPlugin extends Plugin { overlayManager.remove(overlay); keyManager.unregisterKeyListener(inputListener); + points.clear(); } - - protected void markTile(LocalPoint localPoint) + private void markTile(LocalPoint localPoint) { if (localPoint == null) { @@ -318,21 +260,21 @@ public class GroundMarkerPlugin extends Plugin WorldPoint worldPoint = WorldPoint.fromLocalInstance(client, localPoint); int regionId = worldPoint.getRegionID(); - GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getX() & 0x3f, worldPoint.getY() & 0x3f, client.getPlane()); + GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), config.markerColor()); log.debug("Updating point: {} - {}", point, worldPoint); - List points = new ArrayList<>(getPoints(regionId)); - if (points.contains(point)) + List groundMarkerPoints = new ArrayList<>(getPoints(regionId)); + if (groundMarkerPoints.contains(point)) { - points.remove(point); + groundMarkerPoints.remove(point); } else { - points.add(point); + groundMarkerPoints.add(point); } - savePoints(regionId, points); + savePoints(regionId, groundMarkerPoints); loadPoints(); } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java index b31db32222..3e10a654c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java @@ -23,16 +23,22 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - package net.runelite.client.plugins.groundmarkers; +import java.awt.Color; +import lombok.EqualsAndHashCode; import lombok.Value; +/** + * Used for serialization of ground marker points. + */ @Value -public class GroundMarkerPoint +@EqualsAndHashCode(exclude = { "color" }) +class GroundMarkerPoint { private int regionId; private int regionX; private int regionY; private int z; -} \ No newline at end of file + private Color color; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java index 9a47e57de0..c49eb37f8f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java @@ -47,6 +47,7 @@ import net.runelite.api.Varbits; import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.GraphicChanged; import net.runelite.api.events.HitsplatApplied; import net.runelite.api.events.InteractingChanged; import net.runelite.client.Notifier; @@ -196,12 +197,14 @@ public class IdleNotifierPlugin extends Plugin case MINING_MOTHERLODE_INFERNAL: case MINING_MOTHERLODE_3A: /* Herblore */ + case HERBLORE_PESTLE_AND_MORTAR: case HERBLORE_POTIONMAKING: case HERBLORE_MAKE_TAR: /* Magic */ case MAGIC_CHARGING_ORBS: case MAGIC_LUNAR_STRING_JEWELRY: case MAGIC_MAKE_TABLET: + case MAGIC_ENCHANTING_JEWELRY: /* Prayer */ case USING_GILDED_ALTAR: /* Farming */ @@ -329,6 +332,22 @@ public class IdleNotifierPlugin extends Plugin } } + @Subscribe + public void onGraphicChanged(GraphicChanged event) + { + Actor actor = event.getActor(); + + if (actor != client.getLocalPlayer()) + { + return; + } + + if (actor.getGraphic() == GraphicID.SPLASH) + { + lastCombatCountdown = HIGHEST_MONSTER_ATTACK_SPEED; + } + } + @Subscribe public void onGameTick(GameTick event) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index 2edb250135..f9dc12f4e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -40,14 +40,16 @@ import javax.inject.Singleton; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.event.HyperlinkEvent; import net.runelite.api.Client; -import net.runelite.api.events.SessionClose; -import net.runelite.api.events.SessionOpen; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.client.RuneLiteProperties; import net.runelite.client.account.SessionManager; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.ColorScheme; @@ -66,9 +68,12 @@ public class InfoPanel extends PluginPanel private static final ImageIcon DISCORD_ICON; private static final ImageIcon PATREON_ICON; private static final ImageIcon WIKI_ICON; + private static final ImageIcon IMPORT_ICON; private final JLabel loggedLabel = new JLabel(); private final JRichTextPane emailLabel = new JRichTextPane(); + private JPanel syncPanel; + private JPanel actionsContainer; @Inject @Nullable @@ -86,6 +91,9 @@ public class InfoPanel extends PluginPanel @Inject private ScheduledExecutorService executor; + @Inject + private ConfigManager configManager; + static { ARROW_RIGHT_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "/util/arrow_right.png")); @@ -93,6 +101,7 @@ public class InfoPanel extends PluginPanel DISCORD_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "discord_icon.png")); PATREON_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "patreon_icon.png")); WIKI_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "wiki_icon.png")); + IMPORT_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "import_icon.png")); } void init() @@ -150,11 +159,22 @@ public class InfoPanel extends PluginPanel versionPanel.add(loggedLabel); versionPanel.add(emailLabel); - updateLoggedIn(); - - JPanel actionsContainer = new JPanel(); + actionsContainer = new JPanel(); actionsContainer.setBorder(new EmptyBorder(10, 0, 0, 0)); - actionsContainer.setLayout(new GridLayout(4, 1, 0, 10)); + actionsContainer.setLayout(new GridLayout(0, 1, 0, 10)); + + syncPanel = buildLinkPanel(IMPORT_ICON, "Import local settings", "to remote RuneLite account", () -> + { + final int result = JOptionPane.showOptionDialog(syncPanel, + "This will replace your current RuneLite account settings with settings from your local profile.", + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); + + if (result == JOptionPane.YES_OPTION) + { + configManager.importLocal(); + } + }); actionsContainer.add(buildLinkPanel(GITHUB_ICON, "Report an issue or", "make a suggestion", runeLiteProperties.getGithubLink())); actionsContainer.add(buildLinkPanel(DISCORD_ICON, "Talk to us on our", "discord server", runeLiteProperties.getDiscordInvite())); @@ -164,6 +184,7 @@ public class InfoPanel extends PluginPanel add(versionPanel, BorderLayout.NORTH); add(actionsContainer, BorderLayout.CENTER); + updateLoggedIn(); eventBus.register(this); } @@ -171,6 +192,14 @@ public class InfoPanel extends PluginPanel * Builds a link panel with a given icon, text and url to redirect to. */ private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, String url) + { + return buildLinkPanel(icon, topText, bottomText, () -> LinkBrowser.browse(url)); + } + + /** + * Builds a link panel with a given icon, text and callable to call. + */ + private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, Runnable callback) { JPanel container = new JPanel(); container.setBackground(ColorScheme.DARKER_GRAY_COLOR); @@ -193,7 +222,6 @@ public class InfoPanel extends PluginPanel @Override public void mousePressed(MouseEvent mouseEvent) { - LinkBrowser.browse(url); container.setBackground(pressedColor); textContainer.setBackground(pressedColor); } @@ -201,6 +229,7 @@ public class InfoPanel extends PluginPanel @Override public void mouseReleased(MouseEvent e) { + callback.run(); container.setBackground(hoverColor); textContainer.setBackground(hoverColor); } @@ -252,12 +281,14 @@ public class InfoPanel extends PluginPanel emailLabel.setContentType("text/plain"); emailLabel.setText(name); loggedLabel.setText("Logged in as"); + actionsContainer.add(syncPanel, 0); } else { emailLabel.setContentType("text/html"); emailLabel.setText("Login to sync settings to the cloud."); loggedLabel.setText("Not logged in"); + actionsContainer.remove(syncPanel); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java index 40488c5137..28c503b20a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java @@ -203,4 +203,15 @@ public interface ItemChargeConfig extends Config { return false; } + + @ConfigItem( + keyName = "showInfoboxes", + name = "Show Infoboxes", + description = "Configures whether to show an infobox equipped charge items", + position = 15 + ) + default boolean showInfoboxes() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeInfobox.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeInfobox.java new file mode 100644 index 0000000000..7ee70d44b5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeInfobox.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, Hydrox6 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.itemcharges; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import lombok.Getter; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.client.ui.overlay.infobox.Counter; + +@Getter +class ItemChargeInfobox extends Counter +{ + private final ItemChargePlugin plugin; + private final ItemWithSlot item; + private final EquipmentInventorySlot slot; + + ItemChargeInfobox( + ItemChargePlugin plugin, + BufferedImage image, + String name, + int charges, + ItemWithSlot item, + EquipmentInventorySlot slot) + { + super(image, plugin, charges); + setTooltip(name); + this.plugin = plugin; + this.item = item; + this.slot = slot; + } + + @Override + public Color getTextColor() + { + return getPlugin().getColor(getCount()); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index 7730d46ffd..27bb35b21d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.itemcharges; -import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -83,7 +82,7 @@ class ItemChargeOverlay extends Overlay continue; } - charges = itemChargePlugin.getDodgyCharges(); + charges = config.dodgyNecklace(); } else { @@ -112,7 +111,7 @@ class ItemChargeOverlay extends Overlay final TextComponent textComponent = new TextComponent(); textComponent.setPosition(new Point(bounds.x, bounds.y + 16)); textComponent.setText(charges < 0 ? "?" : String.valueOf(charges)); - textComponent.setColor(getColor(charges)); + textComponent.setColor(itemChargePlugin.getColor(charges)); textComponent.render(graphics); } return null; @@ -137,20 +136,6 @@ class ItemChargeOverlay extends Overlay return jewellery; } - private Color getColor(int charges) - { - Color color = Color.WHITE; - if (charges <= config.veryLowWarning()) - { - color = config.veryLowWarningColor(); - } - else if (charges <= config.lowWarning()) - { - color = config.lowWarningolor(); - } - return color; - } - private boolean displayOverlay() { return config.showTeleportCharges() || config.showDodgyCount() || config.showFungicideCharges() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java index c545e9a5bb..e295efd9e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, Seth + * Copyright (c) 2018, Hydrox6 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,19 +26,29 @@ package net.runelite.client.plugins.itemcharges; import com.google.inject.Provides; +import java.awt.Color; +import java.awt.image.BufferedImage; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; @PluginDescriptor( name = "Item Charges", @@ -56,21 +67,27 @@ public class ItemChargePlugin extends Plugin private static final int MAX_DODGY_CHARGES = 10; + @Inject + private Client client; + @Inject private OverlayManager overlayManager; @Inject private ItemChargeOverlay overlay; + @Inject + private ItemManager itemManager; + + @Inject + private InfoBoxManager infoBoxManager; + @Inject private Notifier notifier; @Inject private ItemChargeConfig config; - @Getter(AccessLevel.PACKAGE) - private int dodgyCharges; - @Provides ItemChargeConfig getConfig(ConfigManager configManager) { @@ -81,13 +98,43 @@ public class ItemChargePlugin extends Plugin protected void startUp() { overlayManager.add(overlay); - dodgyCharges = config.dodgyNecklace(); } @Override protected void shutDown() throws Exception { overlayManager.remove(overlay); + infoBoxManager.removeIf(ItemChargeInfobox.class::isInstance); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!event.getGroup().equals("itemCharge")) + { + return; + } + + if (!config.showInfoboxes()) + { + infoBoxManager.removeIf(ItemChargeInfobox.class::isInstance); + return; + } + + if (!config.showTeleportCharges()) + { + removeInfobox(ItemWithSlot.TELEPORT); + } + + if (!config.showAbyssalBraceletCharges()) + { + removeInfobox(ItemWithSlot.ABYSSAL_BRACELET); + } + + if (!config.showDodgyCount()) + { + removeInfobox(ItemWithSlot.DODGY_NECKLACE); + } } @Subscribe @@ -110,22 +157,141 @@ public class ItemChargePlugin extends Plugin notifier.notify("Your dodgy necklace has crumbled to dust."); } - setDodgyCharges(MAX_DODGY_CHARGES); + updateDodgyNecklaceCharges(MAX_DODGY_CHARGES); } else if (dodgyCheckMatcher.find()) { - setDodgyCharges(Integer.parseInt(dodgyCheckMatcher.group(1))); + updateDodgyNecklaceCharges(Integer.parseInt(dodgyCheckMatcher.group(1))); } else if (dodgyProtectMatcher.find()) { - setDodgyCharges(Integer.parseInt(dodgyProtectMatcher.group(1))); + updateDodgyNecklaceCharges(Integer.parseInt(dodgyProtectMatcher.group(1))); } } } - private void setDodgyCharges(int dodgyCharges) + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) { - this.dodgyCharges = dodgyCharges; - config.dodgyNecklace(dodgyCharges); + if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT) || !config.showInfoboxes()) + { + return; + } + + final Item[] items = event.getItemContainer().getItems(); + + if (config.showTeleportCharges()) + { + updateJewelleryInfobox(ItemWithSlot.TELEPORT, items); + } + + if (config.showDodgyCount()) + { + updateJewelleryInfobox(ItemWithSlot.DODGY_NECKLACE, items); + } + + if (config.showAbyssalBraceletCharges()) + { + updateJewelleryInfobox(ItemWithSlot.ABYSSAL_BRACELET, items); + } + } + + private void updateDodgyNecklaceCharges(final int value) + { + config.dodgyNecklace(value); + + if (config.showInfoboxes() && config.showDodgyCount()) + { + final ItemContainer itemContainer = client.getItemContainer(InventoryID.EQUIPMENT); + + if (itemContainer == null) + { + return; + } + + updateJewelleryInfobox(ItemWithSlot.DODGY_NECKLACE, itemContainer.getItems()); + } + } + + private void updateJewelleryInfobox(ItemWithSlot item, Item[] items) + { + for (final EquipmentInventorySlot equipmentInventorySlot : item.getSlots()) + { + updateJewelleryInfobox(item, items, equipmentInventorySlot); + } + } + + private void updateJewelleryInfobox(ItemWithSlot type, Item[] items, EquipmentInventorySlot slot) + { + removeInfobox(type, slot); + + if (slot.getSlotIdx() >= items.length) + { + return; + } + + final int id = items[slot.getSlotIdx()].getId(); + if (id < 0) + { + return; + } + + final ItemWithCharge itemWithCharge = ItemWithCharge.findItem(id); + int charges = -1; + + if (itemWithCharge == null) + { + if (id == ItemID.DODGY_NECKLACE && type == ItemWithSlot.DODGY_NECKLACE) + { + charges = config.dodgyNecklace(); + } + } + else if (itemWithCharge.getType() == type.getType()) + { + charges = itemWithCharge.getCharges(); + } + + if (charges <= 0) + { + return; + } + + final String name = itemManager.getItemComposition(id).getName(); + final BufferedImage image = itemManager.getImage(id); + final ItemChargeInfobox infobox = new ItemChargeInfobox(this, image, name, charges, type, slot); + infoBoxManager.addInfoBox(infobox); + } + + private void removeInfobox(final ItemWithSlot item) + { + infoBoxManager.removeIf(t -> t instanceof ItemChargeInfobox && ((ItemChargeInfobox) t).getItem() == item); + } + + private void removeInfobox(final ItemWithSlot item, final EquipmentInventorySlot slot) + { + infoBoxManager.removeIf(t -> + { + if (!(t instanceof ItemChargeInfobox)) + { + return false; + } + + final ItemChargeInfobox i = (ItemChargeInfobox)t; + return i.getItem() == item && i.getSlot() == slot; + }); + } + + Color getColor(int charges) + { + Color color = Color.WHITE; + if (charges <= config.veryLowWarning()) + { + color = config.veryLowWarningColor(); + } + else if (charges <= config.lowWarning()) + { + color = config.lowWarningolor(); + } + return color; } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java index 2f25c12164..cbe5d20ff3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java @@ -32,5 +32,6 @@ enum ItemChargeType IMPBOX, TELEPORT, WATERCAN, - WATERSKIN + WATERSKIN, + DODGY_NECKLACE } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithSlot.java new file mode 100644 index 0000000000..3fbd2bac66 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithSlot.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019, Tomas Slusny + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.itemcharges; + +import com.google.common.collect.Sets; +import java.util.Set; +import lombok.Getter; +import net.runelite.api.EquipmentInventorySlot; + +@Getter +enum ItemWithSlot +{ + ABYSSAL_BRACELET(ItemChargeType.ABYSSAL_BRACELET, EquipmentInventorySlot.GLOVES), + DODGY_NECKLACE(ItemChargeType.DODGY_NECKLACE, EquipmentInventorySlot.AMULET), + TELEPORT(ItemChargeType.TELEPORT, EquipmentInventorySlot.WEAPON, EquipmentInventorySlot.AMULET, EquipmentInventorySlot.GLOVES, EquipmentInventorySlot.RING); + + private final ItemChargeType type; + private final Set slots; + + ItemWithSlot(final ItemChargeType type, final EquipmentInventorySlot... slots) + { + this.type = type; + this.slots = Sets.newHashSet(slots); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesConfig.java index ed69408341..a7b62e52b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesConfig.java @@ -74,4 +74,16 @@ public interface ItemPricesConfig extends Config { return true; } + + @ConfigItem( + keyName = "showAlchProfit", + name = "Show High Alchemy Profit", + description = "Show the profit from casting high alchemy on items", + position = 5 + ) + default boolean showAlchProfit() + { + return false; + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java index 7e170db214..7c748a7702 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java @@ -196,6 +196,7 @@ class ItemPricesOverlay extends Overlay int gePrice = 0; int haPrice = 0; + int haProfit = 0; if (config.showGEPrice()) { @@ -205,16 +206,20 @@ class ItemPricesOverlay extends Overlay { haPrice = Math.round(itemDef.getPrice() * HIGH_ALCHEMY_CONSTANT); } + if (gePrice > 0 && haPrice > 0 && config.showAlchProfit()) + { + haProfit = calculateHAProfit(haPrice, gePrice); + } if (gePrice > 0 || haPrice > 0) { - return stackValueText(qty, gePrice, haPrice); + return stackValueText(qty, gePrice, haPrice, haProfit); } return null; } - private String stackValueText(int qty, int gePrice, int haValue) + private String stackValueText(int qty, int gePrice, int haValue, int haProfit) { if (gePrice > 0) { @@ -246,9 +251,36 @@ class ItemPricesOverlay extends Overlay } } + if (haProfit != 0) + { + Color haColor = haProfitColor(haProfit); + + itemStringBuilder.append("
"); + itemStringBuilder.append("HA Profit: ") + .append(ColorUtil.wrapWithColorTag(String.valueOf(haProfit * qty), haColor)) + .append(" gp"); + if (config.showEA() && qty > 1) + { + itemStringBuilder.append(" (") + .append(ColorUtil.wrapWithColorTag(String.valueOf(haProfit), haColor)) + .append(" ea)"); + } + } + // Build string and reset builder final String text = itemStringBuilder.toString(); itemStringBuilder.setLength(0); return text; } + + private int calculateHAProfit(int haPrice, int gePrice) + { + int natureRunePrice = itemManager.getItemPrice(ItemID.NATURE_RUNE); + return haPrice - gePrice - natureRunePrice; + } + + private static Color haProfitColor(int haProfit) + { + return haProfit >= 0 ? Color.GREEN : Color.RED; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java index 6b66cf57e0..099b5a16a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java @@ -36,6 +36,7 @@ import net.runelite.client.plugins.itemstats.food.Anglerfish; import net.runelite.client.plugins.itemstats.potions.PrayerPotion; import net.runelite.client.plugins.itemstats.potions.SaradominBrew; import net.runelite.client.plugins.itemstats.potions.SuperRestore; +import net.runelite.client.plugins.itemstats.special.CastleWarsBandage; import net.runelite.client.plugins.itemstats.special.SpicyStew; import static net.runelite.client.plugins.itemstats.stats.Stats.*; @@ -137,6 +138,9 @@ public class ItemStatChanges // Regular overload (NMZ) add(combo(5, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(HITPOINTS, -50)), OVERLOAD_1, OVERLOAD_2, OVERLOAD_3, OVERLOAD_4); + // Bandages (Castle Wars) + add(new CastleWarsBandage(), BANDAGES); + // Recovery potions add(combo(5, heal(ATTACK, perc(.30, 10)), heal(STRENGTH, perc(.30, 10)), heal(DEFENCE, perc(.30, 10)), heal(RANGED, perc(.30, 10)), heal(MAGIC, perc(.30, 10))), RESTORE_POTION1, RESTORE_POTION2, RESTORE_POTION3, RESTORE_POTION4); add(heal(RUN_ENERGY, 10), ENERGY_POTION1, ENERGY_POTION2, ENERGY_POTION3, ENERGY_POTION4); @@ -174,7 +178,7 @@ public class ItemStatChanges // Misc/run energy add(heal(RUN_ENERGY, 10), WHITE_TREE_FRUIT); - add(heal(RUN_ENERGY, 30), STRANGE_FRUIT, BANDAGES); + add(heal(RUN_ENERGY, 30), STRANGE_FRUIT); add(heal(RUN_ENERGY, 50), MINT_CAKE); add(combo(food(12), heal(RUN_ENERGY, 50)), GOUT_TUBER); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatConfig.java index c9fa8af82b..3c7d586a86 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatConfig.java @@ -52,6 +52,16 @@ public interface ItemStatConfig extends Config return true; } + @ConfigItem( + keyName = "geStats", + name = "Enable GE item information", + description = "Shows an item information panel when buying items in the GE" + ) + default boolean geStats() + { + return true; + } + @ConfigItem( keyName = "relative", name = "Show Relative", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java index 986321e966..206ab6fc13 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java @@ -139,7 +139,7 @@ public class ItemStatOverlay extends Overlay if (config.equipmentStats()) { - final ItemStats stats = itemManager.getItemStats(itemId); + final ItemStats stats = itemManager.getItemStats(itemId, false); if (stats != null) { @@ -205,7 +205,7 @@ public class ItemStatOverlay extends Overlay final Item item = items[slot]; if (item != null) { - other = itemManager.getItemStats(item.getId()); + other = itemManager.getItemStats(item.getId(), false); } } @@ -258,7 +258,7 @@ public class ItemStatOverlay extends Overlay if (config.relative()) { - b.append(c.getRelative()); + b.append(c.getFormattedRelative()); } if (config.theoretical()) @@ -267,7 +267,7 @@ public class ItemStatOverlay extends Overlay { b.append("/"); } - b.append(c.getTheoretical()); + b.append(c.getFormattedTheoretical()); } if (config.absolute() && (config.relative() || config.theoretical())) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java index 250a6410cd..d8facce32a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java @@ -24,13 +24,46 @@ */ package net.runelite.client.plugins.itemstats; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.inject.Binder; import com.google.inject.Inject; import com.google.inject.Provides; +import java.awt.FontMetrics; +import java.util.List; +import java.util.Map; +import java.util.Set; +import net.runelite.api.Client; +import net.runelite.api.FontID; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; +import net.runelite.api.SpriteID; +import net.runelite.api.VarPlayer; +import net.runelite.api.Varbits; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.ScriptCallbackEvent; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.widgets.JavaScriptCallback; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetTextAlignment; +import net.runelite.api.widgets.WidgetType; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.StackFormatter; +import net.runelite.http.api.item.ItemEquipmentStats; +import net.runelite.http.api.item.ItemStats; @PluginDescriptor( name = "Item Stats", @@ -39,12 +72,30 @@ import net.runelite.client.ui.overlay.OverlayManager; ) public class ItemStatPlugin extends Plugin { + private static final int ORANGE_TEXT = JagexColors.DARK_ORANGE_INTERFACE_TEXT.getRGB(); + private static final int YELLOW_TEXT = JagexColors.YELLOW_INTERFACE_TEXT.getRGB(); + private static final int TEXT_HEIGHT = 11; + @Inject private OverlayManager overlayManager; @Inject private ItemStatOverlay overlay; + @Inject + private Client client; + + @Inject + private ItemManager itemManager; + + @Inject + private ItemStatConfig config; + + @Inject + private ClientThread clientThread; + + private Widget itemInformationTitle; + @Provides ItemStatConfig getConfig(ConfigManager configManager) { @@ -67,5 +118,320 @@ public class ItemStatPlugin extends Plugin protected void shutDown() throws Exception { overlayManager.remove(overlay); + clientThread.invokeLater(this::resetGEInventory); + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getKey().equals("geStats")) + { + clientThread.invokeLater(this::resetGEInventory); + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (itemInformationTitle != null && config.geStats() + && (client.getWidget(WidgetInfo.GRAND_EXCHANGE_WINDOW_CONTAINER) == null + || client.getWidget(WidgetInfo.GRAND_EXCHANGE_WINDOW_CONTAINER).isHidden())) + { + resetGEInventory(); + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (client.getVar(VarPlayer.CURRENT_GE_ITEM) == -1 && config.geStats()) + { + resetGEInventory(); + } + } + + @Subscribe + public void onScriptCallbackEvent(ScriptCallbackEvent event) + { + if (event.getEventName().equals("geBuilt") && config.geStats()) + { + int currentGeItem = client.getVar(VarPlayer.CURRENT_GE_ITEM); + if (currentGeItem != -1 && client.getVar(Varbits.GE_OFFER_CREATION_TYPE) == 0) + { + createItemInformation(currentGeItem); + } + } + } + + private void createItemInformation(int id) + { + final ItemStats itemStats = itemManager.getItemStats(id, false); + + if (itemStats == null || !itemStats.isEquipable()) + { + return; + } + + final ItemEquipmentStats equipmentStats = itemStats.getEquipment(); + + if (equipmentStats == null) + { + return; + } + + final Widget geInv = client.getWidget(WidgetInfo.GRAND_EXCHANGE_INVENTORY_ITEMS_CONTAINER); + + if (geInv == null) + { + return; + } + + final Widget invContainer = getInventoryContainer(); + + if (invContainer == null) + { + return; + } + + invContainer.deleteAllChildren(); + geInv.setHidden(true); + + int yPos = 0; + + final FontMetrics smallFM = client.getCanvas().getFontMetrics(FontManager.getRunescapeSmallFont()); + + // HEADER + + itemInformationTitle = createText(invContainer, "Item Information", FontID.BOLD_12, ORANGE_TEXT, + 8, 8, invContainer.getWidth(), 16); + itemInformationTitle.setYTextAlignment(WidgetTextAlignment.CENTER); + + Widget closeButton = invContainer.createChild(-1, WidgetType.GRAPHIC); + closeButton.setOriginalY(8); + closeButton.setOriginalX(invContainer.getWidth() - 24); + closeButton.setOriginalHeight(16); + closeButton.setOriginalWidth(16); + closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL); + closeButton.setAction(0, "Close"); + closeButton.setOnMouseOverListener((JavaScriptCallback) (ev) -> + { + closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL_HOVERED); + }); + closeButton.setOnMouseLeaveListener((JavaScriptCallback) (ev) -> + { + closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL); + }); + closeButton.setOnOpListener((JavaScriptCallback) (ev) -> resetGEInventory()); + closeButton.setHasListener(true); + closeButton.revalidate(); + + yPos += 15; + + createSeparator(invContainer, yPos); + + // ICON AND TITLE + + yPos += 25; + + Widget icon = invContainer.createChild(-1, WidgetType.GRAPHIC); + icon.setOriginalX(8); + icon.setOriginalY(yPos); + icon.setOriginalWidth(36); + icon.setOriginalHeight(32); + icon.setItemId(id); + icon.setItemQuantityMode(0); + icon.setBorderType(1); + icon.revalidate(); + + Widget itemName = createText(invContainer, itemManager.getItemComposition(id).getName(), FontID.PLAIN_12, ORANGE_TEXT, + 50, yPos, invContainer.getWidth() - 40, 30); + itemName.setYTextAlignment(WidgetTextAlignment.CENTER); + + yPos += 20; + + createSeparator(invContainer, yPos); + + // STATS HEADER + + yPos += 25; + + createText(invContainer, "Attack", FontID.PLAIN_11, ORANGE_TEXT, 5, yPos, 50, -1); + + int defenceXPos = invContainer.getWidth() - (smallFM.stringWidth("Defence") + 5); + createText(invContainer, "Defence", FontID.PLAIN_11, ORANGE_TEXT, defenceXPos, yPos, 50, -1); + + // STYLE BONUSES + + final Set stats = ImmutableSet.of( + "Stab", + "Slash", + "Crush", + "Magic", + "Ranged" + ); + + final List attackStats = ImmutableList.of( + equipmentStats.getAstab(), + equipmentStats.getAslash(), + equipmentStats.getAcrush(), + equipmentStats.getAmagic(), + equipmentStats.getArange() + ); + + final List defenceStats = ImmutableList.of( + equipmentStats.getDstab(), + equipmentStats.getDslash(), + equipmentStats.getDcrush(), + equipmentStats.getDmagic(), + equipmentStats.getDrange() + ); + + int index = 0; + + for (final String stat : stats) + { + yPos += TEXT_HEIGHT + 2; + + // Style label + final Widget styleText = createText(invContainer, stat, FontID.PLAIN_11, ORANGE_TEXT, + 0, yPos, invContainer.getWidth(), -1); + styleText.setXTextAlignment(WidgetTextAlignment.CENTER); + + // Attack bonus + createText(invContainer, attackStats.get(index).toString(), FontID.PLAIN_11, YELLOW_TEXT, + 5, yPos, 50, -1); + + // Defence bonus + final int defenceX = invContainer.getWidth() - (smallFM.stringWidth(defenceStats.get(index).toString()) + 5); + createText(invContainer, defenceStats.get(index).toString(), FontID.PLAIN_11, YELLOW_TEXT, + defenceX, yPos, 50, -1); + + index++; + } + + // MISC BONUSES + + yPos += TEXT_HEIGHT + 8; + + final Map miscStats = ImmutableMap.of( + "Strength", equipmentStats.getStr(), + "Ranged Strength", equipmentStats.getRstr(), + "Magic Damage", equipmentStats.getMdmg(), + "Prayer Bonus", equipmentStats.getPrayer() + ); + + for (final Map.Entry miscStat : miscStats.entrySet()) + { + final String name = miscStat.getKey(); + final String value = miscStat.getValue().toString(); + + // Stat label + createText(invContainer, name, FontID.PLAIN_11, ORANGE_TEXT, 5, yPos, 50, -1); + + // Stat bonus + int valueXPos = invContainer.getWidth() - (smallFM.stringWidth(value) + 5); + createText(invContainer, value, FontID.PLAIN_11, YELLOW_TEXT, valueXPos, yPos, 50, -1); + + yPos += TEXT_HEIGHT + 2; + } + + // COINS + + createSeparator(invContainer, invContainer.getHeight() - 40); + + final String coinText = "You have " + StackFormatter.quantityToRSStackSize(getCurrentGP()) + + (getCurrentGP() == 1 ? " coin." : " coins."); + + final Widget coinWidget = createText(invContainer, coinText, FontID.PLAIN_12, ORANGE_TEXT, + 0, invContainer.getHeight() - 18, invContainer.getWidth(), -1); + + coinWidget.setXTextAlignment(WidgetTextAlignment.CENTER); + } + + private static Widget createText(Widget parent, String text, int fontId, int textColor, + int x, int y, int width, int height) + { + final Widget widget = parent.createChild(-1, WidgetType.TEXT); + widget.setText(text); + widget.setFontId(fontId); + widget.setTextColor(textColor); + widget.setTextShadowed(true); + widget.setOriginalHeight(height == -1 ? TEXT_HEIGHT : height); + widget.setOriginalWidth(width); + widget.setOriginalY(y); + widget.setOriginalX(x); + widget.revalidate(); + return widget; + } + + private static void createSeparator(Widget parent, int y) + { + Widget separator = parent.createChild(-1, WidgetType.GRAPHIC); + separator.setOriginalWidth(parent.getWidth()); + separator.setOriginalY(y); + separator.setOriginalHeight(32); + separator.setSpriteId(SpriteID.UNKNOWN_BORDER_EDGE_HORIZONTAL_995); + separator.revalidate(); + } + + private void resetGEInventory() + { + final Widget invContainer = getInventoryContainer(); + + if (invContainer == null) + { + return; + } + + if (itemInformationTitle != null && invContainer.getChild(0) == itemInformationTitle) + { + invContainer.deleteAllChildren(); + itemInformationTitle = null; + } + + final Widget geInv = client.getWidget(WidgetInfo.GRAND_EXCHANGE_INVENTORY_ITEMS_CONTAINER); + if (geInv != null) + { + geInv.setHidden(false); + } + } + + private int getCurrentGP() + { + final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); + + if (inventory == null) + { + return 0; + } + + for (final Item item : inventory.getItems()) + { + if (item.getId() == ItemID.COINS_995) + { + return item.getQuantity(); + } + } + + return 0; + } + + private Widget getInventoryContainer() + { + if (client.isResized()) + { + if (client.getVar(Varbits.SIDE_PANELS) == 1) + { + return client.getWidget(WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_CONTAINER); + } + else + { + return client.getWidget(WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_CONTAINER); + } + } + else + { + return client.getWidget(WidgetInfo.FIXED_VIEWPORT_INVENTORY_CONTAINER); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java index abe47cea1c..13011b9f6a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java @@ -42,33 +42,21 @@ public class RangeStatBoost extends SingleEffect @Override public StatChange effect(Client client) { - final StatChange a = this.a.effect(client); - final StatChange b = this.b.effect(client); + final StatChange changeA = this.a.effect(client); + final StatChange changeB = this.b.effect(client); - final StatChange r = new StatChange(); - r.setAbsolute(concat(a.getAbsolute(), b.getAbsolute())); - r.setRelative(concat(a.getRelative(), b.getRelative())); - r.setTheoretical(concat(a.getTheoretical(), b.getTheoretical())); - r.setStat(a.getStat()); + final RangeStatChange r = new RangeStatChange(); + r.setMinAbsolute(Math.min(changeA.getAbsolute(), changeB.getAbsolute())); + r.setAbsolute(Math.max(changeA.getAbsolute(), changeB.getAbsolute())); + r.setMinRelative(Math.min(changeA.getRelative(), changeB.getRelative())); + r.setRelative(Math.max(changeA.getRelative(), changeB.getRelative())); + r.setMinTheoretical(Math.min(changeA.getTheoretical(), changeB.getTheoretical())); + r.setTheoretical(Math.max(changeA.getTheoretical(), changeB.getTheoretical())); + r.setStat(changeA.getStat()); - final int avg = (a.getPositivity().ordinal() + b.getPositivity().ordinal()) / 2; + final int avg = (changeA.getPositivity().ordinal() + changeB.getPositivity().ordinal()) / 2; r.setPositivity(Positivity.values()[avg]); return r; } - - private String concat(String a, String b) - { - // If they share a operator, strip b's duplicate - if (a.length() > 1 && b.length() > 1) - { - final char a0 = a.charAt(0); - if ((a0 == '+' || a0 == '-' || a0 == '±') && b.charAt(0) == a0) - { - b = b.substring(1); - } - } - - return a + "~" + b; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatChange.java new file mode 100644 index 0000000000..90b614bf10 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatChange.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016-2019, Jordan Atwood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.itemstats; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * A stat change which can result in different magnitudes of change to the stat + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class RangeStatChange extends StatChange +{ + /** + * Minimum relative change that will occur if the stat boost is applied now. + * In this class, {@code relative} is representative of the maximum relative change that will + * occur. + */ + private int minRelative; + + /** + * Minimum theoretical change that can occur before boost cap is enforced. + * In this class, {@code theoretical} is representative of the maximum theoretical change that + * will occur. + */ + private int minTheoretical; + + /** + * Minimum absolute total of the stat after applying the boost. + * In this class, {@code absolute} is representative of the maximum absolute change that will + * occur. + */ + private int minAbsolute; + + /** + * Returns a human-readable formatted relative boost. + * Should be the boost range in the format "±N" (for minimum -N and maximum +N values), + * "+MIN~MAX" (for minimum and maximum values of the same sign), + * "-MIN~+MAX" (for negative minimum and positive maximum values), or + * "+MAX" (for equal minimum and maximum values). + * + * @return The formatted relative boost amount + */ + @Override + public String getFormattedRelative() + { + return concat(minRelative, getRelative()); + } + + /** + * Returns a human-readable formatted theoretical boost. + * Should be the boost range in the format "±N" (for minimum -N and maximum +N values), + * "+MIN~MAX" (for minimum and maximum values of the same sign), + * "-MIN~+MAX" (for negative minimum and positive maximum values), or + * "+MAX" (for equal minimum and maximum values). + * + * @return The formatted theoretical boost amount + */ + @Override + public String getFormattedTheoretical() + { + return concat(minTheoretical, getTheoretical()); + } + + private static String concat(int changeA, int changeB) + { + if (changeA == changeB) + { + return formatBoost(changeA); + } + else if (changeA * -1 == changeB) + { + return "±" + Math.abs(changeA); + } + + final StringBuilder sb = new StringBuilder(); + + sb.append(String.format("%+d", changeA)); + sb.append('~'); + + // If they share a operator, strip b's duplicate + if (changeA < 0 && changeB < 0 + || changeA >= 0 && changeB >= 0) + { + sb.append(Math.abs(changeB)); + } + else + { + sb.append(String.format("%+d", changeB)); + } + + return sb.toString(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java index 1bc59d7412..cc5f7797f2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java @@ -88,10 +88,9 @@ public abstract class StatBoost extends SingleEffect { out.setPositivity(Positivity.WORSE); } - out.setAbsolute(Integer.toString(newValue)); - out.setRelative(String.format("%+d", delta)); - out.setTheoretical(String.format("%+d", calcedDelta)); + out.setAbsolute(newValue); + out.setRelative(delta); + out.setTheoretical(calcedDelta); return out; } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java index 3157748083..e9453984f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java @@ -40,23 +40,48 @@ public class StatChange /** * Relative change that will occur if the stat boost is applied now. - * Should be a number prefixed by "+" or "-". */ - private String relative; + private int relative; /** * Theoretical change that can occur before boost cap is enforced. - * Should be a number prefixed by "+" or "-". */ - private String theoretical; + private int theoretical; /** * Absolute total of the stat after applying the boost. */ - private String absolute; + private int absolute; /** * How beneficial this stat boost will be to the player. */ private Positivity positivity; + + /** + * Returns a human-readable formatted relative boost. + * Should be the boost amount prefixed by "+" or "-". + * + * @return The formatted relative boost amount + */ + public String getFormattedRelative() + { + return formatBoost(relative); + } + + /** + * Returns a human-readable formatted theoretical boost. + * Should be the boost amount prefixed by "+" or "-". + * + * @return The formatted theoretical boost amount + */ + public String getFormattedTheoretical() + { + return formatBoost(theoretical); + } + + static String formatBoost(int boost) + { + return String.format("%+d", boost); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/CastleWarsBandage.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/CastleWarsBandage.java new file mode 100644 index 0000000000..e66f9ed709 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/CastleWarsBandage.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019, Giovds + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.itemstats.special; + +import com.google.common.collect.ImmutableSet; +import java.util.Comparator; +import java.util.stream.Stream; +import net.runelite.api.Client; +import net.runelite.api.EquipmentInventorySlot; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.api.ItemID; +import static net.runelite.client.plugins.itemstats.Builders.heal; +import static net.runelite.client.plugins.itemstats.Builders.perc; +import net.runelite.client.plugins.itemstats.Effect; +import net.runelite.client.plugins.itemstats.StatChange; +import net.runelite.client.plugins.itemstats.StatsChanges; +import static net.runelite.client.plugins.itemstats.stats.Stats.HITPOINTS; +import static net.runelite.client.plugins.itemstats.stats.Stats.RUN_ENERGY; + +public class CastleWarsBandage implements Effect +{ + private static final ImmutableSet BRACELETS = ImmutableSet.of( + ItemID.CASTLE_WARS_BRACELET1, ItemID.CASTLE_WARS_BRACELET2, ItemID.CASTLE_WARS_BRACELET3 + ); + + private static final double BASE_HP_PERC = .10; + private static final double BRACELET_HP_PERC = .50; + + @Override + public StatsChanges calculate(Client client) + { + final ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT); + final double percH = hasBracelet(equipmentContainer) ? BRACELET_HP_PERC : BASE_HP_PERC; + final StatChange hitPoints = heal(HITPOINTS, perc(percH, 0)).effect(client); + final StatChange runEnergy = heal(RUN_ENERGY, 30).effect(client); + final StatsChanges changes = new StatsChanges(2); + changes.setStatChanges(new StatChange[]{hitPoints, runEnergy}); + changes.setPositivity(Stream.of(changes.getStatChanges()) + .map(StatChange::getPositivity) + .max(Comparator.comparing(Enum::ordinal)).get()); + + return changes; + } + + private boolean hasBracelet(ItemContainer equipmentContainer) + { + if (equipmentContainer == null) + { + return false; + } + + final Item[] equipment = equipmentContainer.getItems(); + + if (equipment.length > EquipmentInventorySlot.GLOVES.getSlotIdx()) + { + return BRACELETS.contains(equipment[EquipmentInventorySlot.GLOVES.getSlotIdx()].getId()); + } + + return false; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java index 8dab7fd601..7eee548751 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java @@ -132,11 +132,14 @@ public class SpicyStew implements Effect int currentBoost = currentValue - currentBase; // Can be negative int spiceBoostCapped = (currentBoost <= 0) ? spiceBoost : Math.max(0, spiceBoost - currentBoost); - StatChange change = new StatChange(); + final RangeStatChange change = new RangeStatChange(); change.setStat(stat); - change.setRelative("±" + spiceBoostCapped); - change.setTheoretical("±" + spiceBoost); - change.setAbsolute(String.valueOf(stat.getValue(client) + spiceBoostCapped)); + change.setMinRelative(-spiceBoost); + change.setRelative(spiceBoostCapped); + change.setMinTheoretical(-spiceBoost); + change.setTheoretical(spiceBoost); + change.setMinAbsolute(Math.max(-spiceBoost, -currentValue)); + change.setAbsolute(stat.getValue(client) + spiceBoostCapped); Positivity positivity; if (spiceBoostCapped == 0) @@ -155,5 +158,4 @@ public class SpicyStew implements Effect return change; } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomCounter.java index 7dc6aabf35..8a2871125f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomCounter.java @@ -32,9 +32,9 @@ public class KingdomCounter extends Counter { private final KingdomPlugin plugin; - public KingdomCounter(BufferedImage image, KingdomPlugin plugin) + KingdomCounter(BufferedImage image, KingdomPlugin plugin) { - super(image, plugin, String.valueOf(plugin.getFavor())); + super(image, plugin, plugin.getFavor()); this.plugin = plugin; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java index 974ef66f78..49f6ccf7f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Book.java @@ -59,7 +59,7 @@ enum Book TRISTESSAS_TRAGEDY(ItemID.TRISTESSAS_TRAGEDY, "Tristessa's Tragedy", "The Tragedy of Tristessa."), TREACHERY_OF_ROYALTY(ItemID.TREACHERY_OF_ROYALTY, "The Treachery of Royalty", "The Treachery of Royalty, by Professor Answith."), TRANSPORTATION_INCANTATIONS(ItemID.TRANSPORTATION_INCANTATIONS, "Transportation Incantations", "Transportation Incantations, by Amon Ducot."), - SOUL_JORUNEY(ItemID.SOUL_JOURNEY, "Soul Journey", "The Journey of Souls, by Aretha."), + SOUL_JOURNEY(ItemID.SOUL_JOURNEY, "Soul Journey", "The Journey of Souls, by Aretha."), VARLAMORE_ENVOY(ItemID.VARLAMORE_ENVOY, "Varlamore Envoy", "The Envoy to Varlamore, by Deryk Paulson."); private static final Map BY_ID = buildById(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryConfig.java index b61a24c139..6ec40a00fd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryConfig.java @@ -42,4 +42,14 @@ public interface KourendLibraryConfig extends Config { return true; } + + @ConfigItem( + keyName = "hideDuplicateBook", + name = "Hide duplicate book", + description = "Don't show the duplicate book locations in the library" + ) + default boolean hideDuplicateBook() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryOverlay.java index 3c6863af3a..5cf7910ee6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryOverlay.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import javax.annotation.Nullable; import lombok.AccessLevel; import lombok.Setter; import net.runelite.api.Client; @@ -54,15 +55,19 @@ class KourendLibraryOverlay extends Overlay private final static int MAXIMUM_DISTANCE = 24; private final Library library; private final Client client; + private final KourendLibraryConfig config; + private final KourendLibraryPlugin plugin; @Setter(AccessLevel.PACKAGE) private boolean hidden; @Inject - private KourendLibraryOverlay(Library library, Client client) + private KourendLibraryOverlay(Library library, Client client, KourendLibraryConfig config, KourendLibraryPlugin plugin) { this.library = library; this.client = client; + this.config = config; + this.plugin = plugin; setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_SCENE); @@ -133,7 +138,7 @@ class KourendLibraryOverlay extends Overlay Color color = bookIsKnown ? Color.ORANGE : Color.WHITE; // Render the poly on the floor - if (!(bookIsKnown && book == null) && (library.getState() == SolvedState.NO_DATA || book != null || !possible.isEmpty())) + if (!(bookIsKnown && book == null) && (library.getState() == SolvedState.NO_DATA || book != null || !possible.isEmpty()) && !shouldHideOverlayIfDuplicateBook(book)) { Polygon poly = getCanvasTilePoly(client, localBookcase); if (poly != null) @@ -146,7 +151,7 @@ class KourendLibraryOverlay extends Overlay // If the book is singled out, render the text and the book's icon if (bookIsKnown) { - if (book != null) + if (book != null && !shouldHideOverlayIfDuplicateBook(book)) { FontMetrics fm = g.getFontMetrics(); Rectangle2D bounds = fm.getStringBounds(book.getShortName(), g); @@ -216,9 +221,10 @@ class KourendLibraryOverlay extends Overlay .forEach(n -> { Book b = library.getCustomerBook(); + boolean doesPlayerContainBook = b != null && plugin.doesPlayerContainBook(b); LocalPoint local = n.getLocalLocation(); Polygon poly = getCanvasTilePoly(client, local); - OverlayUtil.renderPolygon(g, poly, Color.WHITE); + OverlayUtil.renderPolygon(g, poly, doesPlayerContainBook ? Color.GREEN : Color.WHITE); Point screen = Perspective.localToCanvas(client, local, client.getPlane(), n.getLogicalHeight()); if (screen != null) { @@ -229,4 +235,12 @@ class KourendLibraryOverlay extends Overlay return null; } + + private boolean shouldHideOverlayIfDuplicateBook(@Nullable Book book) + { + return config.hideDuplicateBook() + && book != null + && !book.isDarkManuscript() + && plugin.doesPlayerContainBook(book); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java index 73602299f4..649189fc47 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java @@ -26,6 +26,7 @@ package net.runelite.client.plugins.kourendlibrary; import com.google.inject.Provides; import java.awt.image.BufferedImage; +import java.util.EnumSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; @@ -34,6 +35,9 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.AnimationID; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; import net.runelite.api.MenuAction; import net.runelite.api.Player; import net.runelite.api.coords.WorldPoint; @@ -41,6 +45,7 @@ import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; @@ -94,6 +99,7 @@ public class KourendLibraryPlugin extends Plugin private boolean buttonAttached = false; private WorldPoint lastBookcaseClick = null; private WorldPoint lastBookcaseAnimatedOn = null; + private EnumSet playerBooks = null; @Provides KourendLibraryConfig provideConfig(ConfigManager configManager) @@ -120,6 +126,8 @@ public class KourendLibraryPlugin extends Plugin overlayManager.add(overlay); + updatePlayerBooks(); + if (!config.hideButton()) { clientToolbar.addNavigation(navButton); @@ -135,6 +143,7 @@ public class KourendLibraryPlugin extends Plugin buttonAttached = false; lastBookcaseClick = null; lastBookcaseAnimatedOn = null; + playerBooks = null; } @Subscribe @@ -271,4 +280,37 @@ public class KourendLibraryPlugin extends Plugin } } } + + @Subscribe + public void onItemContainerChanged(ItemContainerChanged itemContainerChangedEvent) + { + updatePlayerBooks(); + } + + boolean doesPlayerContainBook(Book book) + { + return playerBooks.contains(book); + } + + private void updatePlayerBooks() + { + ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY); + + if (itemContainer != null) + { + EnumSet books = EnumSet.noneOf(Book.class); + + for (Item item : itemContainer.getItems()) + { + Book book = Book.byId(item.getId()); + + if (book != null) + { + books.add(book); + } + } + + playerBooks = books; + } + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Library.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Library.java index 62ebba956f..02618031db 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Library.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/Library.java @@ -299,7 +299,7 @@ class Library DARK_MANUSCRIPT_13515, BYRNES_CORONATION_SPEECH, DARK_MANUSCRIPT_13517, - SOUL_JORUNEY, + SOUL_JOURNEY, DARK_MANUSCRIPT_13518, TRANSPORTATION_INCANTATIONS ), @@ -322,7 +322,7 @@ class Library DARK_MANUSCRIPT_13514, EATHRAM_RADA_EXTRACT, DARK_MANUSCRIPT_13522, - SOUL_JORUNEY, + SOUL_JOURNEY, WINTERTODT_PARABLE, TWILL_ACCORD, DARK_MANUSCRIPT_13515, @@ -348,7 +348,7 @@ class Library DARK_MANUSCRIPT_13519, BYRNES_CORONATION_SPEECH, DARK_MANUSCRIPT_13517, - SOUL_JORUNEY, + SOUL_JOURNEY, DARK_MANUSCRIPT_13522, WINTERTODT_PARABLE, TWILL_ACCORD, @@ -384,7 +384,7 @@ class Library TREACHERY_OF_ROYALTY, DARK_MANUSCRIPT_13518, TRANSPORTATION_INCANTATIONS, - SOUL_JORUNEY, + SOUL_JOURNEY, VARLAMORE_ENVOY ), Arrays.asList( @@ -409,7 +409,7 @@ class Library IDEOLOGY_OF_DARKNESS, WINTERTODT_PARABLE, TWILL_ACCORD, - SOUL_JORUNEY, + SOUL_JOURNEY, DARK_MANUSCRIPT_13515, EATHRAM_RADA_EXTRACT, DARK_MANUSCRIPT_13518, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java index 279251e1c9..4da52e1492 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java @@ -36,7 +36,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.SessionOpen; +import net.runelite.client.events.SessionOpen; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyListener; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java index 98b7053117..bba5994d89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java @@ -51,11 +51,23 @@ public interface LootTrackerConfig extends Config @ConfigItem( keyName = "saveLoot", - name = "Save loot", - description = "Save loot between client sessions (requires being logged in)" + name = "Submit loot tracker data", + description = "Submit loot tracker data (requires being logged in)" ) default boolean saveLoot() { return true; } + + @ConfigItem( + keyName = "syncPanel", + name = "Synchronize panel contents", + description = "Synchronize you local loot tracker with your online (requires being logged in). This means" + + " that panel is filled with portion of your remote data on startup and deleting data in panel deletes them" + + " also on server." + ) + default boolean syncPanel() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index 4aaa7e0c7a..ed850cdcbb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -99,6 +99,7 @@ class LootTrackerPanel extends PluginPanel private final ItemManager itemManager; private final LootTrackerPlugin plugin; + private final LootTrackerConfig config; private boolean groupLoot; private boolean hideIgnoredItems; @@ -130,10 +131,11 @@ class LootTrackerPanel extends PluginPanel INVISIBLE_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(invisibleImg, -220)); } - LootTrackerPanel(final LootTrackerPlugin plugin, final ItemManager itemManager) + LootTrackerPanel(final LootTrackerPlugin plugin, final ItemManager itemManager, final LootTrackerConfig config) { this.itemManager = itemManager; this.plugin = plugin; + this.config = config; this.hideIgnoredItems = true; setBorder(new EmptyBorder(6, 6, 6, 6)); @@ -297,7 +299,7 @@ class LootTrackerPanel extends PluginPanel // Delete all loot, or loot matching the current view LootTrackerClient client = plugin.getLootTrackerClient(); - if (client != null) + if (client != null && config.syncPanel()) { client.delete(currentView); } @@ -472,7 +474,7 @@ class LootTrackerPanel extends PluginPanel LootTrackerClient client = plugin.getLootTrackerClient(); // Without loot being grouped we have no way to identify single kills to be deleted - if (client != null && groupLoot) + if (client != null && groupLoot && config.syncPanel()) { client.delete(box.getId()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index acb725db64..ec2bf74aad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -25,9 +25,13 @@ */ package net.runelite.client.plugins.loottracker; +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import com.google.common.collect.Multisets; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.io.IOException; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -54,8 +58,7 @@ import net.runelite.api.SpriteID; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; -import net.runelite.api.events.SessionClose; -import net.runelite.api.events.SessionOpen; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.WidgetID; import net.runelite.client.account.AccountSession; @@ -65,6 +68,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.NpcLootReceived; import net.runelite.client.events.PlayerLootReceived; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemStack; import net.runelite.client.game.SpriteManager; @@ -92,6 +97,10 @@ public class LootTrackerPlugin extends Plugin private static final Pattern CLUE_SCROLL_PATTERN = Pattern.compile("You have completed [0-9]+ ([a-z]+) Treasure Trails."); private static final int THEATRE_OF_BLOOD_REGION = 12867; + // Brimstone loot handling + private static final String BRIMSTONE_CHEST_MESSAGE = "You find some treasure in the chest!"; + private static final String BRIMSTONE_CHEST_EVENT_TYPE = "Brimstone Chest"; + @Inject private ClientToolbar clientToolbar; @@ -122,6 +131,8 @@ public class LootTrackerPlugin extends Plugin private List ignoredItems = new ArrayList<>(); + private Multiset inventorySnapshot; + @Getter(AccessLevel.PACKAGE) private LootTrackerClient lootTrackerClient; @@ -194,7 +205,7 @@ public class LootTrackerPlugin extends Plugin protected void startUp() throws Exception { ignoredItems = Text.fromCSV(config.getIgnoredItems()); - panel = new LootTrackerPanel(this, itemManager); + panel = new LootTrackerPanel(this, itemManager, config); spriteManager.getSpriteAsync(SpriteID.TAB_INVENTORY, 0, panel::loadHeaderIcon); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); @@ -226,9 +237,8 @@ public class LootTrackerPlugin extends Plugin { Collection lootRecords; - if (!config.saveLoot()) + if (!config.syncPanel()) { - // don't load loot if we're not saving loot return; } @@ -274,7 +284,7 @@ public class LootTrackerPlugin extends Plugin if (lootTrackerClient != null && config.saveLoot()) { - LootRecord lootRecord = new LootRecord(name, LootRecordType.NPC, toGameItems(items)); + LootRecord lootRecord = new LootRecord(name, LootRecordType.NPC, toGameItems(items), Instant.now()); lootTrackerClient.submit(lootRecord); } } @@ -291,7 +301,7 @@ public class LootTrackerPlugin extends Plugin if (lootTrackerClient != null && config.saveLoot()) { - LootRecord lootRecord = new LootRecord(name, LootRecordType.PLAYER, toGameItems(items)); + LootRecord lootRecord = new LootRecord(name, LootRecordType.PLAYER, toGameItems(items), Instant.now()); lootTrackerClient.submit(lootRecord); } } @@ -350,7 +360,7 @@ public class LootTrackerPlugin extends Plugin if (lootTrackerClient != null && config.saveLoot()) { - LootRecord lootRecord = new LootRecord(eventType, LootRecordType.EVENT, toGameItems(items)); + LootRecord lootRecord = new LootRecord(eventType, LootRecordType.EVENT, toGameItems(items), Instant.now()); lootTrackerClient.submit(lootRecord); } } @@ -363,8 +373,25 @@ public class LootTrackerPlugin extends Plugin return; } + final String message = event.getMessage(); + + if (message.equals(BRIMSTONE_CHEST_MESSAGE)) + { + eventType = BRIMSTONE_CHEST_EVENT_TYPE; + + final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY); + if (itemContainer != null) + { + inventorySnapshot = HashMultiset.create(); + Arrays.stream(itemContainer.getItems()) + .forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity())); + } + + return; + } + // Check if message is for a clue scroll reward - final Matcher m = CLUE_SCROLL_PATTERN.matcher(Text.removeTags(event.getMessage())); + final Matcher m = CLUE_SCROLL_PATTERN.matcher(Text.removeTags(message)); if (m.find()) { final String type = m.group(1).toLowerCase(); @@ -389,6 +416,50 @@ public class LootTrackerPlugin extends Plugin } } + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) + { + if (eventType == null || !eventType.equals(BRIMSTONE_CHEST_EVENT_TYPE)) + { + return; + } + + if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY)) + { + return; + } + + processBrimstoneChestLoot(event.getItemContainer()); + eventType = null; + } + + private void processBrimstoneChestLoot(ItemContainer inventoryContainer) + { + if (inventorySnapshot != null) + { + Multiset currentInventory = HashMultiset.create(); + Arrays.stream(inventoryContainer.getItems()) + .forEach(item -> currentInventory.add(item.getId(), item.getQuantity())); + + final Multiset diff = Multisets.difference(currentInventory, inventorySnapshot); + + List items = diff.entrySet().stream() + .map(e -> new ItemStack(e.getElement(), e.getCount(), client.getLocalPlayer().getLocalLocation())) + .collect(Collectors.toList()); + + final LootTrackerItem[] entries = buildEntries(stack(items)); + SwingUtilities.invokeLater(() -> panel.add(BRIMSTONE_CHEST_EVENT_TYPE, -1, entries)); + + if (lootTrackerClient != null && config.saveLoot()) + { + LootRecord lootRecord = new LootRecord(BRIMSTONE_CHEST_EVENT_TYPE, LootRecordType.EVENT, toGameItems(items), Instant.now()); + lootTrackerClient.submit(lootRecord); + } + + inventorySnapshot = null; + } + } + void toggleItem(String name, boolean ignore) { final Set ignoredItemSet = new HashSet<>(ignoredItems); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index f2030bd47d..23ab63df16 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -92,6 +92,16 @@ public interface MenuEntrySwapperConfig extends Config return false; } + @ConfigItem( + keyName = "swapContract", + name = "Contract", + description = "Swap Talk-to with Contract on Guildmaster Jane" + ) + default boolean swapContract() + { + return true; + } + @ConfigItem( keyName = "swapChase", name = "Chase", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index e6420bdc99..b164d10b86 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -45,8 +45,10 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PostItemComposition; import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemVariationMapping; import net.runelite.client.input.KeyManager; import net.runelite.client.menus.MenuManager; @@ -101,6 +103,9 @@ public class MenuEntrySwapperPlugin extends Plugin @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private MenuEntrySwapperConfig config; @@ -116,6 +121,9 @@ public class MenuEntrySwapperPlugin extends Plugin @Inject private MenuManager menuManager; + @Inject + private ItemManager itemManager; + @Getter private boolean configuringShiftClick = false; @@ -146,6 +154,11 @@ public class MenuEntrySwapperPlugin extends Plugin @Subscribe public void onConfigChanged(ConfigChanged event) { + if (!CONFIG_GROUP.equals(event.getGroup())) + { + return; + } + if (event.getKey().equals("shiftClickCustomization")) { if (config.shiftClickCustomization()) @@ -157,6 +170,16 @@ public class MenuEntrySwapperPlugin extends Plugin disableCustomization(); } } + else if (event.getKey().startsWith(ITEM_KEY_PREFIX)) + { + clientThread.invoke(this::resetItemCompositionCache); + } + } + + private void resetItemCompositionCache() + { + itemManager.invalidateItemCompositionCache(); + client.getItemCompositionCache().reset(); } private Integer getSwapConfig(int itemId) @@ -179,6 +202,7 @@ public class MenuEntrySwapperPlugin extends Plugin private void unsetSwapConfig(int itemId) { + itemId = ItemVariationMapping.map(itemId); configManager.unsetConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId); } @@ -186,6 +210,7 @@ public class MenuEntrySwapperPlugin extends Plugin { keyManager.registerKeyListener(inputListener); refreshShiftClickCustomizationMenus(); + clientThread.invoke(this::resetItemCompositionCache); } private void disableCustomization() @@ -193,6 +218,7 @@ public class MenuEntrySwapperPlugin extends Plugin keyManager.unregisterKeyListener(inputListener); removeShiftClickCustomizationMenus(); configuringShiftClick = false; + clientThread.invoke(this::resetItemCompositionCache); } @Subscribe @@ -290,7 +316,6 @@ public class MenuEntrySwapperPlugin extends Plugin if (option.equals(RESET) && target.equals(MENU_TARGET)) { unsetSwapConfig(itemId); - itemComposition.resetShiftClickActionIndex(); return; } @@ -323,7 +348,6 @@ public class MenuEntrySwapperPlugin extends Plugin if (valid) { setSwapConfig(itemId, index); - itemComposition.setShiftClickActionIndex(index); } } @@ -364,6 +388,11 @@ public class MenuEntrySwapperPlugin extends Plugin swap("bank", option, target, true); } + if (config.swapContract()) + { + swap("contract", option, target, true); + } + if (config.swapExchange()) { swap("exchange", option, target, true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardCounter.java index 83e74cc6d6..ecfbafd544 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardCounter.java @@ -31,22 +31,15 @@ import net.runelite.client.ui.overlay.infobox.Counter; public class GraveyardCounter extends Counter { - private int count; - - public GraveyardCounter(BufferedImage image, Plugin plugin) + GraveyardCounter(BufferedImage image, Plugin plugin) { - super(image, plugin, "0"); - } - - public void setCount(int count) - { - this.count = count; - this.setText(String.valueOf(count)); + super(image, plugin, 0); } @Override public Color getTextColor() { + int count = getCount(); if (count >= GraveyardRoom.MIN_SCORE) { return Color.GREEN; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java new file mode 100644 index 0000000000..ecef015bd7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2019, Shaun Dreclin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.musicindicator; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.inject.Inject; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.EnumComposition; +import net.runelite.api.EnumID; +import net.runelite.api.VarPlayer; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.VarbitChanged; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "Music Track Indicator", + description = "Show chat notifications when unlocking music tracks" +) +public class MusicIndicatorPlugin extends Plugin +{ + private static final List MUSIC_TRACK_VARPS = ImmutableList.of( + VarPlayer.MUSIC_TRACKS_UNLOCKED_1, VarPlayer.MUSIC_TRACKS_UNLOCKED_2, VarPlayer.MUSIC_TRACKS_UNLOCKED_3, + VarPlayer.MUSIC_TRACKS_UNLOCKED_4, VarPlayer.MUSIC_TRACKS_UNLOCKED_5, VarPlayer.MUSIC_TRACKS_UNLOCKED_6, + VarPlayer.MUSIC_TRACKS_UNLOCKED_7, VarPlayer.MUSIC_TRACKS_UNLOCKED_8, VarPlayer.MUSIC_TRACKS_UNLOCKED_9, + VarPlayer.MUSIC_TRACKS_UNLOCKED_10, VarPlayer.MUSIC_TRACKS_UNLOCKED_11, VarPlayer.MUSIC_TRACKS_UNLOCKED_12, + VarPlayer.MUSIC_TRACKS_UNLOCKED_13, VarPlayer.MUSIC_TRACKS_UNLOCKED_14, VarPlayer.MUSIC_TRACKS_UNLOCKED_15, + VarPlayer.MUSIC_TRACKS_UNLOCKED_16, VarPlayer.MUSIC_TRACKS_UNLOCKED_17, VarPlayer.MUSIC_TRACKS_UNLOCKED_18, + VarPlayer.MUSIC_TRACKS_UNLOCKED_19 + ); + + private static final Map VARP_INDEX_TO_VARPLAYER = MUSIC_TRACK_VARPS.stream() + .collect(Collectors.collectingAndThen(Collectors.toMap(VarPlayer::getId, Function.identity()), + ImmutableMap::copyOf)); + + @Inject + private Client client; + + @Inject + private ChatMessageManager chatMessageManager; + + // Mapping of relevant varps to their values, used to compare against new values + private final Map musicTrackVarpValues = new HashMap<>(); + + private boolean loggingIn; + + @Override + public void startUp() + { + loggingIn = true; + } + + @Override + public void shutDown() + { + musicTrackVarpValues.clear(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + switch (event.getGameState()) + { + case LOGGING_IN: + case CONNECTION_LOST: + case HOPPING: + musicTrackVarpValues.clear(); + loggingIn = true; + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (!loggingIn) + { + return; + } + + loggingIn = false; + + for (VarPlayer musicTrackVarp : MUSIC_TRACK_VARPS) + { + int value = client.getVar(musicTrackVarp); + musicTrackVarpValues.put(musicTrackVarp, value); + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + int idx = event.getIndex(); + + VarPlayer varPlayer = VARP_INDEX_TO_VARPLAYER.get(idx); + if (varPlayer == null) + { + return; + } + + // Old varplayer values have not been initialized yet + if (musicTrackVarpValues.isEmpty()) + { + return; + } + + assert musicTrackVarpValues.containsKey(varPlayer); + + int newValue = client.getVar(varPlayer); + int oldValue = musicTrackVarpValues.put(varPlayer, newValue); + int musicTracksUnlocked = ~oldValue & newValue; + + if (musicTracksUnlocked == 0) + { + return; + } + + final EnumComposition names = client.getEnum(EnumID.MUSIC_TRACK_NAMES); + final int varpId = MUSIC_TRACK_VARPS.indexOf(varPlayer) + 1; + + for (int bit = 0; bit < Integer.SIZE; ++bit) + { + if ((musicTracksUnlocked & (1 << bit)) == 0) + { + continue; + } + + int musicTrackId = getTrackId(varpId, bit); + String musicTrackName = names.getStringValue(musicTrackId); + + sendChatMessage("You have unlocked a new music track: " + musicTrackName + "."); + } + } + + /** + * Get the id for a track identified by the given varp and a bit index + * @param variableId + * @param bit + * @return + */ + private int getTrackId(int variableId, int bit) + { + // values are packed into a coordgrid + int packed = (variableId << 14) | bit; + EnumComposition ids = client.getEnum(EnumID.MUSIC_TRACK_IDS); + for (int key : ids.getKeys()) + { + int value = ids.getIntValue(key); + if (value == packed) + { + return key; + } + } + return -1; + } + + private void sendChatMessage(String chatMessage) + { + final String message = new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append(chatMessage) + .build(); + + chatMessageManager.queue( + QueuedMessage.builder() + .type(ChatMessageType.GAME) + .runeLiteFormattedMessage(message) + .build()); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java index 05d1498312..4671edde12 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java @@ -26,43 +26,27 @@ package net.runelite.client.plugins.nightmarezone; import java.awt.Color; import java.awt.image.BufferedImage; -import lombok.Getter; import lombok.Setter; import net.runelite.client.plugins.Plugin; import net.runelite.client.ui.overlay.infobox.Counter; +@Setter public class AbsorptionCounter extends Counter { - private int absorption; - - @Getter - @Setter private int threshold; - - @Getter - @Setter private Color aboveThresholdColor = Color.GREEN; - - @Getter - @Setter private Color belowThresholdColor = Color.RED; - public AbsorptionCounter(BufferedImage image, Plugin plugin, int absorption, int threshold) + AbsorptionCounter(BufferedImage image, Plugin plugin, int absorption, int threshold) { - super(image, plugin, ""); + super(image, plugin, absorption); this.threshold = threshold; - setAbsorption(absorption); - } - - public void setAbsorption(int absorption) - { - this.absorption = absorption; - setText(String.valueOf(absorption)); } @Override public Color getTextColor() { + int absorption = getCount(); if (absorption >= threshold) { return aboveThresholdColor; @@ -76,6 +60,7 @@ public class AbsorptionCounter extends Counter @Override public String getTooltip() { + int absorption = getCount(); return "Absorption: " + absorption; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index e2a123b1af..71ae196d3e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -129,7 +129,7 @@ class NightmareZoneOverlay extends Overlay } else { - absorptionCounter.setAbsorption(absorptionPoints); + absorptionCounter.setCount(absorptionPoints); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index 69fa0b7164..3c409987af 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -33,6 +33,8 @@ import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -81,6 +83,13 @@ public class NightmareZonePlugin extends Plugin { overlayManager.remove(overlay); overlay.removeAbsorptionCounter(); + + Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); + + if (nmzWidget != null) + { + nmzWidget.setHidden(false); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java index fe0f7e65d3..0b23ac8eb2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.notes; import com.google.inject.Provides; import java.awt.image.BufferedImage; import javax.inject.Inject; -import net.runelite.api.events.SessionOpen; +import net.runelite.client.events.SessionOpen; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java index d4c8c356ec..6c41b2f24d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java @@ -46,6 +46,7 @@ import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.Text; public class NpcSceneOverlay extends Overlay { @@ -87,7 +88,7 @@ public class NpcSceneOverlay extends Overlay for (NPC npc : plugin.getHighlightedNpcs()) { - renderNpcOverlay(graphics, npc, npc.getName(), config.getHighlightColor()); + renderNpcOverlay(graphics, npc, config.getHighlightColor()); } return null; @@ -143,7 +144,7 @@ public class NpcSceneOverlay extends Overlay } } - private void renderNpcOverlay(Graphics2D graphics, NPC actor, String name, Color color) + private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color) { switch (config.renderStyle()) { @@ -176,11 +177,12 @@ public class NpcSceneOverlay extends Overlay if (config.drawNames()) { - Point textLocation = actor.getCanvasTextLocation(graphics, name, actor.getLogicalHeight() + 40); + String npcName = Text.removeTags(actor.getName()); + Point textLocation = actor.getCanvasTextLocation(graphics, npcName, actor.getLogicalHeight() + 40); if (textLocation != null) { - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + OverlayUtil.renderTextLocation(graphics, textLocation, npcName, color); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java new file mode 100644 index 0000000000..7194d2ddd6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/AggressionTimer.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018, Woox + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.npcunaggroarea; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import lombok.Getter; +import lombok.Setter; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.infobox.Timer; + +class AggressionTimer extends Timer +{ + @Getter + @Setter + private boolean visible; + + AggressionTimer(Duration duration, BufferedImage image, Plugin plugin, boolean visible) + { + super(duration.toMillis(), ChronoUnit.MILLIS, image, plugin); + setTooltip("Time until NPCs become unaggressive"); + this.visible = visible; + } + + @Override + public Color getTextColor() + { + Duration timeLeft = Duration.between(Instant.now(), getEndTime()); + + if (timeLeft.getSeconds() < 60) + { + return Color.RED.brighter(); + } + + return Color.WHITE; + } + + @Override + public boolean render() + { + return visible && super.render(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java new file mode 100644 index 0000000000..a0e4992e31 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaConfig.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, Woox + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.npcunaggroarea; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("npcUnaggroArea") +public interface NpcAggroAreaConfig extends Config +{ + String CONFIG_GROUP = "npcUnaggroArea"; + String CONFIG_CENTER1 = "center1"; + String CONFIG_CENTER2 = "center2"; + String CONFIG_LOCATION = "location"; + String CONFIG_DURATION = "duration"; + + @ConfigItem( + keyName = "npcUnaggroAlwaysActive", + name = "Always active", + description = "Always show this plugins overlays
Otherwise, they will only be shown when any NPC name matches the list", + position = 1 + ) + default boolean alwaysActive() + { + return false; + } + + @ConfigItem( + keyName = "npcUnaggroNames", + name = "NPC names", + description = "Enter names of NPCs where you wish to use this plugin", + position = 2 + ) + default String npcNamePatterns() + { + return ""; + } + + @ConfigItem( + keyName = "npcUnaggroShowTimer", + name = "Show timer", + description = "Display a timer until NPCs become unaggressive", + position = 3 + ) + default boolean showTimer() + { + return true; + } + + @ConfigItem( + keyName = "npcUnaggroShowAreaLines", + name = "Show area lines", + description = "Display lines, when walked past, the unaggressive timer resets", + position = 4 + ) + default boolean showAreaLines() + { + return false; + } + + @ConfigItem( + keyName = "npcUnaggroAreaColor", + name = "Area lines colour", + description = "Choose colour to use for marking NPC unaggressive area", + position = 5 + ) + default Color aggroAreaColor() + { + return Color.YELLOW; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaNotWorkingOverlay.java similarity index 53% rename from runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java rename to runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaNotWorkingOverlay.java index 5e66876bce..0a9dedb357 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPointsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaNotWorkingOverlay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Kamiel + * Copyright (c) 2018, Woox * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,73 +22,45 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.client.plugins.raids; +package net.runelite.client.plugins.npcunaggroarea; +import com.google.inject.Inject; import java.awt.Dimension; import java.awt.Graphics2D; -import javax.inject.Inject; -import net.runelite.api.Client; -import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; -import net.runelite.api.Varbits; -import static net.runelite.client.plugins.raids.RaidsPlugin.POINTS_FORMAT; import net.runelite.client.ui.overlay.Overlay; -import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; -import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; -public class RaidsPointsOverlay extends Overlay +class NpcAggroAreaNotWorkingOverlay extends Overlay { - @Inject - private Client client; + private final NpcAggroAreaPlugin plugin; + private final PanelComponent panelComponent; @Inject - private RaidsPlugin plugin; - - private final PanelComponent panel = new PanelComponent(); - - @Inject - private RaidsPointsOverlay(RaidsPlugin plugin) + private NpcAggroAreaNotWorkingOverlay(NpcAggroAreaPlugin plugin) { - super(plugin); - setPosition(OverlayPosition.TOP_RIGHT); - setPriority(OverlayPriority.HIGH); - getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay")); + this.plugin = plugin; + + panelComponent = new PanelComponent(); + panelComponent.setPreferredSize(new Dimension(150, 0)); + panelComponent.getChildren().add(LineComponent.builder() + .left("Unaggressive NPC timers will start working when you teleport far away or enter a dungeon.") + .build()); + + setPriority(OverlayPriority.LOW); + setPosition(OverlayPosition.TOP_LEFT); } @Override public Dimension render(Graphics2D graphics) { - if (!plugin.isInRaidChambers()) + if (!plugin.isActive() || plugin.getSafeCenters()[1] != null) { return null; } - int totalPoints = client.getVar(Varbits.TOTAL_POINTS); - int personalPoints = client.getVar(Varbits.PERSONAL_POINTS); - int partySize = client.getVar(Varbits.RAID_PARTY_SIZE); - - panel.getChildren().clear(); - panel.getChildren().add(LineComponent.builder() - .left("Total:") - .right(POINTS_FORMAT.format(totalPoints)) - .build()); - - panel.getChildren().add(LineComponent.builder() - .left(client.getLocalPlayer().getName() + ":") - .right(POINTS_FORMAT.format(personalPoints)) - .build()); - - if (partySize > 1) - { - panel.getChildren().add(LineComponent.builder() - .left("Party size:") - .right(String.valueOf(partySize)) - .build()); - } - - return panel.render(graphics); + return panelComponent.render(graphics); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java new file mode 100644 index 0000000000..811952de57 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaOverlay.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2018, Woox + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.npcunaggroarea; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.GeneralPath; +import java.time.Instant; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.geometry.Geometry; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; + +class NpcAggroAreaOverlay extends Overlay +{ + private static final int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE; + + private final Client client; + private final NpcAggroAreaConfig config; + private final NpcAggroAreaPlugin plugin; + + @Inject + private NpcAggroAreaOverlay(Client client, NpcAggroAreaConfig config, NpcAggroAreaPlugin plugin) + { + this.client = client; + this.config = config; + this.plugin = plugin; + + setLayer(OverlayLayer.ABOVE_SCENE); + setPriority(OverlayPriority.LOW); + setPosition(OverlayPosition.DYNAMIC); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!plugin.isActive() || plugin.getSafeCenters()[1] == null) + { + return null; + } + + GeneralPath lines = plugin.getLinesToDisplay()[client.getPlane()]; + if (lines == null) + { + return null; + } + + Color outlineColor = config.aggroAreaColor(); + AggressionTimer timer = plugin.getCurrentTimer(); + if (timer == null || Instant.now().compareTo(timer.getEndTime()) < 0) + { + outlineColor = new Color( + outlineColor.getRed(), + outlineColor.getGreen(), + outlineColor.getBlue(), + 100); + } + + renderPath(graphics, lines, outlineColor); + return null; + } + + private void renderPath(Graphics2D graphics, GeneralPath path, Color color) + { + LocalPoint playerLp = client.getLocalPlayer().getLocalLocation(); + Rectangle viewArea = new Rectangle( + playerLp.getX() - MAX_LOCAL_DRAW_LENGTH, + playerLp.getY() - MAX_LOCAL_DRAW_LENGTH, + MAX_LOCAL_DRAW_LENGTH * 2, + MAX_LOCAL_DRAW_LENGTH * 2); + + graphics.setColor(color); + graphics.setStroke(new BasicStroke(1)); + + path = Geometry.clipPath(path, viewArea); + path = Geometry.filterPath(path, (p1, p2) -> + Perspective.localToCanvas(client, new LocalPoint((int)p1[0], (int)p1[1]), client.getPlane()) != null && + Perspective.localToCanvas(client, new LocalPoint((int)p2[0], (int)p2[1]), client.getPlane()) != null); + path = Geometry.transformPath(path, coords -> + { + Point point = Perspective.localToCanvas(client, new LocalPoint((int)coords[0], (int)coords[1]), client.getPlane()); + coords[0] = point.getX(); + coords[1] = point.getY(); + }); + + graphics.draw(path); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java new file mode 100644 index 0000000000..e1c1704762 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2018, Woox + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.npcunaggroarea; + +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.inject.Provides; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.geom.Area; +import java.awt.geom.GeneralPath; +import java.awt.image.BufferedImage; +import java.time.Duration; +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import javax.inject.Inject; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.Constants; +import net.runelite.api.ItemID; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.NpcSpawned; +import net.runelite.api.geometry.Geometry; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.WildcardMatcher; + +@Slf4j +@PluginDescriptor( + name = "NPC Aggression Timer", + description = "Highlights the unaggressive area of NPCs nearby and timer until it becomes active", + tags = {"highlight", "lines", "unaggro", "aggro", "aggressive", "npcs", "area", "slayer"}, + enabledByDefault = false +) +public class NpcAggroAreaPlugin extends Plugin +{ + /* + How it works: The game remembers 2 tiles. When the player goes >10 steps + away from both tiles, the oldest one is moved to under the player and the + NPC aggression timer resets. + So to first figure out where the 2 tiles are, we wait until the player teleports + a long enough distance. At that point it's very likely that the player + moved out of the radius of both tiles, which resets one of them. The other + should reset shortly after as the player starts moving around. + */ + + private static final int SAFE_AREA_RADIUS = 10; + private static final int UNKNOWN_AREA_RADIUS = SAFE_AREA_RADIUS * 2; + private static final int AGGRESSIVE_TIME_SECONDS = 600; + private static final Splitter NAME_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults(); + private static final WorldArea WILDERNESS_ABOVE_GROUND = new WorldArea(2944, 3523, 448, 448, 0); + private static final WorldArea WILDERNESS_UNDERGROUND = new WorldArea(2944, 9918, 320, 442, 0); + + @Inject + private Client client; + + @Inject + private NpcAggroAreaConfig config; + + @Inject + private NpcAggroAreaOverlay overlay; + + @Inject + private NpcAggroAreaNotWorkingOverlay notWorkingOverlay; + + @Inject + private OverlayManager overlayManager; + + @Inject + private ItemManager itemManager; + + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private ConfigManager configManager; + + @Getter + private final WorldPoint[] safeCenters = new WorldPoint[2]; + + @Getter + private final GeneralPath[] linesToDisplay = new GeneralPath[Constants.MAX_Z]; + + @Getter + private boolean active; + + @Getter + private AggressionTimer currentTimer; + + private WorldPoint lastPlayerLocation; + private WorldPoint previousUnknownCenter; + private boolean loggingIn; + private List npcNamePatterns; + + @Provides + NpcAggroAreaConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(NpcAggroAreaConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(overlay); + overlayManager.add(notWorkingOverlay); + npcNamePatterns = NAME_SPLITTER.splitToList(config.npcNamePatterns()); + } + + @Override + protected void shutDown() throws Exception + { + removeTimer(); + overlayManager.remove(overlay); + overlayManager.remove(notWorkingOverlay); + Arrays.fill(safeCenters, null); + lastPlayerLocation = null; + currentTimer = null; + loggingIn = false; + npcNamePatterns = null; + active = false; + + Arrays.fill(linesToDisplay, null); + } + + private Area generateSafeArea() + { + final Area area = new Area(); + + for (WorldPoint wp : safeCenters) + { + if (wp == null) + { + continue; + } + + Polygon poly = new Polygon(); + poly.addPoint(wp.getX() - SAFE_AREA_RADIUS, wp.getY() - SAFE_AREA_RADIUS); + poly.addPoint(wp.getX() - SAFE_AREA_RADIUS, wp.getY() + SAFE_AREA_RADIUS + 1); + poly.addPoint(wp.getX() + SAFE_AREA_RADIUS + 1, wp.getY() + SAFE_AREA_RADIUS + 1); + poly.addPoint(wp.getX() + SAFE_AREA_RADIUS + 1, wp.getY() - SAFE_AREA_RADIUS); + area.add(new Area(poly)); + } + + return area; + } + + private void transformWorldToLocal(float[] coords) + { + final LocalPoint lp = LocalPoint.fromWorld(client, (int)coords[0], (int)coords[1]); + coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2f; + coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2f; + } + + private void reevaluateActive() + { + if (currentTimer != null) + { + currentTimer.setVisible(active && config.showTimer()); + } + + calculateLinesToDisplay(); + } + + private void calculateLinesToDisplay() + { + if (!active || !config.showAreaLines()) + { + Arrays.fill(linesToDisplay, null); + return; + } + + Rectangle sceneRect = new Rectangle( + client.getBaseX() + 1, client.getBaseY() + 1, + Constants.SCENE_SIZE - 2, Constants.SCENE_SIZE - 2); + + for (int i = 0; i < linesToDisplay.length; i++) + { + GeneralPath lines = new GeneralPath(generateSafeArea()); + lines = Geometry.clipPath(lines, sceneRect); + lines = Geometry.splitIntoSegments(lines, 1); + lines = Geometry.transformPath(lines, this::transformWorldToLocal); + linesToDisplay[i] = lines; + } + } + + private void removeTimer() + { + infoBoxManager.removeInfoBox(currentTimer); + currentTimer = null; + } + + private void createTimer(Duration duration) + { + removeTimer(); + BufferedImage image = itemManager.getImage(ItemID.ENSOULED_DEMON_HEAD); + currentTimer = new AggressionTimer(duration, image, this, active && config.showTimer()); + infoBoxManager.addInfoBox(currentTimer); + } + + private void resetTimer() + { + createTimer(Duration.ofSeconds(AGGRESSIVE_TIME_SECONDS)); + } + + private static boolean isInWilderness(WorldPoint location) + { + return WILDERNESS_ABOVE_GROUND.distanceTo2D(location) == 0 || WILDERNESS_UNDERGROUND.distanceTo2D(location) == 0; + } + + private boolean isNpcMatch(NPC npc) + { + NPCComposition composition = npc.getTransformedComposition(); + if (composition == null) + { + return false; + } + + if (Strings.isNullOrEmpty(composition.getName())) + { + return false; + } + + // Most NPCs stop aggroing when the player has more than double + // its combat level. + int playerLvl = client.getLocalPlayer().getCombatLevel(); + int npcLvl = composition.getCombatLevel(); + String npcName = composition.getName().toLowerCase(); + if (npcLvl > 0 && playerLvl > npcLvl * 2 && !isInWilderness(npc.getWorldLocation())) + { + return false; + } + + for (String pattern : npcNamePatterns) + { + if (WildcardMatcher.matches(pattern, npcName)) + { + return true; + } + } + + return false; + } + + private void checkAreaNpcs(final NPC... npcs) + { + for (NPC npc : npcs) + { + if (npc == null) + { + continue; + } + + if (isNpcMatch(npc)) + { + active = true; + break; + } + } + + reevaluateActive(); + } + + private void recheckActive() + { + active = config.alwaysActive(); + checkAreaNpcs(client.getCachedNPCs()); + } + + @Subscribe + public void onNpcSpawned(NpcSpawned event) + { + if (config.alwaysActive()) + { + return; + } + + checkAreaNpcs(event.getNpc()); + } + + @Subscribe + public void onGameTick(GameTick event) + { + WorldPoint newLocation = client.getLocalPlayer().getWorldLocation(); + if (lastPlayerLocation != null) + { + if (safeCenters[1] == null && newLocation.distanceTo2D(lastPlayerLocation) > SAFE_AREA_RADIUS * 4) + { + safeCenters[0] = null; + safeCenters[1] = newLocation; + resetTimer(); + calculateLinesToDisplay(); + + // We don't know where the previous area was, so if the player e.g. + // entered a dungeon and then goes back out, he/she may enter the previous + // area which is unknown and would make the plugin inaccurate + previousUnknownCenter = lastPlayerLocation; + } + } + + if (safeCenters[0] == null && previousUnknownCenter != null && + previousUnknownCenter.distanceTo2D(newLocation) <= UNKNOWN_AREA_RADIUS) + { + // Player went back to their previous unknown area before the 2nd + // center point was found, which means we don't know where it is again. + safeCenters[1] = null; + removeTimer(); + calculateLinesToDisplay(); + } + + if (safeCenters[1] != null) + { + if (Arrays.stream(safeCenters).noneMatch( + x -> x != null && x.distanceTo2D(newLocation) <= SAFE_AREA_RADIUS)) + { + safeCenters[0] = safeCenters[1]; + safeCenters[1] = newLocation; + resetTimer(); + calculateLinesToDisplay(); + previousUnknownCenter = null; + } + } + + lastPlayerLocation = newLocation; + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + String key = event.getKey(); + switch (key) + { + case "npcUnaggroAlwaysActive": + recheckActive(); + break; + case "npcUnaggroShowTimer": + if (currentTimer != null) + { + currentTimer.setVisible(active && config.showTimer()); + } + break; + case "npcUnaggroCollisionDetection": + case "npcUnaggroShowAreaLines": + calculateLinesToDisplay(); + break; + case "npcUnaggroNames": + npcNamePatterns = NAME_SPLITTER.splitToList(config.npcNamePatterns()); + recheckActive(); + break; + } + } + + private void loadConfig() + { + safeCenters[0] = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER1, WorldPoint.class); + safeCenters[1] = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER2, WorldPoint.class); + lastPlayerLocation = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_LOCATION, WorldPoint.class); + + Duration timeLeft = configManager.getConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION, Duration.class); + if (timeLeft != null) + { + createTimer(timeLeft); + } + } + + private void resetConfig() + { + configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER1); + configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER2); + configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_LOCATION); + configManager.unsetConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION); + } + + private void saveConfig() + { + if (safeCenters[0] == null || safeCenters[1] == null || lastPlayerLocation == null || currentTimer == null) + { + resetConfig(); + } + else + { + configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER1, safeCenters[0]); + configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_CENTER2, safeCenters[1]); + configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_LOCATION, lastPlayerLocation); + configManager.setConfiguration(NpcAggroAreaConfig.CONFIG_GROUP, NpcAggroAreaConfig.CONFIG_DURATION, Duration.between(Instant.now(), currentTimer.getEndTime())); + } + } + + private void onLogin() + { + loadConfig(); + resetConfig(); + + WorldPoint newLocation = client.getLocalPlayer().getWorldLocation(); + assert newLocation != null; + + // If the player isn't at the location he/she logged out at, + // the safe unaggro area probably changed, and should be disposed. + if (lastPlayerLocation == null || newLocation.distanceTo(lastPlayerLocation) != 0) + { + safeCenters[0] = null; + safeCenters[1] = null; + lastPlayerLocation = newLocation; + } + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + switch (event.getGameState()) + { + case LOGGED_IN: + if (loggingIn) + { + loggingIn = false; + onLogin(); + } + + recheckActive(); + break; + + case LOGGING_IN: + loggingIn = true; + break; + + case LOGIN_SCREEN: + if (lastPlayerLocation != null) + { + saveConfig(); + } + + safeCenters[0] = null; + safeCenters[1] = null; + lastPlayerLocation = null; + break; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java index af9431038e..f111a6f94f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsOverlay.java @@ -29,6 +29,7 @@ import java.awt.Graphics2D; import java.awt.Polygon; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.DecorativeObject; import net.runelite.api.GameObject; import net.runelite.api.TileObject; import net.runelite.client.ui.overlay.Overlay; @@ -65,22 +66,31 @@ class ObjectIndicatorsOverlay extends Overlay } final Polygon polygon; + Polygon polygon2 = null; if (object instanceof GameObject) { polygon = ((GameObject) object).getConvexHull(); } + else if (object instanceof DecorativeObject) + { + polygon = ((DecorativeObject) object).getConvexHull(); + polygon2 = ((DecorativeObject) object).getConvexHull2(); + } else { polygon = object.getCanvasTilePoly(); } - if (polygon == null) + if (polygon != null) { - continue; + OverlayUtil.renderPolygon(graphics, polygon, config.markerColor()); } - OverlayUtil.renderPolygon(graphics, polygon, config.markerColor()); + if (polygon2 != null) + { + OverlayUtil.renderPolygon(graphics, polygon2, config.markerColor()); + } } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index a352d728db..05fd84d0d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -43,6 +43,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import static net.runelite.api.Constants.REGION_SIZE; +import net.runelite.api.DecorativeObject; import net.runelite.api.GameObject; import net.runelite.api.GameState; import net.runelite.api.MenuAction; @@ -58,6 +59,8 @@ import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.DecorativeObjectSpawned; +import net.runelite.api.events.DecorativeObjectDespawned; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyListener; @@ -158,26 +161,15 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener @Subscribe public void onGameObjectSpawned(GameObjectSpawned event) { - final WorldPoint worldPoint = WorldPoint.fromLocalInstance(client, event.getGameObject().getLocalLocation()); - final Set objectPoints = points.get(worldPoint.getRegionID()); + final GameObject eventObject = event.getGameObject(); + checkObjectPoints(eventObject); + } - if (objectPoints == null) - { - return; - } - - for (ObjectPoint objectPoint : objectPoints) - { - if ((worldPoint.getX() & (REGION_SIZE - 1)) == objectPoint.getRegionX() - && (worldPoint.getY() & (REGION_SIZE - 1)) == objectPoint.getRegionY()) - { - if (objectPoint.getName().equals(client.getObjectDefinition(event.getGameObject().getId()).getName())) - { - objects.add(event.getGameObject()); - break; - } - } - } + @Subscribe + public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + { + final DecorativeObject eventObject = event.getDecorativeObject(); + checkObjectPoints(eventObject); } @Subscribe @@ -186,6 +178,12 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener objects.remove(event.getGameObject()); } + @Subscribe + public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + { + objects.remove(event.getDecorativeObject()); + } + @Subscribe public void onGameStateChanged(GameStateChanged gameStateChanged) { @@ -263,6 +261,30 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener markObject(name, object); } + private void checkObjectPoints(TileObject object) + { + final WorldPoint worldPoint = WorldPoint.fromLocalInstance(client, object.getLocalLocation()); + final Set objectPoints = points.get(worldPoint.getRegionID()); + + if (objectPoints == null) + { + return; + } + + for (ObjectPoint objectPoint : objectPoints) + { + if ((worldPoint.getX() & (REGION_SIZE - 1)) == objectPoint.getRegionX() + && (worldPoint.getY() & (REGION_SIZE - 1)) == objectPoint.getRegionY()) + { + if (objectPoint.getName().equals(client.getObjectDefinition(object.getId()).getName())) + { + objects.add(object); + break; + } + } + } + } + private TileObject findTileObject(Tile tile, int id) { if (tile == null) @@ -271,6 +293,12 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener } final GameObject[] tileGameObjects = tile.getGameObjects(); + final DecorativeObject tileDecorativeObject = tile.getDecorativeObject(); + + if (tileDecorativeObject != null && tileDecorativeObject.getId() == id) + { + return tileDecorativeObject; + } for (GameObject object : tileGameObjects) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index 03110fe35c..0e910ff338 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -128,6 +128,7 @@ public class PartyPlugin extends Plugin implements KeyListener private int lastHp, lastPray; private boolean hotkeyDown, doSync; + private boolean sendAlert; @Override public void configure(Binder binder) @@ -161,6 +162,7 @@ public class PartyPlugin extends Plugin implements KeyListener keyManager.unregisterKeyListener(this); hotkeyDown = false; doSync = false; + sendAlert = false; } @Provides @@ -189,7 +191,7 @@ public class PartyPlugin extends Plugin implements KeyListener .build(); chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.GAME) + .type(ChatMessageType.CLANCHAT_INFO) .runeLiteFormattedMessage(leaveMessage) .build()); } @@ -284,6 +286,12 @@ public class PartyPlugin extends Plugin implements KeyListener @Subscribe public void onGameTick(final GameTick event) { + if (sendAlert && client.getGameState() == GameState.LOGGED_IN) + { + sendAlert = false; + sendInstructionMessage(); + } + if (doSync && !party.getMembers().isEmpty()) { // Request sync @@ -373,7 +381,7 @@ public class PartyPlugin extends Plugin implements KeyListener .build(); chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.GAME) + .type(ChatMessageType.CLANCHAT_INFO) .runeLiteFormattedMessage(joinMessage) .build()); @@ -381,15 +389,7 @@ public class PartyPlugin extends Plugin implements KeyListener if (localMember != null && partyData.getMemberId().equals(localMember.getMemberId())) { - final String helpMessage = new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("To leave party hold SHIFT and right click party stats overlay.") - .build(); - - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.GAME) - .runeLiteFormattedMessage(helpMessage) - .build()); + sendAlert = true; } } @@ -430,7 +430,7 @@ public class PartyPlugin extends Plugin implements KeyListener .build(); chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.GAME) + .type(ChatMessageType.CLANCHAT_INFO) .runeLiteFormattedMessage(joinMessage) .build()); } @@ -510,4 +510,17 @@ public class PartyPlugin extends Plugin implements KeyListener hotkeyDown = false; } } + + private void sendInstructionMessage() + { + final String helpMessage = new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("To leave party hold SHIFT and right click party stats overlay.") + .build(); + + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CLANCHAT_INFO) + .runeLiteFormattedMessage(helpMessage) + .build()); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyStatsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyStatsOverlay.java index 2b9e1820f3..693b23cb89 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyStatsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyStatsOverlay.java @@ -27,6 +27,8 @@ package net.runelite.client.plugins.party; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; import java.util.Map; import java.util.UUID; import javax.inject.Inject; @@ -34,6 +36,7 @@ import net.runelite.api.MenuAction; import net.runelite.client.plugins.party.data.PartyData; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayMenuEntry; +import net.runelite.client.ui.overlay.components.ComponentConstants; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.ProgressBarComponent; import net.runelite.client.ui.overlay.components.TitleComponent; @@ -58,6 +61,8 @@ public class PartyStatsOverlay extends Overlay this.plugin = plugin; this.party = party; this.config = config; + body.setBorder(new Rectangle()); + body.setGap(new Point(0, ComponentConstants.STANDARD_BORDER / 2)); getMenuEntries().add(new OverlayMenuEntry(MenuAction.RUNELITE_OVERLAY, "Leave", "Party")); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java index 0ff6569379..f5bf7131ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java @@ -24,11 +24,13 @@ */ package net.runelite.client.plugins.party.messages; +import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.api.coords.WorldPoint; import net.runelite.http.api.ws.messages.party.PartyMemberMessage; @Value +@EqualsAndHashCode(callSuper = true) public class LocationUpdate extends PartyMemberMessage { private final WorldPoint worldPoint; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java index 1378403333..fb4f812a81 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java @@ -24,11 +24,13 @@ */ package net.runelite.client.plugins.party.messages; +import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.api.coords.WorldPoint; import net.runelite.http.api.ws.messages.party.PartyMemberMessage; @Value +@EqualsAndHashCode(callSuper = true) public class TilePing extends PartyMemberMessage { private final WorldPoint point; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java index 360e56f40d..7e711e66a0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java @@ -92,7 +92,8 @@ public class PestControlPlugin extends Plugin @Subscribe public void onGameStateChanged(GameStateChanged event) { - if (event.getGameState() == GameState.LOADING) + GameState gameState = event.getGameState(); + if (gameState == GameState.CONNECTION_LOST || gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING) { spinners.clear(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java index c40d4a9020..6b032bc8ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsConfig.java @@ -155,13 +155,13 @@ public interface PlayerIndicatorsConfig extends Config @ConfigItem( position = 11, - keyName = "drawOverheadPlayerNames", - name = "Draw names above players", - description = "Configures whether or not player names should be drawn above players" + keyName = "playerNamePosition", + name = "Name position", + description = "Configures the position of drawn player names, or if they should be disabled" ) - default boolean drawOverheadPlayerNames() + default PlayerNameLocation playerNamePosition() { - return true; + return PlayerNameLocation.ABOVE_HEAD; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java index 3795b89f1c..5373fc1eb4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsOverlay.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Tomas Slusny + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,10 +39,14 @@ import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.Text; @Singleton public class PlayerIndicatorsOverlay extends Overlay { + private static final int ACTOR_OVERHEAD_TEXT_MARGIN = 40; + private static final int ACTOR_HORIZONTAL_TEXT_MARGIN = 10; + private final PlayerIndicatorsService playerIndicatorsService; private final PlayerIndicatorsConfig config; private final ClanManager clanManager; @@ -66,39 +71,78 @@ public class PlayerIndicatorsOverlay extends Overlay private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) { - if (!config.drawOverheadPlayerNames()) + final PlayerNameLocation drawPlayerNamesConfig = config.playerNamePosition(); + if (drawPlayerNamesConfig == PlayerNameLocation.DISABLED) { return; } - String name = actor.getName().replace('\u00A0', ' '); - int offset = actor.getLogicalHeight() + 40; - Point textLocation = actor.getCanvasTextLocation(graphics, name, offset); - - if (textLocation != null) + final int zOffset; + switch (drawPlayerNamesConfig) { - if (config.showClanRanks() && actor.isClanMember()) + case MODEL_CENTER: + case MODEL_RIGHT: + zOffset = actor.getLogicalHeight() / 2; + break; + default: + zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN; + } + + final String name = Text.sanitize(actor.getName()); + Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset); + + if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) + { + textLocation = actor.getCanvasTextLocation(graphics, "", zOffset); + + if (textLocation == null) { - ClanMemberRank rank = clanManager.getRank(name); - - if (rank != ClanMemberRank.UNRANKED) - { - BufferedImage clanchatImage = clanManager.getClanImage(rank); - - if (clanchatImage != null) - { - int width = clanchatImage.getWidth(); - int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); - Point imageLocation = new Point(textLocation.getX() - width / 2 - 1, textLocation.getY() - textHeight / 2 - clanchatImage.getHeight() / 2); - OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); - - // move text - textLocation = new Point(textLocation.getX() + width / 2, textLocation.getY()); - } - } + return; } - OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + textLocation = new Point(textLocation.getX() + ACTOR_HORIZONTAL_TEXT_MARGIN, textLocation.getY()); } + + if (textLocation == null) + { + return; + } + + if (config.showClanRanks() && actor.isClanMember()) + { + final ClanMemberRank rank = clanManager.getRank(name); + + if (rank != ClanMemberRank.UNRANKED) + { + final BufferedImage clanchatImage = clanManager.getClanImage(rank); + + if (clanchatImage != null) + { + final int clanImageWidth = clanchatImage.getWidth(); + final int clanImageTextMargin; + final int clanImageNegativeMargin; + + if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT) + { + clanImageTextMargin = clanImageWidth; + clanImageNegativeMargin = 0; + } + else + { + clanImageTextMargin = clanImageWidth / 2; + clanImageNegativeMargin = clanImageWidth / 2; + } + + final int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent(); + final Point imageLocation = new Point(textLocation.getX() - clanImageNegativeMargin - 1, textLocation.getY() - textHeight / 2 - clanchatImage.getHeight() / 2); + OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage); + + // move text + textLocation = new Point(textLocation.getX() + clanImageTextMargin, textLocation.getY()); + } + } + } + + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerNameLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerNameLocation.java new file mode 100644 index 0000000000..14a4eff208 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerNameLocation.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.playerindicators; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum PlayerNameLocation +{ + + DISABLED("Disabled"), + ABOVE_HEAD("Above head"), + MODEL_CENTER("Center of model"), + MODEL_RIGHT("Right of model"); + + private final String name; + + @Override + public String toString() + { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonConfig.java new file mode 100644 index 0000000000..6c723d4f71 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Hydrox6 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.poison; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup(PoisonConfig.GROUP) +public interface PoisonConfig extends Config +{ + String GROUP = "poison"; + + @ConfigItem( + keyName = "showInfoboxes", + name = "Show Infoboxes", + description = "Configures whether to show the infoboxes" + ) + default boolean showInfoboxes() + { + return false; + } + + @ConfigItem( + keyName = "changeHealthIcon", + name = "Change HP Orb Icon", + description = "Configures whether the hp orb icon should change color to match poison/disease" + ) + default boolean changeHealthIcon() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java new file mode 100644 index 0000000000..44d7746781 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonInfobox.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018 Hydrox6 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.poison; + +import java.awt.Color; +import java.time.temporal.ChronoUnit; +import java.awt.image.BufferedImage; +import net.runelite.client.ui.overlay.infobox.Timer; + +class PoisonInfobox extends Timer +{ + private final PoisonPlugin plugin; + + PoisonInfobox(BufferedImage image, PoisonPlugin plugin) + { + super(PoisonPlugin.POISON_TICK_MILLIS, ChronoUnit.MILLIS, image, plugin); + this.plugin = plugin; + } + + @Override + public String getTooltip() + { + return plugin.createTooltip(); + } + + @Override + public Color getTextColor() + { + return Color.RED.brighter(); + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonOverlay.java new file mode 100644 index 0000000000..758811f292 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonOverlay.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018 Hydrox6 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.poison; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.tooltip.Tooltip; +import net.runelite.client.ui.overlay.tooltip.TooltipManager; + +class PoisonOverlay extends Overlay +{ + private final PoisonPlugin plugin; + private final Client client; + private final TooltipManager tooltipManager; + + @Inject + private PoisonOverlay(final PoisonPlugin plugin, final Client client, final TooltipManager tooltipManager) + { + this.plugin = plugin; + this.client = client; + this.tooltipManager = tooltipManager; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getLastDamage() <= 0) + { + return null; + } + + final Widget healthOrb = client.getWidget(WidgetInfo.MINIMAP_HEALTH_ORB); + + if (healthOrb == null || healthOrb.isHidden()) + { + return null; + } + + final Rectangle bounds = healthOrb.getBounds(); + + if (bounds.getX() <= 0) + { + return null; + } + + final Point mousePosition = client.getMouseCanvasPosition(); + + if (bounds.contains(mousePosition.getX(), mousePosition.getY())) + { + tooltipManager.add(new Tooltip(plugin.createTooltip())); + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java new file mode 100644 index 0000000000..84a4c5e3d6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2018 Hydrox6 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.poison; + +import com.google.inject.Provides; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.text.MessageFormat; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import javax.inject.Inject; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.SpriteID; +import net.runelite.api.VarPlayer; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.VarbitChanged; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.ImageUtil; + +@PluginDescriptor( + name = "Poison", + description = "Tracks current damage values for Poison and Venom", + tags = {"combat", "poison", "venom", "heart", "hp"} +) +public class PoisonPlugin extends Plugin +{ + static final int POISON_TICK_MILLIS = 18200; + private static final int VENOM_THRESHOLD = 1000000; + private static final int VENOM_MAXIUMUM_DAMAGE = 20; + + private static final BufferedImage HEART_DISEASE; + private static final BufferedImage HEART_POISON; + private static final BufferedImage HEART_VENOM; + + static + { + HEART_DISEASE = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(PoisonPlugin.class, "1067-DISEASE.png"), 26, 26); + HEART_POISON = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(PoisonPlugin.class, "1067-POISON.png"), 26, 26); + HEART_VENOM = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(PoisonPlugin.class, "1067-VENOM.png"), 26, 26); + } + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private PoisonOverlay poisonOverlay; + + @Inject + private OverlayManager overlayManager; + + @Inject + private InfoBoxManager infoBoxManager; + + @Inject + private SpriteManager spriteManager; + + @Inject + private PoisonConfig config; + + @Getter + private int lastDamage; + private boolean envenomed; + private PoisonInfobox infobox; + private Instant poisonNaturalCure; + private Instant nextPoisonTick; + private int lastValue = -1; + private int lastDiseaseValue = -1; + private BufferedImage heart; + + @Provides + PoisonConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(PoisonConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(poisonOverlay); + + if (client.getGameState() == GameState.LOGGED_IN) + { + clientThread.invoke(this::checkHealthIcon); + } + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(poisonOverlay); + + if (infobox != null) + { + infoBoxManager.removeInfoBox(infobox); + infobox = null; + } + + envenomed = false; + lastDamage = 0; + poisonNaturalCure = null; + nextPoisonTick = null; + lastValue = -1; + lastDiseaseValue = -1; + + clientThread.invoke(this::resetHealthIcon); + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + final int poisonValue = client.getVar(VarPlayer.POISON); + if (poisonValue != lastValue) + { + lastValue = poisonValue; + nextPoisonTick = Instant.now().plus(Duration.of(POISON_TICK_MILLIS, ChronoUnit.MILLIS)); + + final int damage = nextDamage(poisonValue); + this.lastDamage = damage; + + envenomed = poisonValue >= VENOM_THRESHOLD; + + if (poisonValue < VENOM_THRESHOLD) + { + poisonNaturalCure = Instant.now().plus(Duration.of(POISON_TICK_MILLIS * poisonValue, ChronoUnit.MILLIS)); + } + else + { + poisonNaturalCure = null; + } + + if (config.showInfoboxes()) + { + if (infobox != null) + { + infoBoxManager.removeInfoBox(infobox); + infobox = null; + } + + if (damage > 0) + { + final BufferedImage image = getSplat(envenomed ? SpriteID.HITSPLAT_DARK_GREEN_VENOM : SpriteID.HITSPLAT_GREEN_POISON, damage); + + if (image != null) + { + infobox = new PoisonInfobox(image, this); + infoBoxManager.addInfoBox(infobox); + } + } + } + + checkHealthIcon(); + } + + final int diseaseValue = client.getVar(VarPlayer.DISEASE_VALUE); + if (diseaseValue != lastDiseaseValue) + { + lastDiseaseValue = diseaseValue; + checkHealthIcon(); + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!event.getGroup().equals(PoisonConfig.GROUP)) + { + return; + } + + if (!config.showInfoboxes() && infobox != null) + { + infoBoxManager.removeInfoBox(infobox); + infobox = null; + } + + if (config.changeHealthIcon()) + { + clientThread.invoke(this::checkHealthIcon); + } + else + { + clientThread.invoke(this::resetHealthIcon); + } + } + + private static int nextDamage(int poisonValue) + { + int damage; + + if (poisonValue >= VENOM_THRESHOLD) + { + //Venom Damage starts at 6, and increments in twos; + //The VarPlayer increments in values of 1, however. + poisonValue -= VENOM_THRESHOLD - 3; + damage = poisonValue * 2; + //Venom Damage caps at 20, but the VarPlayer keeps increasing + if (damage > VENOM_MAXIUMUM_DAMAGE) + { + damage = VENOM_MAXIUMUM_DAMAGE; + } + } + else + { + damage = (int) Math.ceil(poisonValue / 5.0f); + } + + return damage; + } + + private BufferedImage getSplat(int id, int damage) + { + //Get a copy of the hitsplat to get a clean one each time + final BufferedImage rawSplat = spriteManager.getSprite(id, 0); + if (rawSplat == null) + { + return null; + } + + final BufferedImage splat = new BufferedImage( + rawSplat.getColorModel(), + rawSplat.copyData(null), + rawSplat.getColorModel().isAlphaPremultiplied(), + null); + + final Graphics g = splat.getGraphics(); + g.setFont(FontManager.getRunescapeSmallFont()); + + // Align the text in the centre of the hitsplat + final FontMetrics metrics = g.getFontMetrics(); + final String text = String.valueOf(damage); + final int x = (splat.getWidth() - metrics.stringWidth(text)) / 2; + final int y = (splat.getHeight() - metrics.getHeight()) / 2 + metrics.getAscent(); + + g.setColor(Color.BLACK); + g.drawString(String.valueOf(damage), x + 1, y + 1); + g.setColor(Color.WHITE); + g.drawString(String.valueOf(damage), x, y); + return splat; + } + + private static String getFormattedTime(Instant endTime) + { + final Duration timeLeft = Duration.between(Instant.now(), endTime); + int seconds = (int) (timeLeft.toMillis() / 1000L); + int minutes = seconds / 60; + int secs = seconds % 60; + + return String.format("%d:%02d", minutes, secs); + } + + String createTooltip() + { + String line1 = MessageFormat.format("Next {0} damage: {1}
Time until damage: {2}", + envenomed ? "venom" : "poison", ColorUtil.wrapWithColorTag(String.valueOf(lastDamage), Color.RED), getFormattedTime(nextPoisonTick)); + String line2 = envenomed ? "" : MessageFormat.format("
Time until cure: {0}", getFormattedTime(poisonNaturalCure)); + + return line1 + line2; + } + + private void checkHealthIcon() + { + if (!config.changeHealthIcon()) + { + return; + } + + final BufferedImage newHeart; + final int poison = client.getVar(VarPlayer.IS_POISONED); + + if (poison >= VENOM_THRESHOLD) + { + newHeart = HEART_VENOM; + } + else if (poison > 0) + { + newHeart = HEART_POISON; + } + else if (client.getVar(VarPlayer.DISEASE_VALUE) > 0) + { + newHeart = HEART_DISEASE; + } + else + { + resetHealthIcon(); + return; + } + + // Only update sprites when the heart icon actually changes + if (newHeart != heart) + { + heart = newHeart; + client.getWidgetSpriteCache().reset(); + client.getSpriteOverrides().put(SpriteID.MINIMAP_ORB_HITPOINTS_ICON, ImageUtil.getImageSpritePixels(heart, client)); + } + } + + private void resetHealthIcon() + { + if (heart == null) + { + return; + } + + client.getWidgetSpriteCache().reset(); + client.getSpriteOverrides().remove(SpriteID.MINIMAP_ORB_HITPOINTS_ICON); + heart = null; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerCounter.java index 546c9f98a8..c510dab82e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerCounter.java @@ -24,25 +24,32 @@ */ package net.runelite.client.plugins.prayer; +import java.awt.Color; import lombok.Getter; import net.runelite.client.plugins.Plugin; -import net.runelite.client.ui.overlay.infobox.Counter; +import net.runelite.client.ui.overlay.infobox.InfoBox; -class PrayerCounter extends Counter +class PrayerCounter extends InfoBox { @Getter private final PrayerType prayerType; PrayerCounter(Plugin plugin, PrayerType prayerType) { - super(null, plugin, ""); + super(null, plugin); this.prayerType = prayerType; } @Override - public String toString() + public String getText() { - return "Counter{" + "prayer=" + prayerType.getName() + '}'; + return null; + } + + @Override + public Color getTextColor() + { + return null; } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java index df12b4f247..24ffbc5a56 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java @@ -41,6 +41,9 @@ enum PrayerItems ANCIENT_BLESSING(ItemID.ANCIENT_BLESSING, 1), HONOURABLE_BLESSING(ItemID.HONOURABLE_BLESSING, 1), WAR_BLESSING(ItemID.WAR_BLESSING, 1), + RADAS_BLESSING_2(ItemID.RADAS_BLESSING_2, 1), + RADAS_BLESSING_3(ItemID.RADAS_BLESSING_3, 1), + RADAS_BLESSING_4(ItemID.RADAS_BLESSING_4, 2), // Rings EXPLORERS_RING(ItemID.EXPLORERS_RING, 1), @@ -145,8 +148,8 @@ enum PrayerItems ANCIENT_DHIDE(ItemID.ANCIENT_DHIDE, 1), ARMADYL_DHIDE(ItemID.ARMADYL_DHIDE, 1), BANDOS_DHIDE(ItemID.BANDOS_DHIDE, 1), - GUTHIX_DRAGONHIDE(ItemID.GUTHIX_DRAGONHIDE, 1), - GUTHIX_DRAGONHIDE_10794(ItemID.GUTHIX_DRAGONHIDE_10794, 1), + GUTHIX_DRAGONHIDE(ItemID.GUTHIX_DHIDE, 1), + GUTHIX_DRAGONHIDE_10794(ItemID.GUTHIX_DRAGONHIDE, 1), SARADOMIN_DHIDE(ItemID.SARADOMIN_DHIDE, 1), SARADOMIN_DHIDE_10792(ItemID.SARADOMIN_DHIDE_10792, 1), ZAMORAK_DHIDE(ItemID.ZAMORAK_DHIDE, 1), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 0d4633fe94..46570b3b5a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -49,9 +49,6 @@ import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.VarbitChanged; -import net.runelite.api.events.WidgetHiddenChanged; -import net.runelite.api.widgets.Widget; -import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; @@ -104,9 +101,6 @@ public class RaidsPlugin extends Plugin @Inject private RaidsOverlay overlay; - @Inject - private RaidsPointsOverlay pointsOverlay; - @Inject private LayoutSolver layoutSolver; @@ -152,7 +146,6 @@ public class RaidsPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); - overlayManager.add(pointsOverlay); updateLists(); clientThread.invokeLater(() -> checkRaidPresence(true)); } @@ -161,7 +154,6 @@ public class RaidsPlugin extends Plugin protected void shutDown() throws Exception { overlayManager.remove(overlay); - overlayManager.remove(pointsOverlay); infoBoxManager.removeInfoBox(timer); inRaidChambers = false; raid = null; @@ -186,22 +178,6 @@ public class RaidsPlugin extends Plugin clientThread.invokeLater(() -> checkRaidPresence(true)); } - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged event) - { - if (!inRaidChambers || event.isHidden()) - { - return; - } - - Widget widget = event.getWidget(); - - if (widget == client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX)) - { - widget.setHidden(true); - } - } - @Subscribe public void onVarbitChanged(VarbitChanged event) { @@ -230,7 +206,7 @@ public class RaidsPlugin extends Plugin { if (timer != null) { - timer.timeFloor(); + timer.timeOlm(); timer.setStopped(true); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java index 8b40b09e10..8df3087054 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java @@ -41,6 +41,7 @@ public class RaidsTimer extends InfoBox private LocalTime time; private LocalTime firstFloorTime; private LocalTime secondFloorTime; + private LocalTime thirdFloorTime; private LocalTime olmTime; @Setter @@ -66,14 +67,20 @@ public class RaidsTimer extends InfoBox { secondFloorTime = LocalTime.ofSecondOfDay(elapsed.getSeconds()); } - else if (olmTime == null) + else if (thirdFloorTime == null) { - olmTime = LocalTime.ofSecondOfDay(elapsed.getSeconds()); + thirdFloorTime = LocalTime.ofSecondOfDay(elapsed.getSeconds()); } floorTime = Instant.now(); } + public void timeOlm() + { + Duration elapsed = Duration.between(floorTime, Instant.now()); + olmTime = LocalTime.ofSecondOfDay(elapsed.getSeconds()); + } + @Override public String getText() { @@ -126,6 +133,12 @@ public class RaidsTimer extends InfoBox builder.append(secondFloorTime.format(DateTimeFormatter.ofPattern("mm:ss"))); } + if (thirdFloorTime != null) + { + builder.append("
Third floor: "); + builder.append(thirdFloorTime.format(DateTimeFormatter.ofPattern("mm:ss"))); + } + if (olmTime != null) { builder.append("
Olm: "); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java index b7e8b682b0..9a3908f7d3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Shaun Dreclin + * Copyright (c) 2018-2019, Shaun Dreclin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.roguesden; -import java.time.temporal.ChronoUnit; import java.util.HashMap; import javax.inject.Inject; import lombok.AccessLevel; @@ -33,8 +32,7 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.InventoryID; import net.runelite.api.Item; -import net.runelite.api.ItemContainer; -import static net.runelite.api.ItemID.MYSTIC_JEWEL; +import net.runelite.api.ItemID; import net.runelite.api.Tile; import net.runelite.api.TileObject; import net.runelite.api.events.GameObjectChanged; @@ -44,10 +42,10 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.task.Schedule; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( @@ -90,29 +88,24 @@ public class RoguesDenPlugin extends Plugin hasGem = false; } - @Schedule(period = 600, unit = ChronoUnit.MILLIS) - public void checkGem() + @Subscribe + public void onItemContainerChanged(ItemContainerChanged event) { - hasGem = hasGem(); - } - - private boolean hasGem() - { - ItemContainer container = client.getItemContainer(InventoryID.INVENTORY); - if (container == null) + if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY)) { - return false; + return; } - for (Item item : container.getItems()) + for (Item item : event.getItemContainer().getItems()) { - if (item.getId() == MYSTIC_JEWEL) + if (item.getId() == ItemID.MYSTIC_JEWEL) { - return true; + hasGem = true; + return; } } - return false; + hasGem = false; } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java index 14b53f9995..4662b95d5a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java @@ -229,10 +229,17 @@ public class RunecraftPlugin extends Plugin @Subscribe public void onGameStateChanged(GameStateChanged event) { - if (event.getGameState() == GameState.LOADING) + GameState gameState = event.getGameState(); + switch (gameState) { - abyssObjects.clear(); - darkMage = null; + case LOADING: + abyssObjects.clear(); + break; + case CONNECTION_LOST: + case HOPPING: + case LOGIN_SCREEN: + darkMage = null; + break; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerRenderable.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerRenderable.java index 0d44e01345..95b2da1207 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerRenderable.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerRenderable.java @@ -28,6 +28,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Rectangle; import java.awt.Stroke; import lombok.AccessLevel; import lombok.Getter; @@ -55,6 +56,9 @@ public class ScreenMarkerRenderable implements LayoutableRenderableEntity @Setter(AccessLevel.PACKAGE) private Stroke stroke; + @Getter + private final Rectangle bounds = new Rectangle(); + @Override public Dimension render(Graphics2D graphics) { @@ -72,6 +76,7 @@ public class ScreenMarkerRenderable implements LayoutableRenderableEntity graphics.setColor(color); graphics.setStroke(stroke); graphics.drawRect(offset, offset, width - thickness, height - thickness); + bounds.setSize(preferredSize); return preferredSize; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index e4c6fd2ec9..ee78f3cc22 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -145,6 +145,8 @@ public class ScreenshotPlugin extends Plugin private Integer chambersOfXericNumber; + private Integer chambersOfXericChallengeNumber; + private Integer theatreOfBloodNumber; private boolean shouldTakeScreenshot; @@ -347,6 +349,16 @@ public class ScreenshotPlugin extends Plugin } } + if (chatMessage.startsWith("Your completed Chambers of Xeric Challenge Mode count is:")) + { + Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); + if (m.find()) + { + chambersOfXericChallengeNumber = Integer.valueOf(m.group()); + return; + } + } + if (chatMessage.startsWith("Your completed Theatre of Blood count is:")) { Matcher m = NUMBER_PATTERN.matcher(Text.removeTags(chatMessage)); @@ -453,14 +465,22 @@ public class ScreenshotPlugin extends Plugin } case CHAMBERS_OF_XERIC_REWARD_GROUP_ID: { - if (chambersOfXericNumber == null) + if (chambersOfXericNumber != null) + { + fileName = "Chambers of Xeric(" + chambersOfXericNumber + ")"; + chambersOfXericNumber = null; + break; + } + else if (chambersOfXericChallengeNumber != null) + { + fileName = "Chambers of Xeric Challenge Mode(" + chambersOfXericChallengeNumber + ")"; + chambersOfXericChallengeNumber = null; + break; + } + else { return; } - - fileName = "Chambers of Xeric(" + chambersOfXericNumber + ")"; - chambersOfXericNumber = null; - break; } case THEATRE_OF_BLOOD_REWARD_GROUP_ID: { @@ -720,6 +740,12 @@ public class ScreenshotPlugin extends Plugin return chambersOfXericNumber; } + @VisibleForTesting + int getChambersOfXericChallengeNumber() + { + return chambersOfXericChallengeNumber; + } + @VisibleForTesting int gettheatreOfBloodNumber() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index f0edfc1928..675381b1fb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -73,6 +73,8 @@ class SlayerOverlay extends Overlay ItemID.RED_SLAYER_HELMET_I, ItemID.TURQUOISE_SLAYER_HELMET, ItemID.TURQUOISE_SLAYER_HELMET_I, + ItemID.HYDRA_SLAYER_HELMET, + ItemID.HYDRA_SLAYER_HELMET_I, ItemID.SLAYER_RING_ETERNAL, ItemID.ENCHANTED_GEM, ItemID.ETERNAL_GEM, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 3d3d64b25b..875f1f009d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -60,7 +60,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; -import net.runelite.api.events.SetMessage; import net.runelite.api.vars.SlayerUnlock; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; @@ -581,7 +580,7 @@ public class SlayerPlugin extends Plugin // add and update counter, set timer addCounter(); - counter.setText(String.valueOf(amount)); + counter.setCount(amount); infoTimer = Instant.now(); } @@ -724,14 +723,14 @@ public class SlayerPlugin extends Plugin counter = null; } - void taskLookup(SetMessage setMessage, String message) + void taskLookup(ChatMessage chatMessage, String message) { if (!config.taskCommand()) { return; } - ChatMessageType type = setMessage.getType(); + ChatMessageType type = chatMessage.getType(); final String player; if (type.equals(ChatMessageType.PRIVATE_MESSAGE_SENT)) @@ -740,7 +739,7 @@ public class SlayerPlugin extends Plugin } else { - player = Text.removeTags(setMessage.getName()) + player = Text.removeTags(chatMessage.getName()) .replace('\u00A0', ' '); } @@ -787,7 +786,7 @@ public class SlayerPlugin extends Plugin .append(sb.toString()) .build(); - final MessageNode messageNode = setMessage.getMessageNode(); + final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); chatMessageManager.update(messageNode); client.refreshChat(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java index 5521380e57..ada3f3a727 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TargetWeaknessOverlay.java @@ -59,7 +59,7 @@ class TargetWeaknessOverlay extends Overlay this.itemManager = itemManager; this.npcManager = npcManager; setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); + setLayer(OverlayLayer.UNDER_WIDGETS); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java index 594038aa27..d3663a7def 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java @@ -65,11 +65,11 @@ enum Task CAVE_SLIMES("Cave slimes", ItemID.SWAMP_CAVE_SLIME), CERBERUS("Cerberus", ItemID.HELLPUPPY), CHAOS_ELEMENTAL("Chaos Elemental", ItemID.PET_CHAOS_ELEMENTAL), - CHAOS_FANATIC("Chaos Fanatic", ItemID.PET_CHAOS_ELEMENTAL), + CHAOS_FANATIC("Chaos Fanatic", ItemID.ANCIENT_STAFF), COCKATRICE("Cockatrice", ItemID.COCKATRICE, "Cockathrice"), COWS("Cows", ItemID.COW_MASK), CRAWLING_HANDS("Crawling hands", ItemID.CRAWLING_HAND, "Crushing hand"), - CRAZY_ARCHAEOLOGIST("Crazy Archaeologist", ItemID.FEDORA), + CRAZY_ARCHAEOLOGIST("Crazy Archaeologists", ItemID.FEDORA, "Crazy Archaeologist"), CROCODILES("Crocodiles", ItemID.SWAMP_LIZARD), DAGANNOTH("Dagannoth", ItemID.DAGANNOTH), DAGANNOTH_KINGS("Dagannoth Kings", ItemID.PET_DAGANNOTH_PRIME), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskCounter.java index f4ac0045b9..0d4274c063 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/TaskCounter.java @@ -29,10 +29,10 @@ import net.runelite.client.ui.overlay.infobox.Counter; import java.awt.image.BufferedImage; -public class TaskCounter extends Counter +class TaskCounter extends Counter { - public TaskCounter(BufferedImage img, Plugin plugin, int amount) + TaskCounter(BufferedImage img, Plugin plugin, int amount) { - super(img, plugin, String.valueOf(amount)); + super(img, plugin, amount); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounter.java index 083ef5bba6..425c781b45 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounter.java @@ -25,33 +25,52 @@ package net.runelite.client.plugins.specialcounter; import java.awt.image.BufferedImage; +import java.util.Map; import net.runelite.client.ui.overlay.infobox.Counter; class SpecialCounter extends Counter { - private int hitValue; + private final SpecialCounterPlugin plugin; private SpecialWeapon weapon; SpecialCounter(BufferedImage image, SpecialCounterPlugin plugin, int hitValue, SpecialWeapon weapon) { - super(image, plugin, null); + super(image, plugin, hitValue); + this.plugin = plugin; this.weapon = weapon; - this.hitValue = hitValue; } void addHits(double hit) { - this.hitValue += hit; - } - - @Override - public String getText() - { - return Integer.toString(hitValue); + int count = getCount(); + setCount(count + (int) hit); } @Override public String getTooltip() + { + Map partySpecs = plugin.getPartySpecs(); + int hitValue = getCount(); + + if (partySpecs.isEmpty()) + { + return buildTooltip(hitValue); + } + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(buildTooltip(hitValue)); + + for (Map.Entry entry : partySpecs.entrySet()) + { + stringBuilder.append("
") + .append(entry.getKey() == null ? "You" : entry.getKey()).append(": ") + .append(buildTooltip(entry.getValue())); + } + + return stringBuilder.toString(); + } + + private String buildTooltip(int hitValue) { if (!weapon.isDamage()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 40a50e7c53..4ff5b8ae6f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -24,9 +24,13 @@ */ package net.runelite.client.plugins.specialcounter; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; import net.runelite.api.Actor; import net.runelite.api.Client; import net.runelite.api.EquipmentInventorySlot; @@ -42,11 +46,14 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.VarbitChanged; +import net.runelite.client.callback.ClientThread; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.ws.PartyService; +import net.runelite.client.ws.WSClient; @PluginDescriptor( name = "Special Attack Counter", @@ -65,20 +72,38 @@ public class SpecialCounterPlugin extends Plugin private SpecialWeapon specialWeapon; private final Set interactedNpcIds = new HashSet<>(); private final SpecialCounter[] specialCounter = new SpecialCounter[SpecialWeapon.values().length]; + @Getter(AccessLevel.PACKAGE) + private final Map partySpecs = new HashMap<>(); @Inject private Client client; + @Inject + private ClientThread clientThread; + + @Inject + private WSClient wsClient; + + @Inject + private PartyService party; + @Inject private InfoBoxManager infoBoxManager; @Inject private ItemManager itemManager; + @Override + protected void startUp() + { + wsClient.registerMessage(SpecialCounterUpdate.class); + } + @Override protected void shutDown() { removeCounters(); + wsClient.unregisterMessage(SpecialCounterUpdate.class); } @Subscribe @@ -126,9 +151,9 @@ public class SpecialCounterPlugin extends Plugin return; } - checkInteracting(); + int interactingId = checkInteracting(); - if (specialHitpointsExperience != -1 && specialUsed) + if (interactingId > -1 && specialHitpointsExperience != -1 && specialUsed) { specialUsed = false; int hpXp = client.getSkillExperience(Skill.HITPOINTS); @@ -139,13 +164,22 @@ public class SpecialCounterPlugin extends Plugin { if (specialWeapon != null) { - updateCounter(specialWeapon, deltaExperience); + int hit = getHit(specialWeapon, deltaExperience); + + updateCounter(specialWeapon, null, hit); + + if (!party.getMembers().isEmpty()) + { + final SpecialCounterUpdate specialCounterUpdate = new SpecialCounterUpdate(interactingId, specialWeapon, hit); + specialCounterUpdate.setMemberId(party.getLocalMember().getMemberId()); + wsClient.send(specialCounterUpdate); + } } } } } - private void checkInteracting() + private int checkInteracting() { Player localPlayer = client.getLocalPlayer(); Actor interacting = localPlayer.getInteracting(); @@ -157,17 +191,26 @@ public class SpecialCounterPlugin extends Plugin if (!interactedNpcIds.contains(interactingId)) { removeCounters(); - modifier = 1d; - interactedNpcIds.add(interactingId); - - final Boss boss = Boss.getBoss(interactingId); - if (boss != null) - { - modifier = boss.getModifier(); - interactedNpcIds.addAll(boss.getIds()); - } - + addInteracting(interactingId); } + + return interactingId; + } + + return -1; + } + + private void addInteracting(int npcId) + { + modifier = 1d; + interactedNpcIds.add(npcId); + + // Add alternate forms of bosses + final Boss boss = Boss.getBoss(npcId); + if (boss != null) + { + modifier = boss.getModifier(); + interactedNpcIds.addAll(boss.getIds()); } } @@ -182,6 +225,36 @@ public class SpecialCounterPlugin extends Plugin } } + @Subscribe + public void onSpecialCounterUpdate(SpecialCounterUpdate event) + { + if (party.getLocalMember().getMemberId().equals(event.getMemberId())) + { + return; + } + + String name = party.getMemberById(event.getMemberId()).getName(); + if (name == null) + { + return; + } + + clientThread.invoke(() -> + { + // If not interacting with any npcs currently, add to interacting list + if (interactedNpcIds.isEmpty()) + { + addInteracting(event.getNpcId()); + } + + // Otherwise we only add the count if it is against a npc we are already tracking + if (interactedNpcIds.contains(event.getNpcId())) + { + updateCounter(event.getWeapon(), name, event.getHit()); + } + }); + } + private SpecialWeapon usedSpecialWeapon() { ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT); @@ -210,10 +283,9 @@ public class SpecialCounterPlugin extends Plugin return null; } - private void updateCounter(SpecialWeapon specialWeapon, int deltaExperience) + private void updateCounter(SpecialWeapon specialWeapon, String name, int hit) { SpecialCounter counter = specialCounter[specialWeapon.ordinal()]; - int hit = getHit(specialWeapon, deltaExperience); if (counter == null) { @@ -226,11 +298,25 @@ public class SpecialCounterPlugin extends Plugin { counter.addHits(hit); } + + // If in a party, add hit to partySpecs for the infobox tooltip + if (!party.getMembers().isEmpty()) + { + if (partySpecs.containsKey(name)) + { + partySpecs.put(name, hit + partySpecs.get(name)); + } + else + { + partySpecs.put(name, hit); + } + } } private void removeCounters() { interactedNpcIds.clear(); + partySpecs.clear(); for (int i = 0; i < specialCounter.length; ++i) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java new file mode 100644 index 0000000000..16eff1af25 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Trevor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.specialcounter; + +import lombok.EqualsAndHashCode; +import lombok.Value; +import net.runelite.http.api.ws.messages.party.PartyMemberMessage; + +@Value +@EqualsAndHashCode(callSuper = true) +public class SpecialCounterUpdate extends PartyMemberMessage +{ + private final int npcId; + private final SpecialWeapon weapon; + private final int hit; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java index 0deb55c2ab..ada42169ad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java @@ -24,8 +24,6 @@ */ package net.runelite.client.plugins.statusbars; -import com.google.common.base.Strings; -import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -196,28 +194,16 @@ class StatusBarsOverlay extends Overlay for (final StatChange c : statsChanges.getStatChanges()) { - final String strVar = c.getTheoretical(); - - if (Strings.isNullOrEmpty(strVar)) - { - continue; - } - - final Integer value = Ints.tryParse(strVar.startsWith("+") ? strVar.substring(1) : strVar); - - if (value == null) - { - continue; - } + final int theoreticalBoost = c.getTheoretical(); if (c.getStat().getName().equals(Skill.HITPOINTS.getName())) { - foodHealValue = value; + foodHealValue = theoreticalBoost; } if (c.getStat().getName().equals(Skill.PRAYER.getName())) { - prayerHealValue = value; + prayerHealValue = theoreticalBoost; } if (foodHealValue != 0 && prayerHealValue != 0) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsConfig.java index fcff77c540..d8d9fd7d36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsConfig.java @@ -58,7 +58,7 @@ public interface TileIndicatorsConfig extends Config @ConfigItem( keyName = "highlightCurrentColor", name = "Color of current tile highlighting", - description = "Configures the highlight color of current destination" + description = "Configures the highlight color of current tile position" ) default Color highlightCurrentColor() { @@ -74,6 +74,17 @@ public interface TileIndicatorsConfig extends Config { return false; } + + @Alpha + @ConfigItem( + keyName = "highlightHoveredColor", + name = "Color of current hovered highlighting", + description = "Configures the highlight color of hovered tile" + ) + default Color highlightHoveredColor() + { + return new Color(0, 0, 0, 0); + } @ConfigItem( keyName = "highlightHoveredTile", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsOverlay.java index b4c546ccc9..c45f147ddc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsOverlay.java @@ -42,7 +42,6 @@ import net.runelite.client.ui.overlay.OverlayUtil; public class TileIndicatorsOverlay extends Overlay { - private static final Color EMPTY = new Color(0, 0, 0, 0); private final Client client; private final TileIndicatorsConfig config; @@ -76,7 +75,7 @@ public class TileIndicatorsOverlay extends Overlay // If we have tile "selected" render it if (client.getSelectedSceneTile() != null) { - renderTile(graphics, client.getSelectedSceneTile().getLocalLocation(), EMPTY); + renderTile(graphics, client.getSelectedSceneTile().getLocalLocation(), config.highlightHoveredColor()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 1a039c008f..2a76b949be 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -59,6 +59,7 @@ import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WidgetHiddenChanged; import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import static net.runelite.api.widgets.WidgetInfo.PVP_WORLD_SAFE_ZONE; import net.runelite.client.config.ConfigManager; @@ -217,7 +218,7 @@ public class TimersPlugin extends Plugin { Widget widget = event.getWidget(); if (WorldType.isPvpWorld(client.getWorldType()) - && WidgetInfo.TO_GROUP(widget.getId()) == WidgetInfo.PVP_CONTAINER.getGroupId()) + && WidgetInfo.TO_GROUP(widget.getId()) == WidgetID.PVP_GROUP_ID) { widgetHiddenChangedOnPvpWorld = true; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java index 6be6414259..66883eedba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java @@ -93,8 +93,8 @@ public enum Produce // Tree crops OAK("Oak", ItemID.OAK_LOGS, 40, 5), WILLOW("Willow", ItemID.WILLOW_LOGS, 40, 7), - MAPLE("Maple", ItemID.MAPLE_TREE, 40, 9), - YEW("Yew", ItemID.YEW_TREE, 40, 11), + MAPLE("Maple", ItemID.MAPLE_LOGS, 40, 9), + YEW("Yew", ItemID.YEW_LOGS, 40, 11), MAGIC("Magic", ItemID.MAGIC_LOGS, 40, 13), // Fruit tree crops diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java index c87ca1ad32..275eea5d54 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.twitch; +import com.google.common.base.Strings; import com.google.inject.Provides; import java.time.temporal.ChronoUnit; import java.util.Map; @@ -96,11 +97,18 @@ public class TwitchPlugin extends Plugin implements TwitchListener, ChatboxInput return configManager.getConfig(TwitchConfig.class); } - private void connect() + private synchronized void connect() { - if (twitchConfig.username() != null - && twitchConfig.oauthToken() != null - && twitchConfig.channel() != null) + if (twitchIRCClient != null) + { + log.debug("Terminating Twitch client {}", twitchIRCClient); + twitchIRCClient.close(); + twitchIRCClient = null; + } + + if (!Strings.isNullOrEmpty(twitchConfig.username()) + && !Strings.isNullOrEmpty(twitchConfig.oauthToken()) + && !Strings.isNullOrEmpty(twitchConfig.channel())) { String channel = twitchConfig.channel().toLowerCase(); if (!channel.startsWith("#")) @@ -108,6 +116,8 @@ public class TwitchPlugin extends Plugin implements TwitchListener, ChatboxInput channel = "#" + channel; } + log.debug("Connecting to Twitch as {}", twitchConfig.username()); + twitchIRCClient = new TwitchIRCClient( this, twitchConfig.username(), @@ -145,12 +155,6 @@ public class TwitchPlugin extends Plugin implements TwitchListener, ChatboxInput return; } - if (twitchIRCClient != null) - { - twitchIRCClient.close(); - twitchIRCClient = null; - } - connect(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java new file mode 100644 index 0000000000..afbc30b766 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.wiki; + +import com.google.common.primitives.Ints; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; +import javax.inject.Provider; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.ObjectComposition; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.JavaScriptCallback; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetConfig; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetPositionMode; +import net.runelite.api.widgets.WidgetType; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.game.chatbox.ChatboxPanelManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.LinkBrowser; +import net.runelite.client.util.Text; +import okhttp3.HttpUrl; + +@Slf4j +@PluginDescriptor( + name = "Wiki", + description = "Adds a Wiki button that takes you to the OSRS Wiki" +) +public class WikiPlugin extends Plugin +{ + private static final int[] QUESTLIST_WIDGET_IDS = new int[] + { + WidgetInfo.QUESTLIST_FREE_CONTAINER.getId(), + WidgetInfo.QUESTLIST_MEMBERS_CONTAINER.getId(), + WidgetInfo.QUESTLIST_MINIQUEST_CONTAINER.getId(), + }; + + static final HttpUrl WIKI_BASE = HttpUrl.parse("https://oldschool.runescape.wiki"); + static final HttpUrl WIKI_API = WIKI_BASE.newBuilder().addPathSegments("api.php").build(); + static final String UTM_SORUCE_KEY = "utm_source"; + static final String UTM_SORUCE_VALUE = "runelite"; + + private static final String MENUOP_GUIDE = "Guide"; + private static final String MENUOP_QUICKGUIDE = "Quick Guide"; + private static final String MENUOP_WIKI = "Wiki"; + + private static final Pattern SKILL_REGEX = Pattern.compile("([A-Za-z]+) guide"); + private static final Pattern DIARY_REGEX = Pattern.compile("([A-Za-z &]+) Journal"); + + @Inject + private SpriteManager spriteManager; + + @Inject + private ClientThread clientThread; + + @Inject + private Client client; + + @Inject + private ChatboxPanelManager chatboxPanelManager; + + @Inject + private ItemManager itemManager; + + @Inject + private Provider wikiSearchChatboxTextInputProvider; + + private Widget icon; + + private boolean wikiSelected = false; + + @Override + public void startUp() + { + spriteManager.addSpriteOverrides(WikiSprite.values()); + clientThread.invokeLater(this::addWidgets); + } + + @Override + public void shutDown() + { + spriteManager.removeSpriteOverrides(WikiSprite.values()); + clientThread.invokeLater(() -> + { + Widget minimapOrbs = client.getWidget(WidgetInfo.MINIMAP_ORBS); + if (minimapOrbs == null) + { + return; + } + Widget[] children = minimapOrbs.getChildren(); + if (children == null || children.length < 1) + { + return; + } + children[0] = null; + + onDeselect(); + client.setSpellSelected(false); + }); + } + + @Subscribe + private void onWidgetLoaded(WidgetLoaded l) + { + if (l.getGroupId() == WidgetID.MINIMAP_GROUP_ID) + { + addWidgets(); + } + } + + private void addWidgets() + { + Widget minimapOrbs = client.getWidget(WidgetInfo.MINIMAP_ORBS); + if (minimapOrbs == null) + { + return; + } + + icon = minimapOrbs.createChild(0, WidgetType.GRAPHIC); + icon.setSpriteId(WikiSprite.WIKI_ICON.getSpriteId()); + icon.setOriginalX(0); + icon.setOriginalY(2); + icon.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT); + icon.setYPositionMode(WidgetPositionMode.ABSOLUTE_BOTTOM); + icon.setOriginalWidth(42); + icon.setOriginalHeight(16); + icon.setTargetVerb("Lookup"); + icon.setName("Wiki"); + icon.setClickMask(WidgetConfig.USE_GROUND_ITEM | WidgetConfig.USE_ITEM | WidgetConfig.USE_NPC | WidgetConfig.USE_OBJECT); + icon.setNoClickThrough(true); + icon.setOnTargetEnterListener((JavaScriptCallback) ev -> + { + wikiSelected = true; + icon.setSpriteId(WikiSprite.WIKI_SELECTED_ICON.getSpriteId()); + }); + icon.setAction(5, "Search"); // Start at option 5 so the target op is ontop + icon.setOnOpListener((JavaScriptCallback) ev -> + { + switch (ev.getOp()) + { + case 6: + openSearchInput(); + break; + } + }); + // This doesn't always run because we cancel the menuop + icon.setOnTargetLeaveListener((JavaScriptCallback) ev -> onDeselect()); + icon.revalidate(); + } + + private void onDeselect() + { + wikiSelected = false; + if (icon != null) + { + icon.setSpriteId(WikiSprite.WIKI_ICON.getSpriteId()); + } + } + + @Subscribe + private void onMenuOptionClicked(MenuOptionClicked ev) + { + if (wikiSelected) + { + onDeselect(); + client.setSpellSelected(false); + ev.consume(); + + String type; + int id; + String name; + WorldPoint location; + + switch (ev.getMenuAction()) + { + case CANCEL: + return; + case ITEM_USE_ON_WIDGET: + case SPELL_CAST_ON_GROUND_ITEM: + { + type = "item"; + id = itemManager.canonicalize(ev.getId()); + name = itemManager.getItemComposition(id).getName(); + location = null; + break; + } + case SPELL_CAST_ON_NPC: + { + type = "npc"; + NPC npc = client.getCachedNPCs()[ev.getId()]; + NPCComposition nc = npc.getTransformedComposition(); + id = nc.getId(); + name = nc.getName(); + location = npc.getWorldLocation(); + break; + } + case SPELL_CAST_ON_GAME_OBJECT: + { + type = "object"; + ObjectComposition lc = client.getObjectDefinition(ev.getId()); + if (lc.getImpostorIds() != null) + { + lc = lc.getImpostor(); + } + id = lc.getId(); + name = lc.getName(); + location = WorldPoint.fromScene(client, ev.getActionParam(), ev.getWidgetId(), client.getPlane()); + break; + } + default: + log.info("Unknown menu option: {} {} {}", ev, ev.getMenuAction(), ev.getMenuAction() == MenuAction.CANCEL); + return; + } + + name = Text.removeTags(name); + HttpUrl.Builder urlBuilder = WIKI_BASE.newBuilder(); + urlBuilder.addPathSegments("w/Special:Lookup") + .addQueryParameter("type", type) + .addQueryParameter("id", "" + id) + .addQueryParameter("name", name) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE); + + if (location != null) + { + urlBuilder.addQueryParameter("x", "" + location.getX()) + .addQueryParameter("y", "" + location.getY()) + .addQueryParameter("plane", "" + location.getPlane()); + } + + HttpUrl url = urlBuilder.build(); + + LinkBrowser.browse(url.toString()); + return; + } + + if (ev.getMenuAction() == MenuAction.RUNELITE) + { + boolean quickguide = false; + switch (ev.getMenuOption()) + { + case MENUOP_QUICKGUIDE: + quickguide = true; + //fallthrough; + case MENUOP_GUIDE: + ev.consume(); + String quest = Text.removeTags(ev.getMenuTarget()); + HttpUrl.Builder ub = WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(quest) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE); + if (quickguide) + { + ub.addPathSegment("Quick_guide"); + } + LinkBrowser.browse(ub.build().toString()); + break; + case MENUOP_WIKI: + Matcher skillRegex = WikiPlugin.SKILL_REGEX.matcher(Text.removeTags(ev.getMenuTarget())); + Matcher diaryRegex = WikiPlugin.DIARY_REGEX.matcher(Text.removeTags(ev.getMenuTarget())); + + if (skillRegex.find()) + { + LinkBrowser.browse(WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(skillRegex.group(1)) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) + .build().toString()); + } + else if (diaryRegex.find()) + { + LinkBrowser.browse(WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(diaryRegex.group(1) + " Diary") + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) + .build().toString()); + } + } + } + } + + private void openSearchInput() + { + wikiSearchChatboxTextInputProvider.get() + .build(); + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + int widgetIndex = event.getActionParam0(); + int widgetID = event.getActionParam1(); + MenuEntry[] menuEntries = client.getMenuEntries(); + + if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption())) + { + menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 2); + + MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); + menuEntry.setTarget(event.getTarget()); + menuEntry.setOption(MENUOP_GUIDE); + menuEntry.setParam0(widgetIndex); + menuEntry.setParam1(widgetID); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + menuEntry = menuEntries[menuEntries.length - 2] = new MenuEntry(); + menuEntry.setTarget(event.getTarget()); + menuEntry.setOption(MENUOP_QUICKGUIDE); + menuEntry.setParam0(widgetIndex); + menuEntry.setParam1(widgetID); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + client.setMenuEntries(menuEntries); + } + + if ((WidgetInfo.TO_GROUP(widgetID) == WidgetID.SKILLS_GROUP_ID && event.getOption().startsWith("View")) + || (WidgetInfo.TO_GROUP(widgetID) == WidgetID.DIARY_GROUP_ID && event.getOption().startsWith("Open"))) + { + menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + + MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); + menuEntry.setTarget(event.getOption().replace("View ", "").replace("Open ", "")); + menuEntry.setOption(MENUOP_WIKI); + menuEntry.setParam0(widgetIndex); + menuEntry.setParam1(widgetID); + menuEntry.setIdentifier(event.getIdentifier()); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + client.setMenuEntries(menuEntries); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java new file mode 100644 index 0000000000..ef3b91f9a0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.wiki; + +import com.google.common.collect.ImmutableList; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.inject.Inject; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import javax.inject.Named; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.widgets.JavaScriptCallback; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetPositionMode; +import net.runelite.api.widgets.WidgetSizeMode; +import net.runelite.api.widgets.WidgetTextAlignment; +import net.runelite.api.widgets.WidgetType; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.game.chatbox.ChatboxPanelManager; +import net.runelite.client.game.chatbox.ChatboxTextInput; +import net.runelite.client.util.LinkBrowser; +import net.runelite.http.api.RuneLiteAPI; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.HttpUrl; +import okhttp3.Request; +import okhttp3.Response; + +@Slf4j +public class WikiSearchChatboxTextInput extends ChatboxTextInput +{ + private static final int LINE_HEIGHT = 20; + private static final int CHATBOX_HEIGHT = 120; + private static final int MAX_NUM_PREDICTIONS = (CHATBOX_HEIGHT / LINE_HEIGHT) - 2; // 1 title, 1 edit + + private static final int PREDICTION_DEBOUNCE_DELAY_MS = 200; + + private final ChatboxPanelManager chatboxPanelManager; + private final Gson gson = new Gson(); + + private Future runningRequest = null; + private List predictions = ImmutableList.of(); + + private int selectedPrediction = -1; + private String offPrediction = null; + + @Inject + public WikiSearchChatboxTextInput(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread, + ScheduledExecutorService scheduledExecutorService, @Named("developerMode") final boolean developerMode) + { + super(chatboxPanelManager, clientThread); + this.chatboxPanelManager = chatboxPanelManager; + + lines(1); + prompt("OSRS Wiki Search"); + onDone(string -> + { + if (string != null && string.length() > 0) + { + search(string); + } + }); + onChanged(searchString -> + { + selectedPrediction = -1; + Future rr = runningRequest; + if (rr != null) + { + rr.cancel(false); + } + if (searchString.length() <= 1) + { + runningRequest = null; + clientThread.invokeLater(() -> + { + predictions = ImmutableList.of(); + update(); + }); + return; + } + runningRequest = scheduledExecutorService.schedule(() -> + { + HttpUrl url = WikiPlugin.WIKI_API.newBuilder() + .addQueryParameter("action", "opensearch") + .addQueryParameter("search", searchString) + .addQueryParameter("redirects", "resolve") + .addQueryParameter("format", "json") + .addQueryParameter("warningsaserror", Boolean.toString(developerMode)) + .build(); + + Request req = new Request.Builder() + .url(url) + .build(); + + RuneLiteAPI.CLIENT.newCall(req).enqueue(new Callback() + { + @Override + public void onFailure(Call call, IOException e) + { + log.warn("error searching wiki", e); + } + + @Override + public void onResponse(Call call, Response response) throws IOException + { + String body = response.body().string(); + try + { + JsonArray jar = new JsonParser().parse(body).getAsJsonArray(); + List apredictions = gson.fromJson(jar.get(1), new TypeToken>() + { + }.getType()); + + if (apredictions.size() > MAX_NUM_PREDICTIONS) + { + apredictions = apredictions.subList(0, MAX_NUM_PREDICTIONS); + } + + final List bpredictions = apredictions; + + clientThread.invokeLater(() -> + { + predictions = bpredictions; + update(); + }); + } + catch (JsonParseException | IllegalStateException | IndexOutOfBoundsException e) + { + log.warn("error parsing wiki response {}", body, e); + } + finally + { + response.close(); + } + } + }); + + runningRequest = null; + }, PREDICTION_DEBOUNCE_DELAY_MS, TimeUnit.MILLISECONDS); + }); + } + + @Override + protected void update() + { + Widget container = chatboxPanelManager.getContainerWidget(); + container.deleteAllChildren(); + + Widget promptWidget = container.createChild(-1, WidgetType.TEXT); + promptWidget.setText(getPrompt()); + promptWidget.setTextColor(0x800000); + promptWidget.setFontId(getFontID()); + promptWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER); + promptWidget.setOriginalX(0); + promptWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP); + promptWidget.setOriginalY(5); + promptWidget.setOriginalHeight(LINE_HEIGHT); + promptWidget.setXTextAlignment(WidgetTextAlignment.CENTER); + promptWidget.setYTextAlignment(WidgetTextAlignment.CENTER); + promptWidget.setWidthMode(WidgetSizeMode.MINUS); + promptWidget.revalidate(); + + buildEdit(0, 5 + LINE_HEIGHT, container.getWidth(), LINE_HEIGHT); + + Widget separator = container.createChild(-1, WidgetType.LINE); + separator.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER); + separator.setOriginalX(0); + separator.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP); + separator.setOriginalY(4 + (LINE_HEIGHT * 2)); + separator.setOriginalHeight(0); + separator.setOriginalWidth(16); + separator.setWidthMode(WidgetSizeMode.MINUS); + separator.revalidate(); + + for (int i = 0; i < predictions.size(); i++) + { + String pred = predictions.get(i); + int y = 6 + (LINE_HEIGHT * (2 + i)); + + Widget bg = container.createChild(-1, WidgetType.RECTANGLE); + bg.setTextColor(0x4444DD); + bg.setFilled(true); + bg.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER); + bg.setOriginalX(1); + bg.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP); + bg.setOriginalY(y); + bg.setOriginalHeight(LINE_HEIGHT); + bg.setOriginalWidth(16); + bg.setWidthMode(WidgetSizeMode.MINUS); + bg.revalidate(); + bg.setName("" + pred); + bg.setAction(0, "Open"); + bg.setHasListener(true); + bg.setOnOpListener((JavaScriptCallback) ev -> search(pred)); + + Widget text = container.createChild(-1, WidgetType.TEXT); + text.setText(pred); + text.setFontId(getFontID()); + text.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER); + text.setOriginalX(0); + text.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP); + text.setOriginalY(y); + text.setOriginalHeight(LINE_HEIGHT); + text.setXTextAlignment(WidgetTextAlignment.CENTER); + text.setYTextAlignment(WidgetTextAlignment.CENTER); + text.setWidthMode(WidgetSizeMode.MINUS); + text.revalidate(); + + if (i == selectedPrediction) + { + text.setTextColor(0xFFFFFF); + } + else + { + bg.setOpacity(255); + text.setTextColor(0x000000); + bg.setOnMouseRepeatListener((JavaScriptCallback) ev -> text.setTextColor(0xFFFFFF)); + bg.setOnMouseLeaveListener((JavaScriptCallback) ev -> text.setTextColor(0x000000)); + } + } + } + + @Override + public void keyPressed(KeyEvent ev) + { + switch (ev.getKeyCode()) + { + case KeyEvent.VK_UP: + ev.consume(); + if (selectedPrediction > -1) + { + selectedPrediction--; + if (selectedPrediction == -1) + { + value(offPrediction); + } + else + { + value(predictions.get(selectedPrediction)); + } + } + break; + case KeyEvent.VK_DOWN: + ev.consume(); + + if (selectedPrediction == -1) + { + offPrediction = getValue(); + } + + selectedPrediction++; + if (selectedPrediction >= predictions.size()) + { + selectedPrediction = predictions.size() - 1; + } + + if (selectedPrediction != -1) + { + value(predictions.get(selectedPrediction)); + } + break; + default: + super.keyPressed(ev); + } + } + + private void search(String search) + { + LinkBrowser.browse(WikiPlugin.WIKI_BASE.newBuilder() + .addQueryParameter("search", search) + .addQueryParameter(WikiPlugin.UTM_SORUCE_KEY, WikiPlugin.UTM_SORUCE_VALUE) + .build() + .toString()); + chatboxPanelManager.close(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSprite.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSprite.java new file mode 100644 index 0000000000..188d54837b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSprite.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.wiki; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.runelite.api.SpriteID; +import net.runelite.client.game.SpriteOverride; + +@RequiredArgsConstructor +public enum WikiSprite implements SpriteOverride +{ + WIKI_ICON(-300, "wiki.png"), + WIKI_SELECTED_ICON(-301, "wiki_selected.png"), + FIXED_MODE_MINIMAP_CLICKMASK(SpriteID.MINIMAP_CLICK_MASK, "fixed_mode_minimap_clickmask.png"); + + @Getter + private final int spriteId; + + @Getter + private final String fileName; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java index 32605d4ed0..67ac3ec635 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java @@ -32,7 +32,21 @@ import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import static net.runelite.api.AnimationID.*; +import static net.runelite.api.AnimationID.CONSTRUCTION; +import static net.runelite.api.AnimationID.FIREMAKING; +import static net.runelite.api.AnimationID.FLETCHING_BOW_CUTTING; +import static net.runelite.api.AnimationID.IDLE; +import static net.runelite.api.AnimationID.LOOKING_INTO; +import static net.runelite.api.AnimationID.WOODCUTTING_3A_AXE; +import static net.runelite.api.AnimationID.WOODCUTTING_ADAMANT; +import static net.runelite.api.AnimationID.WOODCUTTING_BLACK; +import static net.runelite.api.AnimationID.WOODCUTTING_BRONZE; +import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON; +import static net.runelite.api.AnimationID.WOODCUTTING_INFERNAL; +import static net.runelite.api.AnimationID.WOODCUTTING_IRON; +import static net.runelite.api.AnimationID.WOODCUTTING_MITHRIL; +import static net.runelite.api.AnimationID.WOODCUTTING_RUNE; +import static net.runelite.api.AnimationID.WOODCUTTING_STEEL; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.InventoryID; @@ -43,9 +57,9 @@ import static net.runelite.api.ItemID.BRUMA_ROOT; import net.runelite.api.MessageNode; import net.runelite.api.Player; import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; -import net.runelite.api.events.SetMessage; import net.runelite.client.Notifier; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; @@ -192,21 +206,21 @@ public class WintertodtPlugin extends Plugin } @Subscribe - public void onSetMessage(SetMessage setMessage) + public void onChatMessage(ChatMessage chatMessage) { if (!isInWintertodt) { return; } - ChatMessageType chatMessageType = setMessage.getType(); + ChatMessageType chatMessageType = chatMessage.getType(); if (chatMessageType != ChatMessageType.SERVER && chatMessageType != ChatMessageType.FILTERED) { return; } - MessageNode messageNode = setMessage.getMessageNode(); + MessageNode messageNode = chatMessage.getMessageNode(); final WintertodtInterruptType interruptType; if (messageNode.getValue().startsWith("The cold of")) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 07f4d727a5..b545939202 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -131,7 +131,7 @@ public class WorldHopperPlugin extends Plugin @Inject private WorldHopperConfig config; - private final ScheduledExecutorService hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); + private ScheduledExecutorService hopperExecutorService; private NavigationButton navButton; private WorldSwitcherPanel panel; @@ -201,6 +201,8 @@ public class WorldHopperPlugin extends Plugin } worldResultFuture = executorService.scheduleAtFixedRate(this::tick, 0, WORLD_FETCH_TIMER, TimeUnit.MINUTES); + + hopperExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); pingFuture = hopperExecutorService.scheduleAtFixedRate(this::pingWorlds, WORLD_PING_TIMER, WORLD_PING_TIMER, TimeUnit.MINUTES); } @@ -221,6 +223,7 @@ public class WorldHopperPlugin extends Plugin clientToolbar.removeNavigation(navButton); hopperExecutorService.shutdown(); + hopperExecutorService = null; } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutLocation.java deleted file mode 100644 index dd2e3771b6..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutLocation.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2018, Morgan Lewis - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.client.plugins.worldmap; - -import lombok.Getter; -import net.runelite.api.coords.WorldPoint; - -@Getter -enum AgilityShortcutLocation -{ - KARAMJA_GLIDER_LOG("Log Balance", 1, new WorldPoint(2906, 3050, 0)), - FALADOR_CRUMBLING_WALL("Crumbling Wall", 5, new WorldPoint(2936, 3357, 0)), - RIVER_LUM_GRAPPLE_WEST("Grapple Broken Raft", 8, new WorldPoint(3245, 3179, 0)), - RIVER_LUM_GRAPPLE_EAST("Grapple Broken Raft", 8, new WorldPoint(3258, 3179, 0)), - CORSAIR_COVE_ROCKS("Rocks", 10, new WorldPoint(2545, 2871, 0)), - FALADOR_GRAPPLE_WALL("Grapple Wall", 11, new WorldPoint(3031, 3391, 0)), - VARROCK_SOUTH_FENCE("Fence", 13, new WorldPoint(3239, 3334, 0)), - GOBLIN_VILLAGE_WALL("Wall", 14, new WorldPoint(2925, 3523, 0)), - CORSAIR_COVE_DUNGEON_PILLAR("Pillar Jump", 15, new WorldPoint(1980, 8996, 0)), - YANILLE_UNDERWALL_TUNNEL("Underwall Tunnel", 16, new WorldPoint(2574, 3109, 0)), - COAL_TRUCKS_LOG_BALANCE("Log Balance", 20, new WorldPoint(2598, 3475, 0)), - GRAND_EXCHANGE_UNDERWALL_TUNNEL("Underwall Tunnel", 21, new WorldPoint(3139, 3515, 0)), - BRIMHAVEN_DUNGEON_PIPE("Pipe Squeeze", 22, new WorldPoint(2654, 9569, 0)), - OBSERVATORY_SCALE_CLIFF("Grapple Rocks", 23, new WorldPoint(2447, 3155, 0)), - EAGLES_PEAK_ROCK_CLIMB("Rock Climb", 25, new WorldPoint(2320, 3499, 0)), - FALADOR_UNDERWALL_TUNNEL("Underwall Tunnel", 26, new WorldPoint(2947, 3313, 0)), - MOUNT_KARUULM_LOWER("Rocks", 29, new WorldPoint(1324, 3782, 0)), - CORSAIR_COVE_RESOURCE_ROCKS("Rocks", 30, new WorldPoint(2545, 2871, 0)), - SOUTHEAST_KARAJMA_STEPPING_STONES("Stepping Stones", 30, new WorldPoint(2924, 2946, 0)), - DRAYNOR_MANOR_STEPPING_STONES("Stepping Stones", 31, new WorldPoint(3150, 3362, 0)), - CATHERBY_CLIFFSIDE_GRAPPLE("Grapple Rock", 32, new WorldPoint(2868, 3429, 0)), - ARDOUGNE_LOG_BALANCE("Log Balance", 33, new WorldPoint(2602, 3336, 0)), - GNOME_STRONGHOLD_ROCKS("Rocks", 37, new WorldPoint(2485, 3515, 0)), - AL_KHARID_MINING_PITCLIFF_SCRAMBLE("Rocks", 38, new WorldPoint(3305, 3315, 0)), - YANILLE_WALL_GRAPPLE("Grapple Wall", 39, new WorldPoint(2552, 3072, 0)), - NEITIZNOT_BRIDGE_REPAIR("Bridge Repair - Quest", 40, new WorldPoint(2315, 3828, 0)), - KOUREND_LAKE_JUMP_WEST("Stepping Stones", 40, new WorldPoint(1604, 3572, 0)), - KOUREND_LAKE_JUMP_EAST("Stepping Stones", 40, new WorldPoint(1612, 3570, 0)), - TROLLHEIM_EASY_CLIFF_SCRAMBLE("Rocks", 41, new WorldPoint(2869, 3670, 0)), - DWARVEN_MINE_NARROW_CREVICE("Narrow Crevice", 42, new WorldPoint(3034, 9806, 0)), - DRAYNOR_UNDERWALL_TUNNEL("Underwall Tunnel", 42, new WorldPoint(3068, 3261, 0)), - TROLLHEIM_MEDIUM_CLIFF_SCRAMBLE_NORTH("Rocks", 43, new WorldPoint(2886, 3684, 0)), - TROLLHEIM_MEDIUM_CLIFF_SCRAMBLE_SOUTH("Rocks", 43, new WorldPoint(2876, 3666, 0)), - TROLLHEIM_ADVANCED_CLIFF_SCRAMBLE("Rocks", 44, new WorldPoint(2907, 3686, 0)), - KOUREND_RIVER_STEPPING_STONES("Stepping Stones", 45, new WorldPoint(1721, 3509, 0)), - COSMIC_ALTAR_MEDIUM_WALKWAY("Narrow Walkway", 46, new WorldPoint(2399, 4403, 0)), - DEEP_WILDERNESS_DUNGEON_CREVICE_NORTH("Narrow Crevice", 46, new WorldPoint(3047, 10335, 0)), - DEEP_WILDERNESS_DUNGEON_CREVICE_SOUTH("Narrow Crevice", 46, new WorldPoint(3045, 10327, 0)), - TROLLHEIM_HARD_CLIFF_SCRAMBLE("Rocks", 47, new WorldPoint(2902, 3680, 0)), - FREMENNIK_LOG_BALANCE("Log Balance", 48, new WorldPoint(2721, 3591, 0)), - ARCEUUS_ESSENCE_MINE_BOULDER("Boulder", 49, new WorldPoint(1774, 3888, 0)), - MORYTANIA_STEPPING_STONE("Stepping Stone", 50, new WorldPoint(3418, 3326, 0)), - VARROCK_SEWERS_PIPE_SQUEEZE("Pipe Squeeze", 51, new WorldPoint(3152, 9905, 0)), - ARCEUUS_ESSENCE_MINE_EAST_SCRAMBLE("Rock Climb", 52, new WorldPoint(1770, 3851, 0)), - KARAMJA_VOLCANO_GRAPPLE_NORTH("Grapple Rock", 53, new WorldPoint(2873, 3143, 0)), - KARAMJA_VOLCANO_GRAPPLE_SOUTH("Grapple Rock", 53, new WorldPoint(2874, 3128, 0)), - MOTHERLODE_MINE_WALL_WEST("Wall", 54, new WorldPoint(3118, 9702, 0)), - MOTHERLODE_MINE_WALL_EAST("Wall", 54, new WorldPoint(3124, 9703, 0)), - MISCELLANIA_DOCK_STEPPING_STONE("Stepping Stone", 55, new WorldPoint(2572, 3862, 0)), - RELEKKA_EAST_FENCE("Fence", 57, new WorldPoint(2688, 3697, 0)), - ELVEN_OVERPASS_CLIFF_SCRAMBLE("Rocks", 59, new WorldPoint(2345, 3300, 0)), - WILDERNESS_GWD_CLIMB_WEST("Rocks", 60, new WorldPoint(2928, 3760, 0)), - WILDERNESS_GWD_CLIMB_EAST("Rocks", 60, new WorldPoint(2943, 3770, 0)), - MOS_LEHARMLESS_STEPPING_STONE("Stepping Stone", 60, new WorldPoint(3710, 2970, 0)), - WINTERTODT_GAP("Gap", 60, new WorldPoint(1629, 4023, 0)), - SLAYER_TOWER_MEDIUM_CHAIN_FIRST("Spiked Chain (Floor 1)", 61, new WorldPoint(3421, 3550, 0)), - SLAYER_TOWER_MEDIUM_CHAIN_SECOND("Spiked Chain (Floor 2)", 61, new WorldPoint(3420, 3551, 0)), - SLAYER_DUNGEON_CREVICE("Narrow Crevice", 62, new WorldPoint(2729, 10008, 0)), - MOUNT_KARUULM_UPPER("Rocks", 62, new WorldPoint(1322, 3791, 0)), - TAVERLEY_DUNGEON_RAILING("Loose Railing", 63, new WorldPoint(2935, 9811, 0)), - TROLLHEIM_WILDERNESS_ROCKS("Rocks", 64, new WorldPoint(2945, 3678, 0)), - FOSSIL_ISLAND_VOLCANO("Rope", 64, new WorldPoint(3780, 3822, 0)), - MORYTANIA_TEMPLE("Loose Railing", 65, new WorldPoint(3422, 3476, 0)), - REVENANT_CAVES_GREEN_DRAGONS("Jump", 65, new WorldPoint(3220, 10086, 0)), - COSMIC_ALTAR_ADVANCED_WALKWAY("Narrow Walkway", 66, new WorldPoint(2408, 4401, 0)), - LUMBRIDGE_DESERT_STEPPING_STONE("Stepping Stone", 66, new WorldPoint(3210, 3135, 0)), - HEROS_GUILD_TUNNEL_WEST("Crevice", 67, new WorldPoint(2898, 9901, 0)), - HEROS_GUILD_TUNNEL_EAST("Crevice", 67, new WorldPoint(2913, 9895, 0)), - ELVEN_OVERPASS_MEDIUM_CLIFF("Rocks", 68, new WorldPoint(2337, 3288, 0)), - ARCEUUS_ESSENSE_NORTH("Rock Climb", 69, new WorldPoint(1759, 3873, 0)), - TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON("Pipe Squeeze", 70, new WorldPoint(2886, 9798, 0)), - FOSSIL_ISLAND_HARDWOOD("Hole", 70, new WorldPoint(3663, 3810, 0)), - GWD_SARADOMIN_ROPE_FIRST("Rope Descent", 70, new WorldPoint(2912, 5300, 0)), - GWD_SARADOMIN_ROPE_SECOND("Rope Descent", 70, new WorldPoint(2951, 5267, 0)), - SLAYER_TOWER_ADVANCED_CHAIN_FIRST("Spiked Chain (Floor 2)", 71, new WorldPoint(3447, 3578, 0)), - SLAYER_TOWER_ADVANCED_CHAIN_SECOND("Spiked Chain (Floor 3)", 71, new WorldPoint(3446, 3576, 0)), - SLAYER_CAVE_WALL_CLIMB("Tunnel", 72, new WorldPoint(2431, 9806, 0)), - TROLL_STRONGHOLD_WALL_CLIMB("Rocks", 73, new WorldPoint(2841, 3694, 0)), - ARCEUUS_ESSENSE_MINE_WEST("Rock Climb", 73, new WorldPoint(1742, 3853, 0)), - LAVA_DRAGON_ISLE_JUMP("Stepping Stone", 74, new WorldPoint(3200, 3807, 0)), - REVENANT_CAVES_DEMONS_JUMP("Jump", 75, new WorldPoint(3199, 10135, 0)), - REVENANT_CAVES_ANKOU_EAST("Jump", 75, new WorldPoint(3201, 10195, 0)), - REVENANT_CAVES_ANKOU_NORTH("Jump", 75, new WorldPoint(3180, 10209, 0)), - ZUL_ANDRA_ISLAND_CROSSING("Stepping Stone", 76, new WorldPoint(2156, 3073, 0)), - SHILO_VILLAGE_STEPPING_STONES("Stepping Stones", 77, new WorldPoint(2863, 2974, 0)), - KHARAZI_JUNGLE_VINE_CLIMB("Vine", 79, new WorldPoint(2897, 2939, 0)), - TAVERLEY_DUNGEON_SPIKED_BLADES("Strange Floor", 80, new WorldPoint(2877, 9813, 0)), - SLAYER_DUNGEON_CHASM_JUMP("Spiked Blades", 81, new WorldPoint(2770, 10003, 0)), - LAVA_MAZE_NORTH_JUMP("Stepping Stone", 82, new WorldPoint(3092, 3880, 0)), - BRIMHAVEN_DUNGEON_EAST_STEPPING_NORTH("Stepping Stones", 83, new WorldPoint(2685, 9547, 0)), - BRIMHAVEN_DUNGEON_EAST_STEPPING_SOUTH("Stepping Stones", 83, new WorldPoint(2693, 9529, 0)), - ELVEN_ADVANCED_CLIFF_SCRAMBLE("Rocks", 85, new WorldPoint(2337, 3253, 0)), - KALPHITE_WALL("Crevice", 86, new WorldPoint(3214, 9508, 0)), - BRIMHAVEN_DUNGEON_VINE_EAST("Vine", 87, new WorldPoint(2672, 9582, 0)), - BRIMHAVEN_DUNGEON_VINE_WEST("Vine", 87, new WorldPoint(2606, 9584, 0)), - RENEVANT_CAVES("Jump", 89, new WorldPoint(3240, 10144, 0)); - - private final String tooltip; - private final WorldPoint location; - private final int levelReq; - - AgilityShortcutLocation(String description, int level, WorldPoint location) - { - this.tooltip = description + " - Level " + level; - this.location = location; - this.levelReq = level; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutPoint.java index 74f4673c85..c99979f103 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/AgilityShortcutPoint.java @@ -27,12 +27,13 @@ package net.runelite.client.plugins.worldmap; import java.awt.image.BufferedImage; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; +import net.runelite.client.game.AgilityShortcut; class AgilityShortcutPoint extends WorldMapPoint { - AgilityShortcutPoint(AgilityShortcutLocation data, BufferedImage icon, boolean showTooltip) + AgilityShortcutPoint(AgilityShortcut data, BufferedImage icon, boolean showTooltip) { - super(data.getLocation(), icon); + super(data.getWorldMapLocation(), icon); if (showTooltip) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java index 66dde6666b..c1d9e9fb88 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java @@ -30,6 +30,7 @@ import net.runelite.api.coords.WorldPoint; enum QuestStartLocation { + //Free Quests COOKS_ASSISTANT_RFD("Cook's Assistant", new WorldPoint(3211, 3216, 0)), THE_CORSAIR_CURSE("The Corsair Curse", new WorldPoint(3029, 3273, 0)), DEMON_SLAYER("Demon Slayer", new WorldPoint(3204, 3424, 0)), @@ -48,8 +49,12 @@ enum QuestStartLocation SHIELD_OF_ARRAV("Shield of Arrav", new WorldPoint(3208, 3495, 0)), VAMPIRE_SLAYER("Vampire Slayer", new WorldPoint(3096, 3266, 0)), WITCHS_POTION("Witch's Potion", new WorldPoint(2967, 3203, 0)), + X_MARKS_THE_SPOT("X Marks the Spot", new WorldPoint(3227, 3242, 0)), + + //Members' Quests ANIMAL_MAGNETISM("Animal Magnetism", new WorldPoint(3094, 3360, 0)), ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M.", new WorldPoint(2799, 5428, 0)), + THE_ASCENT_OF_ARCEUUS("The Ascent of Arceuus", new WorldPoint(1700, 3742, 0)), BETWEEN_A_ROCK("Between a Rock...", new WorldPoint(2823, 10168, 0)), BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting", new WorldPoint(2629, 2981, 0)), BIOHAZARD("Biohazard", new WorldPoint(2591, 3335, 0)), @@ -84,6 +89,7 @@ enum QuestStartLocation FISHING_CONTEST_1("Fishing Contest", new WorldPoint(2875, 3483, 0)), FISHING_CONTEST_2("Fishing Contest", new WorldPoint(2820, 3487, 0)), FORGETTABLE_TALE("Forgettable Tale...", new WorldPoint(2826, 10215, 0)), + THE_FORSAKEN_TOWER("The Forsaken Tower", new WorldPoint(1484, 3747, 0)), THE_FREMENNIK_ISLES("The Fremennik Isles", new WorldPoint(2645, 3711, 0)), THE_FREMENNIK_TRIALS("The Fremennik Trials", new WorldPoint(2657, 3669, 0)), GARDEN_OF_TRANQUILLITY("Garden of Tranquillity", new WorldPoint(3227, 3477, 0)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/RareTreeLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/RareTreeLocation.java index 69eaedcddc..d32dee4c32 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/RareTreeLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/RareTreeLocation.java @@ -38,7 +38,6 @@ enum RareTreeLocation TEAK("Teak tree", 35, // Ape Atoll new WorldPoint(2774, 2697, 0), - new WorldPoint(2716, 2710, 0), // Desert new WorldPoint(3510, 3073, 0), @@ -85,6 +84,7 @@ enum RareTreeLocation new WorldPoint(1237, 3770, 0), // Ape Atoll + new WorldPoint(2716, 2710, 0), new WorldPoint(2725, 2735, 0), // Mos Le'Harmless @@ -140,7 +140,7 @@ enum RareTreeLocation new WorldPoint(3018, 3316, 0), new WorldPoint(3041, 3320, 0), new WorldPoint(3052, 3272, 0), - new WorldPoint(2933, 3234, 0), + new WorldPoint(2931, 3231, 0), // Misthalin new WorldPoint(3085, 3481, 0), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java index fea186927b..276e2083e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java @@ -36,6 +36,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ExperienceChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.AgilityShortcut; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; @@ -167,9 +168,10 @@ public class WorldMapPlugin extends Plugin if (config.agilityShortcutLevelIcon() || config.agilityShortcutTooltips()) { - Arrays.stream(AgilityShortcutLocation.values()) + Arrays.stream(AgilityShortcut.values()) + .filter(value -> value.getWorldMapLocation() != null) .map(value -> new AgilityShortcutPoint(value, - agilityLevel > 0 && config.agilityShortcutLevelIcon() && value.getLevelReq() > agilityLevel ? NOPE_ICON : BLANK_ICON, + agilityLevel > 0 && config.agilityShortcutLevelIcon() && value.getLevel() > agilityLevel ? NOPE_ICON : BLANK_ICON, config.agilityShortcutTooltips())) .forEach(worldMapPointManager::add); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java index f5987290eb..512be6d12e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java @@ -28,7 +28,6 @@ package net.runelite.client.plugins.xptracker; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; -import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; @@ -95,7 +94,7 @@ class XpInfoBox extends JPanel private boolean paused = false; - XpInfoBox(XpTrackerPlugin xpTrackerPlugin, XpTrackerConfig xpTrackerConfig, Client client, JPanel panel, Skill skill, SkillIconManager iconManager) throws IOException + XpInfoBox(XpTrackerPlugin xpTrackerPlugin, XpTrackerConfig xpTrackerConfig, Client client, JPanel panel, Skill skill, SkillIconManager iconManager) { this.xpTrackerConfig = xpTrackerConfig; this.panel = panel; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java index e98f4da4f7..c7bf7c3876 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.xptracker; import java.awt.BorderLayout; import java.awt.GridLayout; -import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.swing.BoxLayout; @@ -129,20 +128,13 @@ class XpPanel extends PluginPanel layoutPanel.add(overallPanel); layoutPanel.add(infoBoxPanel); - try + for (Skill skill : Skill.values()) { - for (Skill skill : Skill.values()) + if (skill == Skill.OVERALL) { - if (skill == Skill.OVERALL) - { - break; - } - infoBoxes.put(skill, new XpInfoBox(xpTrackerPlugin, xpTrackerConfig, client, infoBoxPanel, skill, iconManager)); + break; } - } - catch (IOException e) - { - log.warn(null, e); + infoBoxes.put(skill, new XpInfoBox(xpTrackerPlugin, xpTrackerConfig, client, infoBoxPanel, skill, iconManager)); } errorPanel.setContent("Exp trackers", "You have not gained experience yet."); @@ -193,7 +185,7 @@ class XpPanel extends PluginPanel } } - void updateTotal(XpSnapshotTotal xpSnapshotTotal) + void updateTotal(XpSnapshotSingle xpSnapshotTotal) { // if player has gained exp and hasn't switched displays yet, hide error panel and show overall info if (xpSnapshotTotal.getXpGainedInSession() > 0 && !overallPanel.isVisible()) @@ -201,11 +193,16 @@ class XpPanel extends PluginPanel overallPanel.setVisible(true); remove(errorPanel); } + else if (xpSnapshotTotal.getXpGainedInSession() == 0 && overallPanel.isVisible()) + { + overallPanel.setVisible(false); + add(errorPanel); + } SwingUtilities.invokeLater(() -> rebuildAsync(xpSnapshotTotal)); } - private void rebuildAsync(XpSnapshotTotal xpSnapshotTotal) + private void rebuildAsync(XpSnapshotSingle xpSnapshotTotal) { overallExpGained.setText(XpInfoBox.htmlLabel("Gained: ", xpSnapshotTotal.getXpGainedInSession())); overallExpHour.setText(XpInfoBox.htmlLabel("Per hour: ", xpSnapshotTotal.getXpPerHour())); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseState.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseState.java index 9f57de71c3..194c890c42 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseState.java @@ -49,7 +49,7 @@ class XpPauseState return findPauseState(skill).isPaused(); } - void tickXp(Skill skill, int currentXp, int pauseAfterMinutes) + void tickXp(Skill skill, long currentXp, int pauseAfterMinutes) { final XpPauseStateSingle state = findPauseState(skill); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseStateSingle.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseStateSingle.java index d74d498bd1..9e5cc55622 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseStateSingle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPauseStateSingle.java @@ -39,7 +39,7 @@ class XpPauseStateSingle @Getter private long lastChangeMillis; @Getter - private int xp; + private long xp; boolean isPaused() { @@ -66,7 +66,7 @@ class XpPauseStateSingle return pauseReasons.add(XpPauseReason.PAUSE_MANUAL); } - boolean xpChanged(int xp) + boolean xpChanged(long xp) { this.xp = xp; this.lastChangeMillis = System.currentTimeMillis(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java index a0ebb02341..16602b0cb4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java @@ -40,7 +40,6 @@ class XpState { private static final double DEFAULT_XP_MODIFIER = 4.0; private static final double SHARED_XP_MODIFIER = DEFAULT_XP_MODIFIER / 3.0; - private final XpStateTotal xpTotal = new XpStateTotal(); private final Map xpSkills = new EnumMap<>(Skill.class); private NPC interactedNPC; @@ -49,7 +48,6 @@ class XpState */ void reset() { - xpTotal.reset(); xpSkills.clear(); } @@ -58,25 +56,10 @@ class XpState * @param skill Skill to reset * @param currentXp Current XP to set to, if unknown set to -1 */ - void resetSkill(Skill skill, int currentXp) + void resetSkill(Skill skill, long currentXp) { xpSkills.remove(skill); xpSkills.put(skill, new XpStateSingle(skill, currentXp)); - recalculateTotal(); - } - - /** - * Calculates the total skill changes observed in this session or since the last reset - */ - void recalculateTotal() - { - xpTotal.reset(); - - for (XpStateSingle state : xpSkills.values()) - { - xpTotal.addXpGainedInSession(state.getXpGained()); - xpTotal.addXpPerHour(state.getXpHr()); - } } /** @@ -90,13 +73,13 @@ class XpState * @param goalEndXp Possible XP end goal * @return Whether or not the skill has been initialized, there was no change, or it has been updated */ - XpUpdateResult updateSkill(Skill skill, int currentXp, int goalStartXp, int goalEndXp) + XpUpdateResult updateSkill(Skill skill, long currentXp, int goalStartXp, int goalEndXp) { XpStateSingle state = getSkill(skill); if (state.getStartXp() == -1) { - if (currentXp > 0) + if (currentXp >= 0) { initializeSkill(skill, currentXp); return XpUpdateResult.INITIALIZED; @@ -108,7 +91,7 @@ class XpState } else { - int startXp = state.getStartXp(); + long startXp = state.getStartXp(); int gainedXp = state.getXpGained(); if (startXp + gainedXp > currentXp) @@ -208,11 +191,17 @@ class XpState * @param skill Skill to initialize * @param currentXp Current known XP for the skill */ - void initializeSkill(Skill skill, int currentXp) + void initializeSkill(Skill skill, long currentXp) { xpSkills.put(skill, new XpStateSingle(skill, currentXp)); } + boolean isInitialized(Skill skill) + { + XpStateSingle xpStateSingle = xpSkills.get(skill); + return xpStateSingle != null && xpStateSingle.getStartXp() != -1; + } + @NonNull XpStateSingle getSkill(Skill skill) { @@ -237,8 +226,8 @@ class XpState * @return An immutable snapshot of total information for this session since first login or last reset */ @NonNull - XpSnapshotTotal getTotalSnapshot() + XpSnapshotSingle getTotalSnapshot() { - return xpTotal.snapshot(); + return getSkill(Skill.OVERALL).snapshot(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateSingle.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateSingle.java index 7f4eef8d1c..2b6c694ba1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateSingle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpStateSingle.java @@ -42,7 +42,7 @@ class XpStateSingle private final Map actions = new HashMap<>(); @Getter - private final int startXp; + private final long startXp; @Getter private int xpGained = 0; @@ -60,7 +60,7 @@ class XpStateSingle return actions.get(type); } - private int getCurrentXp() + private long getCurrentXp() { return startXp + xpGained; } @@ -86,7 +86,7 @@ class XpStateSingle private int getXpRemaining() { - return endLevelExp - getCurrentXp(); + return endLevelExp - (int) getCurrentXp(); } private int getActionsRemaining() @@ -170,7 +170,7 @@ class XpStateSingle return toHourly(xpGained); } - boolean update(int currentXp, int goalStartXp, int goalEndXp) + boolean update(long currentXp, int goalStartXp, int goalEndXp) { if (startXp == -1) { @@ -178,8 +178,8 @@ class XpStateSingle return false; } - int originalXp = xpGained + startXp; - int actionExp = currentXp - originalXp; + long originalXp = xpGained + startXp; + int actionExp = (int) (currentXp - originalXp); // No experience gained if (actionExp == 0) @@ -210,28 +210,31 @@ class XpStateSingle action.setActions(action.getActions() + 1); // Calculate experience gained - xpGained = currentXp - startXp; + xpGained = (int) (currentXp - startXp); - // Determine XP goals - if (goalStartXp <= 0 || currentXp > goalEndXp) + // Determine XP goals, overall has no goals + if (skill != Skill.OVERALL) { - startLevelExp = Experience.getXpForLevel(Experience.getLevelForXp(currentXp)); - } - else - { - startLevelExp = goalStartXp; - } + if (goalStartXp <= 0 || currentXp > goalEndXp) + { + startLevelExp = Experience.getXpForLevel(Experience.getLevelForXp((int) currentXp)); + } + else + { + startLevelExp = goalStartXp; + } - if (goalEndXp <= 0 || currentXp > goalEndXp) - { - int currentLevel = Experience.getLevelForXp(currentXp); - endLevelExp = currentLevel + 1 <= Experience.MAX_VIRT_LEVEL - ? Experience.getXpForLevel(currentLevel + 1) - : Experience.MAX_SKILL_XP; - } - else - { - endLevelExp = goalEndXp; + if (goalEndXp <= 0 || currentXp > goalEndXp) + { + int currentLevel = Experience.getLevelForXp((int) currentXp); + endLevelExp = currentLevel + 1 <= Experience.MAX_VIRT_LEVEL + ? Experience.getXpForLevel(currentLevel + 1) + : Experience.MAX_SKILL_XP; + } + else + { + endLevelExp = goalEndXp; + } } return true; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 54dff5a299..a8d65962a5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -73,7 +73,7 @@ public class XpTrackerPlugin extends Plugin /** * Amount of EXP that must be gained for an update to be submitted. */ - private static final int XP_THRESHOLD = 1000; + private static final int XP_THRESHOLD = 10_000; static final List COMBAT = ImmutableList.of( Skill.ATTACK, @@ -146,16 +146,6 @@ public class XpTrackerPlugin extends Plugin clientToolbar.removeNavigation(navButton); } - private long getTotalXp() - { - long total = 0; - for (Skill skill : Skill.values()) - { - total += client.getSkillExperience(skill); - } - return total; - } - @Subscribe public void onGameStateChanged(GameStateChanged event) { @@ -195,7 +185,7 @@ public class XpTrackerPlugin extends Plugin return; } - long totalXp = getTotalXp(); + long totalXp = client.getOverallExperience(); // Don't submit xptrack unless xp threshold is reached if (Math.abs(totalXp - lastXp) > XP_THRESHOLD) { @@ -229,7 +219,16 @@ public class XpTrackerPlugin extends Plugin for (Skill skill : Skill.values()) { - int currentXp = client.getSkillExperience(skill); + long currentXp; + if (skill == Skill.OVERALL) + { + currentXp = client.getOverallExperience(); + } + else + { + currentXp = client.getSkillExperience(skill); + } + xpState.initializeSkill(skill, currentXp); } } @@ -242,7 +241,7 @@ public class XpTrackerPlugin extends Plugin { xpState.reset(); xpPanel.resetAllInfoBoxes(); - xpPanel.updateTotal(XpSnapshotTotal.zero()); + xpPanel.updateTotal(new XpSnapshotSingle.XpSnapshotSingleBuilder().build()); } /** @@ -254,9 +253,7 @@ public class XpTrackerPlugin extends Plugin { int currentXp = client.getSkillExperience(skill); xpState.resetSkill(skill, currentXp); - xpState.recalculateTotal(); xpPanel.resetSkill(skill); - xpPanel.updateTotal(xpState.getTotalSnapshot()); } /** @@ -267,7 +264,8 @@ public class XpTrackerPlugin extends Plugin { for (Skill s : Skill.values()) { - if (skill != s) + // Overall is not reset from resetting individual skills + if (skill != s && s != Skill.OVERALL) { resetSkillState(s); } @@ -302,10 +300,20 @@ public class XpTrackerPlugin extends Plugin } final XpUpdateResult updateResult = xpState.updateSkill(skill, currentXp, startGoalXp, endGoalXp); - final boolean updated = XpUpdateResult.UPDATED.equals(updateResult); - xpPanel.updateSkillExperience(updated, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill)); - xpState.recalculateTotal(); - xpPanel.updateTotal(xpState.getTotalSnapshot()); + xpPanel.updateSkillExperience(updateResult == XpUpdateResult.UPDATED, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill)); + + if (skill == Skill.CONSTRUCTION && updateResult == XpUpdateResult.INITIALIZED) + { + // Construction is the last skill initialized on login, now initialize the total experience + long overallXp = client.getOverallExperience(); + log.debug("Initializing XP tracker with {} overall exp", overallXp); + xpState.initializeSkill(Skill.OVERALL, overallXp); + } + else if (xpState.isInitialized(Skill.OVERALL)) + { + xpState.updateSkill(Skill.OVERALL, client.getOverallExperience(), -1, -1); + xpPanel.updateTotal(xpState.getTotalSnapshot()); + } } @Subscribe @@ -325,7 +333,6 @@ public class XpTrackerPlugin extends Plugin xpPanel.updateSkillExperience(updated, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill)); } - xpState.recalculateTotal(); xpPanel.updateTotal(xpState.getTotalSnapshot()); } @@ -335,7 +342,7 @@ public class XpTrackerPlugin extends Plugin rebuildSkills(); if (fetchXp) { - lastXp = getTotalXp(); + lastXp = client.getOverallExperience(); fetchXp = false; } } @@ -464,7 +471,17 @@ public class XpTrackerPlugin extends Plugin // Adjust unpause states for (Skill skill : Skill.values()) { - xpPauseState.tickXp(skill, client.getSkillExperience(skill), xpTrackerConfig.pauseSkillAfter()); + long skillExperience; + if (skill == Skill.OVERALL) + { + skillExperience = client.getOverallExperience(); + } + else + { + skillExperience = client.getSkillExperience(skill); + } + + xpPauseState.tickXp(skill, skillExperience, xpTrackerConfig.pauseSkillAfter()); } xpPauseState.tickLogout(xpTrackerConfig.pauseOnLogout(), !GameState.LOGIN_SCREEN.equals(client.getGameState())); @@ -498,7 +515,6 @@ public class XpTrackerPlugin extends Plugin xpPanel.updateSkillExperience(false, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill)); } - xpState.recalculateTotal(); xpPanel.updateTotal(xpState.getTotalSnapshot()); } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 9e81d59b00..56ba0799d2 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -38,6 +38,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.jar.JarEntry; @@ -46,7 +51,9 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; -import static net.runelite.client.rs.ClientUpdateCheckMode.*; +import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO; +import static net.runelite.client.rs.ClientUpdateCheckMode.NONE; +import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA; import net.runelite.http.api.RuneLiteAPI; import okhttp3.Request; import okhttp3.Response; @@ -81,6 +88,7 @@ public class ClientLoader Map zipFile = new HashMap<>(); { + Certificate[] jagexCertificateChain = getJagexCertificateChain(); String codebase = config.getCodeBase(); String initialJar = config.getInitialJar(); URL url = new URL(codebase + initialJar); @@ -113,6 +121,20 @@ public class ClientLoader buffer.write(tmp, 0, n); } + if (!Arrays.equals(metadata.getCertificates(), jagexCertificateChain)) + { + if (metadata.getName().startsWith("META-INF/")) + { + // META-INF/JAGEXLTD.SF and META-INF/JAGEXLTD.RSA are not signed, but we don't need + // anything in META-INF anyway. + continue; + } + else + { + throw new VerificationException("Unable to verify jar entry: " + metadata.getName()); + } + } + zipFile.put(metadata.getName(), buffer.toByteArray()); } } @@ -201,7 +223,8 @@ public class ClientLoader return rs; } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException - | CompressorException | InvalidHeaderException e) + | CompressorException | InvalidHeaderException | CertificateException | VerificationException + | SecurityException e) { if (e instanceof ClassNotFoundException) { @@ -211,8 +234,14 @@ public class ClientLoader } log.error("Error loading RS!", e); - System.exit(-1); return null; } } + + private static Certificate[] getJagexCertificateChain() throws CertificateException + { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + Collection certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt")); + return certificates.toArray(new Certificate[certificates.size()]); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/VerificationException.java b/runelite-client/src/main/java/net/runelite/client/rs/VerificationException.java new file mode 100644 index 0000000000..040370e8f0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/rs/VerificationException.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.rs; + +class VerificationException extends Exception +{ + public VerificationException(String message) + { + super(message); + } + + public VerificationException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientPluginToolbar.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientPluginToolbar.java index 13d05def08..e7a280b998 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientPluginToolbar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientPluginToolbar.java @@ -30,6 +30,7 @@ import java.awt.Component; import java.awt.Dimension; import java.util.Map; import java.util.TreeMap; +import javax.swing.Box; import javax.swing.JToolBar; /** @@ -57,7 +58,6 @@ public class ClientPluginToolbar extends JToolBar setMinimumSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT)); setPreferredSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT)); setMaximumSize(new Dimension(TOOLBAR_WIDTH, Integer.MAX_VALUE)); - addSeparator(); } void addComponent(final NavigationButton button, final Component c) @@ -86,6 +86,7 @@ public class ClientPluginToolbar extends JToolBar if (!entry.getKey().isTab() && !isDelimited) { isDelimited = true; + add(Box.createVerticalGlue()); addSeparator(); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 59ce146601..56c3865ae4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -52,6 +52,7 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JOptionPane; +import static javax.swing.JOptionPane.ERROR_MESSAGE; import static javax.swing.JOptionPane.INFORMATION_MESSAGE; import javax.swing.JPanel; import javax.swing.JRootPane; @@ -510,8 +511,14 @@ public class ClientUI }); // Show out of date dialog if needed - final boolean isOutdated = !(client instanceof Client); - if (isOutdated) + if (client == null) + { + SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame, + "Error loading client! Check your logs for more details.", + "Unable to load client", + ERROR_MESSAGE)); + } + else if (!(client instanceof Client)) { SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame, "RuneLite has not yet been updated to work with the latest\n" diff --git a/runelite-client/src/main/java/net/runelite/client/ui/JagexColors.java b/runelite-client/src/main/java/net/runelite/client/ui/JagexColors.java index 7e2faadfad..38b1ea657f 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/JagexColors.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/JagexColors.java @@ -37,6 +37,7 @@ public class JagexColors public static final Color CHAT_PUBLIC_TEXT_OPAQUE_BACKGROUND = Color.BLUE; public static final Color CHAT_PRIVATE_MESSAGE_TEXT_OPAQUE_BACKGROUND = Color.CYAN; public static final Color CHAT_CLAN_TEXT_OPAQUE_BACKGROUND = new Color(127, 0, 0); + public static final Color CHAT_CLAN_NAME_OPAQUE_BACKGROUND = Color.BLUE; public static final Color CHAT_GAME_EXAMINE_TEXT_OPAQUE_BACKGROUND = Color.BLACK; public static final Color CHAT_TYPED_TEXT_OPAQUE_BACKGROUND = Color.BLUE; @@ -45,7 +46,8 @@ public class JagexColors */ public static final Color CHAT_PUBLIC_TEXT_TRANSPARENT_BACKGROUND = new Color(144, 144, 255); public static final Color CHAT_PRIVATE_MESSAGE_TEXT_TRANSPARENT_BACKGROUND = Color.CYAN; - public static final Color CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND = new Color(127, 0, 0); + public static final Color CHAT_CLAN_TEXT_TRANSPARENT_BACKGROUND = new Color(239, 80, 80); + public static final Color CHAT_CLAN_NAME_TRANSPARENT_BACKGROUND = new Color(144, 112, 255); public static final Color CHAT_GAME_EXAMINE_TEXT_TRANSPARENT_BACKGROUND = Color.WHITE; public static final Color CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND = new Color(144, 144, 255); @@ -60,4 +62,10 @@ public class JagexColors public static final Color TOOLTIP_BACKGROUND = new Color(255, 255, 160); public static final Color TOOLTIP_BORDER = Color.BLACK; public static final Color TOOLTIP_TEXT = Color.BLACK; + + /* + * Colors used in interfaces + */ + public static final Color DARK_ORANGE_INTERFACE_TEXT = new Color(255, 152, 31); + public static final Color YELLOW_INTERFACE_TEXT = Color.YELLOW; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java index b5d335e9fb..a90d53eb87 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java @@ -94,7 +94,6 @@ public class ProgressBar extends DimmableJPanel super.paint(g); g.setColor(getForeground()); g.fillRect(0, 0, topWidth, 16); - g.setColor(getForeground().darker()); for (final Double position : positions) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java index b5fd07609c..87a4de12ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java @@ -44,6 +44,7 @@ public class WidgetOverlay extends Overlay .put(WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT) .put(WidgetInfo.FOSSIL_ISLAND_OXYGENBAR, OverlayPosition.TOP_LEFT) .put(WidgetInfo.EXPERIENCE_TRACKER_WIDGET, OverlayPosition.TOP_RIGHT) + .put(WidgetInfo.RAIDS_POINTS_INFOBOX, OverlayPosition.TOP_RIGHT) .put(WidgetInfo.TITHE_FARM, OverlayPosition.TOP_RIGHT) .put(WidgetInfo.PEST_CONTROL_BOAT_INFO, OverlayPosition.TOP_LEFT) .put(WidgetInfo.PEST_CONTROL_INFO, OverlayPosition.TOP_LEFT) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java index 05ddc35395..39ec431697 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java @@ -27,7 +27,9 @@ package net.runelite.client.ui.overlay.components; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Rectangle; import java.awt.image.BufferedImage; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; @@ -36,6 +38,10 @@ import lombok.Setter; public class ImageComponent implements LayoutableRenderableEntity { private final BufferedImage image; + + @Getter + private final Rectangle bounds = new Rectangle(); + private Point preferredLocation = new Point(); @Override @@ -47,7 +53,10 @@ public class ImageComponent implements LayoutableRenderableEntity } graphics.drawImage(image, preferredLocation.x, preferredLocation.y, null); - return new Dimension(image.getWidth(), image.getHeight()); + final Dimension dimension = new Dimension(image.getWidth(), image.getHeight()); + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); + return dimension; } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java index ca6c55d3be..d8f7841099 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java @@ -24,6 +24,7 @@ */ package net.runelite.client.ui.overlay.components; +import com.google.common.base.Strings; import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; @@ -45,11 +46,10 @@ public class InfoBoxComponent implements LayoutableRenderableEntity private String tooltip; @Getter + private final Rectangle bounds = new Rectangle(); + private Point preferredLocation = new Point(); - - @Setter private Dimension preferredSize = new Dimension(DEFAULT_SIZE, DEFAULT_SIZE); - private String text; private Color color = Color.WHITE; private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR; @@ -64,12 +64,14 @@ public class InfoBoxComponent implements LayoutableRenderableEntity } graphics.setFont(getSize() < DEFAULT_SIZE ? FontManager.getRunescapeSmallFont() : FontManager.getRunescapeFont()); - graphics.translate(preferredLocation.x, preferredLocation.y); + + final int baseX = preferredLocation.x; + final int baseY = preferredLocation.y; // Calculate dimensions final FontMetrics metrics = graphics.getFontMetrics(); final int size = getSize(); - final Rectangle bounds = new Rectangle(size, size); + final Rectangle bounds = new Rectangle(baseX, baseY, size, size); // Render background final BackgroundComponent backgroundComponent = new BackgroundComponent(); @@ -80,26 +82,24 @@ public class InfoBoxComponent implements LayoutableRenderableEntity // Render image graphics.drawImage( image, - (size - image.getWidth(null)) / 2, - (size - image.getHeight(null)) / 2, + baseX + (size - image.getWidth(null)) / 2, + baseY + (size - image.getHeight(null)) / 2, null); // Render caption - final TextComponent textComponent = new TextComponent(); - textComponent.setColor(color); - textComponent.setText(text); - textComponent.setPosition(new Point(((size - metrics.stringWidth(text)) / 2), size - SEPARATOR)); - textComponent.render(graphics); + if (!Strings.isNullOrEmpty(text)) + { + final TextComponent textComponent = new TextComponent(); + textComponent.setColor(color); + textComponent.setText(text); + textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - SEPARATOR)); + textComponent.render(graphics); + } - graphics.translate(-preferredLocation.x, -preferredLocation.y); + this.bounds.setBounds(bounds); return bounds.getSize(); } - public Dimension getPreferredSize() - { - return new Dimension(getSize(), getSize()); - } - private int getSize() { return Math.max(preferredSize.width, preferredSize.height); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LayoutableRenderableEntity.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LayoutableRenderableEntity.java index ba7f1e7717..7a736686d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LayoutableRenderableEntity.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LayoutableRenderableEntity.java @@ -26,10 +26,12 @@ package net.runelite.client.ui.overlay.components; import java.awt.Dimension; import java.awt.Point; +import java.awt.Rectangle; import net.runelite.client.ui.overlay.RenderableEntity; public interface LayoutableRenderableEntity extends RenderableEntity { + Rectangle getBounds(); void setPreferredLocation(Point position); void setPreferredSize(Dimension dimension); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java index efe7f407a6..f6c2f5e77c 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java @@ -31,7 +31,9 @@ import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Rectangle; import lombok.Builder; +import lombok.Getter; import lombok.Setter; @Setter @@ -53,17 +55,22 @@ public class LineComponent implements LayoutableRenderableEntity @Builder.Default private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0); + @Builder.Default + @Getter + private final Rectangle bounds = new Rectangle(); + @Override public Dimension render(Graphics2D graphics) { - graphics.translate(preferredLocation.x, preferredLocation.y); // Prevent NPEs final String left = MoreObjects.firstNonNull(this.left, ""); final String right = MoreObjects.firstNonNull(this.right, ""); final FontMetrics metrics = graphics.getFontMetrics(); - int x = 0; - int y = metrics.getHeight(); + final int baseX = preferredLocation.x; + final int baseY = preferredLocation.y + metrics.getHeight(); + int x = baseX; + int y = baseY; final int leftFullWidth = getLineWidth(left, metrics); final int rightFullWidth = getLineWidth(right, metrics); @@ -112,8 +119,10 @@ public class LineComponent implements LayoutableRenderableEntity y += metrics.getHeight(); } - graphics.translate(-preferredLocation.x, -preferredLocation.y); - return new Dimension(preferredSize.width, y - metrics.getHeight()); + final Dimension dimension = new Dimension(preferredSize.width, y - baseY); + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); + return dimension; } final TextComponent leftLineComponent = new TextComponent(); @@ -129,8 +138,10 @@ public class LineComponent implements LayoutableRenderableEntity rightLineComponent.render(graphics); y += metrics.getHeight(); - graphics.translate(-preferredLocation.x, -preferredLocation.y); - return new Dimension(preferredSize.width, y - metrics.getHeight()); + final Dimension dimension = new Dimension(preferredSize.width, y - baseY); + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); + return dimension; } private static int getLineWidth(final String line, final FontMetrics metrics) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java index 974ec37240..5ea81f2006 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java @@ -43,9 +43,8 @@ public class PanelComponent implements LayoutableRenderableEntity VERTICAL; } - @Setter - @Nullable - private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR; + @Getter + private final Rectangle bounds = new Rectangle(); @Setter private Point preferredLocation = new Point(); @@ -53,8 +52,12 @@ public class PanelComponent implements LayoutableRenderableEntity @Setter private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0); + @Setter + @Nullable + private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR; + @Getter - private List children = new ArrayList<>(); + private final List children = new ArrayList<>(); @Setter private Orientation orientation = Orientation.VERTICAL; @@ -82,8 +85,6 @@ public class PanelComponent implements LayoutableRenderableEntity return null; } - graphics.translate(preferredLocation.x, preferredLocation.y); - // Calculate panel dimension final Dimension dimension = new Dimension( border.x + childDimensions.width + border.width, @@ -93,14 +94,14 @@ public class PanelComponent implements LayoutableRenderableEntity if (backgroundColor != null) { final BackgroundComponent backgroundComponent = new BackgroundComponent(); - backgroundComponent.setRectangle(new Rectangle(dimension)); + backgroundComponent.setRectangle(new Rectangle(preferredLocation, dimension)); backgroundComponent.setBackgroundColor(backgroundColor); backgroundComponent.render(graphics); } // Offset children - final int baseX = border.x; - final int baseY = border.y; + final int baseX = preferredLocation.x + border.x; + final int baseY = preferredLocation.y + border.y; int width = 0; int height = 0; int x = baseX; @@ -174,7 +175,9 @@ public class PanelComponent implements LayoutableRenderableEntity // Cache children bounds childDimensions.setSize(totalWidth, totalHeight); - graphics.translate(-preferredLocation.x, -preferredLocation.y); + // Cache bounds + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); return dimension; } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java index 0db182739a..ba4634deec 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java @@ -29,7 +29,9 @@ import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Rectangle; import java.text.DecimalFormat; +import lombok.Getter; import lombok.Setter; @Setter @@ -43,6 +45,7 @@ public class ProgressBarComponent implements LayoutableRenderableEntity private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0"); private static final DecimalFormat DECIMAL_FORMAT_ABS = new DecimalFormat("#0"); + private long minimum; private long maximum = 100; private double value; @@ -53,14 +56,16 @@ public class ProgressBarComponent implements LayoutableRenderableEntity private Point preferredLocation = new Point(); private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 16); + @Getter + private final Rectangle bounds = new Rectangle(); + @Override public Dimension render(Graphics2D graphics) { - graphics.translate(preferredLocation.x, preferredLocation.y); final FontMetrics metrics = graphics.getFontMetrics(); - final int barX = 0; - final int barY = 0; + final int barX = preferredLocation.x; + final int barY = preferredLocation.y; final long span = maximum - minimum; final double currentValue = value - minimum; @@ -82,7 +87,7 @@ public class ProgressBarComponent implements LayoutableRenderableEntity final int progressTextY = barY + ((height - metrics.getHeight()) / 2) + metrics.getHeight(); final int progressFill = (int) (width * Math.min(1, pc)); - //Draw bar + // Draw bar graphics.setColor(backgroundColor); graphics.fillRect(barX, barY, width, height); graphics.setColor(foregroundColor); @@ -94,7 +99,9 @@ public class ProgressBarComponent implements LayoutableRenderableEntity textComponent.setText(textToWrite); textComponent.render(graphics); - graphics.translate(-preferredLocation.x, -preferredLocation.y); - return new Dimension(width, height); + final Dimension dimension = new Dimension(width, height); + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); + return dimension; } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java index 093d596fe9..fa4c9bc3bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java @@ -29,7 +29,9 @@ import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Rectangle; import lombok.Builder; +import lombok.Getter; import lombok.Setter; @Setter @@ -47,17 +49,26 @@ public class TitleComponent implements LayoutableRenderableEntity @Builder.Default private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0); + @Builder.Default + @Getter + private final Rectangle bounds = new Rectangle(); + @Override public Dimension render(Graphics2D graphics) { - graphics.translate(preferredLocation.x, preferredLocation.y); + final int baseX = preferredLocation.x; + final int baseY = preferredLocation.y; final FontMetrics metrics = graphics.getFontMetrics(); final TextComponent titleComponent = new TextComponent(); titleComponent.setText(text); titleComponent.setColor(color); - titleComponent.setPosition(new Point((preferredSize.width - metrics.stringWidth(text)) / 2, metrics.getHeight())); - final Dimension dimension = titleComponent.render(graphics); - graphics.translate(-preferredLocation.x, -preferredLocation.y); - return new Dimension(preferredSize.width, dimension.height); + titleComponent.setPosition(new Point( + baseX + ((preferredSize.width - metrics.stringWidth(text)) / 2), + baseY + metrics.getHeight())); + final Dimension rendered = titleComponent.render(graphics); + final Dimension dimension = new Dimension(preferredSize.width, rendered.height); + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); + return dimension; } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java index 599a178838..a498d4200d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Counter.java @@ -26,33 +26,28 @@ package net.runelite.client.ui.overlay.infobox; import java.awt.Color; import java.awt.image.BufferedImage; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import net.runelite.client.plugins.Plugin; +@ToString public class Counter extends InfoBox { - private String text; + @Getter + @Setter + private int count; - public Counter(BufferedImage image, Plugin plugin, String text) + public Counter(BufferedImage image, Plugin plugin, int count) { super(image, plugin); - this.text = text; - } - - @Override - public String toString() - { - return "Counter{" + "text=" + text + '}'; + this.count = count; } @Override public String getText() { - return text; - } - - public void setText(String text) - { - this.text = text; + return Integer.toString(getCount()); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java index fc498d3635..8c2889e8e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java @@ -26,24 +26,25 @@ package net.runelite.client.ui.overlay.infobox; import java.awt.Color; import java.awt.Image; +import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import net.runelite.client.plugins.Plugin; public abstract class InfoBox { - @Getter + @Getter(AccessLevel.PACKAGE) private final Plugin plugin; @Getter @Setter private Image image; - @Getter - @Setter + @Getter(AccessLevel.PACKAGE) + @Setter(AccessLevel.PACKAGE) private Image scaledImage; - @Getter + @Getter(AccessLevel.PACKAGE) @Setter private InfoBoxPriority priority; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java index 8cea4cc94e..4fd1c1ca11 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java @@ -76,18 +76,18 @@ public class InfoBoxManager public void removeInfoBox(InfoBox infoBox) { - log.debug("Removing InfoBox {}", infoBox); if (infoBoxes.remove(infoBox)) { + log.debug("Removed InfoBox {}", infoBox); refreshInfoBoxes(); } } public void removeIf(Predicate filter) { - log.debug("Removing InfoBoxes for filter {}", filter); if (infoBoxes.removeIf(filter)) { + log.debug("Removed InfoBoxes for filter {}", filter); refreshInfoBoxes(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java index 15165a4edb..58f20aae63 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java @@ -26,6 +26,7 @@ package net.runelite.client.ui.overlay.infobox; import com.google.common.base.Strings; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -37,7 +38,6 @@ import net.runelite.api.Client; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.InfoBoxComponent; import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -95,10 +95,16 @@ public class InfoBoxOverlay extends Overlay continue; } + final String text = box.getText(); + final Color color = box.getTextColor(); + final InfoBoxComponent infoBoxComponent = new InfoBoxComponent(); - infoBoxComponent.setColor(box.getTextColor()); + infoBoxComponent.setText(text); + if (color != null) + { + infoBoxComponent.setColor(color); + } infoBoxComponent.setImage(box.getScaledImage()); - infoBoxComponent.setText(box.getText()); infoBoxComponent.setTooltip(box.getTooltip()); panelComponent.getChildren().add(infoBoxComponent); } @@ -116,15 +122,10 @@ public class InfoBoxOverlay extends Overlay if (!Strings.isNullOrEmpty(component.getTooltip())) { - final Rectangle intersectionRectangle = new Rectangle(component.getPreferredLocation(), component.getPreferredSize()); - - // Move the intersection based on overlay position + // Create intersection rectangle + final Rectangle intersectionRectangle = new Rectangle(component.getBounds()); intersectionRectangle.translate(getBounds().x, getBounds().y); - // Move the intersection based on overlay "orientation" - final Point transformed = OverlayUtil.transformPosition(getPosition(), intersectionRectangle.getSize()); - intersectionRectangle.translate(transformed.x, transformed.y); - if (intersectionRectangle.contains(mouse)) { tooltipManager.add(new Tooltip(component.getTooltip())); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java index 3219b487b2..4d6c2b7be4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/Timer.java @@ -31,9 +31,11 @@ import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; import lombok.Getter; +import lombok.ToString; import net.runelite.client.plugins.Plugin; @Getter +@ToString public class Timer extends InfoBox { private final Instant startTime; @@ -51,12 +53,6 @@ public class Timer extends InfoBox endTime = startTime.plus(duration); } - @Override - public String toString() - { - return "Timer{" + "startTime=" + startTime + ", endTime=" + endTime + ", duration=" + duration + '}'; - } - @Override public String getText() { diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 1fa63d815e..16a6b1c78a 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -30,6 +30,7 @@ import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; +import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.RescaleOp; import java.io.IOException; @@ -426,8 +427,19 @@ public class ImageUtil try { - new PixelGrabber(image, 0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()) - .grabPixels(); + PixelGrabber g = new PixelGrabber(image, 0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + g.setColorModel(new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000)); + g.grabPixels(); + + // Make any fully transparent pixels fully black, because the sprite draw routines + // check for == 0, not actual transparency + for (int i = 0; i < pixels.length; i++) + { + if ((pixels[i] & 0xFF000000) == 0) + { + pixels[i] = 0; + } + } } catch (InterruptedException ex) { diff --git a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java index 173a383bbe..194b1974b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java +++ b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java @@ -43,6 +43,8 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class LinkBrowser { + private static boolean shouldAttemptXdg = OSType.getOSType() == OSType.Linux; + /** * Tries to navigate to specified URL in browser. In case operation fails, displays message box with message * and copies link to clipboard to navigate to. @@ -56,9 +58,55 @@ public class LinkBrowser return false; } + if (attemptDesktopBrowse(url)) + { + log.debug("Opened browser through Desktop#browse to {}", url); + return true; + } + + if (shouldAttemptXdg && attemptXdgOpen(url)) + { + log.debug("Opened browser through xdg-open to {}", url); + return true; + } + + showMessageBox("Unable to open link. Press 'OK' and link will be copied to your clipboard.", url); + return false; + } + + private static boolean attemptXdgOpen(String url) + { + try + { + final Process exec = Runtime.getRuntime().exec(new String[]{"xdg-open", url}); + exec.waitFor(); + + final int ret = exec.exitValue(); + if (ret == 0) + { + return true; + } + + log.warn("xdg-open {} returned with error code {}", url, ret); + return false; + } + catch (IOException ex) + { + // xdg-open not found + shouldAttemptXdg = false; + return false; + } + catch (InterruptedException ex) + { + log.warn("Interrupted while waiting for xdg-open {} to execute", url); + return false; + } + } + + private static boolean attemptDesktopBrowse(String url) + { if (!Desktop.isDesktopSupported()) { - showMessageBox("Desktop is not supported. Press 'OK' and link will be copied to your clipboard.", url); return false; } @@ -66,20 +114,17 @@ public class LinkBrowser if (!desktop.isSupported(Desktop.Action.BROWSE)) { - showMessageBox("Desktop browser is not supported. Press 'OK' and link will be copied to your clipboard.", url); return false; } try { desktop.browse(new URI(url)); - log.debug("Opened browser to {}", url); return true; } catch (IOException | URISyntaxException ex) { - log.warn("Unable to open URL {}. Error: {}", url, ex); - showMessageBox("Unable to open a URL. Press 'OK' and link will be copied to your clipboard.", url); + log.warn("Failed to open Desktop#browser {}", url, ex); return false; } } diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 194ea684f2..d196c9e9d2 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -6705,10 +6705,6 @@ 10370, 10790 ], - "guthix dragonhide": [ - 10378, - 10794 - ], "saradomin dhide": [ 10386, 10792 @@ -8908,5 +8904,11 @@ 23067, 23068, 23070 + ], + "mystic set": [ + 23110, + 23113, + 23116, + 23119 ] } \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/info/import_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/info/import_icon.png new file mode 100644 index 0000000000..32263bf159 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/info/import_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-DISEASE.png b/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-DISEASE.png new file mode 100644 index 0000000000..f2ff5ac911 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-DISEASE.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-POISON.png b/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-POISON.png new file mode 100644 index 0000000000..a4b05c1ca1 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-POISON.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-VENOM.png b/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-VENOM.png new file mode 100644 index 0000000000..df6816bb74 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/poison/1067-VENOM.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json index ae795fdcc4..d78b804943 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_farming.json @@ -60,6 +60,12 @@ "name": "Sweetcorn", "xp": 17 }, + { + "level": 23, + "icon": 21504, + "name": "Giant seaweed", + "xp": 21 + }, { "level": 26, "icon": 255, @@ -180,18 +186,36 @@ "name": "Papaya Tree", "xp": 6218.4 }, + { + "level": 57, + "icon": 22932, + "name": "White lily", + "xp": 292 + }, { "level": 60, "icon": 1515, "name": "Yew Tree", "xp": 7150.9 }, + { + "level": 61, + "icon": 231, + "name": "Snape grass", + "xp": 82 + }, { "level": 62, "icon": 3000, "name": "Snapdragon", "xp": 87.5 }, + { + "level": 65, + "icon": 23044, + "name": "Hespori", + "xp": 12662 + }, { "level": 67, "icon": 265, @@ -228,17 +252,35 @@ "name": "Dwarf Weed", "xp": 170.5 }, + { + "level": 82, + "icon": 22929, + "name": "Dragonfruit Tree", + "xp": 17895 + }, { "level": 83, "icon": 6063, "name": "Spirit Tree", "xp": 19501.3 }, + { + "level": 85, + "icon": 22935, + "name": "Celastrus Tree", + "xp": 14334 + }, { "level": 85, "icon": 269, "name": "Torstol", "xp": 199.5 + }, + { + "level": 90, + "icon": 19669, + "name": "Redwood Tree", + "xp": 22680 } ] } \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json index f546d5947b..c25cb8beda 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json @@ -60,6 +60,12 @@ "name": "Harralander", "xp": 6.3 }, + { + "level": 21, + "icon": 6472, + "name": "Compost Potion (3)", + "xp": 60 + }, { "level": 22, "icon": 127, @@ -282,6 +288,18 @@ "name": "Antidote++ (3)", "xp": 177.5 }, + { + "level": 80, + "icon": 22464, + "name": "Bastion Potion (3)", + "xp": 155 + }, + { + "level": 80, + "icon": 22452, + "name": "Battlemage Potion (3)", + "xp": 155 + }, { "level": 81, "icon": 6687, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_magic.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_magic.json index 38719b3d00..15905e0a0c 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_magic.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_magic.json @@ -238,7 +238,7 @@ "level": 37, "sprite": 33, "name": "Falador Teleport", - "xp": 47 + "xp": 48 }, { "level": 39, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_prayer.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_prayer.json index 7cfb4a790e..292fab6b8f 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_prayer.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_prayer.json @@ -235,12 +235,6 @@ "name": "Babydragon Bones", "xp": 30 }, - { - "level": 1, - "icon": 22780, - "name": "Wyrm Bones", - "xp": 30 - }, { "level": 1, "icon": 3398, @@ -250,9 +244,9 @@ }, { "level": 1, - "icon": 4834, - "name": "Ourg Bones", - "xp": 140 + "icon": 22780, + "name": "Wyrm Bones", + "xp": 50 }, { "level": 1, @@ -261,12 +255,6 @@ "xp": 59.5, "ignoreBonus": true }, - { - "level": 1, - "icon": 22783, - "name": "Drake Bones", - "xp": 60 - }, { "level": 1, "icon": 6812, @@ -279,6 +267,12 @@ "name": "Dragon Bones", "xp": 72 }, + { + "level": 1, + "icon": 22783, + "name": "Drake Bones", + "xp": 80 + }, { "level": 1, "icon": 3402, @@ -305,24 +299,30 @@ "name": "Lava Dragon Bones", "xp": 85 }, - { - "level": 1, - "icon": 22786, - "name": "Hydra Bones", - "xp": 90 - }, { "level": 1, "icon": 4832, "name": "Raurg Bones", "xp": 96 }, + { + "level": 1, + "icon": 22786, + "name": "Hydra Bones", + "xp": 110 + }, { "level": 1, "icon": 6729, "name": "Dagannoth Bones", "xp": 125 }, + { + "level": 1, + "icon": 4834, + "name": "Ourg Bones", + "xp": 140 + }, { "level": 70, "icon": 22124, diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/fixed_mode_minimap_clickmask.png b/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/fixed_mode_minimap_clickmask.png new file mode 100644 index 0000000000..ba5a23c151 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/fixed_mode_minimap_clickmask.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/wiki.png b/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/wiki.png new file mode 100644 index 0000000000..ef2ff20ff0 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/wiki.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/wiki_selected.png b/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/wiki_selected.png new file mode 100644 index 0000000000..80838fb5c4 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/wiki/wiki_selected.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/rs/jagex.crt b/runelite-client/src/main/resources/net/runelite/client/rs/jagex.crt new file mode 100644 index 0000000000..06777e1b5e --- /dev/null +++ b/runelite-client/src/main/resources/net/runelite/client/rs/jagex.crt @@ -0,0 +1,79 @@ +-----BEGIN CERTIFICATE----- +MIIEozCCA4ugAwIBAgIPG66Q8BYiduuCbyAdmzRTMA0GCSqGSIb3DQEBCwUAMEwx +CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xJjAkBgNVBAMTHXRo +YXd0ZSBTSEEyNTYgQ29kZSBTaWduaW5nIENBMB4XDTE4MDgxNDAwMDAwMFoXDTIx +MTEwMzIzNTk1OVowYjELMAkGA1UEBhMCR0IxFzAVBgNVBAgMDkNhbWJyaWRnZXNo +aXJlMRIwEAYDVQQHDAlDYW1icmlkZ2UxEjAQBgNVBAoMCUphZ2V4IEx0ZDESMBAG +A1UEAwwJSmFnZXggTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +idEgJi0xj7hhEyCMdXHxN31gyHS9Iwmzrda2a10BljKl6DGiSia1UWJ/zaJ88hcU +CjIFeUu0B5WZTXOjtLyxhpSSfVFjjNucCMFZLJ0NPSU554ZircHanCxj+rDxaHid +GBasfyrEujhhrcm9H4p1gyhZoMs5KGbxcdwJoCyNv9rIHiQnJhgzZLqG/rRE4JH7 +pjaijU519ZL8iZpz7oRSYIM1LzwMZcBsO4N71cHLvZpEi9B6wExS2W7/o1CEIqXv +tEHtxEFP5XWaWI/toLUBMdXYoKsVEhHs/zkNrjjMGXXQAcS6KOHHg0S+tZEGms30 +SY/69mtefjQceb5YwPjGuwIDAQABo4IBajCCAWYwCQYDVR0TBAIwADAfBgNVHSME +GDAWgBRXhptUuL6mKYrk9sLiExiJhc3ctzAdBgNVHQ4EFgQU7aoWtfnySWo/xlH3 +pkcMyJ9cLdwwKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3RsLnN5bWNiLmNvbS90 +bC5jcmwwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMG4GA1Ud +IARnMGUwYwYGZ4EMAQQBMFkwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0 +ZS5jb20vY3BzMC8GCCsGAQUFBwICMCMMIWh0dHBzOi8vd3d3LnRoYXd0ZS5jb20v +cmVwb3NpdG9yeTBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly90 +bC5zeW1jZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly90bC5zeW1jYi5jb20vdGwu +Y3J0MA0GCSqGSIb3DQEBCwUAA4IBAQCWhdlN3dalo14zBJURh3CtITGakbBF6N/T +4xSEVNUtIaJSMHWHVXCMnCEazRKX8C/AaroTuJ1ceUdXJc1CINjIABXz5rVpkWPQ +lPul1PfWyEYIIIEq0PjIEyapnWIDHsZu+HtDIHtRoya3e9p3Ac9+57MsiXLSX9D3 +jueMLakZ20Sy0JLWp2l7WkMjU27Wi3QxpZ3sw7reUzGBPLhGjcbABkqGCHXm+LqT +IrL6j3Co1fSeTGi43siPdP+JI6XK1+mcmTFX6Zktx15UDkYJzn0gqXmzgNQAYNss +iQR8TmbXjlvehDwcVmy/uRW8mWKjlqkMWRJVLoHc+jdUhosApE/5 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEmTCCA4GgAwIBAgIQcaC3NpXdsa/COyuaGO5UyzANBgkqhkiG9w0BAQsFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMjEwMDAwMDAwWhcNMjMx +MjA5MjM1OTU5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu +MSYwJAYDVQQDEx10aGF3dGUgU0hBMjU2IENvZGUgU2lnbmluZyBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJtVAkwXBenQZsP8KK3TwP7v4Ol+1B72 +qhuRRv31Fu2YB1P6uocbfZ4fASerudJnyrcQJVP0476bkLjtI1xC72QlWOWIIhq+ +9ceu9b6KsRERkxoiqXRpwXS2aIengzD5ZPGx4zg+9NbB/BL+c1cXNVeK3VCNA/hm +zcp2gxPI1w5xHeRjyboX+NG55IjSLCjIISANQbcL4i/CgOaIe1Nsw0RjgX9oR4wr +Ks9b9IxJYbpphf1rAHgFJmkTMIA4TvFaVcnFUNaqOIlHQ1z+TXOlScWTaf53lpqv +84wOV7oz2Q7GQtMDd8S7Oa2R+fP3llw6ZKbtJ1fB6EDzU/K+KTT+X/kCAwEAAaOC +ARcwggETMC8GCCsGAQUFBwEBBCMwITAfBggrBgEFBQcwAYYTaHR0cDovL3QyLnN5 +bWNiLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMDIGA1UdHwQrMCkwJ6AloCOGIWh0 +dHA6Ly90MS5zeW1jYi5jb20vVGhhd3RlUENBLmNybDAdBgNVHSUEFjAUBggrBgEF +BQcDAgYIKwYBBQUHAwMwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRow +GAYDVQQDExFTeW1hbnRlY1BLSS0xLTU2ODAdBgNVHQ4EFgQUV4abVLi+pimK5PbC +4hMYiYXN3LcwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJKoZI +hvcNAQELBQADggEBACQ79degNhPHQ/7wCYdo0ZgxbhLkPx4flntrTB6HnovFbKOx +DHtQktWBnLGPLCm37vmRBbmOQfEs9tBZLZjgueqAAUdAlbg9nQO9ebs1tq2cTCf2 +Z0UQycW8h05Ve9KHu93cMO/G1GzMmTVtHOBg081ojylZS4mWCEbJjvx1T8XcCcxO +J4tEzQe8rATgtTOlh5/03XMMkeoSgW/jdfAetZNsRBfVPpfJvQcsVncfhd1G6L/e +LIGUo/flt6fBN591ylV3TV42KcqF2EVBcld1wHlb+jQQBm1kIEK3OsgfHUZkAl/G +R77wxDooVNr2Hk+aohlDpG9J+PxeQiAohItHIG4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/runelite-client/src/main/scripts/BankSearchFilter.rs2asm b/runelite-client/src/main/scripts/BankSearchFilter.rs2asm index 60b9f12aa6..fd3f415b5d 100644 --- a/runelite-client/src/main/scripts/BankSearchFilter.rs2asm +++ b/runelite-client/src/main/scripts/BankSearchFilter.rs2asm @@ -3,68 +3,68 @@ .string_stack_count 0 .int_var_count 1 .string_var_count 2 - load_string "" + sconst "" sstore 0 - load_string "" + sconst "" sstore 1 invoke 514 - load_int 1 + iconst 1 if_icmpeq LABEL8 jump LABEL34 LABEL8: - get_varc_string 22 ; Skip truncating of varcstr 22 by not calling 280 - tolowercase ; instead get the var directly and lowercase it + get_varc_string 359 ; Skip truncating of varcstr 22 by not calling 280 + lowercase ; instead get the var directly and lowercase it sstore 1 sload 1 - string_length - load_int 0 + string_length + iconst 0 if_icmpgt LABEL15 jump LABEL34 LABEL15: iload 0 - load_int -1 + iconst -1 if_icmpne LABEL19 jump LABEL23 LABEL19: iload 0 - get_item_name - tolowercase + oc_name + lowercase sstore 0 -LABEL1337: ; check if the bank tags plugin is active - load_int 1 ; true - load_int 0 ; load active boolean - load_string "bankTagsActive" ; push event name - runelite_callback ; invoke callback +LABEL1337:; check if the bank tags plugin is active + iconst 1 ; true + iconst 0 ; load active boolean + sconst "bankTagsActive" ; push event name + runelite_callback ; invoke callback if_icmpeq LABEL1338 ; if the plugin is active then jump to the label that decides if the ; item should be shown jump LABEL23 ; if the plugin is not active then jump to the normal label -LABEL1338: ; let the bank tag plugin decide if the item should be shown - load_int 0 ; load return value +LABEL1338:; let the bank tag plugin decide if the item should be shown + iconst 0 ; load return value iload 0 ; load item id sload 0 ; load item name sload 1 ; load search string - load_string "bankSearchFilter" ; push event name - runelite_callback ; invoke callback - pop_int ; pop item id - pop_string ; pop search string - pop_string ; pop item name - return ; return value + sconst "bankSearchFilter" ; push event name + runelite_callback ; invoke callback + pop_int ; pop item id + pop_string ; pop search string + pop_string ; pop item name + return ; return value LABEL23: sload 0 sload 1 - load_int 0 - string_indexof_from - load_int -1 + iconst 0 + string_indexof_string + iconst -1 if_icmpne LABEL30 jump LABEL32 LABEL30: - load_int 1 - return + iconst 1 + return LABEL32: - load_int 0 - return + iconst 0 + return LABEL34: - load_int 1 - return - load_int -1 - return \ No newline at end of file + iconst 1 + return + iconst -1 + return diff --git a/runelite-client/src/main/scripts/BankSearchLayout.rs2asm b/runelite-client/src/main/scripts/BankSearchLayout.rs2asm index bd3bceac89..47dad19197 100644 --- a/runelite-client/src/main/scripts/BankSearchLayout.rs2asm +++ b/runelite-client/src/main/scripts/BankSearchLayout.rs2asm @@ -4,165 +4,165 @@ .int_var_count 31 .string_var_count 1 get_varbit 5102 - load_int 1 + iconst 1 if_icmpeq LABEL4 jump LABEL8 LABEL4: - load_int 0 + iconst 0 iload 10 - widget_put_hidden_widget + if_sethide jump LABEL13 LABEL8: - load_int 1 + iconst 1 iload 10 - widget_put_hidden_widget + if_sethide iload 12 invoke 41 LABEL13: get_varbit 5364 - load_int 1 + iconst 1 if_icmpeq LABEL17 jump LABEL24 LABEL17: - load_int 37 - load_int 37 - load_int 1 - load_int 0 + iconst 37 + iconst 37 + iconst 1 + iconst 0 iload 5 - widget_put_size_widget + if_setsize jump LABEL30 LABEL24: - load_int 0 - load_int 37 - load_int 1 - load_int 0 + iconst 0 + iconst 37 + iconst 1 + iconst 0 iload 5 - widget_put_size_widget + if_setsize LABEL30: - load_int 1 + iconst 1 iload 11 - widget_put_hidden_widget + if_sethide iload 11 - widget_unset_children - load_int 0 + cc_deleteall + iconst 0 istore 13 get_varbit 4170 - load_int 3 + iconst 3 if_icmpeq LABEL41 jump LABEL74 LABEL41: get_varbit 4171 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4172 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4173 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4174 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4175 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4176 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4177 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4178 - load_int 0 + iconst 0 if_icmpgt LABEL69 get_varbit 4179 - load_int 0 + iconst 0 if_icmpgt LABEL69 jump LABEL72 LABEL69: - load_int 0 + iconst 0 istore 13 jump LABEL74 LABEL72: - load_int 1 + iconst 1 istore 13 LABEL74: - load_int 0 + iconst 0 istore 14 iload 13 - load_int 1 + iconst 1 if_icmpeq LABEL80 jump LABEL110 LABEL80: - load_int 1 + iconst 1 iload 9 - widget_put_hidden_widget - load_int 11 + if_sethide + iconst 11 istore 14 - load_int 0 - load_int 26 - load_int 1 - load_int 1 + iconst 0 + iconst 26 + iconst 1 + iconst 1 iload 1 - widget_put_size_widget - load_int 460 - load_int 39 - load_int 0 - load_int 1 + if_setsize + iconst 460 + iconst 39 + iconst 0 + iconst 1 iload 3 - widget_put_size_widget - load_int 16 - load_int 39 - load_int 0 - load_int 1 + if_setsize + iconst 16 + iconst 39 + iconst 0 + iconst 1 iload 4 - widget_put_size_widget - load_int 30 - load_int 48 - load_int 2 - load_int 0 + if_setsize + iconst 30 + iconst 48 + iconst 2 + iconst 0 iload 2 - widget_put_position_widget + if_setposition jump LABEL137 LABEL110: - load_int 0 + iconst 0 iload 9 - widget_put_hidden_widget - load_int 0 - load_int 0 - load_int 1 - load_int 1 + if_sethide + iconst 0 + iconst 0 + iconst 1 + iconst 1 iload 1 - widget_put_size_widget - load_int 460 - load_int 81 - load_int 0 - load_int 1 + if_setsize + iconst 460 + iconst 81 + iconst 0 + iconst 1 iload 3 - widget_put_size_widget - load_int 16 - load_int 81 - load_int 0 - load_int 1 + if_setsize + iconst 16 + iconst 81 + iconst 0 + iconst 1 iload 4 - widget_put_size_widget - load_int 12 - load_int 42 - load_int 2 - load_int 0 + if_setsize + iconst 12 + iconst 42 + iconst 2 + iconst 0 iload 2 - widget_put_position_widget + if_setposition LABEL137: iload 4 iload 3 invoke 231 - load_int 816 + iconst 816 istore 15 - load_int 816 - load_int 9 - load_int 3 - imul - iadd + iconst 816 + iconst 9 + iconst 3 + multiply + add istore 16 LABEL148: iload 15 @@ -172,133 +172,133 @@ LABEL148: LABEL152: iload 3 iload 15 - widget_load_child - load_int 1 + cc_find + iconst 1 if_icmpeq LABEL158 jump LABEL160 LABEL158: - load_int 1 - widget_put_hidden + iconst 1 + cc_sethide LABEL160: iload 15 - load_int 1 - iadd + iconst 1 + add istore 15 jump LABEL148 LABEL165: - load_int 0 + iconst 0 istore 15 - load_int 8 - load_int 1 - isub + iconst 8 + iconst 1 + sub istore 17 iload 3 - widget_get_width_widget - load_int 51 - isub - load_int 35 - isub + if_getwidth + iconst 51 + sub + iconst 35 + sub istore 18 iload 18 - load_int 8 - load_int 36 - imul - isub + iconst 8 + iconst 36 + multiply + sub iload 17 - idiv + div istore 19 - load_int -1 + iconst -1 istore 20 - load_int 0 + iconst 0 istore 21 - load_int 0 + iconst 0 istore 22 - load_int 0 + iconst 0 istore 23 - load_int 0 + iconst 0 istore 24 - load_int -1 + iconst -1 istore 25 - load_int 0 + iconst 0 istore 26 - load_string "" + sconst "" sstore 0 get_varbit 4150 - load_int 0 + iconst 0 if_icmple LABEL209 get_varbit 4150 - load_int 9 + iconst 9 if_icmpgt LABEL209 jump LABEL658 LABEL209: iload 15 - load_int 816 + iconst 816 if_icmplt LABEL213 jump LABEL238 LABEL213: iload 3 iload 15 - widget_load_child - load_int 1 + cc_find + iconst 1 if_icmpeq LABEL219 jump LABEL221 LABEL219: - load_int 1 - widget_put_hidden + iconst 1 + cc_sethide LABEL221: - load_int 95 + iconst 95 iload 15 - get_itemcontainer_itemid - load_int -1 + inv_getobj + iconst -1 if_icmpne LABEL227 jump LABEL233 LABEL227: iload 24 - load_int 1 - iadd + iconst 1 + add iload 15 istore 25 istore 24 LABEL233: iload 15 - load_int 1 - iadd + iconst 1 + add istore 15 jump LABEL209 LABEL238: get_varbit 4171 get_varbit 4172 - iadd + add get_varbit 4173 - iadd + add get_varbit 4174 - iadd + add get_varbit 4175 - iadd + add get_varbit 4176 - iadd + add get_varbit 4177 - iadd + add get_varbit 4178 - iadd + add get_varbit 4179 - iadd + add istore 26 iload 26 - load_int 0 + iconst 0 if_icmple LABEL260 jump LABEL264 LABEL260: - load_int 816 - load_int 1 - isub + iconst 816 + iconst 1 + sub istore 25 LABEL264: iload 26 iload 25 - load_int 1 - iadd - load_int 0 + iconst 1 + add + iconst 0 iload 3 iload 4 iload 10 @@ -313,16 +313,16 @@ LABEL264: istore 23 iload 22 iload 21 - iadd + add istore 22 - load_int 0 + iconst 0 istore 15 get_varbit 4171 - load_int 0 + iconst 0 if_icmpgt LABEL291 jump LABEL321 LABEL291: - load_int 1 + iconst 1 iload 3 iload 23 invoke 510 @@ -330,8 +330,8 @@ LABEL291: iload 15 iload 15 get_varbit 4171 - iadd - load_int 1 + add + iconst 1 iload 3 iload 4 iload 10 @@ -346,19 +346,19 @@ LABEL291: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4171 - iadd + add istore 15 LABEL321: get_varbit 4172 - load_int 0 + iconst 0 if_icmpgt LABEL325 jump LABEL355 LABEL325: - load_int 2 + iconst 2 iload 3 iload 23 invoke 510 @@ -366,8 +366,8 @@ LABEL325: iload 15 iload 15 get_varbit 4172 - iadd - load_int 2 + add + iconst 2 iload 3 iload 4 iload 10 @@ -382,19 +382,19 @@ LABEL325: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4172 - iadd + add istore 15 LABEL355: get_varbit 4173 - load_int 0 + iconst 0 if_icmpgt LABEL359 jump LABEL389 LABEL359: - load_int 3 + iconst 3 iload 3 iload 23 invoke 510 @@ -402,8 +402,8 @@ LABEL359: iload 15 iload 15 get_varbit 4173 - iadd - load_int 3 + add + iconst 3 iload 3 iload 4 iload 10 @@ -418,19 +418,19 @@ LABEL359: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4173 - iadd + add istore 15 LABEL389: get_varbit 4174 - load_int 0 + iconst 0 if_icmpgt LABEL393 jump LABEL423 LABEL393: - load_int 4 + iconst 4 iload 3 iload 23 invoke 510 @@ -438,8 +438,8 @@ LABEL393: iload 15 iload 15 get_varbit 4174 - iadd - load_int 4 + add + iconst 4 iload 3 iload 4 iload 10 @@ -454,19 +454,19 @@ LABEL393: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4174 - iadd + add istore 15 LABEL423: get_varbit 4175 - load_int 0 + iconst 0 if_icmpgt LABEL427 jump LABEL457 LABEL427: - load_int 5 + iconst 5 iload 3 iload 23 invoke 510 @@ -474,8 +474,8 @@ LABEL427: iload 15 iload 15 get_varbit 4175 - iadd - load_int 5 + add + iconst 5 iload 3 iload 4 iload 10 @@ -490,19 +490,19 @@ LABEL427: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4175 - iadd + add istore 15 LABEL457: get_varbit 4176 - load_int 0 + iconst 0 if_icmpgt LABEL461 jump LABEL491 LABEL461: - load_int 6 + iconst 6 iload 3 iload 23 invoke 510 @@ -510,8 +510,8 @@ LABEL461: iload 15 iload 15 get_varbit 4176 - iadd - load_int 6 + add + iconst 6 iload 3 iload 4 iload 10 @@ -526,19 +526,19 @@ LABEL461: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4176 - iadd + add istore 15 LABEL491: get_varbit 4177 - load_int 0 + iconst 0 if_icmpgt LABEL495 jump LABEL525 LABEL495: - load_int 7 + iconst 7 iload 3 iload 23 invoke 510 @@ -546,8 +546,8 @@ LABEL495: iload 15 iload 15 get_varbit 4177 - iadd - load_int 7 + add + iconst 7 iload 3 iload 4 iload 10 @@ -562,19 +562,19 @@ LABEL495: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4177 - iadd + add istore 15 LABEL525: get_varbit 4178 - load_int 0 + iconst 0 if_icmpgt LABEL529 jump LABEL559 LABEL529: - load_int 8 + iconst 8 iload 3 iload 23 invoke 510 @@ -582,8 +582,8 @@ LABEL529: iload 15 iload 15 get_varbit 4178 - iadd - load_int 8 + add + iconst 8 iload 3 iload 4 iload 10 @@ -598,19 +598,19 @@ LABEL529: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4178 - iadd + add istore 15 LABEL559: get_varbit 4179 - load_int 0 + iconst 0 if_icmpgt LABEL563 jump LABEL593 LABEL563: - load_int 9 + iconst 9 iload 3 iload 23 invoke 510 @@ -618,8 +618,8 @@ LABEL563: iload 15 iload 15 get_varbit 4179 - iadd - load_int 9 + add + iconst 9 iload 3 iload 4 iload 10 @@ -634,78 +634,78 @@ LABEL563: istore 23 iload 22 iload 21 - iadd + add istore 22 iload 15 get_varbit 4179 - iadd + add istore 15 LABEL593: invoke 514 - load_int 1 + iconst 1 if_icmpeq LABEL597 jump LABEL638 LABEL597: - get_varc_string 22 ; Skip truncating of varcstr 22 by not calling 280 - tolowercase ; instead get the var directly and lowercase it + get_varc_string 359 ; Skip truncating of varcstr 22 by not calling 280 + lowercase ; instead get the var directly and lowercase it sstore 0 sload 0 string_length - load_int 0 + iconst 0 if_icmpgt LABEL604 jump LABEL623 LABEL604: - load_string "Showing items: " - load_string "" + sconst "Showing items: " + sconst "" sload 0 - load_string "" - string_append 4 + sconst "" + join_string 4 iload 6 - widget_put_text_widget - get_varc 5 - load_int 11 + if_settext + get_varc_int 5 + iconst 11 if_icmpeq LABEL615 jump LABEL622 LABEL615: - load_string "Show items whose names contain the following text: (" + sconst "Show items whose names contain the following text: (" iload 22 - int_to_string - load_string " found)" - string_append 3 + tostring + sconst " found)" + join_string 3 iload 21 ; load number of matches - load_string "setSearchBankInputTextFound" ; load event name + sconst "setSearchBankInputTextFound" ; load event name runelite_callback ; invoke callback pop_int ; pop number of matches - load_int 10616876 - widget_put_text_widget + iconst 10616876 + if_settext LABEL622: jump LABEL637 LABEL623: - load_string "Showing items: " - load_string "" - load_string "*" - load_string "" - string_append 4 + sconst "Showing items: " + sconst "" + sconst "*" + sconst "" + join_string 4 iload 6 - widget_put_text_widget - get_varc 5 - load_int 11 + if_settext + get_varc_int 5 + iconst 11 if_icmpeq LABEL634 jump LABEL637 LABEL634: - load_string "Show items whose names contain the following text:" - load_string "setSearchBankInputText" ; load event name + sconst "Show items whose names contain the following text:" + sconst "setSearchBankInputText" ; load event name runelite_callback ; invoke callback - load_int 10616876 - widget_put_text_widget + iconst 10616876 + if_settext LABEL637: jump LABEL641 LABEL638: - load_string "The Bank of Gielinor" - load_string "setBankTitle" ; - runelite_callback ; + sconst "The Bank of Gielinor" + sconst "setBankTitle" ; + runelite_callback ; iload 6 - widget_put_text_widget + if_settext LABEL641: iload 0 iload 1 @@ -726,51 +726,51 @@ LABEL641: return LABEL658: invoke 514 - load_int 1 + iconst 1 if_icmpeq LABEL662 jump LABEL665 LABEL662: - load_int 1 - load_int 1 + iconst 1 + iconst 1 invoke 299 LABEL665: - load_int -1 + iconst -1 istore 27 - load_int -1 + iconst -1 istore 28 get_varbit 4150 invoke 513 istore 28 istore 27 - load_int 0 + iconst 0 istore 29 - load_int 0 + iconst 0 istore 30 LABEL677: iload 15 - load_int 816 + iconst 816 if_icmplt LABEL681 jump LABEL761 LABEL681: iload 3 iload 15 - widget_load_child - load_int 1 + cc_find + iconst 1 if_icmpeq LABEL687 jump LABEL756 LABEL687: - load_int 95 + iconst 95 iload 15 - get_itemcontainer_itemid + inv_getobj istore 20 iload 20 - load_int -1 + iconst -1 if_icmpne LABEL695 jump LABEL699 LABEL695: iload 24 - load_int 1 - iadd + iconst 1 + add istore 24 LABEL699: iload 15 @@ -783,12 +783,12 @@ LABEL703: if_icmplt LABEL707 jump LABEL754 LABEL707: - load_int 0 - widget_put_hidden + iconst 0 + cc_sethide iload 20 - load_int 95 + iconst 95 iload 15 - get_itemcontainer_stacksize + inv_getnum iload 3 iload 4 iload 10 @@ -796,23 +796,23 @@ LABEL707: iload 12 invoke 278 iload 30 - load_int 36 - imul + iconst 36 + multiply istore 23 - load_int 51 + iconst 51 iload 29 - load_int 36 + iconst 36 iload 19 - iadd - imul - iadd + add + multiply + add iload 23 - load_int 0 - load_int 0 - widget_put_position + iconst 0 + iconst 0 + cc_setposition iload 23 - load_int 32 - iadd + iconst 32 + add istore 23 iload 29 iload 17 @@ -820,55 +820,55 @@ LABEL707: jump LABEL747 LABEL742: iload 29 - load_int 1 - iadd + iconst 1 + add istore 29 jump LABEL753 LABEL747: - load_int 0 + iconst 0 iload 30 - load_int 1 - iadd + iconst 1 + add istore 30 istore 29 LABEL753: jump LABEL756 LABEL754: - load_int 1 - widget_put_hidden + iconst 1 + cc_sethide LABEL756: iload 15 - load_int 1 - iadd + iconst 1 + add istore 15 jump LABEL677 LABEL761: get_varbit 4170 - load_int 2 + iconst 2 if_icmpeq LABEL765 jump LABEL775 LABEL765: - load_string "Tab " - load_int 105 - load_int 115 - load_int 207 + sconst "Tab " + iconst 105 + iconst 115 + iconst 207 get_varbit 4150 - get_enum_value - string_append 2 - load_string "setBankTitle" ; - runelite_callback ; + enum + join_string 2 + sconst "setBankTitle" ; + runelite_callback ; iload 6 - widget_put_text_widget + if_settext jump LABEL781 LABEL775: - load_string "Tab " + sconst "Tab " get_varbit 4150 - int_to_string - string_append 2 - load_string "setBankTitle" ; - runelite_callback ; + tostring + join_string 2 + sconst "setBankTitle" ; + runelite_callback ; iload 6 - widget_put_text_widget + if_settext LABEL781: iload 0 iload 1 diff --git a/runelite-client/src/main/scripts/ChatBuilder.rs2asm b/runelite-client/src/main/scripts/ChatBuilder.rs2asm index 2e0b41bec1..c30307da67 100644 --- a/runelite-client/src/main/scripts/ChatBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatBuilder.rs2asm @@ -3,175 +3,175 @@ .string_stack_count 0 .int_var_count 15 .string_var_count 13 - load_int 10616890 - widget_get_width_widget + iconst 10616890 + if_getwidth istore 1 - get_localplayer_name - string_remove_html + chat_playername + removetags sstore 0 - load_int 0 + iconst 0 istore 2 - get_varc 41 - load_int 3 + get_varc_int 41 + iconst 3 if_icmpeq LABEL12 jump LABEL14 LABEL12: - load_int 1 + iconst 1 istore 2 LABEL14: - load_int 0 + iconst 0 istore 3 - load_int 0 + iconst 0 istore 4 - load_string "" + sconst "" sstore 1 - load_string "" + sconst "" sstore 2 - load_string "" + sconst "" sstore 3 - load_string "" + sconst "" sstore 4 - load_string "" + sconst "" sstore 5 - load_string "" + sconst "" sstore 6 - load_string "" + sconst "" sstore 7 - load_string "" + sconst "" sstore 8 invoke 921 - load_int 1 + iconst 1 if_icmpeq LABEL38 jump LABEL58 LABEL38: - load_int 16777215 - load_int 1 + iconst 16777215 + iconst 1 istore 4 istore 3 - load_string "" - load_string "" - load_string "" - load_string "" + sconst "" + sconst "" + sconst "" + sconst "" sstore 4 sstore 3 sstore 2 sstore 1 - load_string "" - load_string "" - load_string "" - load_string "" + sconst "" + sconst "" + sconst "" + sconst "" sstore 8 sstore 7 sstore 6 sstore 5 LABEL58: - load_int 0 + iconst 0 istore 5 - load_int 0 + iconst 0 istore 6 - load_int 0 + iconst 0 istore 7 - load_int 105 - load_int 73 - load_int 579 + iconst 105 + iconst 73 + iconst 579 iload 7 - get_enum_value + enum istore 8 - get_varc 41 - load_int 0 + get_varc_int 41 + iconst 0 if_icmpeq LABEL77 - get_varc 41 - load_int 2 + get_varc_int 41 + iconst 2 if_icmpeq LABEL77 jump LABEL133 LABEL77: - 5022 + chat_getmessagefilter string_length - load_int 0 + iconst 0 if_icmpgt LABEL82 jump LABEL133 LABEL82: sload 1 - load_string "Public chat filtering:" - load_string "" - load_string " " - load_string "" - 5022 - appendtags - tolowercase - load_string "" - string_append 7 + sconst "Public chat filtering:" + sconst "" + sconst " " + sconst "" + chat_getmessagefilter + escape + lowercase + sconst "" + join_string 7 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 istore 6 iload 8 - widget_put_actions_null_widget - load_int -1 - load_string "" + if_clearops + iconst -1 + sconst "" iload 8 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget + if_setonmouseleave iload 5 iload 6 - isub + sub istore 5 iload 7 - load_int 1 - iadd + iconst 1 + add istore 7 - load_int 105 - load_int 73 - load_int 579 + iconst 105 + iconst 73 + iconst 579 iload 7 - get_enum_value + enum istore 8 LABEL133: iload 0 istore 9 - load_int 0 + iconst 0 istore 10 - load_int -1 + iconst -1 istore 11 - load_string "" + sconst "" sstore 9 - load_string "" + sconst "" sstore 10 - load_string "" + sconst "" sstore 11 - load_string "" + sconst "" sstore 12 - load_int 0 + iconst 0 istore 12 LABEL149: iload 9 - load_int -1 + iconst -1 if_icmpne LABEL153 jump LABEL645 LABEL153: iload 8 - load_int -1 + iconst -1 if_icmpne LABEL157 jump LABEL645 LABEL157: iload 9 - get_chat_message + chat_gethistory_byuid istore 12 sstore 11 sstore 10 @@ -182,8 +182,19 @@ LABEL157: sload 9 iload 12 invoke 193 - load_int 1 - if_icmpeq LABEL172 + iconst 1 + if_icmpeq CHAT_FILTER ; Jump to our new label instead + jump LABEL641 +CHAT_FILTER: + sload 11 ; Load the message + iconst 1 ; Gets changed to 0 if message is blocked + iload 10 ; Load the messageType + sconst "chatFilterCheck" + runelite_callback + pop_int ; Pop the messageType + iconst 1 ; 2nd half of conditional + sstore 11 ; Override the message with our filtered message + if_icmpeq LABEL172 ; Check if we are building this message jump LABEL641 LABEL172: iload 10 @@ -194,7 +205,7 @@ LABEL172: sload 0 iload 12 invoke 90 - load_int 1 + iconst 1 if_icmpeq LABEL183 jump LABEL641 LABEL183: @@ -217,26 +228,26 @@ LABEL183: jump LABEL426 LABEL186: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int sload 9 - load_string ":" - string_append 3 ; We need to append an extra string since we added the timestamp + sconst ":" + join_string 3 ; We need to append an extra string since we added the timestamp sload 1 sload 11 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 203 @@ -244,26 +255,26 @@ LABEL186: jump LABEL440 LABEL207: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int sload 9 - load_string ":" - string_append 3 ; We need to append an extra string since we added the timestamp + sconst ":" + join_string 3 ; We need to append an extra string since we added the timestamp sload 3 sload 11 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 203 @@ -271,29 +282,29 @@ LABEL207: jump LABEL440 LABEL228: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int - load_string "From " + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int + sconst "From " sload 9 - load_string ":" - load_string "privateChatFrom" - runelite_callback - string_append 4 ; We need to append an extra string since we added the timestamp + sconst ":" + sconst "privateChatFrom" + runelite_callback + join_string 4 ; We need to append an extra string since we added the timestamp sload 2 sload 11 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 203 @@ -301,23 +312,23 @@ LABEL228: jump LABEL440 LABEL250: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int sload 7 sload 11 - load_string "" - string_append 4 ; We need to append an extra string since we added the timestamp + sconst "" + join_string 4 ; We need to append an extra string since we added the timestamp iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 @@ -325,70 +336,70 @@ LABEL250: jump LABEL440 LABEL268: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int sload 2 sload 11 - load_string "" - string_append 4 ; We need to append an extra string since we added the timestamp + sconst "" + join_string 4 ; We need to append an extra string since we added the timestamp iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 istore 6 get_varbit 1627 - load_int 0 + iconst 0 if_icmpeq LABEL289 jump LABEL300 LABEL289: iload 11 - load_int 500 - iadd - load_int 1 - iadd - put_varc 65 - load_int 664 - load_int 0 - load_string "1" - load_int 10616832 - widget_put_render_listener_widget + iconst 500 + add + iconst 1 + add + set_varc_int 65 + iconst 664 + iconst 0 + sconst "1" + iconst 10616832 + if_setontimer LABEL300: jump LABEL440 LABEL301: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int - load_string "To " + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int + sconst "To " sload 9 - load_string ":" - load_string "privateChatTo" - runelite_callback - string_append 4 ; We need to append an extra string since we added the timestamp + sconst ":" + sconst "privateChatTo" + runelite_callback + join_string 4 ; We need to append an extra string since we added the timestamp sload 2 sload 11 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 203 @@ -396,23 +407,23 @@ LABEL301: jump LABEL440 LABEL323: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int sload 8 sload 11 - load_string "" - string_append 4 ; We need to append an extra string since we added the timestamp + sconst "" + join_string 4 ; We need to append an extra string since we added the timestamp iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 @@ -420,31 +431,31 @@ LABEL323: jump LABEL440 LABEL341: iload 9 ; The id of the messageNode of the message being built - load_string "" - load_string "addTimestamp" - runelite_callback - pop_int - load_string "[" + sconst "" + sconst "addTimestamp" + runelite_callback + pop_int + sconst "[" sload 5 sload 10 - load_string "" - load_string "] " + sconst "" + sconst "] " sload 9 - load_string ":" - string_append 8 ; We need to append an extra string since we added the timestamp + sconst ":" + join_string 8 ; We need to append an extra string since we added the timestamp sload 6 sload 11 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 203 @@ -456,42 +467,42 @@ LABEL367: sstore 12 sstore 11 sload 4 - load_string "Broadcast:" - load_string "" - string_append 3 + sconst "Broadcast:" + sconst "" + join_string 3 sload 11 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 203 istore 6 jump LABEL440 LABEL390: - get_gamecycle + clientclock iload 11 - isub - load_int 500 + sub + iconst 500 if_icmpgt LABEL396 jump LABEL411 LABEL396: - load_string "jk :P" + sconst "jk :P" iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 @@ -501,13 +512,13 @@ LABEL411: sload 11 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 @@ -518,20 +529,20 @@ LABEL426: sload 11 iload 7 iload 8 - load_int 10616890 + iconst 10616890 iload 1 - load_int 3 - load_int 14 + iconst 3 + iconst 14 iload 5 - load_int 0 - load_int 103 + iconst 0 + iconst 103 iload 3 iload 4 invoke 199 istore 6 LABEL440: iload 8 - widget_put_actions_null_widget + if_clearops iload 10 switch 1: LABEL445 @@ -549,221 +560,221 @@ LABEL440: 91: LABEL445 jump LABEL615 LABEL445: - load_string "" + sconst "" sload 9 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 8 - widget_put_name_widget - load_int 86 - load_int -2147483644 - load_string "event_opbase" - load_string "is" + if_setopbase + iconst 86 + iconst -2147483644 + sconst "event_opbase" + sconst "is" iload 8 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget + if_setonmouseleave sload 0 sload 9 - string_remove_html - string_compare - load_int 0 + removetags + compare + iconst 0 if_icmpne LABEL472 jump LABEL509 LABEL472: iload 12 - load_int 1 + iconst 1 if_icmpeq LABEL476 jump LABEL481 LABEL476: - load_int 6 - load_string "Message" + iconst 6 + sconst "Message" iload 8 - widget_put_action_widget + if_setop jump LABEL489 LABEL481: - load_int 6 - load_string "Add friend" + iconst 6 + sconst "Add friend" iload 8 - widget_put_action_widget - load_int 7 - load_string "Add ignore" + if_setop + iconst 7 + sconst "Add ignore" iload 8 - widget_put_action_widget + if_setop LABEL489: - load_int 8 - load_string "Report" + iconst 8 + sconst "Report" iload 8 - widget_put_action_widget + if_setop iload 10 - load_int 9 + iconst 9 if_icmpeq LABEL497 jump LABEL509 LABEL497: - get_clanchatcount - load_int 0 + clan_getchatcount + iconst 0 if_icmpgt LABEL501 jump LABEL509 LABEL501: - get_clanchat_rank - clanchat_kick_rank + clan_getchatrank + clan_getchatminkick if_icmpge LABEL505 jump LABEL509 LABEL505: - load_int 9 - load_string "Kick" + iconst 9 + sconst "Kick" iload 8 - widget_put_action_widget + if_setop LABEL509: jump LABEL627 LABEL510: - load_string "" + sconst "" sload 9 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 8 - widget_put_name_widget - load_int 86 - load_int -2147483644 - load_string "event_opbase" - load_string "is" + if_setopbase + iconst 86 + iconst -2147483644 + sconst "event_opbase" + sconst "is" iload 8 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget - load_int 1 - load_string "Accept trade" + if_setonmouseleave + iconst 1 + sconst "Accept trade" iload 8 - widget_put_action_widget + if_setop jump LABEL627 LABEL535: - load_string "" + sconst "" sload 9 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 8 - widget_put_name_widget - load_int 86 - load_int -2147483644 - load_string "event_opbase" - load_string "is" + if_setopbase + iconst 86 + iconst -2147483644 + sconst "event_opbase" + sconst "is" iload 8 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget - load_int 2 - load_string "Accept challenge" + if_setonmouseleave + iconst 2 + sconst "Accept challenge" iload 8 - widget_put_action_widget + if_setop jump LABEL627 LABEL560: sload 12 string_length - load_int 0 + iconst 0 if_icmpgt LABEL565 jump LABEL590 LABEL565: - load_int 6 - load_string "Open" + iconst 6 + sconst "Open" iload 8 - widget_put_action_widget - load_int 7 - load_string "Check" + if_setop + iconst 7 + sconst "Check" iload 8 - widget_put_action_widget - load_int 2065 + if_setop + iconst 2065 iload 8 - widget_get_parentid_widget + if_getlayer iload 7 - load_int 3158271 - load_string "Iii" + iconst 3158271 + sconst "Iii" iload 8 - widget_put_mouse_hover_listener_widget - load_int 2065 + if_setonmouserepeat + iconst 2065 iload 8 - widget_get_parentid_widget + if_getlayer iload 7 iload 3 - load_string "Iii" + sconst "Iii" iload 8 - widget_put_mouse_exit_listener_widget + if_setonmouseleave jump LABEL598 LABEL590: - load_int -1 - load_string "" + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget + if_setonmouseleave LABEL598: - load_int 9 - load_string "Clear history" + iconst 9 + sconst "Clear history" iload 8 - widget_put_action_widget - load_string "" - load_string "Notification" - load_string "" - string_append 3 + if_setop + sconst "" + sconst "Notification" + sconst "" + join_string 3 iload 8 - widget_put_name_widget - load_int 2064 - load_int -2147483644 + if_setopbase + iconst 2064 + iconst -2147483644 sload 12 - load_string "is" + sconst "is" iload 8 - widget_put_option_click_listener_widget + if_setonop jump LABEL627 LABEL615: - load_int -1 - load_string "" + iconst -1 + sconst "" iload 8 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget + if_setonmouseleave LABEL627: iload 5 iload 6 - isub + sub istore 5 iload 7 - load_int 1 - iadd + iconst 1 + add istore 7 - load_int 105 - load_int 73 - load_int 579 + iconst 105 + iconst 73 + iconst 579 iload 7 - get_enum_value + enum istore 8 LABEL641: iload 9 - get_messagenode_next_id + chat_getprevuid istore 9 jump LABEL149 LABEL645: @@ -771,82 +782,82 @@ LABEL645: istore 13 LABEL647: iload 8 - load_int -1 + iconst -1 if_icmpne LABEL651 jump LABEL708 LABEL651: iload 8 - widget_put_actions_null_widget - load_int -1 - load_string "" + if_clearops + iconst -1 + sconst "" iload 8 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 8 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 8 - widget_put_mouse_exit_listener_widget - load_int 0 - load_int 0 - load_int 0 - load_int 0 + if_setonmouseleave + iconst 0 + iconst 0 + iconst 0 + iconst 0 iload 8 - widget_put_size_widget - load_int 10616890 + if_setsize + iconst 10616890 iload 7 - load_int 2 - imul - widget_load_child - load_int 1 + iconst 2 + multiply + cc_find + iconst 1 if_icmpeq LABEL679 jump LABEL683 LABEL679: - load_string "" - widget_put_text - load_int 1 - widget_put_hidden + sconst "" + cc_settext + iconst 1 + cc_sethide LABEL683: - load_int 10616890 + iconst 10616890 iload 7 - load_int 2 - imul - load_int 1 - iadd - widget_load_child - load_int 1 + iconst 2 + multiply + iconst 1 + add + cc_find + iconst 1 if_icmpeq LABEL693 jump LABEL697 LABEL693: - load_string "" - widget_put_text - load_int 1 - widget_put_hidden + sconst "" + cc_settext + iconst 1 + cc_sethide LABEL697: iload 7 - load_int 1 - iadd + iconst 1 + add istore 7 - load_int 105 - load_int 73 - load_int 579 + iconst 105 + iconst 73 + iconst 579 iload 7 - get_enum_value + enum istore 8 jump LABEL647 LABEL708: iload 5 - load_int 2 - isub + iconst 2 + sub istore 5 - load_int 0 + iconst 0 iload 5 - isub + sub istore 5 - load_int 10616890 - widget_get_height_widget + iconst 10616890 + if_getheight istore 14 iload 5 iload 14 @@ -860,83 +871,83 @@ LABEL725: istore 7 LABEL727: iload 7 - load_int 0 + iconst 0 if_icmpgt LABEL731 jump LABEL784 LABEL731: iload 7 - load_int 1 - isub + iconst 1 + sub istore 7 - load_int 105 - load_int 73 - load_int 579 + iconst 105 + iconst 73 + iconst 579 iload 7 - get_enum_value + enum istore 8 iload 8 - widget_get_relativey_widget + if_gety iload 14 - iadd - load_int 2 - isub + add + iconst 2 + sub istore 5 iload 8 - widget_get_relativex_widget + if_getx iload 5 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 8 - widget_put_position_widget - load_int 10616890 + if_setposition + iconst 10616890 iload 7 - load_int 2 - imul - widget_load_child - load_int 1 + iconst 2 + multiply + cc_find + iconst 1 if_icmpeq LABEL763 jump LABEL768 LABEL763: - widget_get_relativex + cc_getx iload 5 - load_int 0 - load_int 0 - widget_put_position + iconst 0 + iconst 0 + cc_setposition LABEL768: - load_int 10616890 + iconst 10616890 iload 7 - load_int 2 - imul - load_int 1 - iadd - widget_load_child - load_int 1 + iconst 2 + multiply + iconst 1 + add + cc_find + iconst 1 if_icmpeq LABEL778 jump LABEL783 LABEL778: - widget_get_relativex + cc_getx iload 5 - load_int 0 - load_int 0 - widget_put_position + iconst 0 + iconst 0 + cc_setposition LABEL783: jump LABEL727 LABEL784: - load_int 0 + iconst 0 iload 14 - load_int 10616890 - widget_put_scrollwidthheight_widget - load_int 10617391 - load_int 10616890 - get_varc 7 + iconst 10616890 + if_setscrollsize + iconst 10617391 + iconst 10616890 + get_varc_int 7 iload 14 - get_varc 8 - isub - iadd + get_varc_int 8 + sub + add invoke 72 - load_int 10616890 - widget_get_scrolly_widget + iconst 10616890 + if_getscrolly iload 14 - put_varc 8 - put_varc 7 + set_varc_int 8 + set_varc_int 7 return diff --git a/runelite-client/src/main/scripts/ChatSplitBuilder.hash b/runelite-client/src/main/scripts/ChatSplitBuilder.hash index e71389fb55..9e67531c83 100644 --- a/runelite-client/src/main/scripts/ChatSplitBuilder.hash +++ b/runelite-client/src/main/scripts/ChatSplitBuilder.hash @@ -1 +1 @@ -008FA4B7983DF14899909AF361AD2DE955DE552E78FAF8C6604E848D1776B4F0 \ No newline at end of file +5BCAA21926CF079794AAF3DA80E512297DD6F8353741929302FE6490D17DDF8C \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm b/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm index 39fa1e7b3c..45b420248d 100644 --- a/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatSplitBuilder.rs2asm @@ -3,207 +3,207 @@ .string_stack_count 0 .int_var_count 16 .string_var_count 4 - load_int 0 + iconst 0 istore 1 - load_int 2 + iconst 2 istore 2 - load_int 103 + iconst 103 istore 3 - load_int 4 + iconst 4 istore 4 - load_int 23 + iconst 23 istore 5 invoke 900 istore 6 - load_int 103 - load_int 105 - load_int 1136 + iconst 103 + iconst 105 + iconst 1136 iload 6 - get_enum_value - load_int 0 + enum + iconst 0 if_icmpgt LABEL20 jump LABEL58 LABEL20: iload 6 - load_int 1745 + iconst 1745 if_icmpeq LABEL24 jump LABEL36 LABEL24: - load_int 0 - load_int 102 - load_int 103 - load_int 105 - load_int 1960 + iconst 0 + iconst 102 + iconst 103 + iconst 105 + iconst 1960 iload 6 - get_enum_value - load_int 30 + enum + iconst 30 istore 5 istore 1 istore 3 istore 2 LABEL36: - get_varc 41 - load_int -1 + get_varc_int 41 + iconst 1337 if_icmpeq LABEL40 jump LABEL49 LABEL40: invoke 922 - load_int 1 + iconst 1 if_icmpeq LABEL44 jump LABEL49 LABEL44: iload 4 iload 5 - iadd + add istore 4 jump LABEL58 LABEL49: iload 4 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 6 - load_int 10551325 - get_enum_value - widget_get_height_widget - iadd + iconst 10551325 + enum + if_getheight + add istore 4 LABEL58: iload 4 istore 7 - load_int 10682368 - widget_get_width_widget + iconst 10682368 + if_getwidth istore 8 - load_int 0 + iconst 0 istore 9 - load_int 105 - load_int 73 - load_int 580 + iconst 105 + iconst 73 + iconst 580 iload 9 - get_enum_value + enum istore 10 - load_int 0 + iconst 0 istore 11 - load_string "" + sconst "" sstore 0 - get_system_update_timer - load_int 0 + reboottimer + iconst 0 if_icmpgt LABEL79 jump LABEL156 LABEL79: - get_system_update_timer - load_int 50 - idiv - load_int 60 - modulo + reboottimer + iconst 50 + div + iconst 60 + mod istore 11 iload 11 - load_int 10 + iconst 10 if_icmplt LABEL89 jump LABEL100 LABEL89: - load_string "System update in: " - get_system_update_timer - load_int 3000 - idiv - int_to_string - load_string ":0" + sconst "System update in: " + reboottimer + iconst 3000 + div + tostring + sconst ":0" iload 11 - int_to_string - string_append 4 + tostring + join_string 4 sstore 0 jump LABEL110 LABEL100: - load_string "System update in: " - get_system_update_timer - load_int 3000 - idiv - int_to_string - load_string ":" + sconst "System update in: " + reboottimer + iconst 3000 + div + tostring + sconst ":" iload 11 - int_to_string - string_append 4 + tostring + join_string 4 sstore 0 LABEL110: iload 7 sload 0 iload 9 iload 10 - load_int 10682368 + iconst 10682368 iload 8 iload 1 - load_int 13 + iconst 13 iload 7 iload 2 iload 3 - load_int 16776960 - load_int 1 + iconst 16776960 + iconst 1 invoke 199 - iadd + add istore 7 iload 10 - widget_put_actions_null_widget - load_int -1 - load_string "" + if_clearops + iconst -1 + sconst "" iload 10 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 10 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 10 - widget_put_mouse_exit_listener_widget - load_int 0 - load_int 0 - load_int 0 - load_int 0 + if_setonmouseleave + iconst 0 + iconst 0 + iconst 0 + iconst 0 iload 10 - widget_put_size_widget + if_setsize iload 9 - load_int 1 - iadd + iconst 1 + add istore 9 - load_int 105 - load_int 73 - load_int 580 + iconst 105 + iconst 73 + iconst 580 iload 9 - get_enum_value + enum istore 10 LABEL156: - load_int -1 + iconst -1 istore 12 - load_int -1 + iconst -1 istore 13 - load_string "" + sconst "" sstore 1 - load_int 0 + iconst 0 istore 14 - load_string "" + sconst "" sstore 2 - load_string "" + sconst "" sstore 3 - get_varc 55 - get_varc 202 + get_varc_int 55 + get_varc_int 202 if_icmpge LABEL172 jump LABEL282 LABEL172: - get_varc 55 - get_gamecycle - load_int 3000 - isub + get_varc_int 55 + clientclock + iconst 3000 + sub if_icmpgt LABEL178 jump LABEL282 LABEL178: - load_int 14 - get_chatlinebuffer_length - load_int 0 + iconst 14 + chat_gethistorylength + iconst 0 if_icmpgt LABEL183 jump LABEL282 LABEL183: - load_int 14 - load_int 0 - get_chat_message_type + iconst 14 + iconst 0 + chat_gethistory_bytypeandline istore 14 sstore 0 sstore 2 @@ -211,7 +211,7 @@ LABEL183: istore 13 istore 12 iload 12 - load_int -1 + iconst -1 if_icmpne LABEL196 jump LABEL282 LABEL196: @@ -223,124 +223,124 @@ LABEL196: sload 0 iload 9 iload 10 - load_int 10682368 + iconst 10682368 iload 8 iload 1 - load_int 13 + iconst 13 iload 7 iload 2 iload 3 - load_int 16776960 - load_int 1 + iconst 16776960 + iconst 1 invoke 199 - iadd + add istore 7 iload 10 - widget_put_actions_null_widget + if_clearops sload 3 string_length - load_int 0 + iconst 0 if_icmpgt LABEL223 jump LABEL248 LABEL223: - load_int 6 - load_string "Open" + iconst 6 + sconst "Open" iload 10 - widget_put_action_widget - load_int 7 - load_string "Check" + if_setop + iconst 7 + sconst "Check" iload 10 - widget_put_action_widget - load_int 2065 + if_setop + iconst 2065 iload 10 - widget_get_parentid_widget + if_getlayer iload 9 - load_int 16777215 - load_string "Iii" + iconst 16777215 + sconst "Iii" iload 10 - widget_put_mouse_hover_listener_widget - load_int 2065 + if_setonmouserepeat + iconst 2065 iload 10 - widget_get_parentid_widget + if_getlayer iload 9 - load_int 16776960 - load_string "Iii" + iconst 16776960 + sconst "Iii" iload 10 - widget_put_mouse_exit_listener_widget + if_setonmouseleave jump LABEL256 LABEL248: - load_int -1 - load_string "" + iconst -1 + sconst "" iload 10 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 10 - widget_put_mouse_exit_listener_widget + if_setonmouseleave LABEL256: - load_int 9 - load_string "Clear history" + iconst 9 + sconst "Clear history" iload 10 - widget_put_action_widget - load_string "" - load_string "Notification" - load_string "" - string_append 3 + if_setop + sconst "" + sconst "Notification" + sconst "" + join_string 3 iload 10 - widget_put_name_widget - load_int 2064 - load_int -2147483644 + if_setopbase + iconst 2064 + iconst -2147483644 sload 3 - load_string "is" + sconst "is" iload 10 - widget_put_option_click_listener_widget + if_setonop iload 9 - load_int 1 - iadd + iconst 1 + add istore 9 - load_int 105 - load_int 73 - load_int 580 + iconst 105 + iconst 73 + iconst 580 iload 9 - get_enum_value + enum istore 10 LABEL282: iload 0 istore 12 - load_int 0 + iconst 0 istore 15 get_varp 287 - load_int 1 + iconst 1 if_icmpeq LABEL290 jump LABEL479 LABEL290: - get_varc 41 - load_int -1 + get_varc_int 41 + iconst 1337 if_icmpne LABEL297 get_varbit 4089 - load_int 0 + iconst 0 if_icmpeq LABEL297 jump LABEL479 LABEL297: iload 12 - load_int -1 + iconst -1 if_icmpne LABEL301 jump LABEL479 LABEL301: iload 10 - load_int -1 + iconst -1 if_icmpne LABEL305 jump LABEL479 LABEL305: iload 7 iload 4 - isub - load_int 57 + sub + iconst 57 if_icmplt LABEL311 jump LABEL479 LABEL311: iload 12 - get_chat_message + chat_gethistory_byuid istore 14 sstore 0 sstore 2 @@ -352,8 +352,19 @@ LABEL311: iload 13 iload 14 invoke 91 - load_int 1 - if_icmpeq LABEL327 + iconst 1 + if_icmpeq CHAT_FILTER ; Jump to our new label instead + jump LABEL475 +CHAT_FILTER: + sload 0 ; Load the message + iconst 1 ; Gets changed to 0 if message is blocked + iload 15 ; Load the messageType + sconst "chatFilterCheck" + runelite_callback + pop_int ; Pop the messageType + iconst 1 ; 2nd half of conditional + sstore 0 ; Override the message with our filtered message + if_icmpeq LABEL327 ; Check if we are building this message jump LABEL475 LABEL327: iload 15 @@ -364,50 +375,50 @@ LABEL327: jump LABEL372 LABEL330: iload 7 - load_string "From " + sconst "From " sload 1 - load_string ":" - load_string "privateChatSplitFrom" - runelite_callback - string_append 3 + sconst ":" + sconst "privateChatSplitFrom" + runelite_callback + join_string 3 sload 0 iload 9 iload 10 - load_int 10682368 + iconst 10682368 iload 8 iload 1 - load_int 13 + iconst 13 iload 7 iload 2 iload 3 - load_int 65535 - load_int 1 + iconst 65535 + iconst 1 invoke 203 - iadd + add istore 7 jump LABEL407 LABEL351: iload 7 - load_string "To " + sconst "To " sload 1 - load_string ":" - load_string "privateChatSplitTo" - runelite_callback - string_append 3 + sconst ":" + sconst "privateChatSplitTo" + runelite_callback + join_string 3 sload 0 iload 9 iload 10 - load_int 10682368 + iconst 10682368 iload 8 iload 1 - load_int 13 + iconst 13 iload 7 iload 2 iload 3 - load_int 65535 - load_int 1 + iconst 65535 + iconst 1 invoke 203 - iadd + add istore 7 jump LABEL407 LABEL372: @@ -415,184 +426,184 @@ LABEL372: sload 0 iload 9 iload 10 - load_int 10682368 + iconst 10682368 iload 8 iload 1 - load_int 13 + iconst 13 iload 7 iload 2 iload 3 - load_int 65535 - load_int 1 + iconst 65535 + iconst 1 invoke 199 - iadd + add istore 7 iload 15 - load_int 5 + iconst 5 if_icmpeq LABEL392 jump LABEL407 LABEL392: get_varbit 1627 - load_int 0 + iconst 0 if_icmpeq LABEL396 jump LABEL407 LABEL396: iload 13 - load_int 500 - iadd - load_int 1 - iadd - put_varc 65 - load_int 664 - load_int 0 - load_string "1" - load_int 10616832 - widget_put_render_listener_widget + iconst 500 + add + iconst 1 + add + set_varc_int 65 + iconst 664 + iconst 0 + sconst "1" + iconst 10616832 + if_setontimer LABEL407: iload 10 - widget_put_actions_null_widget + if_clearops iload 15 - load_int 3 + iconst 3 if_icmpeq LABEL419 iload 15 - load_int 6 + iconst 6 if_icmpeq LABEL419 iload 15 - load_int 7 + iconst 7 if_icmpeq LABEL419 jump LABEL453 LABEL419: iload 14 - load_int 1 + iconst 1 if_icmpeq LABEL423 jump LABEL428 LABEL423: - load_int 8 - load_string "Message" + iconst 8 + sconst "Message" iload 10 - widget_put_action_widget + if_setop jump LABEL436 LABEL428: - load_int 8 - load_string "Add friend" + iconst 8 + sconst "Add friend" iload 10 - widget_put_action_widget - load_int 9 - load_string "Add ignore" + if_setop + iconst 9 + sconst "Add ignore" iload 10 - widget_put_action_widget + if_setop LABEL436: - load_int 10 - load_string "Report" + iconst 10 + sconst "Report" iload 10 - widget_put_action_widget - load_string "" + if_setop + sconst "" sload 1 - load_string "" - string_append 3 + sconst "" + join_string 3 iload 10 - widget_put_name_widget - load_int 88 - load_int -2147483644 - load_string "event_opbase" - load_string "is" + if_setopbase + iconst 88 + iconst -2147483644 + sconst "event_opbase" + sconst "is" iload 10 - widget_put_option_click_listener_widget + if_setonop jump LABEL457 LABEL453: - load_int -1 - load_string "" + iconst -1 + sconst "" iload 10 - widget_put_option_click_listener_widget + if_setonop LABEL457: - load_int -1 - load_string "" + iconst -1 + sconst "" iload 10 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 10 - widget_put_mouse_exit_listener_widget + if_setonmouseleave iload 9 - load_int 1 - iadd + iconst 1 + add istore 9 - load_int 105 - load_int 73 - load_int 580 + iconst 105 + iconst 73 + iconst 580 iload 9 - get_enum_value + enum istore 10 LABEL475: iload 12 - get_messagenode_next_id + chat_getprevuid istore 12 jump LABEL297 LABEL479: iload 10 - load_int -1 + iconst -1 if_icmpne LABEL483 jump LABEL540 LABEL483: iload 10 - widget_put_actions_null_widget - load_int -1 - load_string "" + if_clearops + iconst -1 + sconst "" iload 10 - widget_put_option_click_listener_widget - load_int -1 - load_string "" + if_setonop + iconst -1 + sconst "" iload 10 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" + if_setonmouserepeat + iconst -1 + sconst "" iload 10 - widget_put_mouse_exit_listener_widget - load_int 0 - load_int 0 - load_int 0 - load_int 0 + if_setonmouseleave + iconst 0 + iconst 0 + iconst 0 + iconst 0 iload 10 - widget_put_size_widget - load_int 10682368 + if_setsize + iconst 10682368 iload 9 - load_int 2 - imul - widget_load_child - load_int 1 + iconst 2 + multiply + cc_find + iconst 1 if_icmpeq LABEL511 jump LABEL515 LABEL511: - load_string "" - widget_put_text - load_int 1 - widget_put_hidden + sconst "" + cc_settext + iconst 1 + cc_sethide LABEL515: - load_int 10682368 + iconst 10682368 iload 9 - load_int 2 - imul - load_int 1 - iadd - widget_load_child - load_int 1 + iconst 2 + multiply + iconst 1 + add + cc_find + iconst 1 if_icmpeq LABEL525 jump LABEL529 LABEL525: - load_string "" - widget_put_text - load_int 1 - widget_put_hidden + sconst "" + cc_settext + iconst 1 + cc_sethide LABEL529: iload 9 - load_int 1 - iadd + iconst 1 + add istore 9 - load_int 105 - load_int 73 - load_int 580 + iconst 105 + iconst 73 + iconst 580 iload 9 - get_enum_value + enum istore 10 jump LABEL479 LABEL540: diff --git a/runelite-client/src/main/scripts/ChatboxInput.rs2asm b/runelite-client/src/main/scripts/ChatboxInput.rs2asm index a9f0cf7f57..98567e8f1c 100644 --- a/runelite-client/src/main/scripts/ChatboxInput.rs2asm +++ b/runelite-client/src/main/scripts/ChatboxInput.rs2asm @@ -5,47 +5,47 @@ .string_var_count 1 sload 0 ; load input iload 0 ; load chat type - load_string "chatboxInput" ; event name - runelite_callback ; invoke callback - pop_int ; pop chat type - string_length ; get string length of chat message - load_int 0 ; load 0 + sconst "chatboxInput" ; event name + runelite_callback ; invoke callback + pop_int ; pop chat type + string_length ; get string length of chat message + iconst 0 ; load 0 if_icmpne LABEL100 ; if length is not 0, continue - return + return LABEL100: get_varbit 4394 - load_int 1 + iconst 1 if_icmpeq LABEL4 jump LABEL24 LABEL4: iload 0 - load_int 1 + iconst 1 if_icmpeq LABEL8 jump LABEL16 LABEL8: - get_localplayer_name - load_string ": " - load_string "" + chat_playername + sconst ": " + sconst "" sload 0 - load_string "" - string_append 5 - send_game_message + sconst "" + join_string 5 + mes jump LABEL23 LABEL16: - get_localplayer_name - load_string ": " - load_string "" + chat_playername + sconst ": " + sconst "" sload 0 - load_string "" - string_append 5 - send_game_message + sconst "" + join_string 5 + mes LABEL23: jump LABEL27 LABEL24: sload 0 iload 0 - chatbox_input + chat_sendpublic LABEL27: - get_gamecycle - put_varc 61 - return + clientclock + set_varc_int 61 + return diff --git a/runelite-client/src/main/scripts/ChatboxInputHandler.rs2asm b/runelite-client/src/main/scripts/ChatboxInputHandler.rs2asm deleted file mode 100644 index 106f53218e..0000000000 --- a/runelite-client/src/main/scripts/ChatboxInputHandler.rs2asm +++ /dev/null @@ -1,79 +0,0 @@ -; Copyright (c) 2018 Abex -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; -; 1. Redistributions of source code must retain the above copyright notice, this -; list of conditions and the following disclaimer. -; 2. Redistributions in binary form must reproduce the above copyright notice, -; this list of conditions and the following disclaimer in the documentation -; and/or other materials provided with the distribution. -; -; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -;; -; Keylistener for ChatboxInputInit -; -; Script 112 Normal keylistener -; -; @param int pressedKey -; @param int typedKey -;; - -.id 10002 -.int_stack_count 1 -.string_stack_count 1 -.int_var_count 2 -.string_var_count 1 - -; If we are not the active listener, the widget ids have probably changed - get_varc 5 - load_int -2 - if_icmpeq LABEL2 - -; Log the error - load_string "Got input while not active; Widget ids in ChatboxInputInit are probably wrong." - load_string "debug" - runelite_callback - return - -LABEL2: -; Discard zero presses - iload 0 - load_int 0 - if_icmpeq LABEL1 - -; Call runelite - iload 0 - get_varc_string 22 - load_string "chatboxInputHandler" - runelite_callback - istore 0 - put_varc_string 22 - -; Check return value - iload 0 - load_int 1 - if_icmpne LABEL0 - -; Close the dialog - load_int 1 - load_int 1 - invoke 299 - -; Update UI -LABEL0: - load_string "" - invoke 222 -LABEL1: - return diff --git a/runelite-client/src/main/scripts/ChatboxInputInit.rs2asm b/runelite-client/src/main/scripts/ChatboxInputInit.rs2asm deleted file mode 100644 index a29faa76c6..0000000000 --- a/runelite-client/src/main/scripts/ChatboxInputInit.rs2asm +++ /dev/null @@ -1,88 +0,0 @@ -; Copyright (c) 2018 Abex -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; -; 1. Redistributions of source code must retain the above copyright notice, this -; list of conditions and the following disclaimer. -; 2. Redistributions in binary form must reproduce the above copyright notice, -; this list of conditions and the following disclaimer in the documentation -; and/or other materials provided with the distribution. -; -; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -;; -; Creates a chatbox text input -; -; @param String Prompt text -; @param String Default value -; -; Script 752 GE input panel -; Script 103-111 various input panels -; Script 74 validates input -; script 112 key callback -;; - -.id 10001 -.int_stack_count 0 -.string_stack_count 2 -.int_var_count 0 -.string_var_count 2 - -; Hide the chat pane - invoke 677 - -; Set current value - sload 1 - put_varc_string 22 - -; Mark varcstring22 for our use - load_int -2 - put_varc 5 - -; Set text - sload 0 - load_int 10616876 - widget_put_text_widget - -; Init the widgets - load_string "" - invoke 222 - -; Register the key listener - load_int 10002 - load_int -2147483639 ; typedKey - load_string "i" - load_int 10616877 - widget_put_key_listener_widget - -; Restore the chatbox on exit - load_int 299 - load_int 1 - load_int 1 - load_string "ii" - load_int 10616877 - widget_put_dialog_abort_listener_widget - -; 70% sure this opens the keyboard on mobile - invoke 1972 - load_int 1 - if_icmpeq LABEL25 - jump LABEL26 -LABEL25: - load_int 1 - load_int 10 - invoke 1983 -LABEL26: - - return diff --git a/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash index 31eec732bf..7e9ed52814 100644 --- a/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash +++ b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash @@ -1 +1 @@ -30FB61D1C8600C402F57F493B09BDA050FD8381E9BAA5D13BB1BC95372FBA5D5 \ No newline at end of file +62630EDCE5CEB8733A496E2CAD89A4298F6EC05B8751DC6C9D2B25ED9D7BA391 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm index 21ca38aa88..7d608c5d0c 100644 --- a/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm +++ b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm @@ -3,166 +3,166 @@ .string_stack_count 0 .int_var_count 4 .string_var_count 3 - load_string "" + sconst "" sstore 0 - load_int 0 + iconst 0 istore 0 - load_int 6250335 + iconst 6250335 istore 1 invoke 921 - load_int 1 + iconst 1 if_icmpeq LABEL10 jump LABEL20 LABEL10: - load_string "" - load_int 16777215 - load_int 12566463 + sconst "" + iconst 16777215 + iconst 12566463 istore 1 istore 0 sstore 0 - load_int 1 - load_int 10616889 - widget_put_text_shadowed_widget + iconst 1 + iconst 10616889 + if_settextshadow jump LABEL23 LABEL20: - load_int 0 - load_int 10616889 - widget_put_text_shadowed_widget + iconst 0 + iconst 10616889 + if_settextshadow LABEL23: iload 0 - load_int 10616889 - widget_put_textcolor_widget - get_varc_string 1 + iconst 10616889 + if_setcolour + get_varc_string 335 string_length istore 2 - get_varc_string 1 - appendtags + get_varc_string 335 + escape sstore 1 - load_string "" + sconst "" sstore 2 - load_int 0 + iconst 0 istore 3 - get_varc 203 - load_int 1 + get_varbit 8119 + iconst 1 if_icmpeq LABEL40 jump LABEL99 LABEL40: - load_int 105 - load_int 115 - load_int 1894 + iconst 105 + iconst 115 + iconst 1894 get_varbit 1777 - get_enum_value - get_localplayer_name - load_string ": " + enum + chat_playername + sconst ": " sload 0 sload 1 - load_string "" - string_append 6 + sconst "" + join_string 6 sstore 2 iload 2 - load_int 80 + iconst 80 if_icmplt LABEL56 jump LABEL63 LABEL56: sload 2 sload 0 - load_string "*" - load_string "" - string_append 3 - concat_string + sconst "*" + sconst "" + join_string 3 + append sstore 2 LABEL63: sload 2 - load_int 2147483647 - load_int 495 - get_max_line_width + iconst 2147483647 + iconst 495 + parawidth istore 3 iload 3 - load_int 10616889 - widget_get_width_widget + iconst 10616889 + if_getwidth if_icmpgt LABEL73 jump LABEL79 LABEL73: - load_int 2 - load_int 2 - load_int 0 - load_int 10616889 - widget_put_text_alignment_widget + iconst 2 + iconst 2 + iconst 0 + iconst 10616889 + if_settextalign jump LABEL84 LABEL79: - load_int 0 - load_int 2 - load_int 0 - load_int 10616889 - widget_put_text_alignment_widget + iconst 0 + iconst 2 + iconst 0 + iconst 10616889 + if_settextalign LABEL84: - load_int 10616889 - widget_put_actions_null_widget - load_int -1 - load_string "" - load_int 10616889 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" - load_int 10616889 - widget_put_mouse_exit_listener_widget - load_int -1 - load_string "" - load_int 10616889 - widget_put_option_click_listener_widget + iconst 10616889 + if_clearops + iconst -1 + sconst "" + iconst 10616889 + if_setonmouserepeat + iconst -1 + sconst "" + iconst 10616889 + if_setonmouseleave + iconst -1 + sconst "" + iconst 10616889 + if_setonop jump LABEL140 LABEL99: - load_int 105 - load_int 115 - load_int 1894 + iconst 105 + iconst 115 + iconst 1894 get_varbit 1777 - get_enum_value - load_string " You must set a name before you can chat." - string_append 2 + enum + sconst " You must set a name before you can chat." + join_string 2 sstore 2 - load_int 1 - load_int 2 - load_int 0 - load_int 10616889 - widget_put_text_alignment_widget - load_int 10 - load_string "Configure" - load_int 10616889 - widget_put_action_widget - load_string "" - load_string "Display name" - load_string "" - string_append 3 - load_int 10616889 - widget_put_name_widget - load_int 45 - load_int -2147483645 + iconst 1 + iconst 2 + iconst 0 + iconst 10616889 + if_settextalign + iconst 10 + sconst "Configure" + iconst 10616889 + if_setop + sconst "" + sconst "Display name" + sconst "" + join_string 3 + iconst 10616889 + if_setopbase + iconst 45 + iconst -2147483645 iload 1 - load_string "Ii" - load_int 10616889 - widget_put_mouse_hover_listener_widget - load_int 45 - load_int -2147483645 + sconst "Ii" + iconst 10616889 + if_setonmouserepeat + iconst 45 + iconst -2147483645 iload 0 - load_string "Ii" - load_int 10616889 - widget_put_mouse_exit_listener_widget - load_int 489 - load_int -2147483644 - load_int 1024 - load_string "ii" - load_int 10616889 - widget_put_option_click_listener_widget + sconst "Ii" + iconst 10616889 + if_setonmouseleave + iconst 489 + iconst -2147483644 + iconst 1024 + sconst "ii" + iconst 10616889 + if_setonop LABEL140: sload 2 - load_int 10616889 - widget_put_text_widget - load_string "setChatboxInput" + iconst 10616889 + if_settext + sconst "setChatboxInput" runelite_callback - load_int 3 - load_int 16 - load_int 1 - load_int 0 - load_int 10616889 - widget_put_size_widget + iconst 3 + iconst 16 + iconst 1 + iconst 0 + iconst 10616889 + if_setsize return diff --git a/runelite-client/src/main/scripts/CommandScript.hash b/runelite-client/src/main/scripts/CommandScript.hash index 6a13a6985e..c278c005ee 100644 --- a/runelite-client/src/main/scripts/CommandScript.hash +++ b/runelite-client/src/main/scripts/CommandScript.hash @@ -1 +1 @@ -C42CD26AA6484029ACED50325EF8157741A9641BA28218315551B3762CE903A6 \ No newline at end of file +2F7E219C24E4725FA8F3BCDD9F2A640666CC589B514FEBD9F5938B207F06C0EB \ No newline at end of file diff --git a/runelite-client/src/main/scripts/CommandScript.rs2asm b/runelite-client/src/main/scripts/CommandScript.rs2asm index df1e10e0d4..0926703d6b 100644 --- a/runelite-client/src/main/scripts/CommandScript.rs2asm +++ b/runelite-client/src/main/scripts/CommandScript.rs2asm @@ -3,325 +3,322 @@ .string_stack_count 0 .int_var_count 5 .string_var_count 0 - load_int 10616887 - widget_get_hidden_widget - load_int 1 + iconst 10616887 + if_gethide + iconst 1 if_icmpeq LABEL9 - load_int 10616888 - widget_get_hidden_widget - load_int 1 + iconst 10616888 + if_gethide + iconst 1 if_icmpeq LABEL9 jump LABEL10 LABEL9: return LABEL10: - get_varc 203 - load_int 0 - if_icmpeq LABEL22 - get_varc 203 - load_int -1 - if_icmpeq LABEL22 - load_int -1 - load_int 162 + get_varbit 8119 + iconst 0 + if_icmpeq LABEL19 + iconst -1 + iconst 162 invoke 1701 - load_int 0 - if_icmpeq LABEL22 - jump LABEL23 -LABEL22: + iconst 0 + if_icmpeq LABEL19 + jump LABEL20 +LABEL19: return -LABEL23: - get_varc_string 1 +LABEL20: + get_varc_string 335 string_length istore 2 - load_int 0 + iconst 0 istore 3 - load_int 0 + iconst 0 istore 4 invoke 1972 - load_int 1 - if_icmpeq LABEL34 - jump LABEL40 -LABEL34: - get_varc 41 - load_int 4 - if_icmpeq LABEL38 - jump LABEL40 -LABEL38: - load_int 1 + iconst 1 + if_icmpeq LABEL31 + jump LABEL37 +LABEL31: + get_varc_int 41 + iconst 4 + if_icmpeq LABEL35 + jump LABEL37 +LABEL35: + iconst 1 istore 4 -LABEL40: - get_rights - load_int 0 - if_icmpgt LABEL44 - jump LABEL46 -LABEL44: - load_int 1 +LABEL37: + staffmodlevel + iconst 0 + if_icmpgt LABEL41 + jump LABEL43 +LABEL41: + iconst 1 istore 3 -LABEL46: +LABEL43: iload 3 - load_int 1 - if_icmpeq LABEL50 - jump LABEL61 -LABEL50: - load_string "`" + iconst 1 + if_icmpeq LABEL47 + jump LABEL58 +LABEL47: + sconst "`" iload 1 - string_indexof - load_int -1 - if_icmpne LABEL56 - jump LABEL61 -LABEL56: + string_indexof_char + iconst -1 + if_icmpne LABEL53 + jump LABEL58 +LABEL53: iload 2 - load_int 0 - if_icmpeq LABEL60 - jump LABEL61 -LABEL60: + iconst 0 + if_icmpeq LABEL57 + jump LABEL58 +LABEL57: return -LABEL61: +LABEL58: iload 0 - load_int 84 - if_icmpeq LABEL65 - jump LABEL182 -LABEL65: + iconst 84 + if_icmpeq LABEL62 + jump LABEL179 +LABEL62: invoke 1984 iload 2 - load_int 0 - if_icmpgt LABEL70 - jump LABEL181 -LABEL70: - get_varc_string 1 - load_string "/" - load_int 0 - string_indexof_from - load_int 0 - if_icmpeq LABEL80 + iconst 0 + if_icmpgt LABEL67 + jump LABEL178 +LABEL67: + get_varc_string 335 + sconst "/" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL77 iload 4 - load_int 1 - if_icmpeq LABEL80 - jump LABEL115 -LABEL80: - get_clanchatcount - load_int 0 - if_icmpgt LABEL84 - jump LABEL111 -LABEL84: + iconst 1 + if_icmpeq LABEL77 + jump LABEL112 +LABEL77: + clan_getchatcount + iconst 0 + if_icmpgt LABEL81 + jump LABEL108 +LABEL81: iload 2 - load_int 1 - if_icmple LABEL88 - jump LABEL93 -LABEL88: + iconst 1 + if_icmple LABEL85 + jump LABEL90 +LABEL85: iload 4 - load_int 0 - if_icmpeq LABEL92 - jump LABEL93 -LABEL92: + iconst 0 + if_icmpeq LABEL89 + jump LABEL90 +LABEL89: return -LABEL93: +LABEL90: get_varbit 4394 - load_int 1 - if_icmpeq LABEL97 - jump LABEL99 -LABEL97: - part_clanchat - jump LABEL110 -LABEL99: - iload 4 - load_int 1 - if_icmpeq LABEL103 + iconst 1 + if_icmpeq LABEL94 + jump LABEL96 +LABEL94: + clan_leavechat jump LABEL107 -LABEL103: - load_string "/" - get_varc_string 1 - concat_string - put_varc_string 1 +LABEL96: + iload 4 + iconst 1 + if_icmpeq LABEL100 + jump LABEL104 +LABEL100: + sconst "/" + get_varc_string 335 + append + set_varc_string 335 +LABEL104: + get_varc_string 335 + iconst 2 + invoke 96 LABEL107: - get_varc_string 1 - load_int 2 + jump LABEL111 +LABEL108: + get_varc_string 335 + iconst 0 invoke 96 -LABEL110: - jump LABEL114 LABEL111: - get_varc_string 1 - load_int 0 - invoke 96 -LABEL114: - jump LABEL177 -LABEL115: - get_varc_string 1 - load_string "::" - load_int 0 - string_indexof_from - load_int 0 - if_icmpeq LABEL122 jump LABEL174 -LABEL122: +LABEL112: + get_varc_string 335 + sconst "::" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL119 + jump LABEL171 +LABEL119: iload 2 - load_int 2 - if_icmpgt LABEL126 - jump LABEL170 -LABEL126: - get_varc_string 1 - load_string "::toggleroof" - load_int 0 - string_indexof_from - load_int 0 - if_icmpeq LABEL133 - jump LABEL147 -LABEL133: - get_hideroofs - load_int 1 - if_icmpeq LABEL137 - jump LABEL142 -LABEL137: - load_int 0 - set_hideroofs - load_string "Roofs will only be removed selectively." - send_game_message - jump LABEL146 -LABEL142: - load_int 1 - set_hideroofs - load_string "Roofs are now all hidden." - send_game_message -LABEL146: - jump LABEL169 -LABEL147: - get_varc_string 1 - load_string "::bank" - load_int 0 - string_indexof_from - load_int 0 - if_icmpeq LABEL154 - load_string "runeliteCommand" ; load callback name + iconst 2 + if_icmpgt LABEL123 + jump LABEL167 +LABEL123: + get_varc_string 335 + sconst "::toggleroof" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL130 + jump LABEL144 +LABEL130: + getremoveroofs + iconst 1 + if_icmpeq LABEL134 + jump LABEL139 +LABEL134: + iconst 0 + setremoveroofs + sconst "Roofs will only be removed selectively." + mes + jump LABEL143 +LABEL139: + iconst 1 + setremoveroofs + sconst "Roofs are now all hidden." + mes +LABEL143: + jump LABEL166 +LABEL144: + get_varc_string 335 + sconst "::bank" + iconst 0 + string_indexof_string + iconst 0 + if_icmpeq LABEL151 + sconst "runeliteCommand" ; load callback name runelite_callback ; invoke callback - jump LABEL158 -LABEL154: - load_string "Hey, everyone, I just tried to do something very silly!" - load_int 0 + jump LABEL155 +LABEL151: + sconst "Hey, everyone, I just tried to do something very silly!" + iconst 0 invoke 96 - jump LABEL169 -LABEL158: - get_varc_string 1 + jump LABEL166 +LABEL155: + get_varc_string 335 invoke 224 - put_varc_string 1 - get_varc_string 1 + set_varc_string 335 + get_varc_string 335 string_length istore 2 - get_varc_string 1 - load_int 2 + get_varc_string 335 + iconst 2 iload 2 - string_substring - run_command -LABEL169: - jump LABEL173 + substring + docheat +LABEL166: + jump LABEL170 +LABEL167: + get_varc_string 335 + iconst 0 + invoke 96 LABEL170: - get_varc_string 1 - load_int 0 + jump LABEL174 +LABEL171: + get_varc_string 335 + iconst 0 invoke 96 -LABEL173: - jump LABEL177 LABEL174: - get_varc_string 1 - load_int 0 - invoke 96 -LABEL177: - get_varc_string 1 + get_varc_string 335 invoke 77 - load_string "" - put_varc_string 1 -LABEL181: - jump LABEL250 -LABEL182: + sconst "" + set_varc_string 335 +LABEL178: + jump LABEL247 +LABEL179: iload 0 - load_int 104 - if_icmpeq LABEL186 - jump LABEL192 -LABEL186: + iconst 104 + if_icmpeq LABEL183 + jump LABEL189 +LABEL183: iload 3 - load_int 1 - if_icmpeq LABEL190 - jump LABEL191 -LABEL190: + iconst 1 + if_icmpeq LABEL187 + jump LABEL188 +LABEL187: invoke 75 -LABEL191: - jump LABEL250 -LABEL192: +LABEL188: + jump LABEL247 +LABEL189: iload 0 - load_int 105 - if_icmpeq LABEL196 - jump LABEL202 -LABEL196: + iconst 105 + if_icmpeq LABEL193 + jump LABEL199 +LABEL193: iload 3 - load_int 1 - if_icmpeq LABEL200 - jump LABEL201 -LABEL200: + iconst 1 + if_icmpeq LABEL197 + jump LABEL198 +LABEL197: invoke 76 -LABEL201: - jump LABEL250 -LABEL202: +LABEL198: + jump LABEL247 +LABEL199: iload 0 - load_int 80 - if_icmpeq LABEL206 - jump LABEL244 -LABEL206: - get_varc_string + iconst 80 + if_icmpeq LABEL203 + jump LABEL241 +LABEL203: + get_varc_string 356 string_length - load_int 0 - if_icmpgt LABEL211 - jump LABEL231 -LABEL211: - get_varc_string - is_friend - load_int 1 - if_icmpeq LABEL216 - jump LABEL219 -LABEL216: - get_varc_string + iconst 0 + if_icmpgt LABEL208 + jump LABEL228 +LABEL208: + get_varc_string 356 + friend_test + iconst 1 + if_icmpeq LABEL213 + jump LABEL216 +LABEL213: + get_varc_string 356 invoke 107 return -LABEL219: - get_varc 60 - get_gamecycle - if_icmpgt LABEL223 - jump LABEL224 -LABEL223: +LABEL216: + get_varc_int 60 + clientclock + if_icmpgt LABEL220 + jump LABEL221 +LABEL220: return -LABEL224: - get_gamecycle - load_int 50 - iadd - put_varc 60 - load_string "That player was not found on your Friends list." - send_game_message +LABEL221: + clientclock + iconst 50 + add + set_varc_int 60 + sconst "That player was not found on your Friends list." + mes return -LABEL231: - get_varc 60 - get_gamecycle - if_icmpgt LABEL235 - jump LABEL236 -LABEL235: +LABEL228: + get_varc_int 60 + clientclock + if_icmpgt LABEL232 + jump LABEL233 +LABEL232: return -LABEL236: - get_gamecycle - load_int 50 - iadd - put_varc 60 - load_string "You haven't received any messages to which you can reply." - send_game_message +LABEL233: + clientclock + iconst 50 + add + set_varc_int 60 + sconst "You haven't received any messages to which you can reply." + mes return - jump LABEL250 -LABEL244: - get_varc_string 1 - load_int 0 + jump LABEL247 +LABEL241: + get_varc_string 335 + iconst 0 iload 0 iload 1 invoke 74 - load_int 1 ; check if we're ignoring input - load_int 0 ; - load_string "blockChatInput" ; + iconst 1 ; check if we're ignoring input + iconst 0 ; + sconst "blockChatInput" ; runelite_callback ; - if_icmpeq LABEL250 ; don't add to input varcstr - put_varc_string 1 -LABEL250: + if_icmpeq LABEL247 ; don't add to input varcstr + set_varc_string 335 +LABEL247: invoke 223 return diff --git a/runelite-client/src/main/scripts/GEOffersSetupInit.hash b/runelite-client/src/main/scripts/GEOffersSetupInit.hash new file mode 100644 index 0000000000..689d72d678 --- /dev/null +++ b/runelite-client/src/main/scripts/GEOffersSetupInit.hash @@ -0,0 +1 @@ +B370DDEEF61E0F420C1990DDA4FBBEDCEE8324F3750ABAC79B072A27268D887B \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GEOffersSetupInit.rs2asm b/runelite-client/src/main/scripts/GEOffersSetupInit.rs2asm new file mode 100644 index 0000000000..e884731804 --- /dev/null +++ b/runelite-client/src/main/scripts/GEOffersSetupInit.rs2asm @@ -0,0 +1,394 @@ +.id 779 +.int_stack_count 15 +.string_stack_count 0 +.int_var_count 16 +.string_var_count 1 + get_varbit 4397 + iconst 1 + if_icmpeq LABEL4 + jump LABEL65 +LABEL4: + iload 0 + iload 1 + cc_find + iconst 1 + if_icmpeq LABEL10 + jump LABEL12 +LABEL10: + iconst 1 + cc_sethide +LABEL12: + iload 0 + iload 6 + cc_find + iconst 1 + if_icmpeq LABEL18 + jump LABEL23 +LABEL18: + iconst 0 + cc_settrans + iconst -1 + sconst "" + cc_setontimer +LABEL23: + iload 0 + iload 12 + cc_find + iconst 1 + if_icmpeq LABEL29 + jump LABEL31 +LABEL29: + iconst 1 + cc_sethide +LABEL31: + iload 0 + iload 4 + cc_find + iconst 1 + if_icmpeq LABEL37 + jump LABEL39 +LABEL37: + sconst "Sell offer" + cc_settext +LABEL39: + iload 0 + iload 5 + cc_find + iconst 1 + if_icmpeq LABEL45 + jump LABEL47 +LABEL45: + iconst 1119 + cc_setgraphic +LABEL47: + iload 0 + iload 2 + cc_find + iconst 1 + if_icmpeq LABEL53 + jump LABEL56 +LABEL53: + iconst 1 + sconst "All" + cc_setop +LABEL56: + iload 0 + iload 3 + cc_find + iconst 1 + if_icmpeq LABEL62 + jump LABEL64 +LABEL62: + sconst "All" + cc_settext +LABEL64: + jump LABEL130 +LABEL65: + iload 0 + iload 1 + cc_find + iconst 1 + if_icmpeq LABEL71 + jump LABEL73 +LABEL71: + iconst 0 + cc_sethide +LABEL73: + iload 0 + iload 6 + cc_find + iconst 1 + if_icmpeq LABEL79 + jump LABEL89 +LABEL79: + iconst 100 + cc_settrans + iconst 811 + iconst -2147483645 + iconst -2147483643 + clientclock + iconst 100 + iconst 250 + sconst "Iiiii" + cc_setontimer +LABEL89: + iload 0 + iload 12 + cc_find + iconst 1 + if_icmpeq LABEL95 + jump LABEL97 +LABEL95: + iconst 0 + cc_sethide +LABEL97: + iload 0 + iload 4 + cc_find + iconst 1 + if_icmpeq LABEL103 + jump LABEL105 +LABEL103: + sconst "Buy offer" + cc_settext +LABEL105: + iload 0 + iload 5 + cc_find + iconst 1 + if_icmpeq LABEL111 + jump LABEL113 +LABEL111: + iconst 1118 + cc_setgraphic +LABEL113: + iload 0 + iload 2 + cc_find + iconst 1 + if_icmpeq LABEL119 + jump LABEL122 +LABEL119: + iconst 1 + sconst "+1K" + cc_setop +LABEL122: + iload 0 + iload 3 + cc_find + iconst 1 + if_icmpeq LABEL128 + jump LABEL130 +LABEL128: + sconst "+1K" + cc_settext +LABEL130: + sconst "," + sstore 0 + iconst 0 + istore 15 + get_varp 1151 + iconst -1 + if_icmpne LABEL138 + jump LABEL274 +LABEL138: + iload 0 + iload 7 + cc_find + iconst 1 + if_icmpeq LABEL144 + jump LABEL147 +LABEL144: + get_varp 1151 + get_varbit 4396 + cc_setobject_nonum +LABEL147: + iload 0 + iload 8 + cc_find + iconst 1 + if_icmpeq LABEL153 + jump LABEL156 +LABEL153: + get_varp 1151 + oc_name + cc_settext +LABEL156: + iload 0 + iload 9 + cc_find + iconst 1 + if_icmpeq LABEL162 + jump LABEL166 +LABEL162: + get_varbit 4396 + sload 0 + invoke 46 + cc_settext +LABEL166: + iload 0 + iload 10 + cc_find + iconst 1 + if_icmpeq LABEL172 + jump LABEL185 +LABEL172: + get_varbit 4398 + iconst 1 + if_icmpeq LABEL176 + jump LABEL179 +LABEL176: + sconst "1 coin" + cc_settext + jump LABEL185 +LABEL179: + get_varbit 4398 + sload 0 + invoke 46 + sconst " coins" + join_string 2 + cc_settext +LABEL185: + get_varbit 4396 + iconst 0 + if_icmpgt LABEL189 + jump LABEL211 +LABEL189: + iconst 2147483647 + get_varbit 4396 + div + get_varbit 4398 + if_icmplt LABEL195 + jump LABEL211 +LABEL195: + iload 0 + iload 11 + cc_find + iconst 1 + if_icmpeq LABEL201 + jump LABEL206 +LABEL201: + sconst "" + sconst "Too much money!" + sconst "" + join_string 3 + cc_settext +LABEL206: + iload 0 + iload 14 + iload 13 + invoke 780 + jump LABEL273 +LABEL211: + get_varbit 4396 + get_varbit 4398 + multiply + istore 15 + iload 0 + iload 11 + cc_find + iconst 1 + if_icmpeq LABEL221 + jump LABEL234 +LABEL221: + iload 15 + iconst 1 + if_icmpeq LABEL225 + jump LABEL228 +LABEL225: + sconst "1 coin" + cc_settext + jump LABEL234 +LABEL228: + iload 15 + sload 0 + invoke 46 + sconst " coins" + join_string 2 + cc_settext +LABEL234: + iload 15 + iconst 0 + if_icmpgt LABEL238 + jump LABEL269 +LABEL238: + iload 13 + invoke 208 + pop_int + iconst 772 + iconst -2147483645 + sconst "I" + iload 13 + if_setonmouserepeat + iconst 97 + iconst -2147483645 + sconst "I" + iload 13 + if_setonmouseleave + iconst 489 + iconst -2147483644 + iconst 2 + sconst "ii" + iload 13 + if_setonop + iload 0 + iload 14 + cc_find + iconst 1 + if_icmpeq LABEL263 + jump LABEL268 +LABEL263: + sconst "" + sconst "Confirm" + sconst "" + join_string 3 + cc_settext +LABEL268: + jump LABEL273 +LABEL269: + iload 0 + iload 14 + iload 13 + invoke 780 +LABEL273: + jump LABEL319 +LABEL274: + iload 0 + iload 7 + cc_find + iconst 1 + if_icmpeq LABEL280 + jump LABEL283 +LABEL280: + iconst 6512 + iconst 1 + cc_setobject_nonum +LABEL283: + iload 0 + iload 8 + cc_find + iconst 1 + if_icmpeq LABEL289 + jump LABEL291 +LABEL289: + sconst "Choose an item..." + cc_settext +LABEL291: + iload 0 + iload 9 + cc_find + iconst 1 + if_icmpeq LABEL297 + jump LABEL299 +LABEL297: + sconst "" + cc_settext +LABEL299: + iload 0 + iload 10 + cc_find + iconst 1 + if_icmpeq LABEL305 + jump LABEL307 +LABEL305: + sconst "" + cc_settext +LABEL307: + iload 0 + iload 11 + cc_find + iconst 1 + if_icmpeq LABEL313 + jump LABEL315 +LABEL313: + sconst "" + cc_settext +LABEL315: + iload 0 + iload 14 + iload 13 + invoke 780 +LABEL319: + sconst "geBuilt" ; + runelite_callback ; + return diff --git a/runelite-client/src/main/scripts/OpenBankSearchInput.rs2asm b/runelite-client/src/main/scripts/OpenBankSearchInput.rs2asm index aa38d28de9..547863277a 100644 --- a/runelite-client/src/main/scripts/OpenBankSearchInput.rs2asm +++ b/runelite-client/src/main/scripts/OpenBankSearchInput.rs2asm @@ -3,42 +3,42 @@ .string_stack_count 0 .int_var_count 0 .string_var_count 1 - get_varc 11 - load_int 1 + get_varc_int 11 + iconst 1 if_icmpeq LABEL4 jump LABEL5 LABEL4: - close_window + if_close LABEL5: - load_int 11 + iconst 11 invoke 677 - load_string "Show items whose names contain the following text:" - load_string "setSearchBankInputText" ; load event name + sconst "Show items whose names contain the following text:" + sconst "setSearchBankInputText" ; load event name runelite_callback ; invoke callback - load_int 10616876 - widget_put_text_widget - load_string "" + iconst 10616876 + if_settext + sconst "" invoke 222 - load_string "" + sconst "" sstore 0 - load_int 112 - load_int -2147483640 - load_int -2147483639 + iconst 112 + iconst -2147483640 + iconst -2147483639 sload 0 - load_string "izs" - load_int 10616877 - widget_put_key_listener_widget - load_int 138 - load_string "" - load_int 10616877 - widget_put_dialog_abort_listener_widget + sconst "izs" + iconst 10616877 + if_setonkey + iconst 138 + sconst "" + iconst 10616877 + if_setondialogabort invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL29 jump LABEL32 LABEL29: - load_int 0 - load_int 80 + iconst 0 + iconst 80 invoke 1983 LABEL32: return diff --git a/runelite-client/src/main/scripts/OptionsPanelRebuilder.rs2asm b/runelite-client/src/main/scripts/OptionsPanelRebuilder.rs2asm index bb6da79dd8..afb820ff0f 100644 --- a/runelite-client/src/main/scripts/OptionsPanelRebuilder.rs2asm +++ b/runelite-client/src/main/scripts/OptionsPanelRebuilder.rs2asm @@ -3,253 +3,253 @@ .string_stack_count 0 .int_var_count 21 .string_var_count 0 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551298 - get_enum_value + iconst 10551298 + enum istore 2 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551306 - get_enum_value + iconst 10551306 + enum istore 3 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551301 - get_enum_value + iconst 10551301 + enum istore 4 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551308 - get_enum_value + iconst 10551308 + enum istore 5 - load_int 103 - load_int 105 - load_int 1960 + iconst 103 + iconst 105 + iconst 1960 iload 1 - get_enum_value + enum istore 6 - load_int 103 - load_int 105 - load_int 1961 + iconst 103 + iconst 105 + iconst 1961 iload 1 - get_enum_value + enum istore 7 - load_int 103 - load_int 105 - load_int 1135 + iconst 103 + iconst 105 + iconst 1135 iload 1 - get_enum_value + enum istore 8 - load_int 103 - load_int 105 - load_int 1136 + iconst 103 + iconst 105 + iconst 1136 iload 1 - get_enum_value + enum istore 9 - load_int 0 + iconst 0 istore 10 - load_int 0 + iconst 0 istore 11 - load_int 0 + iconst 0 istore 12 - load_int 0 + iconst 0 istore 13 - load_int 0 + iconst 0 istore 14 - load_int 0 + iconst 0 istore 15 iload 0 - widget_get_width_widget + if_getwidth istore 16 iload 0 - widget_get_height_widget + if_getheight istore 17 iload 1 - load_int 1745 + iconst 1745 if_icmpeq LABEL70 jump LABEL84 LABEL70: - load_int 0 + iconst 0 iload 16 - load_int 39387148 - widget_get_width_widget - isub + iconst 39387148 + if_getwidth + sub invoke 1045 istore 14 - load_int 0 + iconst 0 iload 17 - load_int 39387148 - widget_get_height_widget - isub + iconst 39387148 + if_getheight + sub invoke 1045 istore 15 LABEL84: get_varbit 4606 - load_int 0 + iconst 0 if_icmpne LABEL88 jump LABEL253 LABEL88: get_varbit 4606 - load_int 2 + iconst 2 if_icmpeq LABEL92 jump LABEL101 LABEL92: - load_int 512 - load_int 220 - 6200 - load_int 0 - load_int 0 - load_int 0 - load_int 0 - 6202 + iconst 512 + iconst 220 + viewport_setfov + iconst 0 + iconst 0 + iconst 0 + iconst 0 + viewport_clampfov jump LABEL106 LABEL101: - load_int 512 - load_int 512 - load_int 512 - load_int 512 - 6202 + iconst 512 + iconst 512 + iconst 512 + iconst 512 + viewport_clampfov LABEL106: - load_int 50 - set_camera_focal_point_height + iconst 50 + cam_setfollowheight iload 2 - load_int -1 + iconst -1 if_icmpne LABEL112 jump LABEL252 LABEL112: iload 3 - load_int -1 + iconst -1 if_icmpne LABEL116 jump LABEL252 LABEL116: - get_viewport_size + viewport_geteffectivesize istore 11 istore 10 - load_int 0 + iconst 0 iload 16 iload 10 - isub + sub invoke 1045 - load_int 0 + iconst 0 iload 17 iload 11 - isub + sub invoke 1045 istore 13 istore 12 iload 10 iload 11 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 2 - widget_put_size_widget + if_setsize iload 10 - load_int 0 + iconst 0 iload 14 iload 12 - isub + sub invoke 1045 - isub + sub iload 11 - load_int 0 + iconst 0 iload 15 iload 13 - isub + sub invoke 1045 - isub - load_int 0 - load_int 0 + sub + iconst 0 + iconst 0 iload 3 - widget_put_size_widget + if_setsize iload 4 - load_int -1 + iconst -1 if_icmpne LABEL159 jump LABEL242 LABEL159: iload 5 - load_int -1 + iconst -1 if_icmpne LABEL163 jump LABEL242 LABEL163: iload 12 iload 14 - isub - load_int 2 - idiv + sub + iconst 2 + div iload 13 iload 15 - isub - load_int 2 - idiv + sub + iconst 2 + div istore 13 istore 12 - load_int 0 + iconst 0 iload 6 iload 12 - isub + sub invoke 1045 - load_int 0 + iconst 0 iload 8 iload 12 - isub + sub invoke 1045 istore 8 istore 6 - load_int 0 + iconst 0 iload 7 iload 13 - isub + sub invoke 1045 - load_int 0 + iconst 0 iload 9 iload 13 - isub + sub invoke 1045 istore 9 istore 7 iload 6 iload 7 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 4 - widget_put_position_widget + if_setposition iload 6 iload 7 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 5 - widget_put_position_widget + if_setposition iload 6 iload 8 - iadd + add iload 7 iload 9 - iadd - load_int 1 - load_int 1 + add + iconst 1 + iconst 1 iload 4 - widget_put_size_widget + if_setsize iload 6 iload 8 - iadd + add iload 7 iload 9 - iadd - load_int 1 - load_int 1 + add + iconst 1 + iconst 1 iload 5 - widget_put_size_widget + if_setsize iload 1 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551307 - get_enum_value + iconst 10551307 + enum iload 5 iload 8 iload 9 @@ -257,137 +257,137 @@ LABEL163: jump LABEL252 LABEL242: iload 1 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551307 - get_enum_value + iconst 10551307 + enum iload 3 - load_int 0 - load_int 0 + iconst 0 + iconst 0 invoke 910 LABEL252: jump LABEL369 LABEL253: - load_int 0 - load_int 0 - load_int 0 - load_int 0 - 6202 - get_varc 73 - load_int 128 - load_string "outerZoomLimit" - runelite_callback + iconst 0 + iconst 0 + iconst 0 + iconst 0 + viewport_clampfov + get_varc_int 73 + iconst 128 + sconst "outerZoomLimit" + runelite_callback if_icmpge LABEL262 jump LABEL278 LABEL262: - get_varc 73 - load_int 896 - load_string "innerZoomLimit" + get_varc_int 73 + iconst 896 + sconst "innerZoomLimit" runelite_callback if_icmple LABEL266 jump LABEL278 LABEL266: - get_varc 74 - load_int 128 - load_string "outerZoomLimit" - runelite_callback + get_varc_int 74 + iconst 128 + sconst "outerZoomLimit" + runelite_callback if_icmpge LABEL270 jump LABEL278 LABEL270: - get_varc 74 - load_int 896 - load_string "innerZoomLimit" + get_varc_int 74 + iconst 896 + sconst "innerZoomLimit" runelite_callback if_icmple LABEL274 jump LABEL278 LABEL274: - get_varc 73 - get_varc 74 + get_varc_int 73 + get_varc_int 74 invoke 42 jump LABEL281 LABEL278: - load_int 512 - load_int 512 + iconst 512 + iconst 512 invoke 42 LABEL281: - get_viewport_size + viewport_geteffectivesize istore 11 istore 10 iload 2 - load_int -1 + iconst -1 if_icmpne LABEL288 jump LABEL369 LABEL288: iload 3 - load_int -1 + iconst -1 if_icmpne LABEL292 jump LABEL369 LABEL292: iload 10 iload 11 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 2 - widget_put_size_widget + if_setsize iload 10 iload 14 - isub + sub iload 11 iload 15 - isub - load_int 0 - load_int 0 + sub + iconst 0 + iconst 0 iload 3 - widget_put_size_widget + if_setsize iload 4 - load_int -1 + iconst -1 if_icmpne LABEL312 jump LABEL359 LABEL312: iload 5 - load_int -1 + iconst -1 if_icmpne LABEL316 jump LABEL359 LABEL316: iload 6 iload 7 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 4 - widget_put_position_widget + if_setposition iload 6 iload 7 - load_int 0 - load_int 0 + iconst 0 + iconst 0 iload 5 - widget_put_position_widget + if_setposition iload 6 iload 8 - iadd + add iload 7 iload 9 - iadd - load_int 1 - load_int 1 + add + iconst 1 + iconst 1 iload 4 - widget_put_size_widget + if_setsize iload 6 iload 8 - iadd + add iload 7 iload 9 - iadd - load_int 1 - load_int 1 + add + iconst 1 + iconst 1 iload 5 - widget_put_size_widget + if_setsize iload 1 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551307 - get_enum_value + iconst 10551307 + enum iload 5 iload 8 iload 9 @@ -395,191 +395,191 @@ LABEL316: jump LABEL369 LABEL359: iload 1 - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551307 - get_enum_value + iconst 10551307 + enum iload 3 - load_int 0 - load_int 0 + iconst 0 + iconst 0 invoke 910 LABEL369: - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551309 - get_enum_value + iconst 10551309 + enum istore 18 iload 18 - load_int -1 + iconst -1 if_icmpne LABEL379 jump LABEL423 LABEL379: invoke 1972 - load_int 0 + iconst 0 if_icmpeq LABEL383 jump LABEL417 LABEL383: iload 18 - widget_get_index_widget - load_int 1 + if_hassub + iconst 1 if_icmpeq LABEL388 jump LABEL417 LABEL388: - get_varc 173 - load_int -2 + get_varc_int 173 + iconst -2 if_icmpeq LABEL392 jump LABEL399 LABEL392: - load_int 512 - load_int 0 - load_int 0 - load_int 1 + iconst 512 + iconst 0 + iconst 0 + iconst 1 iload 18 - widget_put_size_widget + if_setsize jump LABEL416 LABEL399: - get_varc 173 - load_int -3 + get_varc_int 173 + iconst -3 if_icmpeq LABEL403 jump LABEL410 LABEL403: - load_int 0 - load_int 0 - load_int 1 - load_int 1 + iconst 0 + iconst 0 + iconst 1 + iconst 1 iload 18 - widget_put_size_widget + if_setsize jump LABEL416 LABEL410: - load_int 512 - load_int 334 - load_int 0 - load_int 0 + iconst 512 + iconst 334 + iconst 0 + iconst 0 iload 18 - widget_put_size_widget + if_setsize LABEL416: jump LABEL423 LABEL417: - load_int 512 - load_int 334 - load_int 0 - load_int 0 + iconst 512 + iconst 334 + iconst 0 + iconst 0 iload 18 - widget_put_size_widget + if_setsize LABEL423: - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551311 - get_enum_value + iconst 10551311 + enum istore 18 - load_int 0 + iconst 0 istore 19 - load_int 0 + iconst 0 istore 20 iload 18 - load_int -1 + iconst -1 if_icmpne LABEL437 jump LABEL481 LABEL437: - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551303 - get_enum_value - widget_get_index_widget - load_int 1 + iconst 10551303 + enum + if_hassub + iconst 1 if_icmpeq LABEL446 jump LABEL455 LABEL446: get_varbit 4692 - load_int 0 + iconst 0 if_icmpne LABEL450 jump LABEL453 LABEL450: - load_int 0 + iconst 0 istore 20 jump LABEL455 LABEL453: - load_int 38 + iconst 38 istore 20 LABEL455: invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL459 jump LABEL473 LABEL459: get_varbit 6254 - load_int 0 + iconst 0 if_icmpeq LABEL463 jump LABEL468 LABEL463: - load_int 182 - load_int 4 - iadd + iconst 182 + iconst 4 + add istore 19 jump LABEL472 LABEL468: - load_int 120 - load_int 4 - iadd + iconst 120 + iconst 4 + add istore 19 LABEL472: jump LABEL475 LABEL473: - load_int 0 + iconst 0 istore 19 LABEL475: iload 19 iload 20 - load_int 2 - load_int 0 + iconst 2 + iconst 0 iload 18 - widget_put_position_widget + if_setposition LABEL481: - load_int 73 - load_int 73 + iconst 73 + iconst 73 iload 1 - load_int 10551303 - get_enum_value + iconst 10551303 + enum istore 18 - load_int 0 + iconst 0 istore 19 iload 18 - load_int -1 + iconst -1 if_icmpne LABEL493 jump LABEL515 LABEL493: invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL497 jump LABEL507 LABEL497: get_varbit 6254 - load_int 0 + iconst 0 if_icmpeq LABEL501 jump LABEL504 LABEL501: - load_int 182 + iconst 182 istore 19 jump LABEL506 LABEL504: - load_int 120 + iconst 120 istore 19 LABEL506: jump LABEL509 LABEL507: - load_int 0 + iconst 0 istore 19 LABEL509: iload 19 - load_int 0 - load_int 1 - load_int 1 + iconst 0 + iconst 1 + iconst 1 iload 18 - widget_put_size_widget + if_setsize LABEL515: iload 0 iload 1 diff --git a/runelite-client/src/main/scripts/OptionsPanelZoomMouseListener.rs2asm b/runelite-client/src/main/scripts/OptionsPanelZoomMouseListener.rs2asm index 35bc2c04d4..a9aa9f62ad 100644 --- a/runelite-client/src/main/scripts/OptionsPanelZoomMouseListener.rs2asm +++ b/runelite-client/src/main/scripts/OptionsPanelZoomMouseListener.rs2asm @@ -6,77 +6,77 @@ ; locals ; 2 bar size get_varbit 4606 - load_int 0 + iconst 0 if_icmpne LABEL4 jump LABEL5 LABEL4: return LABEL5: - load_int 512 + iconst 512 istore 3 - load_int 512 + iconst 512 istore 4 iload 1 - widget_get_width_widget + if_getwidth iload 0 - widget_get_width_widget - isub + if_getwidth + sub istore 5 - load_int 0 + iconst 0 iload 2 invoke 1045 istore 2 iload 1 - widget_get_width_widget + if_getwidth iload 0 - widget_get_width_widget - isub + if_getwidth + sub iload 2 invoke 1046 istore 2 - load_int 896 - load_string "innerZoomLimit" + iconst 896 + sconst "innerZoomLimit" runelite_callback - load_int 128 - load_string "outerZoomLimit" - runelite_callback - isub + iconst 128 + sconst "outerZoomLimit" + runelite_callback + sub istore 6 ; resizable delta - load_int 896 - load_string "innerZoomLimit" + iconst 896 + sconst "innerZoomLimit" runelite_callback - load_int 128 - load_string "outerZoomLimit" - runelite_callback - isub + iconst 128 + sconst "outerZoomLimit" + runelite_callback + sub istore 7 ; fixed delta iload 2 iload 6 - imul + multiply iload 5 - idiv + div iload 6 - load_string "zoomLinToExp" - runelite_callback - pop_int - load_int 128 - load_string "outerZoomLimit" - runelite_callback - iadd + sconst "zoomLinToExp" + runelite_callback + pop_int + iconst 128 + sconst "outerZoomLimit" + runelite_callback + add istore 3 iload 2 iload 7 - imul + multiply iload 5 - idiv + div iload 7 - load_string "zoomLinToExp" - runelite_callback - pop_int - load_int 128 - load_string "outerZoomLimit" - runelite_callback - iadd + sconst "zoomLinToExp" + runelite_callback + pop_int + iconst 128 + sconst "outerZoomLimit" + runelite_callback + add istore 4 iload 4 iload 3 diff --git a/runelite-client/src/main/scripts/OptionsPanelZoomUpdater.rs2asm b/runelite-client/src/main/scripts/OptionsPanelZoomUpdater.rs2asm index ae8b33dd98..3abf21a570 100644 --- a/runelite-client/src/main/scripts/OptionsPanelZoomUpdater.rs2asm +++ b/runelite-client/src/main/scripts/OptionsPanelZoomUpdater.rs2asm @@ -7,77 +7,77 @@ ; 0 resizableZoomRange ; 1 fixedZoomRange ; 2 bar size - load_int 896 - load_string "innerZoomLimit" + iconst 896 + sconst "innerZoomLimit" runelite_callback - load_int 128 - load_string "outerZoomLimit" - runelite_callback - isub + iconst 128 + sconst "outerZoomLimit" + runelite_callback + sub istore 0 - load_int 896 - load_string "innerZoomLimit" + iconst 896 + sconst "innerZoomLimit" runelite_callback - load_int 128 - load_string "outerZoomLimit" - runelite_callback - isub + iconst 128 + sconst "outerZoomLimit" + runelite_callback + sub istore 1 - load_int 17104910 - widget_get_width_widget - load_int 17104911 - widget_get_width_widget - isub + iconst 17104910 + if_getwidth + iconst 17104911 + if_getwidth + sub istore 2 - load_int 0 + iconst 0 istore 3 - load_int 0 + iconst 0 istore 4 - get_viewport_size + viewport_geteffectivesize istore 4 istore 3 - load_int 0 + iconst 0 istore 5 iload 3 - load_int 334 + iconst 334 if_icmpgt LABEL27 jump LABEL36 LABEL27: - get_varc 74 - load_int 128 - load_string "outerZoomLimit" - runelite_callback - isub + get_varc_int 74 + iconst 128 + sconst "outerZoomLimit" + runelite_callback + sub iload 0 - load_string "zoomExpToLin" + sconst "zoomExpToLin" runelite_callback pop_int iload 2 - imul + multiply iload 0 - idiv + div istore 5 jump LABEL44 LABEL36: - get_varc 73 - load_int 128 - load_string "outerZoomLimit" - runelite_callback - isub + get_varc_int 73 + iconst 128 + sconst "outerZoomLimit" + runelite_callback + sub iload 0 - load_string "zoomExpToLin" + sconst "zoomExpToLin" runelite_callback pop_int iload 2 - imul + multiply iload 1 - idiv + div istore 5 LABEL44: iload 5 - load_int 0 - load_int 0 - load_int 0 - load_int 17104911 - widget_put_position_widget + iconst 0 + iconst 0 + iconst 0 + iconst 17104911 + if_setposition return diff --git a/runelite-client/src/main/scripts/PrivateMessage.hash b/runelite-client/src/main/scripts/PrivateMessage.hash index 5f3c129619..883f7d3747 100644 --- a/runelite-client/src/main/scripts/PrivateMessage.hash +++ b/runelite-client/src/main/scripts/PrivateMessage.hash @@ -1 +1 @@ -3DC9C314EBA5630A8237016DDAC99272696B37650E8671DD42DAEE9363F2D006 \ No newline at end of file +BDBD51EF867D393E41B723CD28720A91E2ED34FAFF581AC69B37C648EAC7B714 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/PrivateMessage.rs2asm b/runelite-client/src/main/scripts/PrivateMessage.rs2asm index bc8bb34d0f..3d9d8901f6 100644 --- a/runelite-client/src/main/scripts/PrivateMessage.rs2asm +++ b/runelite-client/src/main/scripts/PrivateMessage.rs2asm @@ -3,28 +3,28 @@ .string_stack_count 0 .int_var_count 2 .string_var_count 1 - get_varc 5 - load_int 14 + get_varc_int 5 + iconst 14 if_icmpeq LABEL4 jump LABEL7 LABEL4: - load_int 1 - put_varc 66 + iconst 1 + set_varc_int 66 return LABEL7: - load_int -1 + iconst -1 istore 0 - load_string "" + sconst "" sstore 0 - get_varc_string 22 + get_varc_string 359 string_length istore 1 iload 1 - load_int 0 + iconst 0 if_icmpgt LABEL18 - jump LABEL193 + jump LABEL184 LABEL18: - get_varc 5 + get_varc_int 5 switch 1: LABEL21 2: LABEL44 @@ -32,104 +32,101 @@ LABEL18: 4: LABEL23 5: LABEL23 6: LABEL44 - 7: LABEL110 - 8: LABEL114 - 9: LABEL120 - 10: LABEL123 - 11: LABEL185 - 12: LABEL142 - 13: LABEL160 - 15: LABEL120 - 16: LABEL190 - jump LABEL192 + 7: LABEL107 + 8: LABEL111 + 9: LABEL117 + 10: LABEL120 + 11: LABEL176 + 12: LABEL136 + 13: LABEL154 + 15: LABEL117 + 16: LABEL181 + jump LABEL183 LABEL21: return - jump LABEL192 + jump LABEL183 LABEL23: - get_ignorecount - load_int 0 + ignore_count + iconst 0 if_icmplt LABEL27 jump LABEL30 LABEL27: - load_string "Unable to update ignore list - system busy." - send_game_message + sconst "Unable to update ignore list - system busy." + mes jump LABEL43 LABEL30: - get_varc 5 - load_int 4 + get_varc_int 5 + iconst 4 if_icmpeq LABEL34 jump LABEL37 LABEL34: - get_varc_string 22 - add_ignore + get_varc_string 359 + ignore_add jump LABEL43 LABEL37: - get_varc 5 - load_int 5 + get_varc_int 5 + iconst 5 if_icmpeq LABEL41 jump LABEL43 LABEL41: - get_varc_string 22 - remove_ignore + get_varc_string 359 + ignore_del LABEL43: - jump LABEL192 + jump LABEL183 LABEL44: - get_friendcount - load_int 0 + friend_count + iconst 0 if_icmplt LABEL48 jump LABEL51 LABEL48: - load_string "Unable to complete action - system busy." - send_game_message - jump LABEL109 + sconst "Unable to complete action - system busy." + mes + jump LABEL106 LABEL51: - get_varc 5 - load_int 2 + get_varc_int 5 + iconst 2 if_icmpeq LABEL55 jump LABEL58 LABEL55: - get_varc_string 22 - add_friend - jump LABEL109 + get_varc_string 359 + friend_add + jump LABEL106 LABEL58: - get_varc 5 - load_int 3 + get_varc_int 5 + iconst 3 if_icmpeq LABEL62 jump LABEL65 LABEL62: - get_varc_string 22 - remove_friend - jump LABEL109 + get_varc_string 359 + friend_del + jump LABEL106 LABEL65: - get_varc 5 - load_int 6 + get_varc_int 5 + iconst 6 if_icmpeq LABEL69 - jump LABEL109 + jump LABEL106 LABEL69: - get_varc 203 - load_int 0 - if_icmpeq LABEL76 - get_varc 203 - load_int -1 - if_icmpeq LABEL76 - jump LABEL82 -LABEL76: - load_int 1 - load_int 1 + get_varbit 8119 + iconst 0 + if_icmpeq LABEL73 + jump LABEL79 +LABEL73: + iconst 1 + iconst 1 invoke 299 - load_string "You must set a name before you can chat." - send_game_message + sconst "You must set a name before you can chat." + mes return -LABEL82: - 5005 - load_int 2 - if_icmpeq LABEL86 - jump LABEL97 -LABEL86: - 5000 - load_int 1 - 5016 - chatfilter_update +LABEL79: + chat_getfilter_private + iconst 2 + if_icmpeq LABEL83 + jump LABEL94 +LABEL83: + chat_getfilter_public + iconst 1 + chat_getfilter_trade + chat_setfilter invoke 178 invoke 553 istore 0 @@ -137,144 +134,138 @@ LABEL86: invoke 84 iload 0 invoke 89 -LABEL97: +LABEL94: get_varbit 4394 - load_int 1 - if_icmpeq LABEL101 + iconst 1 + if_icmpeq LABEL98 + jump LABEL101 +LABEL98: + get_varc_string 360 + friend_del jump LABEL104 LABEL101: - get_varc_string 23 - remove_friend - jump LABEL107 + get_varc_string 360 + get_varc_string 359 + sconst "privateMessage" ; load event name + iconst 0 ; whether or not to skip + runelite_callback ; invoke callback + iconst 1 + if_icmpeq LABEL104 ; if skipped, do not message + chat_sendprivate LABEL104: - get_varc_string 23 - get_varc_string 22 - load_string "privateMessage" ; load event name - load_int 0 ; whether or not to skip - runelite_callback ; invoke callback - load_int 1 - if_icmpeq LABEL107 ; if skipped, do not message - privmsg + clientclock + set_varc_int 61 +LABEL106: + jump LABEL183 LABEL107: - get_gamecycle - put_varc 61 -LABEL109: - jump LABEL192 -LABEL110: - get_varc_string 22 + get_varc_string 359 invoke 212 - numeric_input - jump LABEL192 -LABEL114: - get_varc_string 22 - string_remove_html - put_varc_string 128 - get_varc_string 22 - string_input_1 - jump LABEL192 + resume_countdialog + jump LABEL183 +LABEL111: + get_varc_string 359 + removetags + set_varc_string 361 + get_varc_string 359 + resume_namedialog + jump LABEL183 +LABEL117: + get_varc_string 359 + resume_stringdialog + jump LABEL183 LABEL120: - get_varc_string 22 - string_input_2 - jump LABEL192 -LABEL123: - get_varc 203 - load_int 0 - if_icmpeq LABEL130 - get_varc 203 - load_int -1 - if_icmpeq LABEL130 - jump LABEL136 -LABEL130: - load_int 1 - load_int 1 + get_varbit 8119 + iconst 0 + if_icmpeq LABEL124 + jump LABEL130 +LABEL124: + iconst 1 + iconst 1 invoke 299 - load_string "You must set a name before you can chat." - send_game_message + sconst "You must set a name before you can chat." + mes return +LABEL130: + get_varc_string 359 + removetags + set_varc_string 362 + get_varc_string 359 + clan_joinchat + jump LABEL183 LABEL136: - get_varc_string 22 - string_remove_html - put_varc_string 129 - get_varc_string 22 - join_clanchat - jump LABEL192 -LABEL142: iload 1 - load_int 10 - if_icmpgt LABEL146 - jump LABEL152 + iconst 10 + if_icmpgt LABEL140 + jump LABEL146 +LABEL140: + get_varc_string 359 + iconst 0 + iconst 9 + substring + sstore 0 + jump LABEL148 LABEL146: - get_varc_string 22 - load_int 0 - load_int 9 - string_substring + get_varc_string 359 sstore 0 - jump LABEL154 -LABEL152: - get_varc_string 22 - sstore 0 -LABEL154: +LABEL148: sload 0 - tolowercase - 5021 + lowercase + chat_setmessagefilter invoke 553 invoke 84 - jump LABEL192 -LABEL160: - get_varc 203 - load_int 0 - if_icmpeq LABEL167 - get_varc 203 - load_int -1 - if_icmpeq LABEL167 - jump LABEL173 -LABEL167: - load_int 1 - load_int 1 + jump LABEL183 +LABEL154: + get_varbit 8119 + iconst 0 + if_icmpeq LABEL158 + jump LABEL164 +LABEL158: + iconst 1 + iconst 1 invoke 299 - load_string "You must set a name before you can chat." - send_game_message + sconst "You must set a name before you can chat." + mes return -LABEL173: - get_varc_string 22 - load_int 0 - put_varc 62 - put_varc_string 28 +LABEL164: + get_varc_string 359 + iconst 0 + set_varc_int 62 + set_varc_string 358 invoke 95 - load_int 552 - load_int -2147483645 - load_int 1 - load_string "I1" - load_int 10616845 - widget_put_render_listener_widget - jump LABEL192 -LABEL185: - load_int 0 - load_int 1 + iconst 552 + iconst -2147483645 + iconst 1 + sconst "I1" + iconst 10616845 + if_setontimer + jump LABEL183 +LABEL176: + iconst 0 + iconst 1 invoke 299 return - jump LABEL192 -LABEL190: - get_varc_string 22 + jump LABEL183 +LABEL181: + get_varc_string 359 invoke 2061 -LABEL192: - jump LABEL199 -LABEL193: - get_varc 5 +LABEL183: + jump LABEL190 +LABEL184: + get_varc_int 5 switch - 16: LABEL198 - 7: LABEL196 - 8: LABEL196 - 9: LABEL196 - 15: LABEL196 - jump LABEL199 -LABEL196: + 16: LABEL189 + 7: LABEL187 + 8: LABEL187 + 9: LABEL187 + 15: LABEL187 + jump LABEL190 +LABEL187: return - jump LABEL199 -LABEL198: + jump LABEL190 +LABEL189: return -LABEL199: - load_int 1 - load_int 1 +LABEL190: + iconst 1 + iconst 1 invoke 299 return diff --git a/runelite-client/src/main/scripts/PvpWidgetBuilder.hash b/runelite-client/src/main/scripts/PvpWidgetBuilder.hash new file mode 100644 index 0000000000..144ac0aea6 --- /dev/null +++ b/runelite-client/src/main/scripts/PvpWidgetBuilder.hash @@ -0,0 +1 @@ +08461B2A942D4D792EEB9D9BCCEB9B11256AD8B217B1EAF1BDBA71314F816D6F \ No newline at end of file diff --git a/runelite-client/src/main/scripts/PvpWidgetBuilder.rs2asm b/runelite-client/src/main/scripts/PvpWidgetBuilder.rs2asm new file mode 100644 index 0000000000..ba8bf2ec2f --- /dev/null +++ b/runelite-client/src/main/scripts/PvpWidgetBuilder.rs2asm @@ -0,0 +1,119 @@ +.id 388 +.int_stack_count 1 +.string_stack_count 0 +.int_var_count 3 +.string_var_count 0 + invoke 384 + istore 1 + invoke 1138 + istore 2 + iload 2 + iconst 1 + if_icmpeq LABEL8 + jump LABEL74 +LABEL8: + get_varp 1676 + iconst 4 + if_icmpgt LABEL12 + jump LABEL31 +LABEL12: + iload 1 + iconst 0 + if_icmpgt LABEL16 + jump LABEL27 +LABEL16: + get_varbit 5954 + iconst 1 + if_icmpeq LABEL20 + jump LABEL27 +LABEL20: + sconst "Level: " + iload 1 + tostring + join_string 2 + iload 0 + if_settext + jump LABEL30 +LABEL27: + sconst "Deadman" + iload 0 + if_settext +LABEL30: + jump LABEL73 +LABEL31: + get_varbit 4965 + iconst 0 + if_icmpgt LABEL35 + jump LABEL39 +LABEL35: + sconst "Protection" + iload 0 + if_settext + jump LABEL73 +LABEL39: + iload 1 + iconst 0 + if_icmpgt LABEL43 + jump LABEL54 +LABEL43: + get_varbit 5954 + iconst 1 + if_icmpeq LABEL47 + jump LABEL54 +LABEL47: + sconst "Level: " + iload 1 + tostring + join_string 2 + iload 0 + if_settext + jump LABEL73 +LABEL54: + get_varc_int 78 + iconst 1 + if_icmpeq LABEL58 + jump LABEL62 +LABEL58: + sconst "Guarded" + iload 0 + if_settext + jump LABEL73 +LABEL62: + get_varc_int 78 + iconst 2 + if_icmpeq LABEL66 + jump LABEL70 +LABEL66: + sconst "No PvP" + iload 0 + if_settext + jump LABEL73 +LABEL70: + sconst "Deadman" + iload 0 + if_settext +LABEL73: + jump LABEL88 +LABEL74: + iload 1 + iconst 0 + if_icmpgt LABEL78 + jump LABEL85 +LABEL78: + sconst "Level: " + iload 1 + tostring + join_string 2 + iload 0 + if_settext + jump LABEL88 +LABEL85: + sconst "" + iload 0 + if_settext +LABEL88: + iload 1 + invoke 387 + sconst "wildernessWidgetTextSet" ; set callback name + runelite_callback ; invoke callback + return diff --git a/runelite-client/src/main/scripts/ResetChatboxInput.hash b/runelite-client/src/main/scripts/ResetChatboxInput.hash index 9332eb1f8a..12bd3c5bb1 100644 --- a/runelite-client/src/main/scripts/ResetChatboxInput.hash +++ b/runelite-client/src/main/scripts/ResetChatboxInput.hash @@ -1 +1 @@ -BA21C990EACCA53E54286CA139D58C3C7EA053BBB63C340B7BE4A0B91B156089 \ No newline at end of file +E8B1910003198AB024BADC89831AF1735A2C77256C23551212105F25439E022D \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ResetChatboxInput.rs2asm b/runelite-client/src/main/scripts/ResetChatboxInput.rs2asm index 2ab7967304..40f4b02c6f 100644 --- a/runelite-client/src/main/scripts/ResetChatboxInput.rs2asm +++ b/runelite-client/src/main/scripts/ResetChatboxInput.rs2asm @@ -3,19 +3,19 @@ .string_stack_count 0 .int_var_count 3 .string_var_count 0 - load_string "resetChatboxInput" - runelite_callback - load_int 1 - load_int 10616872 - widget_put_hidden_widget - load_int 0 - load_int 10616887 - widget_put_hidden_widget + sconst "resetChatboxInput" + runelite_callback + iconst 1 + iconst 10616872 + if_sethide + iconst 0 + iconst 10616887 + if_sethide invoke 923 - load_int 0 + iconst 0 istore 2 iload 1 - load_int 1 + iconst 1 if_icmpeq LABEL13 jump LABEL27 LABEL13: @@ -26,144 +26,144 @@ LABEL13: iload 2 invoke 89 invoke 223 - load_int 1 + iconst 1 invoke 927 invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL26 jump LABEL27 LABEL26: invoke 1984 LABEL27: invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL31 jump LABEL32 LABEL31: invoke 2581 LABEL32: - load_int 0 - put_varc 5 + iconst 0 + set_varc_int 5 iload 0 - load_int 1 + iconst 1 if_icmpeq LABEL38 jump LABEL40 LABEL38: - load_string "" - put_varc_string 22 + sconst "" + set_varc_string 359 LABEL40: - load_int 0 - load_int -8 - load_int 1 - load_int 1 - load_int 10616876 - widget_put_position_widget - load_int 0 - load_int 40 - load_int 1 - load_int 0 - load_int 10616876 - widget_put_size_widget - load_int 0 - load_int 22 - load_int 1 - load_int 1 - load_int 10616877 - widget_put_position_widget - load_int 0 - load_int 20 - load_int 1 - load_int 0 - load_int 10616877 - widget_put_size_widget - load_int 0 - load_int 10616876 - widget_put_hidden_widget - load_int 0 - load_int 10616877 - widget_put_hidden_widget - load_int 1 - load_int 10616881 - widget_put_hidden_widget - load_int 10616885 - widget_unset_children - load_int 10616886 - widget_unset_children - load_int -1 - load_string "" - load_int 10616872 - widget_put_mouse_press_listener_widget - load_int -1 - load_string "" - load_int 10616872 - widget_put_render_listener_widget - load_int 10616872 - widget_unset_children - load_int 10616878 - widget_unset_children - load_int 10616879 - widget_unset_children - load_int 10616880 - widget_unset_children - load_int 1 - load_int 10616878 - widget_put_hidden_widget - load_int 1 - load_int 10616879 - widget_put_hidden_widget - load_int 1 - load_int 10616880 - widget_put_hidden_widget - load_int -1 - load_string "" - load_int 10616878 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" - load_int 10616879 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" - load_int 10616880 - widget_put_mouse_hover_listener_widget - load_int -1 - load_string "" - load_int 10616878 - widget_put_mouse_exit_listener_widget - load_int -1 - load_string "" - load_int 10616879 - widget_put_mouse_exit_listener_widget - load_int -1 - load_string "" - load_int 10616880 - widget_put_mouse_exit_listener_widget - load_int -1 - load_string "" - load_int 10616878 - widget_put_render_listener_widget - load_int -1 - load_string "" - load_int 10616879 - widget_put_render_listener_widget - load_int -1 - load_string "" - load_int 10616880 - widget_put_render_listener_widget - load_int -1 - load_string "" - load_int 10616878 - widget_put_mouse_press_listener_widget - load_int -1 - load_string "" - load_int 10616879 - widget_put_mouse_press_listener_widget - load_int -1 - load_string "" - load_int 10616880 - widget_put_mouse_press_listener_widget - get_varc 41 - load_int -1 + iconst 0 + iconst -8 + iconst 1 + iconst 1 + iconst 10616876 + if_setposition + iconst 0 + iconst 40 + iconst 1 + iconst 0 + iconst 10616876 + if_setsize + iconst 0 + iconst 22 + iconst 1 + iconst 1 + iconst 10616877 + if_setposition + iconst 0 + iconst 20 + iconst 1 + iconst 0 + iconst 10616877 + if_setsize + iconst 0 + iconst 10616876 + if_sethide + iconst 0 + iconst 10616877 + if_sethide + iconst 1 + iconst 10616881 + if_sethide + iconst 10616885 + cc_deleteall + iconst 10616886 + cc_deleteall + iconst -1 + sconst "" + iconst 10616872 + if_setonclick + iconst -1 + sconst "" + iconst 10616872 + if_setontimer + iconst 10616872 + cc_deleteall + iconst 10616878 + cc_deleteall + iconst 10616879 + cc_deleteall + iconst 10616880 + cc_deleteall + iconst 1 + iconst 10616878 + if_sethide + iconst 1 + iconst 10616879 + if_sethide + iconst 1 + iconst 10616880 + if_sethide + iconst -1 + sconst "" + iconst 10616878 + if_setonmouserepeat + iconst -1 + sconst "" + iconst 10616879 + if_setonmouserepeat + iconst -1 + sconst "" + iconst 10616880 + if_setonmouserepeat + iconst -1 + sconst "" + iconst 10616878 + if_setonmouseleave + iconst -1 + sconst "" + iconst 10616879 + if_setonmouseleave + iconst -1 + sconst "" + iconst 10616880 + if_setonmouseleave + iconst -1 + sconst "" + iconst 10616878 + if_setontimer + iconst -1 + sconst "" + iconst 10616879 + if_setontimer + iconst -1 + sconst "" + iconst 10616880 + if_setontimer + iconst -1 + sconst "" + iconst 10616878 + if_setonclick + iconst -1 + sconst "" + iconst 10616879 + if_setonclick + iconst -1 + sconst "" + iconst 10616880 + if_setonclick + get_varc_int 41 + iconst 1337 if_icmpeq LABEL154 jump LABEL156 LABEL154: @@ -171,7 +171,7 @@ LABEL154: pop_int LABEL156: invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL160 jump LABEL161 LABEL160: diff --git a/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm b/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm index 9ca40fbbf2..665eb44242 100644 --- a/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm +++ b/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm @@ -3,43 +3,43 @@ .string_stack_count 0 .int_var_count 4 .string_var_count 0 - load_int 1 - load_int 0 - load_string "scrollWheelZoom" + iconst 1 + iconst 0 + sconst "scrollWheelZoom" runelite_callback if_icmpeq LABEL18 - load_int 0 + iconst 0 iload 0 - load_int 25 - imul - isub + iconst 25 + multiply + sub istore 1 - load_int 512 + iconst 512 istore 2 - load_int 512 + iconst 512 istore 3 get_varbit 6357 - load_int 0 + iconst 0 if_icmpeq LABEL14 jump LABEL33 LABEL14: get_varbit 4606 - load_int 0 + iconst 0 if_icmpne LABEL18 jump LABEL19 LABEL18: return LABEL19: - 6205 + viewport_getfov istore 2 istore 3 iload 3 iload 1 - iadd + add istore 3 iload 2 iload 1 - iadd + add istore 2 iload 3 iload 2 diff --git a/runelite-client/src/main/scripts/SendPrivateMessage.rs2asm b/runelite-client/src/main/scripts/SendPrivateMessage.rs2asm index f2102c1328..1803820d2d 100644 --- a/runelite-client/src/main/scripts/SendPrivateMessage.rs2asm +++ b/runelite-client/src/main/scripts/SendPrivateMessage.rs2asm @@ -30,5 +30,5 @@ ; Send a private message sload 0 sload 1 - privmsg - return \ No newline at end of file + chat_sendprivate + return diff --git a/runelite-client/src/main/scripts/SkillTabBuilder.rs2asm b/runelite-client/src/main/scripts/SkillTabBuilder.rs2asm index c3e1f8261b..a9529b3efb 100644 --- a/runelite-client/src/main/scripts/SkillTabBuilder.rs2asm +++ b/runelite-client/src/main/scripts/SkillTabBuilder.rs2asm @@ -3,112 +3,112 @@ .string_stack_count 1 .int_var_count 11 .string_var_count 4 - load_int 83 - load_int 49 - load_int 1497 + iconst 83 + iconst 49 + iconst 1497 iload 0 - get_enum_value + enum istore 3 iload 0 - get_boostedskilllevels - int_to_string - widget_put_text + stat + tostring + cc_settext iload 0 - get_realskilllevels + stat_base istore 4 iload 0 ; load the skill id from arguments iload 4 ; load the current real skill level - load_string "skillTabBaseLevel" ; push event name + sconst "skillTabBaseLevel" ; push event name runelite_callback ; invoke callback istore 4 ; store the (possibly) edited real skill level iload 4 - int_to_string - widget_put_text 1 + tostring + cc_settext 1 iload 0 - get_skillexperiences + stat_xp istore 5 - load_string "," + sconst "," sstore 1 sload 0 - load_string " XP:" - string_append 2 + sconst " XP:" + join_string 2 sstore 2 iload 5 sload 1 invoke 46 sstore 3 - load_int 0 + iconst 0 istore 6 get_varbit 4181 - load_int 0 + iconst 0 if_icmpeq LABEL35 jump LABEL66 LABEL35: iload 4 - load_int 99 - load_string "skillTabMaxLevel" ; push event name + iconst 99 + sconst "skillTabMaxLevel" ; push event name runelite_callback ; invoke callback if_icmplt LABEL39 jump LABEL65 LABEL39: - load_int 105 - load_int 105 - load_int 256 + iconst 105 + iconst 105 + iconst 256 iload 4 - load_int 1 - iadd - get_enum_value + iconst 1 + add + enum istore 6 sload 2 - load_string "|Next level at:|Remaining XP:" - concat_string + sconst "|Next level at:|Remaining XP:" + append sstore 2 sload 3 - load_string "|" + sconst "|" iload 6 sload 1 invoke 46 - load_string "|" + sconst "|" iload 6 iload 5 - isub + sub sload 1 invoke 46 - string_append 4 - concat_string + join_string 4 + append sstore 3 LABEL65: jump LABEL84 LABEL66: sload 2 - load_string "|Next level at:" - concat_string + sconst "|Next level at:" + append sstore 2 sload 3 - load_string "|" - load_int 105 - load_int 105 - load_int 256 + sconst "|" + iconst 105 + iconst 105 + iconst 256 iload 4 - load_int 1 - iadd - get_enum_value + iconst 1 + add + enum sload 1 invoke 46 - string_append 2 - concat_string + join_string 2 + append sstore 3 LABEL84: - load_int 0 + iconst 0 istore 7 - load_int 0 + iconst 0 istore 8 - load_int 0 + iconst 0 istore 9 - load_int 0 + iconst 0 istore 10 invoke 1138 - load_int 1 + iconst 1 if_icmpeq LABEL96 jump LABEL278 LABEL96: @@ -116,13 +116,13 @@ LABEL96: invoke 1936 istore 7 iload 7 - load_int -1 + iconst -1 if_icmpne LABEL103 jump LABEL133 LABEL103: iload 7 - load_int 10 - idiv + iconst 10 + div istore 7 iload 7 iload 5 @@ -130,35 +130,35 @@ LABEL103: jump LABEL133 LABEL111: sload 2 - load_string "|" - load_string "" - load_string "XP to regain:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP to regain:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" + sconst "|" + sconst "" iload 7 iload 5 - isub + sub sload 1 invoke 46 - load_string "" - string_append 4 - concat_string + sconst "" + join_string 4 + append sstore 3 - load_int 1 + iconst 1 istore 8 LABEL133: iload 8 - load_int 0 + iconst 0 if_icmpeq LABEL137 jump LABEL278 LABEL137: get_varp 1588 - load_int 0 + iconst 0 if_icmpgt LABEL141 jump LABEL278 LABEL141: @@ -171,279 +171,279 @@ LABEL141: 6: LABEL144 jump LABEL278 LABEL144: - load_int 20 + iconst 20 invoke 2031 istore 10 iload 10 - load_int 0 + iconst 0 if_icmpgt LABEL151 jump LABEL170 LABEL151: sload 2 - load_string "|" - load_string "" - load_string "XP permitted:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP permitted:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" + sconst "|" + sconst "" iload 10 sload 1 invoke 46 - load_string "" - string_append 4 - concat_string + sconst "" + join_string 4 + append sstore 3 jump LABEL188 LABEL170: - load_int 1 + iconst 1 istore 9 sload 2 - load_string "|" - load_string "" - load_string "XP permitted:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP permitted:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" - load_string "NONE" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "NONE" + sconst "" + join_string 4 + append sstore 3 LABEL188: jump LABEL278 LABEL189: - load_int 30 + iconst 30 invoke 2031 istore 10 iload 10 - load_int 0 + iconst 0 if_icmpgt LABEL196 jump LABEL215 LABEL196: sload 2 - load_string "|" - load_string "" - load_string "XP permitted:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP permitted:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" + sconst "|" + sconst "" iload 10 sload 1 invoke 46 - load_string "" - string_append 4 - concat_string + sconst "" + join_string 4 + append sstore 3 jump LABEL233 LABEL215: - load_int 1 + iconst 1 istore 9 sload 2 - load_string "|" - load_string "" - load_string "XP permitted:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP permitted:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" - load_string "NONE" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "NONE" + sconst "" + join_string 4 + append sstore 3 LABEL233: jump LABEL278 LABEL234: - load_int 40 + iconst 40 invoke 2031 istore 10 iload 10 - load_int 0 + iconst 0 if_icmpgt LABEL241 jump LABEL260 LABEL241: sload 2 - load_string "|" - load_string "" - load_string "XP permitted:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP permitted:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" + sconst "|" + sconst "" iload 10 sload 1 invoke 46 - load_string "" - string_append 4 - concat_string + sconst "" + join_string 4 + append sstore 3 jump LABEL278 LABEL260: - load_int 1 + iconst 1 istore 9 sload 2 - load_string "|" - load_string "" - load_string "XP permitted:" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "XP permitted:" + sconst "" + join_string 4 + append sstore 2 sload 3 - load_string "|" - load_string "" - load_string "NONE" - load_string "" - string_append 4 - concat_string + sconst "|" + sconst "" + sconst "NONE" + sconst "" + join_string 4 + append sstore 3 LABEL278: iload 1 - load_int 5 - widget_load_child 1 - load_int 1 + iconst 5 + cc_find 1 + iconst 1 if_icmpeq LABEL284 jump LABEL294 LABEL284: iload 9 - load_int 1 + iconst 1 if_icmpeq LABEL288 jump LABEL291 LABEL288: - load_int 0 - widget_put_hidden 1 + iconst 0 + cc_sethide 1 jump LABEL293 LABEL291: - load_int 1 - widget_put_hidden 1 + iconst 1 + cc_sethide 1 LABEL293: jump LABEL321 LABEL294: iload 1 - load_int 5 - load_int 5 - widget_create_child 1 - load_int 6 - load_int 0 - load_int 0 - load_int 1 - widget_put_position 1 - load_int 19 - load_int 19 - load_int 0 - load_int 0 - widget_put_size 1 - load_int 940 - widget_put_spriteid 1 - load_int 65793 - widget_put_sprite2 1 + iconst 5 + iconst 5 + cc_create 1 + iconst 6 + iconst 0 + iconst 0 + iconst 1 + cc_setposition 1 + iconst 19 + iconst 19 + iconst 0 + iconst 0 + cc_setsize 1 + iconst 940 + cc_setgraphic 1 + iconst 65793 + cc_setgraphicshadow 1 iload 9 - load_int 1 + iconst 1 if_icmpeq LABEL316 jump LABEL319 LABEL316: - load_int 0 - widget_put_hidden 1 + iconst 0 + cc_sethide 1 jump LABEL321 LABEL319: - load_int 1 - widget_put_hidden 1 + iconst 1 + cc_sethide 1 LABEL321: iload 3 - load_int 1 + iconst 1 if_icmpeq LABEL325 jump LABEL344 LABEL325: - get_ismembers - load_int 0 + map_members + iconst 0 if_icmpeq LABEL329 jump LABEL344 LABEL329: - get_varc 103 - load_int 0 + get_varc_int 103 + iconst 0 if_icmpeq LABEL333 jump LABEL344 LABEL333: - load_string "" + sconst "" sload 0 - load_string ":" - load_string "" - string_append 4 + sconst ":" + sconst "" + join_string 4 sstore 2 - load_string "" - load_string "Members Only" - load_string "" - string_append 3 + sconst "" + sconst "Members Only" + sconst "" + join_string 3 sstore 3 LABEL344: invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL348 jump LABEL375 LABEL348: - load_int 2367 - load_int -2147483644 - load_int -2147483645 - load_int -1 + iconst 2367 + iconst -2147483644 + iconst -2147483645 + iconst -1 iload 2 sload 2 sload 3 - load_int 495 - load_string "iIiIssf" + iconst 495 + sconst "iIiIssf" iload 1 - widget_put_option_click_listener_widget - get_varc 218 + if_setonop + get_varc_int 218 iload 1 if_icmpeq LABEL363 jump LABEL374 LABEL363: - get_varc 217 - load_int -1 + get_varc_int 217 + iconst -1 if_icmpeq LABEL367 jump LABEL374 LABEL367: iload 1 - load_int -1 + iconst -1 iload 2 sload 2 sload 3 - load_int 495 + iconst 495 invoke 2344 LABEL374: jump LABEL390 LABEL375: - load_int 992 - load_int -2147483645 - load_int -1 + iconst 992 + iconst -2147483645 + iconst -1 iload 2 sload 2 sload 3 - load_int 495 - load_int 25 - load_int 5 - idiv - load_string "IiIssfi" + iconst 495 + iconst 25 + iconst 5 + div + sconst "IiIssfi" iload 1 - widget_put_mouse_hover_listener_widget - load_int 0 - put_varc 2 + if_setonmouserepeat + iconst 0 + set_varc_int 2 LABEL390: return diff --git a/runelite-client/src/main/scripts/SkillTabTotalLevel.rs2asm b/runelite-client/src/main/scripts/SkillTabTotalLevel.rs2asm index 2d1142dc7a..2f623396d6 100644 --- a/runelite-client/src/main/scripts/SkillTabTotalLevel.rs2asm +++ b/runelite-client/src/main/scripts/SkillTabTotalLevel.rs2asm @@ -5,105 +5,105 @@ .string_var_count 2 invoke 1007 istore 2 - load_string "Total level:" - load_string "
" + sconst "Total level:" + sconst "
" iload 2 - int_to_string - string_append 3 + tostring + join_string 3 iload 0 - load_string "skillTabTotalLevel" ; push event name + sconst "skillTabTotalLevel" ; push event name runelite_callback ; invoke callback - widget_put_text_widget + if_settext iload 0 - widget_put_actions_null_widget - load_string "" + if_clearops + sconst "" sstore 0 - load_string "" + sconst "" sstore 1 - get_ismembers - load_int 1 + map_members + iconst 1 if_icmpeq LABEL22 - get_varc 103 - load_int 1 + get_varc_int 103 + iconst 1 if_icmpeq LABEL22 jump LABEL28 LABEL22: - load_string "Total XP:" + sconst "Total XP:" sstore 0 invoke 1008 invoke 1009 sstore 1 jump LABEL37 LABEL28: - load_string "Total XP:|Free Total Level:" + sconst "Total XP:|Free Total Level:" sstore 0 invoke 1008 invoke 1009 - load_string "|" + sconst "|" invoke 1320 - int_to_string - string_append 3 + tostring + join_string 3 sstore 1 LABEL37: invoke 1972 - load_int 1 + iconst 1 if_icmpeq LABEL41 jump LABEL72 LABEL41: - load_int 1 - load_string "Toggle Total XP" + iconst 1 + sconst "Toggle Total XP" iload 0 - widget_put_action_widget - load_int 2367 - load_int -2147483644 - load_int -2147483645 - load_int -1 + if_setop + iconst 2367 + iconst -2147483644 + iconst -2147483645 + iconst -1 iload 1 sload 0 sload 1 - load_int 495 - load_string "iIiIssf" + iconst 495 + sconst "iIiIssf" iload 0 - widget_put_option_click_listener_widget - get_varc 218 + if_setonop + get_varc_int 218 iload 0 if_icmpeq LABEL60 jump LABEL71 LABEL60: - get_varc 217 - load_int -1 + get_varc_int 217 + iconst -1 if_icmpeq LABEL64 jump LABEL71 LABEL64: iload 0 - load_int -1 + iconst -1 iload 1 sload 0 sload 1 - load_int 495 + iconst 495 invoke 2344 LABEL71: jump LABEL92 LABEL72: - load_int 992 - load_int -2147483645 - load_int -1 + iconst 992 + iconst -2147483645 + iconst -1 iload 1 sload 0 sload 1 - load_int 495 - load_int 25 - load_int 5 - idiv - load_string "IiIssfi" + iconst 495 + iconst 25 + iconst 5 + div + sconst "IiIssfi" iload 0 - widget_put_mouse_hover_listener_widget - load_int 40 + if_setonmouserepeat + iconst 40 iload 1 - load_string "I" + sconst "I" iload 0 - widget_put_mouse_exit_listener_widget - load_int 0 - put_varc 2 + if_setonmouseleave + iconst 0 + set_varc_int 2 LABEL92: return diff --git a/runelite-client/src/main/scripts/TriggerBankLayout.rs2asm b/runelite-client/src/main/scripts/TriggerBankLayout.rs2asm index 4b739a959c..a9fd094407 100644 --- a/runelite-client/src/main/scripts/TriggerBankLayout.rs2asm +++ b/runelite-client/src/main/scripts/TriggerBankLayout.rs2asm @@ -5,24 +5,24 @@ .string_var_count 0 ; Check if we should allow server to relayout bank - load_int 1 ; true - load_int 0 ; load active boolean - load_string "getSearchingTagTab" ; push event name - runelite_callback ; invoke callback + iconst 1 ; true + iconst 0 ; load active boolean + sconst "getSearchingTagTab" ; push event name + runelite_callback ; invoke callback if_icmpne LABEL2 ; Let layout continue if current bank tab is 0 get_varbit 4150 - load_int 0 + iconst 0 if_icmpeq LABEL2 ; Reset the current bank tab to 0 otherwise - load_int 0 + iconst 0 set_varbit 4150 - load_string "Server attempted to reset bank tab." - load_string "debug" - runelite_callback + sconst "Server attempted to reset bank tab." + sconst "debug" + runelite_callback LABEL2: iload 0 @@ -39,4 +39,4 @@ LABEL2: iload 11 iload 12 invoke 277 - return + return diff --git a/runelite-client/src/main/scripts/ZoomHandler.rs2asm b/runelite-client/src/main/scripts/ZoomHandler.rs2asm index b19086168e..5ff5fa6fe6 100644 --- a/runelite-client/src/main/scripts/ZoomHandler.rs2asm +++ b/runelite-client/src/main/scripts/ZoomHandler.rs2asm @@ -4,88 +4,88 @@ .int_var_count 6 .string_var_count 0 get_varbit 4606 - load_int 0 + iconst 0 if_icmpne LABEL4 jump LABEL5 LABEL4: return LABEL5: - load_int 896 - load_string "innerZoomLimit" + iconst 896 + sconst "innerZoomLimit" runelite_callback iload 0 invoke 1046 istore 0 - load_int 128 - load_string "outerZoomLimit" - runelite_callback + iconst 128 + sconst "outerZoomLimit" + runelite_callback iload 0 invoke 1045 istore 0 - load_int 896 - load_string "innerZoomLimit" + iconst 896 + sconst "innerZoomLimit" runelite_callback iload 1 invoke 1046 istore 1 - load_int 128 - load_string "outerZoomLimit" - runelite_callback + iconst 128 + sconst "outerZoomLimit" + runelite_callback iload 1 invoke 1045 istore 1 iload 0 iload 1 - 6200 - load_int 0 + viewport_setfov + iconst 0 istore 2 - load_int 0 + iconst 0 istore 3 - get_viewport_size + viewport_geteffectivesize istore 3 istore 2 iload 3 - load_int 334 - isub + iconst 334 + sub istore 4 iload 4 - load_int 0 + iconst 0 if_icmplt LABEL39 jump LABEL42 LABEL39: - load_int 0 + iconst 0 istore 4 jump LABEL48 LABEL42: iload 4 - load_int 100 + iconst 100 if_icmpgt LABEL46 jump LABEL48 LABEL46: - load_int 100 + iconst 100 istore 4 LABEL48: iload 0 iload 1 iload 0 - isub + sub iload 4 - imul - load_int 100 - idiv - iadd + multiply + iconst 100 + div + add istore 5 - load_int 25 - load_int 25 + iconst 25 + iconst 25 iload 5 - imul - load_int 256 - idiv - iadd - set_camera_focal_point_height + multiply + iconst 256 + div + add + cam_setfollowheight iload 0 iload 1 - put_varc 74 - put_varc 73 + set_varc_int 74 + set_varc_int 73 invoke 1049 return diff --git a/runelite-client/src/main/scripts/null.rs2asm b/runelite-client/src/main/scripts/null.rs2asm index 81afec5354..6c402affd9 100644 --- a/runelite-client/src/main/scripts/null.rs2asm +++ b/runelite-client/src/main/scripts/null.rs2asm @@ -34,4 +34,4 @@ .int_var_count 0 .string_var_count 0 -return +return diff --git a/runelite-client/src/test/java/net/runelite/client/game/ItemVariationMappingTest.java b/runelite-client/src/test/java/net/runelite/client/game/ItemVariationMappingTest.java index 831aef746d..ba67d6b9c2 100644 --- a/runelite-client/src/test/java/net/runelite/client/game/ItemVariationMappingTest.java +++ b/runelite-client/src/test/java/net/runelite/client/game/ItemVariationMappingTest.java @@ -342,7 +342,8 @@ public class ItemVariationMappingTest @Test public void testMappedNames() { - ITEMS_MAP.forEach((key, value) -> { + ITEMS_MAP.forEach((key, value) -> + { assertEquals(value, (Integer) ItemVariationMapping.map(key)); }); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java index 0981299754..8f63169574 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java @@ -47,6 +47,7 @@ import java.util.Set; import net.runelite.api.Client; import net.runelite.client.RuneLite; import net.runelite.client.RuneLiteModule; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.rs.ClientUpdateCheckMode; import static org.junit.Assert.assertEquals; import org.junit.Before; @@ -117,6 +118,10 @@ public class PluginManagerTest pluginManager.loadCorePlugins(); plugins = pluginManager.getPlugins(); + // Check that the plugins register with the eventbus without errors + EventBus eventBus = new EventBus(); + plugins.forEach(eventBus::register); + expected = pluginClasses.stream() .map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class)) .filter(Objects::nonNull) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/bankvalue/BankCalculationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/bankvalue/BankCalculationTest.java index 06e4bdd1ac..1e57823ab4 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/bankvalue/BankCalculationTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/bankvalue/BankCalculationTest.java @@ -35,15 +35,11 @@ import net.runelite.api.Item; import net.runelite.api.ItemComposition; import net.runelite.api.ItemContainer; import net.runelite.api.ItemID; -import net.runelite.api.queries.BankItemQuery; -import net.runelite.api.widgets.WidgetItem; import net.runelite.client.game.ItemManager; -import net.runelite.client.util.QueryRunner; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import static org.mockito.Matchers.any; import org.mockito.Mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -116,4 +112,4 @@ public class BankCalculationTest long value = bankCalculation.getHaPrice(); assertTrue(value > Integer.MAX_VALUE); } -} \ No newline at end of file +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 74e5fc25ae..cc6703db91 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -80,7 +80,7 @@ public class ChatCommandsPluginTest { when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", "Your Corporeal Beast kill count is: 4.", null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", "Your Corporeal Beast kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setConfiguration("killcount.adam", "corporeal beast", 4); @@ -91,7 +91,7 @@ public class ChatCommandsPluginTest { when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", "Your completed Theatre of Blood count is: 73.", null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", "Your completed Theatre of Blood count is: 73.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setConfiguration("killcount.adam", "theatre of blood", 73); @@ -102,7 +102,7 @@ public class ChatCommandsPluginTest { when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", "Your subdued Wintertodt count is: 4.", null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", "Your subdued Wintertodt count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setConfiguration("killcount.adam", "wintertodt", 4); @@ -113,7 +113,7 @@ public class ChatCommandsPluginTest { when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", "Your Kree'arra kill count is: 4.", null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", "Your Kree'arra kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setConfiguration("killcount.adam", "kree'arra", 4); @@ -124,7 +124,7 @@ public class ChatCommandsPluginTest { when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", "Your Barrows chest count is: 277.", null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", "Your Barrows chest count is: 277.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); verify(configManager).setConfiguration("killcount.adam", "barrows chests", 277); @@ -138,10 +138,10 @@ public class ChatCommandsPluginTest when(client.getUsername()).thenReturn("Adam"); // This sets lastBoss - ChatMessage chatMessage = new ChatMessage(SERVER, "", "Your Kree'arra kill count is: 4.", null); + ChatMessage chatMessage = new ChatMessage(null, SERVER, "", "Your Kree'arra kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); - chatMessage = new ChatMessage(SERVER, "", FIGHT_DURATION, null); + chatMessage = new ChatMessage(null, SERVER, "", FIGHT_DURATION, null, 0); chatCommandsPlugin.onChatMessage(chatMessage); verify(configManager).setConfiguration(eq("personalbest.adam"), eq("kree'arra"), eq(79)); @@ -155,10 +155,10 @@ public class ChatCommandsPluginTest when(client.getUsername()).thenReturn("Adam"); // This sets lastBoss - ChatMessage chatMessage = new ChatMessage(SERVER, "", "Your Zulrah kill count is: 4.", null); + ChatMessage chatMessage = new ChatMessage(null, SERVER, "", "Your Zulrah kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); - chatMessage = new ChatMessage(SERVER, "", FIGHT_DURATION, null); + chatMessage = new ChatMessage(null, SERVER, "", FIGHT_DURATION, null, 0); chatCommandsPlugin.onChatMessage(chatMessage); verify(configManager).setConfiguration(eq("personalbest.adam"), eq("zulrah"), eq(55)); @@ -172,10 +172,10 @@ public class ChatCommandsPluginTest when(client.getUsername()).thenReturn("Adam"); // This sets lastBoss - ChatMessage chatMessage = new ChatMessage(SERVER, "", "Your Kree'arra kill count is: 4.", null); + ChatMessage chatMessage = new ChatMessage(null, SERVER, "", "Your Kree'arra kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); - chatMessage = new ChatMessage(SERVER, "", NEW_PB, null); + chatMessage = new ChatMessage(null, SERVER, "", NEW_PB, null, 0); chatCommandsPlugin.onChatMessage(chatMessage); verify(configManager).setConfiguration(eq("personalbest.adam"), eq("kree'arra"), eq(181)); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java new file mode 100644 index 0000000000..2fe4d88e05 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.chatfilter; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import javax.inject.Inject; +import net.runelite.api.Client; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.when; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ChatFilterPluginTest +{ + @Mock + @Bind + private Client client; + + @Mock + @Bind + private ChatFilterConfig chatFilterConfig; + + @Inject + private ChatFilterPlugin chatFilterPlugin; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS); + when(chatFilterConfig.filteredWords()).thenReturn(""); + when(chatFilterConfig.filteredRegex()).thenReturn(""); + } + + @Test + public void testCensorWords() + { + when(chatFilterConfig.filteredWords()).thenReturn("hat"); + + chatFilterPlugin.updateFilteredPatterns(); + assertEquals("w***s up", chatFilterPlugin.censorMessage("whats up")); + } + + @Test + public void testCensorRegex() + { + when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE); + when(chatFilterConfig.filteredRegex()).thenReturn("5[0-9]x2\n("); + + chatFilterPlugin.updateFilteredPatterns(); + assertNull(chatFilterPlugin.censorMessage("55X2 Dicing | Trusted Ranks | Huge Pay Outs!")); + } + + @Test + public void testBrokenRegex() + { + when(chatFilterConfig.filteredRegex()).thenReturn("Test\n)\n73"); + + chatFilterPlugin.updateFilteredPatterns(); + assertEquals("** isn't funny", chatFilterPlugin.censorMessage("73 isn't funny")); + } + + @Test + public void testCaseSensitivity() + { + when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE); + when(chatFilterConfig.filteredWords()).thenReturn("ReGeX!!!"); + + chatFilterPlugin.updateFilteredPatterns(); + assertEquals("Hey, everyone, I just tried to say something very silly!", + chatFilterPlugin.censorMessage("I love regex!!!!!!!!")); + } + + @Test + public void testNonPrintableCharacters() + { + when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE); + when(chatFilterConfig.filteredWords()).thenReturn("test"); + + chatFilterPlugin.updateFilteredPatterns(); + assertNull(chatFilterPlugin.censorMessage("te\u008Cst")); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPluginTest.java index a120339da0..68d2a8cc1a 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPluginTest.java @@ -33,7 +33,7 @@ import javax.inject.Inject; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.MessageNode; -import net.runelite.api.events.SetMessage; +import net.runelite.api.events.ChatMessage; import net.runelite.client.Notifier; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.util.Text; @@ -76,19 +76,19 @@ public class ChatNotificationsPluginTest } @Test - public void onSetMessage() + public void onChatMessage() { when(config.highlightWordsString()).thenReturn("Deathbeam, Deathbeam OSRS , test"); MessageNode messageNode = mock(MessageNode.class); when(messageNode.getValue()).thenReturn("Deathbeam, Deathbeam OSRS"); - SetMessage setMessage = new SetMessage(); - setMessage.setType(ChatMessageType.PUBLIC); - setMessage.setMessageNode(messageNode); + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.PUBLIC); + chatMessage.setMessageNode(messageNode); chatNotificationsPlugin.startUp(); // load highlight config - chatNotificationsPlugin.onSetMessage(setMessage); + chatNotificationsPlugin.onChatMessage(chatMessage); verify(messageNode).setValue("Deathbeam, Deathbeam OSRS"); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java index 16400b651d..3c1ff06f0c 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java @@ -64,7 +64,8 @@ public class CombatLevelPluginTest when(client.getLocalPlayer()).thenReturn(player); } - private HashMap getBaseValues() { + private HashMap getBaseValues() + { int attackLevel = client.getRealSkillLevel(Skill.ATTACK); int strengthLevel = client.getRealSkillLevel(Skill.STRENGTH); int defenceLevel = client.getRealSkillLevel(Skill.DEFENCE); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java index 33b969015d..024a4de8b3 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cooking/CookingPluginTest.java @@ -79,7 +79,7 @@ public class CookingPluginTest { for (String message : COOKING_MESSAGES) { - ChatMessage chatMessage = new ChatMessage(ChatMessageType.FILTERED, "", message, ""); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.FILTERED, "", message, "", 0); cookingPlugin.onChatMessage(chatMessage); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java index 7c00bab4a9..f7416f4aad 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/examine/ExaminePluginTest.java @@ -94,7 +94,7 @@ public class ExaminePluginTest menuOptionClicked.setId(ItemID.ABYSSAL_WHIP); examinePlugin.onMenuOptionClicked(menuOptionClicked); - ChatMessage chatMessage = new ChatMessage(ChatMessageType.EXAMINE_ITEM, "", "A weapon from the abyss.", ""); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.EXAMINE_ITEM, "", "A weapon from the abyss.", "", 0); examinePlugin.onChatMessage(chatMessage); // This passes due to not mocking the ItemComposition for the whip @@ -112,7 +112,7 @@ public class ExaminePluginTest menuOptionClicked.setId(ItemID.ABYSSAL_WHIP); examinePlugin.onMenuOptionClicked(menuOptionClicked); - ChatMessage chatMessage = new ChatMessage(ChatMessageType.EXAMINE_ITEM, "", "100000 x Abyssal whip", ""); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.EXAMINE_ITEM, "", "100000 x Abyssal whip", "", 0); examinePlugin.onChatMessage(chatMessage); verify(examineClient, never()).submitItem(anyInt(), anyString()); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java index 84925b2d84..c814cbd6a7 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java @@ -31,7 +31,8 @@ public class HiscorePanelTest @Test public void testConstructor() { - new HiscorePanel(new HiscoreConfig() {}); + new HiscorePanel(new HiscoreConfig() + { + }); } - } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java index 36ffcf643e..165c7d50a7 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java @@ -28,16 +28,20 @@ import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.concurrent.ScheduledExecutorService; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.events.ChatMessage; import net.runelite.client.Notifier; +import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.ui.overlay.OverlayManager; -import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import static org.mockito.Matchers.eq; import org.mockito.Mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) @@ -52,6 +56,14 @@ public class ItemChargePluginTest @Bind private Client client; + @Mock + @Bind + private ScheduledExecutorService scheduledExecutorService; + + @Mock + @Bind + private RuneLiteConfig runeLiteConfig; + @Mock @Bind private OverlayManager overlayManager; @@ -76,20 +88,24 @@ public class ItemChargePluginTest @Test public void testOnChatMessage() { - ChatMessage chatMessage = new ChatMessage(ChatMessageType.SERVER, "", CHECK, ""); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SERVER, "", CHECK, "", 0); itemChargePlugin.onChatMessage(chatMessage); - assertEquals(10, itemChargePlugin.getDodgyCharges()); + verify(config).dodgyNecklace(eq(10)); + reset(config); - chatMessage = new ChatMessage(ChatMessageType.SERVER, "", PROTECT, ""); + chatMessage = new ChatMessage(null, ChatMessageType.SERVER, "", PROTECT, "", 0); itemChargePlugin.onChatMessage(chatMessage); - assertEquals(9, itemChargePlugin.getDodgyCharges()); + verify(config).dodgyNecklace(eq(9)); + reset(config); - chatMessage = new ChatMessage(ChatMessageType.SERVER, "", PROTECT_1, ""); + chatMessage = new ChatMessage(null, ChatMessageType.SERVER, "", PROTECT_1, "", 0); itemChargePlugin.onChatMessage(chatMessage); - assertEquals(1, itemChargePlugin.getDodgyCharges()); + verify(config).dodgyNecklace(eq(1)); + reset(config); - chatMessage = new ChatMessage(ChatMessageType.SERVER, "", BREAK, ""); + chatMessage = new ChatMessage(null, ChatMessageType.SERVER, "", BREAK, "", 0); itemChargePlugin.onChatMessage(chatMessage); - assertEquals(10, itemChargePlugin.getDodgyCharges()); + verify(config).dodgyNecklace(eq(10)); + reset(config); } } \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java index 18e6e23700..be5b08e71b 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java @@ -110,7 +110,7 @@ public class ScreenshotPluginTest @Test public void testClueScroll() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Seth", CLUE_SCROLL, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Seth", CLUE_SCROLL, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); assertEquals("medium", screenshotPlugin.getClueType()); @@ -120,7 +120,7 @@ public class ScreenshotPluginTest @Test public void testBarrowsChest() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Seth", BARROWS_CHEST, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Seth", BARROWS_CHEST, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); assertEquals(310, screenshotPlugin.getBarrowsNumber()); @@ -129,7 +129,7 @@ public class ScreenshotPluginTest @Test public void testChambersOfXericChest() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Seth", CHAMBERS_OF_XERIC_CHEST, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Seth", CHAMBERS_OF_XERIC_CHEST, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); assertEquals(489, screenshotPlugin.getChambersOfXericNumber()); @@ -138,7 +138,7 @@ public class ScreenshotPluginTest @Test public void testTheatreOfBloodChest() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Magic fTail", THEATRE_OF_BLOOD_CHEST, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Magic fTail", THEATRE_OF_BLOOD_CHEST, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); assertEquals(73, screenshotPlugin.gettheatreOfBloodNumber()); @@ -147,7 +147,7 @@ public class ScreenshotPluginTest @Test public void testValuableDrop() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", VALUABLE_DROP, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", VALUABLE_DROP, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); verify(drawManager).requestNextFrameListener(Matchers.any(Consumer.class)); @@ -156,7 +156,7 @@ public class ScreenshotPluginTest @Test public void testUntradeableDrop() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", UNTRADEABLE_DROP, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", UNTRADEABLE_DROP, null, 0); screenshotPlugin.onChatMessage(chatMessageEvent); verify(drawManager).requestNextFrameListener(Matchers.any(Consumer.class)); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java index c0a16d3df0..6bfa00f4f2 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java @@ -38,7 +38,6 @@ import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; -import net.runelite.api.events.SetMessage; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; @@ -255,7 +254,7 @@ public class SlayerPluginTest @Test public void testPartnerTask() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", TASK_NEW_FROM_PARTNER, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", TASK_NEW_FROM_PARTNER, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals("Dust Devils", slayerPlugin.getTaskName()); @@ -265,7 +264,7 @@ public class SlayerPluginTest @Test public void testCheckSlayerGem() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", TASK_CHECKSLAYERGEM, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", TASK_CHECKSLAYERGEM, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals("Suqahs", slayerPlugin.getTaskName()); assertEquals(211, slayerPlugin.getAmount()); @@ -274,7 +273,7 @@ public class SlayerPluginTest @Test public void testCheckSlayerGemWildernessTask() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", TASK_CHECKSLAYERGEM_WILDERNESS, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", TASK_CHECKSLAYERGEM_WILDERNESS, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals("Suqahs", slayerPlugin.getTaskName()); assertEquals(211, slayerPlugin.getAmount()); @@ -284,7 +283,7 @@ public class SlayerPluginTest @Test public void testCheckSlayerGemKonarTask() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", TASK_CHECKSLAYERGEM_KONAR, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", TASK_CHECKSLAYERGEM_KONAR, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals("Blue dragons", slayerPlugin.getTaskName()); @@ -322,7 +321,7 @@ public class SlayerPluginTest @Test public void testOneTask() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Perterter", TASK_ONE, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Perterter", TASK_ONE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(1, slayerPlugin.getStreak()); @@ -333,7 +332,7 @@ public class SlayerPluginTest @Test public void testNoPoints() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Perterter", TASK_COMPLETE_NO_POINTS, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Perterter", TASK_COMPLETE_NO_POINTS, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(3, slayerPlugin.getStreak()); @@ -344,7 +343,7 @@ public class SlayerPluginTest @Test public void testPoints() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Perterter", TASK_POINTS, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Perterter", TASK_POINTS, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(9, slayerPlugin.getStreak()); @@ -356,7 +355,7 @@ public class SlayerPluginTest @Test public void testLargeStreak() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Perterter", TASK_LARGE_STREAK, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Perterter", TASK_LARGE_STREAK, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(2465, slayerPlugin.getStreak()); @@ -371,7 +370,7 @@ public class SlayerPluginTest slayerPlugin.setTaskName("cows"); slayerPlugin.setAmount(42); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Perterter", TASK_COMPLETE, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Perterter", TASK_COMPLETE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals("", slayerPlugin.getTaskName()); @@ -384,7 +383,7 @@ public class SlayerPluginTest slayerPlugin.setTaskName("cows"); slayerPlugin.setAmount(42); - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Perterter", TASK_CANCELED, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Perterter", TASK_CANCELED, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals("", slayerPlugin.getTaskName()); @@ -394,7 +393,7 @@ public class SlayerPluginTest @Test public void testSuperiorNotification() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "Superior", SUPERIOR_MESSAGE, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "Superior", SUPERIOR_MESSAGE, null, 0); when(slayerConfig.showSuperiorNotification()).thenReturn(true); slayerPlugin.onChatMessage(chatMessageEvent); @@ -408,7 +407,7 @@ public class SlayerPluginTest @Test public void testBraceletSlaughter() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_SLAUGHTER, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", BRACLET_SLAUGHTER, null, 0); slayerPlugin.setAmount(42); slayerPlugin.setSlaughterChargeCount(10); @@ -418,18 +417,18 @@ public class SlayerPluginTest assertEquals(9, slayerPlugin.getSlaughterChargeCount()); assertEquals(43, slayerPlugin.getAmount()); - chatMessageEvent = new ChatMessage(SERVER, "", CHAT_BRACELET_SLAUGHTER_CHARGE, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", CHAT_BRACELET_SLAUGHTER_CHARGE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(12, slayerPlugin.getSlaughterChargeCount()); - chatMessageEvent = new ChatMessage(SERVER, "", CHAT_BRACELET_SLAUGHTER_CHARGE_ONE, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", CHAT_BRACELET_SLAUGHTER_CHARGE_ONE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(1, slayerPlugin.getSlaughterChargeCount()); slayerPlugin.setSlaughterChargeCount(1); - chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_SLAUGHTER_V3, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", BRACLET_SLAUGHTER_V3, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(30, slayerPlugin.getSlaughterChargeCount()); @@ -442,7 +441,7 @@ public class SlayerPluginTest slayerPlugin.onGameTick(new GameTick()); assertEquals(30, slayerPlugin.getSlaughterChargeCount()); - chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_SLAUGHTER_V2, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", BRACLET_SLAUGHTER_V2, null, 0); slayerPlugin.setAmount(42); slayerPlugin.setSlaughterChargeCount(2); @@ -456,7 +455,7 @@ public class SlayerPluginTest @Test public void testBraceletExpeditious() { - ChatMessage chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_EXPEDITIOUS, null); + ChatMessage chatMessageEvent = new ChatMessage(null, SERVER, "", BRACLET_EXPEDITIOUS, null, 0); slayerPlugin.setAmount(42); slayerPlugin.setExpeditiousChargeCount(10); @@ -466,18 +465,18 @@ public class SlayerPluginTest assertEquals(41, slayerPlugin.getAmount()); assertEquals(9, slayerPlugin.getExpeditiousChargeCount()); - chatMessageEvent = new ChatMessage(SERVER, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(12, slayerPlugin.getExpeditiousChargeCount()); - chatMessageEvent = new ChatMessage(SERVER, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE_ONE, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", CHAT_BRACELET_EXPEDITIOUS_CHARGE_ONE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(1, slayerPlugin.getExpeditiousChargeCount()); slayerPlugin.setExpeditiousChargeCount(1); - chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_EXPEDITIOUS_V3, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", BRACLET_EXPEDITIOUS_V3, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); assertEquals(30, slayerPlugin.getExpeditiousChargeCount()); @@ -490,7 +489,7 @@ public class SlayerPluginTest slayerPlugin.onGameTick(new GameTick()); assertEquals(30, slayerPlugin.getExpeditiousChargeCount()); - chatMessageEvent = new ChatMessage(SERVER, "", BRACLET_EXPEDITIOUS_V2, null); + chatMessageEvent = new ChatMessage(null, SERVER, "", BRACLET_EXPEDITIOUS_V2, null, 0); slayerPlugin.setAmount(42); slayerPlugin.setExpeditiousChargeCount(2); @@ -511,7 +510,7 @@ public class SlayerPluginTest slayerPlugin.setTaskName("Suqahs"); slayerPlugin.setAmount(231); - ChatMessage chatMessage = new ChatMessage(SERVER, "", TASK_UPDATE_COMBAT_BRACELET, null); + ChatMessage chatMessage = new ChatMessage(null, SERVER, "", TASK_UPDATE_COMBAT_BRACELET, null, 0); slayerPlugin.onChatMessage(chatMessage); assertEquals("Suqahs", slayerPlugin.getTaskName()); @@ -531,7 +530,7 @@ public class SlayerPluginTest when(slayerConfig.taskCommand()).thenReturn(true); when(chatClient.getTask(anyString())).thenReturn(task); - SetMessage setMessage = new SetMessage(); + ChatMessage setMessage = new ChatMessage(); setMessage.setType(ChatMessageType.PUBLIC); setMessage.setName("Adam"); setMessage.setMessageNode(mock(MessageNode.class)); @@ -553,12 +552,12 @@ public class SlayerPluginTest when(slayerConfig.taskCommand()).thenReturn(true); when(chatClient.getTask(anyString())).thenReturn(task); - SetMessage setMessage = new SetMessage(); - setMessage.setType(ChatMessageType.PUBLIC); - setMessage.setName("Adam"); - setMessage.setMessageNode(mock(MessageNode.class)); + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.PUBLIC); + chatMessage.setName("Adam"); + chatMessage.setMessageNode(mock(MessageNode.class)); - slayerPlugin.taskLookup(setMessage, "!task"); + slayerPlugin.taskLookup(chatMessage, "!task"); verify(chatMessageManager, never()).update(any(MessageNode.class)); } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/clocks/ClockPanelTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/clocks/ClockPanelTest.java index 8e80c3e5c7..09849de72b 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/clocks/ClockPanelTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/clocks/ClockPanelTest.java @@ -25,7 +25,6 @@ package net.runelite.client.plugins.timetracking.clocks; import java.time.format.DateTimeParseException; -import org.junit.Assert; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java index 71049e0976..067205bd3b 100644 --- a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java +++ b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java @@ -27,7 +27,6 @@ package net.runelite.client.ui.overlay.components; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics2D; -import java.awt.Point; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -85,4 +84,4 @@ public class TextComponentTest verify(graphics, atLeastOnce()).setColor(Color.BLUE); verify(graphics, atLeastOnce()).setColor(Color.GREEN); } -} \ No newline at end of file +} diff --git a/runelite-client/src/test/java/net/runelite/client/util/ColorUtilTest.java b/runelite-client/src/test/java/net/runelite/client/util/ColorUtilTest.java index 3697dac28c..0399a3634b 100644 --- a/runelite-client/src/test/java/net/runelite/client/util/ColorUtilTest.java +++ b/runelite-client/src/test/java/net/runelite/client/util/ColorUtilTest.java @@ -28,6 +28,8 @@ import java.awt.Color; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; public class ColorUtilTest @@ -47,7 +49,8 @@ public class ColorUtilTest @Test public void colorTag() { - COLOR_HEXSTRING_MAP.forEach((color, hex) -> { + COLOR_HEXSTRING_MAP.forEach((color, hex) -> + { assertEquals("", ColorUtil.colorTag(color)); }); } @@ -55,7 +58,8 @@ public class ColorUtilTest @Test public void prependColorTag() { - COLOR_HEXSTRING_MAP.forEach((color, hex) -> { + COLOR_HEXSTRING_MAP.forEach((color, hex) -> + { assertEquals("test", ColorUtil.prependColorTag("test", color)); assertEquals("", ColorUtil.prependColorTag("", color)); }); @@ -66,7 +70,8 @@ public class ColorUtilTest @Test public void wrapWithColorTag() { - COLOR_HEXSTRING_MAP.forEach((color, hex) -> { + COLOR_HEXSTRING_MAP.forEach((color, hex) -> + { assertEquals("test", ColorUtil.wrapWithColorTag("test", color)); assertEquals("", ColorUtil.wrapWithColorTag("", color)); }); @@ -75,7 +80,8 @@ public class ColorUtilTest @Test public void toHexColor() { - COLOR_HEXSTRING_MAP.forEach((color, hex) -> { + COLOR_HEXSTRING_MAP.forEach((color, hex) -> + { assertEquals("#" + hex, ColorUtil.toHexColor(color)); }); } @@ -92,7 +98,8 @@ public class ColorUtilTest @Test public void colorToHexCode() { - COLOR_HEXSTRING_MAP.forEach((color, hex) -> { + COLOR_HEXSTRING_MAP.forEach((color, hex) -> + { assertEquals(hex, ColorUtil.colorToHexCode(color)); }); } @@ -102,10 +109,10 @@ public class ColorUtilTest { for (Color color : COLOR_HEXSTRING_MAP.keySet()) { - assert(!ColorUtil.isFullyTransparent(color)); + assertFalse(ColorUtil.isFullyTransparent(color)); } - assert(ColorUtil.isFullyTransparent(new Color(0, 0, 0, 0))); - assert(!ColorUtil.isFullyTransparent(new Color(0, 0, 0, 1))); + assertTrue(ColorUtil.isFullyTransparent(new Color(0, 0, 0, 0))); + assertFalse(ColorUtil.isFullyTransparent(new Color(0, 0, 0, 1))); } @Test @@ -113,9 +120,9 @@ public class ColorUtilTest { for (Color color : COLOR_HEXSTRING_MAP.keySet()) { - assert(ColorUtil.isNotFullyTransparent(color)); + assertTrue(ColorUtil.isNotFullyTransparent(color)); } - assert(!ColorUtil.isNotFullyTransparent(new Color(0, 0, 0, 0))); - assert(ColorUtil.isNotFullyTransparent(new Color(0, 0, 0, 1))); + assertFalse(ColorUtil.isNotFullyTransparent(new Color(0, 0, 0, 0))); + assertTrue(ColorUtil.isNotFullyTransparent(new Color(0, 0, 0, 1))); } } diff --git a/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java b/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java index a5d64b6a43..829e90368b 100644 --- a/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java +++ b/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java @@ -39,6 +39,8 @@ import java.util.function.Predicate; import javax.annotation.Nonnull; import org.apache.commons.lang3.ArrayUtils; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; public class ImageUtilTest @@ -79,50 +81,50 @@ public class ImageUtilTest public void grayscaleOffset() { // grayscaleOffset(BufferedImage image, int offset) - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), -255))); - assert(bufferedImagesEqual(oneByOne(new Color(50, 50, 50)), ImageUtil.grayscaleOffset(oneByOne(BLACK), 50))); - assert(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(BLACK), 128))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), -255))); - assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(BLACK), 255))); - assert(bufferedImagesEqual(oneByOne(new Color(200, 200, 200)), ImageUtil.grayscaleOffset(oneByOne(WHITE), -55))); - assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 55))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), -255))); + assertTrue(bufferedImagesEqual(oneByOne(new Color(50, 50, 50)), ImageUtil.grayscaleOffset(oneByOne(BLACK), 50))); + assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(BLACK), 128))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), -255))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(BLACK), 255))); + assertTrue(bufferedImagesEqual(oneByOne(new Color(200, 200, 200)), ImageUtil.grayscaleOffset(oneByOne(WHITE), -55))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 55))); // grayscaleOffset(BufferedImage image, float percentage) - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 0f))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 1f))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 2f))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), 0f))); - assert(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(GRAY), 1f))); - assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(GRAY), 2f))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0f))); - assert(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0.503f))); // grayscaleOffset does Math.floor - assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 1f))); - assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(GRAY), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(GRAY), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0.503f))); // grayscaleOffset does Math.floor + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 2f))); } @Test public void alphaOffset() { // alphaOffset(BufferedImage image, int offset) - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), -255))); - assert(bufferedImagesEqual(oneByOne(new Color(0, 0, 0, 50)), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 50))); - assert(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 128))); - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), -255))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 255))); - assert(bufferedImagesEqual(oneByOne(new Color(0, 0, 0, 200)), ImageUtil.alphaOffset(oneByOne(BLACK), -55))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 255))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), -255))); + assertTrue(bufferedImagesEqual(oneByOne(new Color(0, 0, 0, 50)), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 50))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 128))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), -255))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 255))); + assertTrue(bufferedImagesEqual(oneByOne(new Color(0, 0, 0, 200)), ImageUtil.alphaOffset(oneByOne(BLACK), -55))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 255))); // alphaOffset(BufferedImage image, float offset) - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 0f))); - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 1f))); - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 2f))); - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 0f))); - assert(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 1f))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 2f))); - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK), 0f))); - assert(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK), 0.503f))); // opacityOffset does Math.floor - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 1f))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK), 0.503f))); // opacityOffset does Math.floor + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 2f))); } @Test @@ -143,15 +145,15 @@ public class ImageUtilTest for (BufferedImage image : grayscaleColors) { - assert(isGrayscale(image)); + assertTrue(isGrayscale(image)); } for (BufferedImage image : nonGrayscaleColors) { - assert(!isGrayscale(image)); + assertFalse(isGrayscale(image)); } for (BufferedImage image : ArrayUtils.addAll(grayscaleColors, nonGrayscaleColors)) { - assert(isGrayscale(ImageUtil.grayscaleImage(image))); + assertTrue(isGrayscale(ImageUtil.grayscaleImage(image))); } } @@ -190,24 +192,24 @@ public class ImageUtilTest }; for (BufferedImage image : assertSameAfterResize) { - assert(bufferedImagesEqual(image, ImageUtil.resizeImage(image, image.getWidth(), image.getHeight()))); + assertTrue(bufferedImagesEqual(image, ImageUtil.resizeImage(image, image.getWidth(), image.getHeight()))); } } @Test public void resizeCanvas() { - assert(bufferedImagesEqual(centeredPixel(BLACK), ImageUtil.resizeCanvas(oneByOne(BLACK), 3, 3))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.resizeCanvas(oneByOne(BLACK), 1, 1))); - assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.resizeCanvas(centeredPixel(BLACK), 1, 1))); + assertTrue(bufferedImagesEqual(centeredPixel(BLACK), ImageUtil.resizeCanvas(oneByOne(BLACK), 3, 3))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.resizeCanvas(oneByOne(BLACK), 1, 1))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.resizeCanvas(centeredPixel(BLACK), 1, 1))); BufferedImage expected = new BufferedImage(2, 1, BufferedImage.TYPE_INT_ARGB); expected.setRGB(1, 0, BLACK.getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.resizeCanvas(oneByOne(BLACK), 2, 1))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.resizeCanvas(oneByOne(BLACK), 2, 1))); expected = new BufferedImage(1, 2, BufferedImage.TYPE_INT_ARGB); expected.setRGB(0, 1, BLACK.getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.resizeCanvas(oneByOne(BLACK), 1, 2))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.resizeCanvas(oneByOne(BLACK), 1, 2))); } @Test @@ -216,10 +218,10 @@ public class ImageUtilTest // TODO: Test more than 90° rotations // Evenly-sized images (2x2) - assert(bufferedImagesEqual(BLACK_PIXEL_TOP_RIGHT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI / 2))); - assert(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_RIGHT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI))); - assert(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_LEFT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI * 3 / 2))); - assert(bufferedImagesEqual(BLACK_PIXEL_TOP_LEFT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI * 2))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_TOP_RIGHT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI / 2))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_RIGHT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_LEFT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI * 3 / 2))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_TOP_LEFT, ImageUtil.rotateImage(BLACK_PIXEL_TOP_LEFT, Math.PI * 2))); // Unevenly-sized images (2x1); when rotated 90° become (2x2) images final BufferedImage twoByOneLeft = new BufferedImage(2, 1, BufferedImage.TYPE_INT_ARGB); @@ -232,33 +234,33 @@ public class ImageUtilTest oneByTwoBottom.setRGB(0, 0, new Color(0, 0, 0, 127).getRGB()); oneByTwoBottom.setRGB(0, 1, BLACK.getRGB()); - assert(bufferedImagesEqual(oneByTwoTop, ImageUtil.rotateImage(twoByOneLeft, Math.PI / 2))); - assert(bufferedImagesEqual(twoByTwoRight, ImageUtil.rotateImage(twoByOneLeft, Math.PI))); - assert(bufferedImagesEqual(oneByTwoBottom, ImageUtil.rotateImage(twoByOneLeft, Math.PI * 3 / 2))); - assert(bufferedImagesEqual(twoByOneLeft, ImageUtil.rotateImage(twoByOneLeft, Math.PI * 2))); + assertTrue(bufferedImagesEqual(oneByTwoTop, ImageUtil.rotateImage(twoByOneLeft, Math.PI / 2))); + assertTrue(bufferedImagesEqual(twoByTwoRight, ImageUtil.rotateImage(twoByOneLeft, Math.PI))); + assertTrue(bufferedImagesEqual(oneByTwoBottom, ImageUtil.rotateImage(twoByOneLeft, Math.PI * 3 / 2))); + assertTrue(bufferedImagesEqual(twoByOneLeft, ImageUtil.rotateImage(twoByOneLeft, Math.PI * 2))); } @Test public void flipImage() { - assert(bufferedImagesEqual(BLACK_PIXEL_TOP_LEFT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, false, false))); - assert(bufferedImagesEqual(BLACK_PIXEL_TOP_RIGHT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, true, false))); - assert(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_LEFT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, false, true))); - assert(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_RIGHT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, true, true))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_TOP_LEFT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, false, false))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_TOP_RIGHT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, true, false))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_LEFT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, false, true))); + assertTrue(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_RIGHT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, true, true))); } @Test public void fillImage() { // fillImage(BufferedImage image, Color color) - assert(bufferedImagesEqual(centeredPixel(GRAY), ImageUtil.fillImage(centeredPixel(BLACK), GRAY))); - assert(bufferedImagesEqual(solidColor(3, 3, GREEN), ImageUtil.fillImage(solidColor(3, 3, BLACK), GREEN))); - assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.fillImage(oneByOne(BLACK_TRANSPARENT), WHITE))); + assertTrue(bufferedImagesEqual(centeredPixel(GRAY), ImageUtil.fillImage(centeredPixel(BLACK), GRAY))); + assertTrue(bufferedImagesEqual(solidColor(3, 3, GREEN), ImageUtil.fillImage(solidColor(3, 3, BLACK), GREEN))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.fillImage(oneByOne(BLACK_TRANSPARENT), WHITE))); // fillImage(BufferedImage image, Color color, Predicate fillCondition) BufferedImage expected = solidColor(CORNER_SIZE, CORNER_SIZE, WHITE); expected.setRGB(0, 0, new Color(0, true).getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.fillImage(BLACK_PIXEL_TOP_LEFT, WHITE, ColorUtil::isFullyTransparent))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.fillImage(BLACK_PIXEL_TOP_LEFT, WHITE, ColorUtil::isFullyTransparent))); } @Test @@ -277,13 +279,13 @@ public class ImageUtilTest expected.setRGB(x, y, BLACK.getRGB()); } } - assert(bufferedImagesEqual(expected, ImageUtil.outlineImage(centeredPixel(BLACK), BLACK))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(centeredPixel(BLACK), BLACK))); expected.setRGB(1, 1, WHITE.getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.outlineImage(centeredPixel(WHITE), BLACK))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(centeredPixel(WHITE), BLACK))); expected = solidColor(CORNER_SIZE, CORNER_SIZE, WHITE); expected.setRGB(0, 0, BLACK.getRGB()); expected.setRGB(1, 1, new Color(0, true).getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE))); // outlineImage(BufferedImage image, Color color, Predicate fillCondition) BufferedImage test = new BufferedImage(CORNER_SIZE, CORNER_SIZE, BufferedImage.TYPE_INT_ARGB); @@ -291,18 +293,18 @@ public class ImageUtilTest test.setRGB(1, 0, GRAY.getRGB()); expected = test; expected.setRGB(0, 1, BLUE.getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.outlineImage(test, BLUE, (color -> color.equals(BLACK))))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(test, BLUE, (color -> color.equals(BLACK))))); // outlineImage(BufferedImage image, Color color, Boolean outlineCorners) expected = solidColor(CORNER_SIZE, CORNER_SIZE, WHITE); expected.setRGB(0, 0, BLACK.getRGB()); - assert(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE, true))); - assert(bufferedImagesEqual(solidColor(3, 3, BLACK), ImageUtil.outlineImage(centeredPixel(BLACK), BLACK, true))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(BLACK_PIXEL_TOP_LEFT, WHITE, true))); + assertTrue(bufferedImagesEqual(solidColor(3, 3, BLACK), ImageUtil.outlineImage(centeredPixel(BLACK), BLACK, true))); // outlineImage(BufferedImage image, Color color, Predicate fillCondition, Boolean outlineCorners) test = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB); test.setRGB(2, 2, BLACK.getRGB()); - test.setRGB(1,2, new Color(50, 50, 50).getRGB()); + test.setRGB(1, 2, new Color(50, 50, 50).getRGB()); test.setRGB(3, 2, new Color(100, 100, 100).getRGB()); test.setRGB(2, 3, new Color(150, 150, 150).getRGB()); expected = test; @@ -317,7 +319,7 @@ public class ImageUtilTest expected.setRGB(2, 4, RED.getRGB()); expected.setRGB(3, 4, RED.getRGB()); Predicate testPredicate = (color -> ColorUtil.isNotFullyTransparent(color) && color.getRed() > 75 && color.getGreen() > 75 && color.getBlue() > 75); - assert(bufferedImagesEqual(expected, ImageUtil.outlineImage(test, RED, testPredicate, true))); + assertTrue(bufferedImagesEqual(expected, ImageUtil.outlineImage(test, RED, testPredicate, true))); } /** diff --git a/runelite-mixins/pom.xml b/runelite-mixins/pom.xml index 2bbd0bb214..31cc93c5d4 100644 --- a/runelite-mixins/pom.xml +++ b/runelite-mixins/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT mixins diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/ProcessClientErrorMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/ProcessClientErrorMixin.java index a4498ea814..eb3e971a3a 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/ProcessClientErrorMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/ProcessClientErrorMixin.java @@ -55,7 +55,7 @@ public abstract class ProcessClientErrorMixin implements RSClient throwableToScan = ((RSRunException) throwable).getParent(); } - client.getLogger().error("Game crash", throwableToScan); + client.getLogger().error("Game crash: {}", string, throwableToScan); StackTraceElement[] stackTrace = throwableToScan.getStackTrace(); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java index 437e2a76d9..cc72387a6d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java @@ -43,6 +43,7 @@ import net.runelite.api.events.GraphicChanged; import net.runelite.api.events.HitsplatApplied; import net.runelite.api.events.InteractingChanged; import net.runelite.api.events.LocalPlayerDeath; +import net.runelite.api.events.OverheadTextChanged; import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.MethodHook; @@ -208,6 +209,18 @@ public abstract class RSActorMixin implements RSActor client.getCallbacks().post(interactingChanged); } + @FieldHook("overhead") + @Inject + public void overheadTextChanged(int idx) + { + String overheadText = getOverheadText(); + if (overheadText != null) + { + OverheadTextChanged overheadTextChanged = new OverheadTextChanged(this, overheadText); + client.getCallbacks().post(overheadTextChanged); + } + } + @Inject @Override public Polygon getConvexHull() diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSChatLineBufferMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSChatLineBufferMixin.java new file mode 100644 index 0000000000..6b720a26f8 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSChatLineBufferMixin.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018, trimbe + * Copyright (c) 2018, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.mixins; + +import net.runelite.api.MessageNode; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSCacheableNode; +import net.runelite.rs.api.RSChatLineBuffer; + +@Mixin(RSChatLineBuffer.class) +public abstract class RSChatLineBufferMixin implements RSChatLineBuffer +{ + @Inject + @Override + public void removeMessageNode(MessageNode node) + { + MessageNode[] lines = getLines(); + final int length = getLength(); + int found = -1; + + // Find the index of the node + for (int idx = 0; idx < length; idx++) + { + if (lines[idx] == node) + { + found = idx; + break; + } + } + + if (found == -1) + { + return; + } + + // Shift down all other messages + for (int i = found; i < length - 1; i++) + { + lines[i] = lines[i + 1]; + } + lines[length - 1] = null; + setLength(length - 1); + + RSCacheableNode rsCacheableNode = (RSCacheableNode) node; + rsCacheableNode.unlink(); + rsCacheableNode.unlinkDual(); + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java new file mode 100644 index 0000000000..25e01ce1ca --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClanMemberManagerMixin.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.mixins; + +import net.runelite.api.ClanMember; +import net.runelite.api.events.ClanMemberJoined; +import net.runelite.api.events.ClanMemberLeft; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSClanMemberManager; +import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSName; +import net.runelite.rs.api.RSNameable; + +@Mixin(RSClanMemberManager.class) +public abstract class RSClanMemberManagerMixin implements RSClanMemberManager +{ + @Shadow("clientInstance") + private static RSClient client; + + @Inject + @Override + public void rl$add(RSName name, RSName prevName) + { + ClanMember member = findByName(name); + if (member == null) + { + return; + } + + ClanMemberJoined event = new ClanMemberJoined(member); + client.getCallbacks().postDeferred(event); + } + + @Inject + @Override + public void rl$remove(RSNameable nameable) + { + ClanMember member = findByName(nameable.getRsName()); + if (member == null) + { + return; + } + + ClanMemberLeft event = new ClanMemberLeft(member); + client.getCallbacks().postDeferred(event); + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 0c99443490..430bfb7d35 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -24,13 +24,17 @@ */ package net.runelite.mixins; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; import javax.inject.Named; import net.runelite.api.ChatMessageType; import net.runelite.api.ClanMember; +import net.runelite.api.EnumComposition; import net.runelite.api.Friend; import net.runelite.api.GameState; import net.runelite.api.GrandExchangeOffer; @@ -51,6 +55,7 @@ import static net.runelite.api.MenuAction.PLAYER_SEVENTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_SIXTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_THIRD_OPTION; import net.runelite.api.MenuEntry; +import net.runelite.api.MessageNode; import net.runelite.api.NPC; import net.runelite.api.Node; import net.runelite.api.PacketBuffer; @@ -72,9 +77,9 @@ import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.CanvasSizeChanged; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ClanChanged; +import net.runelite.api.events.ClientTick; import net.runelite.api.events.DraggingWidgetChanged; import net.runelite.api.events.ExperienceChanged; -import net.runelite.api.events.ClientTick; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GrandExchangeOfferChanged; import net.runelite.api.events.MenuEntryAdded; @@ -100,9 +105,11 @@ import net.runelite.api.mixins.Shadow; import net.runelite.api.vars.AccountType; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.rs.api.RSChatLineBuffer; import net.runelite.rs.api.RSClanMemberManager; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSDeque; +import net.runelite.rs.api.RSEnum; import net.runelite.rs.api.RSFriendContainer; import net.runelite.rs.api.RSFriendManager; import net.runelite.rs.api.RSHashTable; @@ -113,7 +120,6 @@ import net.runelite.rs.api.RSItem; import net.runelite.rs.api.RSItemContainer; import net.runelite.rs.api.RSNPC; import net.runelite.rs.api.RSName; -import net.runelite.rs.api.RSNameable; import net.runelite.rs.api.RSPlayer; import net.runelite.rs.api.RSSpritePixels; import net.runelite.rs.api.RSWidget; @@ -173,6 +179,16 @@ public abstract class RSClientMixin implements RSClient @Inject static int skyboxColor; + @Inject + private final Cache enumCache = CacheBuilder.newBuilder() + .maximumSize(64) + .build(); + + @Inject + public RSClientMixin() + { + } + @Inject @Override public Callbacks getCallbacks() @@ -488,14 +504,8 @@ public abstract class RSClientMixin implements RSClient if (skill == Skill.OVERALL) { - int totalExperience = 0; - - for (int experience : experiences) - { - totalExperience += experience; - } - - return totalExperience; + logger.debug("getSkillExperience called for {}!", skill); + return (int) getOverallExperience(); } int idx = skill.ordinal(); @@ -510,6 +520,22 @@ public abstract class RSClientMixin implements RSClient return experiences[idx]; } + @Inject + @Override + public long getOverallExperience() + { + int[] experiences = getSkillExperiences(); + + long totalExperience = 0L; + + for (int experience : experiences) + { + totalExperience += experience; + } + + return totalExperience; + } + @Inject @Override public void refreshChat() @@ -708,7 +734,21 @@ public abstract class RSClientMixin implements RSClient public ClanMember[] getClanMembers() { final RSClanMemberManager clanMemberManager = getClanMemberManager(); - return clanMemberManager != null ? (ClanMember[]) getClanMemberManager().getNameables() : null; + return clanMemberManager != null ? getClanMemberManager().getNameables() : null; + } + + @Inject + @Override + public String getClanOwner() + { + return getClanMemberManager().getClanOwner(); + } + + @Inject + @Override + public String getClanChatName() + { + return getClanMemberManager().getClanChatName(); } @Inject @@ -727,8 +767,7 @@ public abstract class RSClientMixin implements RSClient return null; } - RSNameable[] nameables = friendContainer.getNameables(); - return (Friend[]) nameables; + return friendContainer.getNameables(); } @Inject @@ -766,8 +805,7 @@ public abstract class RSClientMixin implements RSClient return null; } - RSNameable[] nameables = ignoreContainer.getNameables(); - return (Ignore[]) nameables; + return ignoreContainer.getNameables(); } @Inject @@ -996,6 +1034,7 @@ public abstract class RSClientMixin implements RSClient public static void settingsChanged(int idx) { VarbitChanged varbitChanged = new VarbitChanged(); + varbitChanged.setIndex(idx); client.getCallbacks().post(varbitChanged); } @@ -1236,7 +1275,7 @@ public abstract class RSClientMixin implements RSClient } @Inject - @MethodHook("addChatMessage") + @MethodHook(value = "addChatMessage", end = true) public static void onAddChatMessage(int type, String name, String message, String sender) { Logger logger = client.getLogger(); @@ -1245,8 +1284,13 @@ public abstract class RSClientMixin implements RSClient logger.debug("Chat message type {}: {}", ChatMessageType.of(type), message); } + // Get the message node which was added + Map chatLineMap = client.getChatLineMap(); + RSChatLineBuffer chatLineBuffer = chatLineMap.get(type); + MessageNode messageNode = chatLineBuffer.getLines()[0]; + final ChatMessageType chatMessageType = ChatMessageType.of(type); - final ChatMessage chatMessage = new ChatMessage(chatMessageType, name, message, sender); + final ChatMessage chatMessage = new ChatMessage(messageNode, chatMessageType, name, message, sender, messageNode.getTimestamp()); client.getCallbacks().post(chatMessage); } @@ -1257,9 +1301,9 @@ public abstract class RSClientMixin implements RSClient callbacks.clientMainLoop(); } - @MethodHook("gameDraw") + @MethodHook("renderWidgetLayer") @Inject - public static void gameDraw(Widget[] widgets, int parentId, int var2, int var3, int var4, int var5, int x, int y, int var8) + public static void renderWidgetLayer(Widget[] widgets, int parentId, int var2, int var3, int var4, int var5, int x, int y, int var8) { for (Widget rlWidget : widgets) { @@ -1434,4 +1478,21 @@ public abstract class RSClientMixin implements RSClient return false; } + + @Inject + @Override + public EnumComposition getEnum(int id) + { + assert isClientThread() : "getEnum must be called on client thread"; + + RSEnum rsEnum = enumCache.getIfPresent(id); + if (rsEnum != null) + { + return rsEnum; + } + + rsEnum = getRsEnum(id); + enumCache.put(id, rsEnum); + return rsEnum; + } } \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSDecorativeObjectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSDecorativeObjectMixin.java index f278609c9b..7ae4685ef3 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSDecorativeObjectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSDecorativeObjectMixin.java @@ -82,6 +82,29 @@ public abstract class RSDecorativeObjectMixin implements RSDecorativeObject return model; } + @Inject + private RSModel getModel2() + { + RSRenderable renderable = getRenderable2(); + if (renderable == null) + { + return null; + } + + RSModel model; + + if (renderable instanceof Model) + { + model = (RSModel) renderable; + } + else + { + model = renderable.getModel(); + } + + return model; + } + @Inject @Override public Area getClickbox() @@ -100,6 +123,20 @@ public abstract class RSDecorativeObjectMixin implements RSDecorativeObject return null; } - return model.getConvexHull(getX(), getY(), getOrientation()); + return model.getConvexHull(getX() + getXOffset(), getY() + getYOffset(), 0); + } + + @Inject + @Override + public Polygon getConvexHull2() + { + RSModel model = getModel2(); + + if (model == null) + { + return null; + } + + return model.getConvexHull(getX(), getY(), 0); } } diff --git a/http-service/src/main/java/net/runelite/http/service/ws/SessionManager.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSEnumMixin.java similarity index 61% rename from http-service/src/main/java/net/runelite/http/service/ws/SessionManager.java rename to runelite-mixins/src/main/java/net/runelite/mixins/RSEnumMixin.java index 815ab911e8..06dd3ab2e8 100644 --- a/http-service/src/main/java/net/runelite/http/service/ws/SessionManager.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSEnumMixin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Adam + * Copyright (c) 2019, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,46 +22,54 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.http.service.ws; +package net.runelite.mixins; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSEnum; -public class SessionManager +@Mixin(RSEnum.class) +public abstract class RSEnumMixin implements RSEnum { - private static final ConcurrentMap sessions = new ConcurrentHashMap<>(); - - public static void changeSessionUID(WSService service, UUID uuid) + @Inject + @Override + public int getIntValue(int key) { - synchronized (service) + final int[] keys = getKeys(); + if (keys == null) { - remove(service); - service.setUuid(uuid); - sessions.put(uuid, service); + return getDefaultInt(); } - } - static void remove(WSService service) - { - synchronized (service) + for (int i = 0; i < keys.length; ++i) { - UUID current = service.getUuid(); - if (current != null) + if (keys[i] == key) { - sessions.remove(current); - service.setUuid(null); + final int[] values = getIntVals(); + return values[i]; } } + return getDefaultInt(); } - public static WSService findSession(UUID uuid) + @Inject + @Override + public String getStringValue(int key) { - return sessions.get(uuid); - } + final int[] keys = getKeys(); + if (keys == null) + { + return getDefaultString(); + } - public static int getCount() - { - return sessions.size(); + for (int i = 0; i < keys.length; ++i) + { + if (keys[i] == key) + { + final String[] values = getStringVals(); + return values[i]; + } + } + return getDefaultString(); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSMessageNodeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSMessageNodeMixin.java index c8ed6cc772..da716252e7 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSMessageNodeMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSMessageNodeMixin.java @@ -25,7 +25,6 @@ package net.runelite.mixins; import net.runelite.api.ChatMessageType; -import net.runelite.api.events.SetMessage; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.MethodHook; import net.runelite.api.mixins.Mixin; @@ -49,15 +48,6 @@ public abstract class RSMessageNodeMixin implements RSMessageNode RSMessageNodeMixin() { rl$timestamp = (int) (System.currentTimeMillis() / 1000L); - - final SetMessage setMessage = new SetMessage(); - setMessage.setMessageNode(this); - setMessage.setType(getType()); - setMessage.setName(getName()); - setMessage.setSender(getSender()); - setMessage.setValue(getValue()); - setMessage.setTimestamp(rl$timestamp); - client.getCallbacks().post(setMessage); } @Inject @@ -103,14 +93,5 @@ public abstract class RSMessageNodeMixin implements RSMessageNode // Clear the runelite formatted message then. runeLiteFormatMessage = null; rl$timestamp = (int) (System.currentTimeMillis() / 1000L); - - final SetMessage setMessage = new SetMessage(); - setMessage.setMessageNode(this); - setMessage.setType(ChatMessageType.of(type)); - setMessage.setName(name); - setMessage.setSender(sender); - setMessage.setValue(value); - setMessage.setTimestamp(rl$timestamp); - client.getCallbacks().post(setMessage); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNameableContainerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNameableContainerMixin.java new file mode 100644 index 0000000000..8a3a1492e0 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNameableContainerMixin.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018, trimbe + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.mixins; + +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.MethodHook; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSName; +import net.runelite.rs.api.RSNameable; +import net.runelite.rs.api.RSNameableContainer; + +@Mixin(RSNameableContainer.class) +public abstract class RSNameableContainerMixin implements RSNameableContainer +{ + /** + * Default implementation of rl$add + * @param name + * @param prevName + */ + @Inject + @Override + public void rl$add(RSName name, RSName prevName) + { + } + + /** + * Default implementation of rl$del + * @param nameable + */ + @Inject + @Override + public void rl$remove(RSNameable nameable) + { + } + + @Inject + @MethodHook(value = "add", end = true) + public void add(RSName name, RSName prevName) + { + rl$add(name, prevName); + } + + @Inject + @MethodHook("remove") + public void remove(RSNameable nameable) + { + rl$remove(nameable); + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java index c30a1388ae..2c9a0d4e1e 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java @@ -2,8 +2,8 @@ package net.runelite.mixins; import net.runelite.api.events.VarClientIntChanged; import net.runelite.api.events.VarClientStrChanged; -import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.MethodHook; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; @@ -15,17 +15,17 @@ public abstract class RSVarcsMixin implements RSVarcs @Shadow("clientInstance") private static RSClient client; - @FieldHook("varCInts") + @MethodHook(value = "putVarc", end = true) @Inject - public void onVarCIntChanged(int idx) + public void onVarCIntChanged(int id, int value) { - client.getCallbacks().post(new VarClientIntChanged(idx)); + client.getCallbacks().post(new VarClientIntChanged(id)); } - @FieldHook("varCStrings") + @MethodHook(value = "putVarcStringNew", end = true) @Inject - public void onVarCStrChanged(int idx) + public void onVarCStrChanged(int id, String value) { - client.getCallbacks().post(new VarClientStrChanged(idx)); + client.getCallbacks().post(new VarClientStrChanged(id)); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 455c0c36a8..4130ce5930 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -519,7 +519,15 @@ public abstract class RSWidgetMixin implements RSWidget } else { - index = siblings.length; + index = 0; + for (int i = siblings.length - 1; i >= 0; i--) + { + if (siblings[i] != null) + { + index = i + 1; + break; + } + } } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java index 23488c694e..a473dad4a9 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java @@ -26,6 +26,7 @@ package net.runelite.mixins; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; +import java.util.Map; import net.runelite.api.VarClientInt; import net.runelite.api.VarClientStr; import net.runelite.api.Varbits; @@ -118,43 +119,40 @@ public abstract class VarbitMixin implements RSClient @Override public int getVar(VarClientInt varClientInt) { - return getIntVarcs()[varClientInt.getIndex()]; + Map varcmap = getVarcMap(); + Object object = varcmap.get(varClientInt.getIndex()); + return object instanceof Integer ? (Integer) object : 0; } @Inject @Override public String getVar(VarClientStr varClientStr) { - return getStrVarcs()[varClientStr.getIndex()]; + Map varcmap = getVarcMap(); + Object var2 = varcmap.get(varClientStr.getIndex()); + return var2 instanceof String ? (String) var2 : ""; } @Inject @Override public void setVar(VarClientStr varClientStr, String value) { - String[] vars = getStrVarcs(); - vars[varClientStr.getIndex()] = value; + Map varcmap = getVarcMap(); + varcmap.put(varClientStr.getIndex(), value); } @Inject @Override public void setVar(VarClientInt varClientInt, int value) { - int[] vars = getIntVarcs(); - vars[varClientInt.getIndex()] = value; + Map varcmap = getVarcMap(); + varcmap.put(varClientInt.getIndex(), value); } @Inject @Override - public int[] getIntVarcs() + public Map getVarcMap() { - return getVarcs().getIntVarcs(); - } - - @Inject - @Override - public String[] getStrVarcs() - { - return getVarcs().getStrVarcs(); + return getVarcs().getVarcMap(); } } diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index 5ce6ad3a0a..a83d595c1c 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT script-assembler-plugin diff --git a/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java index 654e5e407c..02073e8144 100644 --- a/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java +++ b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java @@ -33,6 +33,6 @@ public class RuneLiteInstructions extends Instructions public void init() { super.init(); - add(RUNELITE_EXECUTE, "runelite_callback", 0, 0, 1, 0); + add(RUNELITE_EXECUTE, "runelite_callback"); } } diff --git a/runescape-api/pom.xml b/runescape-api/pom.xml index 10f3c0e190..fb65af2e3f 100644 --- a/runescape-api/pom.xml +++ b/runescape-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.5.12-SNAPSHOT + 1.5.18-SNAPSHOT net.runelite.rs diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSActor.java b/runescape-api/src/main/java/net/runelite/rs/api/RSActor.java index 225d62b72e..801cf4413a 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSActor.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSActor.java @@ -34,7 +34,11 @@ public interface RSActor extends RSRenderable, Actor @Import("overhead") @Override - String getOverhead(); + String getOverheadText(); + + @Import("overhead") + @Override + void setOverheadText(String overheadText); @Import("x") int getX(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSCacheableNode.java b/runescape-api/src/main/java/net/runelite/rs/api/RSCacheableNode.java index f443f11425..44d7b876cc 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSCacheableNode.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSCacheableNode.java @@ -24,6 +24,10 @@ */ package net.runelite.rs.api; +import net.runelite.mapping.Import; + public interface RSCacheableNode extends RSNode { + @Import("unlinkDual") + void unlinkDual(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSChatLineBuffer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSChatLineBuffer.java index fa2a798cdd..9aa9b35c3b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSChatLineBuffer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSChatLineBuffer.java @@ -39,4 +39,7 @@ public interface RSChatLineBuffer extends ChatLineBuffer @Import("length") @Override int getLength(); + + @Import("length") + void setLength(int length); } \ No newline at end of file diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClanMemberManager.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClanMemberManager.java index 1247b940d5..36a486c28b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClanMemberManager.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClanMemberManager.java @@ -24,7 +24,13 @@ */ package net.runelite.rs.api; -public interface RSClanMemberManager extends RSNameableContainer -{ +import net.runelite.mapping.Import; +public interface RSClanMemberManager extends RSNameableContainer +{ + @Import("clanOwner") + String getClanOwner(); + + @Import("clanChatName") + String getClanChatName(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 04ac90d398..654e0048ea 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -785,6 +785,10 @@ public interface RSClient extends RSGameEngine, Client @Override RSNodeCache getWidgetSpriteCache(); + @Import("items") + @Override + RSNodeCache getItemCompositionCache(); + @Import("oculusOrbState") @Override int getOculusOrbState(); @@ -921,4 +925,11 @@ public interface RSClient extends RSGameEngine, Client @Import("endY") int getEndY(); + + @Import("spellSelected") + @Override + void setSpellSelected(boolean selected); + + @Import("getEnum") + RSEnum getRsEnum(int id); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSDecorativeObject.java b/runescape-api/src/main/java/net/runelite/rs/api/RSDecorativeObject.java index 1a53a49cb9..910c5acc1b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSDecorativeObject.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSDecorativeObject.java @@ -39,6 +39,12 @@ public interface RSDecorativeObject extends DecorativeObject @Import("y") int getY(); + @Import("offsetX") + int getXOffset(); + + @Import("offsetY") + int getYOffset(); + @Import("rotation") int getOrientation(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSEnum.java b/runescape-api/src/main/java/net/runelite/rs/api/RSEnum.java new file mode 100644 index 0000000000..afad5c131e --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSEnum.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.rs.api; + +import net.runelite.api.EnumComposition; +import net.runelite.mapping.Import; + +public interface RSEnum extends EnumComposition, RSCacheableNode +{ + @Import("keys") + @Override + int[] getKeys(); + + @Import("intVals") + @Override + int[] getIntVals(); + + @Import("stringVals") + @Override + String[] getStringVals(); + + @Import("defaultInt") + int getDefaultInt(); + + @Import("defaultString") + String getDefaultString(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendContainer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendContainer.java index 165730c323..2b3793f478 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendContainer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendContainer.java @@ -24,6 +24,6 @@ */ package net.runelite.rs.api; -public interface RSFriendContainer extends RSNameableContainer +public interface RSFriendContainer extends RSNameableContainer { } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSIgnoreContainer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSIgnoreContainer.java index 350a3b083e..74fb4d5f37 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSIgnoreContainer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSIgnoreContainer.java @@ -24,6 +24,6 @@ */ package net.runelite.rs.api; -public interface RSIgnoreContainer extends RSNameableContainer +public interface RSIgnoreContainer extends RSNameableContainer { } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSNPCComposition.java b/runescape-api/src/main/java/net/runelite/rs/api/RSNPCComposition.java index 0ed50491f6..87c781cea8 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSNPCComposition.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSNPCComposition.java @@ -47,11 +47,11 @@ public interface RSNPCComposition extends NPCComposition @Import("isMinimapVisible") @Override - boolean isMinimapVisable(); + boolean isMinimapVisible(); @Import("isVisible") @Override - boolean isVisable(); + boolean isVisible(); @Import("id") @Override diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSNameableContainer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSNameableContainer.java index 4c0fe5c77a..33f2070048 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSNameableContainer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSNameableContainer.java @@ -26,14 +26,30 @@ package net.runelite.rs.api; import net.runelite.mapping.Import; -public interface RSNameableContainer +public interface RSNameableContainer { @Import("count") int getCount(); @Import("nameables") - RSNameable[] getNameables(); + T[] getNameables(); @Import("isMember") boolean isMember(RSName var1); + + @Import("findByName") + T findByName(RSName name); + + /** + * Method called by the container when an element is added + * @param name + * @param prevName + */ + void rl$add(RSName name, RSName prevName); + + /** + * Method called by the container when an element is removed + * @param nameable + */ + void rl$remove(RSNameable nameable); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSVarcs.java b/runescape-api/src/main/java/net/runelite/rs/api/RSVarcs.java index 5f330cf167..527377ae7b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSVarcs.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSVarcs.java @@ -24,13 +24,11 @@ */ package net.runelite.rs.api; +import java.util.Map; import net.runelite.mapping.Import; public interface RSVarcs { - @Import("varCInts") - int[] getIntVarcs(); - - @Import("varCStrings") - String[] getStrVarcs(); + @Import("varcMap") + Map getVarcMap(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java b/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java index 75315b0514..0dd5b24d4f 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java @@ -328,6 +328,10 @@ public interface RSWidget extends Widget @Override void setOnMouseOverListener(Object... args); + @Import("onMouseRepeatListener") + @Override + void setOnMouseRepeatListener(Object... args); + @Import("onMouseLeaveListener") @Override void setOnMouseLeaveListener(Object... args); @@ -336,6 +340,14 @@ public interface RSWidget extends Widget @Override void setOnTimerListener(Object... args); + @Import("onTargetEnterListener") + @Override + void setOnTargetEnterListener(Object... args); + + @Import("onTargetLeaveListener") + @Override + void setOnTargetLeaveListener(Object... args); + @Import("fontId") @Override int getFontId(); @@ -435,4 +447,28 @@ public interface RSWidget extends Widget @Import("filled") @Override void setFilled(boolean filled); + + @Import("targetVerb") + @Override + String getTargetVerb(); + + @Import("targetVerb") + @Override + void setTargetVerb(String targetVerb); + + @Import("noClickThrough") + @Override + boolean getNoClickThrough(); + + @Import("noClickThrough") + @Override + void setNoClickThrough(boolean noClickThrough); + + @Import("noScrollThrough") + @Override + boolean getNoScrollThrough(); + + @Import("noScrollThrough") + @Override + void setNoScrollThrough(boolean noScrollThrough); } diff --git a/suppressions.xml b/suppressions.xml index 5c940d0c48..7a6d858208 100644 --- a/suppressions.xml +++ b/suppressions.xml @@ -24,9 +24,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> + "-//Checkstyle//DTD SuppressionFilter Configuration 1.1//EN" + "https://checkstyle.org/dtds/suppressions_1_1.dtd"> - - + +