diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 48258f6387..e125baaf00 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -25,9 +25,9 @@ object ProjectVersions { const val launcherVersion = "2.2.0" - const val rlVersion = "1.8.6" + const val rlVersion = "1.8.7" - const val openosrsVersion = "4.16.2" + const val openosrsVersion = "4.17.0" const val rsversion = 202 const val cacheversion = 165 diff --git a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java index 2259026a4d..939fdf90da 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java +++ b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java @@ -12,45 +12,40 @@ public class ModelDefinition public int id; public int vertexCount = 0; - public int[] vertexPositionsX; - public int[] vertexPositionsY; - public int[] vertexPositionsZ; + public int[] vertexX; + public int[] vertexY; + public int[] vertexZ; public transient VertexNormal[] vertexNormals; public int faceCount; - public int[] faceVertexIndices1; - public int[] faceVertexIndices2; - public int[] faceVertexIndices3; - public byte[] faceAlphas; + public int[] faceIndices1; + public int[] faceIndices2; + public int[] faceIndices3; + public byte[] faceTransparencies; public short[] faceColors; public byte[] faceRenderPriorities; public byte[] faceRenderTypes; public transient FaceNormal[] faceNormals; - public int textureTriangleCount; - public short[] textureTriangleVertexIndices1; - public short[] textureTriangleVertexIndices2; - public short[] textureTriangleVertexIndices3; + public int numTextureFaces; + public short[] texIndices1; + public short[] texIndices2; + public short[] texIndices3; public transient float[][] faceTextureUCoordinates; public transient float[][] faceTextureVCoordinates; public short[] texturePrimaryColors; public short[] faceTextures; - public byte[] textureCoordinates; + public byte[] textureCoords; public byte[] textureRenderTypes; - public int[] vertexSkins; - public int[] faceSkins; + public int[] packedVertexGroups; + public int[] packedTransparencyVertexGroups; public byte priority; - public short[] aShortArray2574; - public short[] aShortArray2575; - public short[] aShortArray2577; - public short[] aShortArray2578; - public byte[] aByteArray2580; - public short[] aShortArray2586; - private transient int[][] vertexGroups; + public int[][] animayaGroups; + public int[][] animayaScales; private transient int[] origVX; private transient int[] origVY; @@ -77,17 +72,17 @@ public class ModelDefinition for (var1 = 0; var1 < this.faceCount; ++var1) { - int vertexA = this.faceVertexIndices1[var1]; - int vertexB = this.faceVertexIndices2[var1]; - int vertexC = this.faceVertexIndices3[var1]; + int vertexA = this.faceIndices1[var1]; + int vertexB = this.faceIndices2[var1]; + int vertexC = this.faceIndices3[var1]; - int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA]; - int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA]; - int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA]; + int xA = this.vertexX[vertexB] - this.vertexX[vertexA]; + int yA = this.vertexY[vertexB] - this.vertexY[vertexA]; + int zA = this.vertexZ[vertexB] - this.vertexZ[vertexA]; - int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA]; - int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA]; - int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[vertexA]; + int xB = this.vertexX[vertexC] - this.vertexX[vertexA]; + int yB = this.vertexY[vertexC] - this.vertexY[vertexA]; + int zB = this.vertexZ[vertexC] - this.vertexZ[vertexA]; // Compute cross product int var11 = yA * zB - yB * zA; @@ -168,13 +163,13 @@ public class ModelDefinition for (int i = 0; i < faceCount; i++) { int textureCoordinate; - if (textureCoordinates == null) + if (textureCoords == null) { textureCoordinate = -1; } else { - textureCoordinate = textureCoordinates[i]; + textureCoordinate = textureCoords[i]; } int textureIdx; @@ -215,33 +210,33 @@ public class ModelDefinition if (textureRenderType == 0) { - int faceVertexIdx1 = faceVertexIndices1[i]; - int faceVertexIdx2 = faceVertexIndices2[i]; - int faceVertexIdx3 = faceVertexIndices3[i]; + int faceVertexIdx1 = faceIndices1[i]; + int faceVertexIdx2 = faceIndices2[i]; + int faceVertexIdx3 = faceIndices3[i]; - short triangleVertexIdx1 = textureTriangleVertexIndices1[textureCoordinate]; - short triangleVertexIdx2 = textureTriangleVertexIndices2[textureCoordinate]; - short triangleVertexIdx3 = textureTriangleVertexIndices3[textureCoordinate]; + short triangleVertexIdx1 = texIndices1[textureCoordinate]; + short triangleVertexIdx2 = texIndices2[textureCoordinate]; + short triangleVertexIdx3 = texIndices3[textureCoordinate]; - float triangleX = (float) vertexPositionsX[triangleVertexIdx1]; - float triangleY = (float) vertexPositionsY[triangleVertexIdx1]; - float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1]; + float triangleX = (float) vertexX[triangleVertexIdx1]; + float triangleY = (float) vertexY[triangleVertexIdx1]; + float triangleZ = (float) vertexZ[triangleVertexIdx1]; - float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX; - float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY; - float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ; - float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX; - float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY; - float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ; - float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX; - float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY; - float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ; - float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX; - float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY; - float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ; - float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX; - float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY; - float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ; + float f_882_ = (float) vertexX[triangleVertexIdx2] - triangleX; + float f_883_ = (float) vertexY[triangleVertexIdx2] - triangleY; + float f_884_ = (float) vertexZ[triangleVertexIdx2] - triangleZ; + float f_885_ = (float) vertexX[triangleVertexIdx3] - triangleX; + float f_886_ = (float) vertexY[triangleVertexIdx3] - triangleY; + float f_887_ = (float) vertexZ[triangleVertexIdx3] - triangleZ; + float f_888_ = (float) vertexX[faceVertexIdx1] - triangleX; + float f_889_ = (float) vertexY[faceVertexIdx1] - triangleY; + float f_890_ = (float) vertexZ[faceVertexIdx1] - triangleZ; + float f_891_ = (float) vertexX[faceVertexIdx2] - triangleX; + float f_892_ = (float) vertexY[faceVertexIdx2] - triangleY; + float f_893_ = (float) vertexZ[faceVertexIdx2] - triangleZ; + float f_894_ = (float) vertexX[faceVertexIdx3] - triangleX; + float f_895_ = (float) vertexY[faceVertexIdx3] - triangleY; + float f_896_ = (float) vertexZ[faceVertexIdx3] - triangleZ; float f_897_ = f_883_ * f_887_ - f_884_ * f_886_; float f_898_ = f_884_ * f_885_ - f_882_ * f_887_; @@ -274,7 +269,7 @@ public class ModelDefinition public void computeAnimationTables() { - if (this.vertexSkins != null) + if (this.packedVertexGroups != null) { int[] groupCounts = new int[256]; int numGroups = 0; @@ -282,7 +277,7 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; ++var3) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; ++groupCounts[var4]; if (var4 > numGroups) { @@ -300,10 +295,10 @@ public class ModelDefinition for (var3 = 0; var3 < this.vertexCount; this.vertexGroups[var4][groupCounts[var4]++] = var3++) { - var4 = this.vertexSkins[var3]; + var4 = this.packedVertexGroups[var3]; } - this.vertexSkins = null; + this.packedVertexGroups = null; } // triangleSkinValues is here @@ -314,13 +309,13 @@ public class ModelDefinition int sin = CircularAngle.SINE[orientation]; int cos = CircularAngle.COSINE[orientation]; - assert vertexPositionsX.length == vertexPositionsY.length; - assert vertexPositionsY.length == vertexPositionsZ.length; + assert vertexX.length == vertexY.length; + assert vertexY.length == vertexZ.length; - for (int i = 0; i < vertexPositionsX.length; ++i) + for (int i = 0; i < vertexX.length; ++i) { - vertexPositionsX[i] = vertexPositionsX[i] * cos + vertexPositionsZ[i] * sin >> 16; - vertexPositionsZ[i] = vertexPositionsZ[i] * cos - vertexPositionsX[i] * sin >> 16; + vertexX[i] = vertexX[i] * cos + vertexZ[i] * sin >> 16; + vertexZ[i] = vertexZ[i] * cos - vertexX[i] * sin >> 16; } reset(); @@ -333,23 +328,23 @@ public class ModelDefinition return; } - System.arraycopy(origVX, 0, vertexPositionsX, 0, origVX.length); - System.arraycopy(origVY, 0, vertexPositionsY, 0, origVY.length); - System.arraycopy(origVZ, 0, vertexPositionsZ, 0, origVZ.length); + System.arraycopy(origVX, 0, vertexX, 0, origVX.length); + System.arraycopy(origVY, 0, vertexY, 0, origVY.length); + System.arraycopy(origVZ, 0, vertexZ, 0, origVZ.length); } public void animate(int type, int[] frameMap, int dx, int dy, int dz) { if (origVX == null) { - origVX = Arrays.copyOf(vertexPositionsX, vertexPositionsX.length); - origVY = Arrays.copyOf(vertexPositionsY, vertexPositionsY.length); - origVZ = Arrays.copyOf(vertexPositionsZ, vertexPositionsZ.length); + origVX = Arrays.copyOf(vertexX, vertexX.length); + origVY = Arrays.copyOf(vertexY, vertexY.length); + origVZ = Arrays.copyOf(vertexZ, vertexZ.length); } - final int[] verticesX = vertexPositionsX; - final int[] verticesY = vertexPositionsY; - final int[] verticesZ = vertexPositionsZ; + final int[] verticesX = vertexX; + final int[] verticesY = vertexY; + final int[] verticesZ = vertexZ; int var6 = frameMap.length; int var7; int var8; @@ -512,14 +507,14 @@ public class ModelDefinition int var1; for (var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } for (var1 = 0; var1 < this.faceCount; ++var1) { - int var2 = this.faceVertexIndices1[var1]; - this.faceVertexIndices1[var1] = this.faceVertexIndices3[var1]; - this.faceVertexIndices3[var1] = var2; + int var2 = this.faceIndices1[var1]; + this.faceIndices1[var1] = this.faceIndices3[var1]; + this.faceIndices3[var1] = var2; } reset(); @@ -529,9 +524,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = -var2; + int var2 = this.vertexX[var1]; + this.vertexX[var1] = this.vertexZ[var1]; + this.vertexZ[var1] = -var2; } reset(); @@ -541,8 +536,8 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - this.vertexPositionsX[var1] = -this.vertexPositionsX[var1]; - this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1]; + this.vertexX[var1] = -this.vertexX[var1]; + this.vertexZ[var1] = -this.vertexZ[var1]; } reset(); @@ -552,9 +547,9 @@ public class ModelDefinition { for (int var1 = 0; var1 < this.vertexCount; ++var1) { - int var2 = this.vertexPositionsZ[var1]; - this.vertexPositionsZ[var1] = this.vertexPositionsX[var1]; - this.vertexPositionsX[var1] = -var2; + int var2 = this.vertexZ[var1]; + this.vertexZ[var1] = this.vertexX[var1]; + this.vertexX[var1] = -var2; } reset(); @@ -571,9 +566,9 @@ public class ModelDefinition { for (int var4 = 0; var4 < this.vertexCount; ++var4) { - this.vertexPositionsX[var4] = this.vertexPositionsX[var4] * var1 / 128; - this.vertexPositionsY[var4] = var2 * this.vertexPositionsY[var4] / 128; - this.vertexPositionsZ[var4] = var3 * this.vertexPositionsZ[var4] / 128; + this.vertexX[var4] = this.vertexX[var4] * var1 / 128; + this.vertexY[var4] = var2 * this.vertexY[var4] / 128; + this.vertexZ[var4] = var3 * this.vertexZ[var4] / 128; } reset(); @@ -610,9 +605,9 @@ public class ModelDefinition { for (int i = 0; i < this.vertexCount; i++) { - this.vertexPositionsX[i] += xOffset; - this.vertexPositionsY[i] += yOffset; - this.vertexPositionsZ[i] += zOffset; + this.vertexX[i] += xOffset; + this.vertexY[i] += yOffset; + this.vertexZ[i] += zOffset; } this.reset(); } diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java index 4529f8a069..22226c3d8a 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java @@ -10,13 +10,21 @@ public class ModelLoader ModelDefinition def = new ModelDefinition(); def.id = modelId; - if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + if (b[b.length - 1] == -3 && b[b.length - 2] == -1) { - this.load1(def, b); + decodeType3(def, b); + } + else if (b[b.length - 1] == -2 && b[b.length - 2] == -1) + { + decodeType2(def, b); + } + else if (b[b.length - 1] == -1 && b[b.length - 2] == -1) + { + decodeType1(def, b); } else { - this.load2(def, b); + decodeOldFormat(def, b); } def.computeNormals(); @@ -26,702 +34,1356 @@ public class ModelLoader return def; } - private void load1(ModelDefinition model, byte[] var1) + void decodeType3(ModelDefinition def, byte[] var1) { InputStream var2 = new InputStream(var1); - InputStream var24 = new InputStream(var1); InputStream var3 = new InputStream(var1); - InputStream var28 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); InputStream var6 = new InputStream(var1); - InputStream var55 = new InputStream(var1); - InputStream var51 = new InputStream(var1); - var2.setOffset(var1.length - 23); - int verticeCount = var2.readUnsignedShort(); - int triangleCount = var2.readUnsignedShort(); - int textureTriangleCount = var2.readUnsignedByte(); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 26); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); int var13 = var2.readUnsignedByte(); - int modelPriority = var2.readUnsignedByte(); - int var50 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); int var17 = var2.readUnsignedByte(); - int modelTexture = var2.readUnsignedByte(); - int modelVertexSkins = var2.readUnsignedByte(); + int var18 = var2.readUnsignedByte(); + int var19 = var2.readUnsignedShort(); int var20 = var2.readUnsignedShort(); int var21 = var2.readUnsignedShort(); - int var42 = var2.readUnsignedShort(); int var22 = var2.readUnsignedShort(); - int var38 = var2.readUnsignedShort(); - int textureAmount = 0; - int var7 = 0; - int var29 = 0; - int position; - if (textureTriangleCount > 0) + int var23 = var2.readUnsignedShort(); + int var24 = var2.readUnsignedShort(); + int var25 = 0; + int var26 = 0; + int var27 = 0; + int var28; + if (var11 > 0) { - model.textureRenderTypes = new byte[textureTriangleCount]; + def.textureRenderTypes = new byte[var11]; var2.setOffset(0); - for (position = 0; position < textureTriangleCount; ++position) + for (var28 = 0; var28 < var11; ++var28) { - byte renderType = model.textureRenderTypes[position] = var2.readByte(); - if (renderType == 0) + byte var29 = def.textureRenderTypes[var28] = var2.readByte(); + if (var29 == 0) { - ++textureAmount; + ++var25; } - if (renderType >= 1 && renderType <= 3) + if (var29 >= 1 && var29 <= 3) { - ++var7; + ++var26; } - if (renderType == 2) + if (var29 == 2) { - ++var29; + ++var27; } } } - position = textureTriangleCount + verticeCount; - int renderTypePos = position; - if (var13 == 1) + var28 = var11 + var9; + int var58 = var28; + if (var12 == 1) { - position += triangleCount; + var28 += var10; } - int var49 = position; - position += triangleCount; - int priorityPos = position; - if (modelPriority == 255) + int var30 = var28; + var28 += var10; + int var31 = var28; + if (var13 == 255) { - position += triangleCount; + var28 += var10; } - int triangleSkinPos = position; + int var32 = var28; + if (var15 == 1) + { + var28 += var10; + } + + int var33 = var28; + var28 += var24; + int var34 = var28; + if (var14 == 1) + { + var28 += var10; + } + + int var35 = var28; + var28 += var22; + int var36 = var28; + if (var16 == 1) + { + var28 += var10 * 2; + } + + int var37 = var28; + var28 += var23; + int var38 = var28; + var28 += var10 * 2; + int var39 = var28; + var28 += var19; + int var40 = var28; + var28 += var20; + int var41 = var28; + var28 += var21; + int var42 = var28; + var28 += var25 * 6; + int var43 = var28; + var28 += var26 * 6; + int var44 = var28; + var28 += var26 * 6; + int var45 = var28; + var28 += var26 * 2; + int var46 = var28; + var28 += var26; + int var47 = var28; + var28 = var28 + var26 * 2 + var27 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; if (var17 == 1) { - position += triangleCount; + def.packedVertexGroups = new int[var9]; } - int var35 = position; - if (modelVertexSkins == 1) + if (var12 == 1) { - position += verticeCount; + def.faceRenderTypes = new byte[var10]; } - int alphaPos = position; - if (var50 == 1) + if (var13 == 255) { - position += triangleCount; - } - - int var11 = position; - position += var22; - int texturePos = position; - if (modelTexture == 1) - { - position += triangleCount * 2; - } - - int textureCoordPos = position; - position += var38; - int colorPos = position; - position += triangleCount * 2; - int var40 = position; - position += var20; - int var41 = position; - position += var21; - int var8 = position; - position += var42; - int var43 = position; - position += textureAmount * 6; - int var37 = position; - position += var7 * 6; - int var48 = position; - position += var7 * 6; - int var56 = position; - position += var7 * 2; - int var45 = position; - position += var7; - int var46 = position; - position += var7 * 2 + var29 * 2; - model.vertexCount = verticeCount; - model.faceCount = triangleCount; - model.textureTriangleCount = textureTriangleCount; - model.vertexPositionsX = new int[verticeCount]; - model.vertexPositionsY = new int[verticeCount]; - model.vertexPositionsZ = new int[verticeCount]; - model.faceVertexIndices1 = new int[triangleCount]; - model.faceVertexIndices2 = new int[triangleCount]; - model.faceVertexIndices3 = new int[triangleCount]; - if (modelVertexSkins == 1) - { - model.vertexSkins = new int[verticeCount]; - } - - if (var13 == 1) - { - model.faceRenderTypes = new byte[triangleCount]; - } - - if (modelPriority == 255) - { - model.faceRenderPriorities = new byte[triangleCount]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) modelPriority; + def.priority = (byte) var13; } - if (var50 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[triangleCount]; + def.faceTransparencies = new byte[var10]; } - if (var17 == 1) + if (var15 == 1) { - model.faceSkins = new int[triangleCount]; + def.packedTransparencyVertexGroups = new int[var10]; } - if (modelTexture == 1) + if (var16 == 1) { - model.faceTextures = new short[triangleCount]; + def.faceTextures = new short[var10]; } - if (modelTexture == 1 && textureTriangleCount > 0) + if (var16 == 1 && var11 > 0) { - model.textureCoordinates = new byte[triangleCount]; + def.textureCoords = new byte[var10]; } - model.faceColors = new short[triangleCount]; - if (textureTriangleCount > 0) + if (var18 == 1) { - model.textureTriangleVertexIndices1 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices2 = new short[textureTriangleCount]; - model.textureTriangleVertexIndices3 = new short[textureTriangleCount]; - if (var7 > 0) - { - model.aShortArray2574 = new short[var7]; - model.aShortArray2575 = new short[var7]; - model.aShortArray2586 = new short[var7]; - model.aShortArray2577 = new short[var7]; - model.aByteArray2580 = new byte[var7]; - model.aShortArray2578 = new short[var7]; - } - - if (var29 > 0) - { - model.texturePrimaryColors = new short[var29]; - } + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; } - var2.setOffset(textureTriangleCount); - var24.setOffset(var40); - var3.setOffset(var41); - var28.setOffset(var8); - var6.setOffset(var35); - int vX = 0; - int vY = 0; - int vZ = 0; - - int vertexZOffset; - int var10; - int vertexYOffset; - int var15; - int point; - for (point = 0; point < verticeCount; ++point) + def.faceColors = new short[var10]; + if (var11 > 0) { - int vertexFlags = var2.readUnsignedByte(); - int vertexXOffset = 0; - if ((vertexFlags & 1) != 0) - { - vertexXOffset = var24.readShortSmart(); - } - - vertexYOffset = 0; - if ((vertexFlags & 2) != 0) - { - vertexYOffset = var3.readShortSmart(); - } - - vertexZOffset = 0; - if ((vertexFlags & 4) != 0) - { - vertexZOffset = var28.readShortSmart(); - } - - model.vertexPositionsX[point] = vX + vertexXOffset; - model.vertexPositionsY[point] = vY + vertexYOffset; - model.vertexPositionsZ[point] = vZ + vertexZOffset; - vX = model.vertexPositionsX[point]; - vY = model.vertexPositionsY[point]; - vZ = model.vertexPositionsZ[point]; - if (modelVertexSkins == 1) - { - model.vertexSkins[point] = var6.readUnsignedByte(); - } - } - - var2.setOffset(colorPos); - var24.setOffset(renderTypePos); - var3.setOffset(priorityPos); - var28.setOffset(alphaPos); - var6.setOffset(triangleSkinPos); - var55.setOffset(texturePos); - var51.setOffset(textureCoordPos); - - for (point = 0; point < triangleCount; ++point) - { - model.faceColors[point] = (short) var2.readUnsignedShort(); - if (var13 == 1) - { - model.faceRenderTypes[point] = var24.readByte(); - } - - if (modelPriority == 255) - { - model.faceRenderPriorities[point] = var3.readByte(); - } - - if (var50 == 1) - { - model.faceAlphas[point] = var28.readByte(); - } - - if (var17 == 1) - { - model.faceSkins[point] = var6.readUnsignedByte(); - } - - if (modelTexture == 1) - { - model.faceTextures[point] = (short) (var55.readUnsignedShort() - 1); - } - - if (model.textureCoordinates != null && model.faceTextures[point] != -1) - { - model.textureCoordinates[point] = (byte) (var51.readUnsignedByte() - 1); - } + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } var2.setOffset(var11); - var24.setOffset(var49); - int trianglePointX = 0; - int trianglePointY = 0; - int trianglePointZ = 0; - vertexYOffset = 0; + var3.setOffset(var39); + var4.setOffset(var40); + var5.setOffset(var41); + var6.setOffset(var33); + int var48 = 0; + int var49 = 0; + int var50 = 0; - int var16; - for (vertexZOffset = 0; vertexZOffset < triangleCount; ++vertexZOffset) + int var51; + int var52; + int var53; + int var54; + int var55; + for (var51 = 0; var51 < var9; ++var51) { - int numFaces = var24.readUnsignedByte(); - if (numFaces == 1) + var52 = var2.readUnsignedByte(); + var53 = 0; + if ((var52 & 1) != 0) { - trianglePointX = var2.readShortSmart() + vertexYOffset; - trianglePointY = var2.readShortSmart() + trianglePointX; - trianglePointZ = var2.readShortSmart() + trianglePointY; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var53 = var3.readShortSmart(); } - if (numFaces == 2) + var54 = 0; + if ((var52 & 2) != 0) { - trianglePointY = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var54 = var4.readShortSmart(); } - if (numFaces == 3) + var55 = 0; + if ((var52 & 4) != 0) { - trianglePointX = trianglePointZ; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = trianglePointY; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + var55 = var5.readShortSmart(); } - if (numFaces == 4) + def.vertexX[var51] = var48 + var53; + def.vertexY[var51] = var49 + var54; + def.vertexZ[var51] = var50 + var55; + var48 = def.vertexX[var51]; + var49 = def.vertexY[var51]; + var50 = def.vertexZ[var51]; + if (var17 == 1) { - int var57 = trianglePointX; - trianglePointX = trianglePointY; - trianglePointY = var57; - trianglePointZ = var2.readShortSmart() + vertexYOffset; - vertexYOffset = trianglePointZ; - model.faceVertexIndices1[vertexZOffset] = trianglePointX; - model.faceVertexIndices2[vertexZOffset] = var57; - model.faceVertexIndices3[vertexZOffset] = trianglePointZ; + def.packedVertexGroups[var51] = var6.readUnsignedByte(); } } - var2.setOffset(var43); - var24.setOffset(var37); - var3.setOffset(var48); - var28.setOffset(var56); - var6.setOffset(var45); - var55.setOffset(var46); - - for (int texIndex = 0; texIndex < textureTriangleCount; ++texIndex) + if (var18 == 1) { - int type = model.textureRenderTypes[texIndex] & 255; - if (type == 0) + for (var51 = 0; var51 < var9; ++var51) { - model.textureTriangleVertexIndices1[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var2.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var2.readUnsignedShort(); - } + var52 = var6.readUnsignedByte(); + def.animayaGroups[var51] = new int[var52]; + def.animayaScales[var51] = new int[var52]; - if (type == 1) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 2) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); - model.texturePrimaryColors[texIndex] = (short) var55.readUnsignedShort(); - } - - if (type == 3) - { - model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort(); - model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort(); - model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort(); - model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort(); - model.aByteArray2580[texIndex] = var6.readByte(); - model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort(); + for (var53 = 0; var53 < var52; ++var53) + { + def.animayaGroups[var51][var53] = var6.readUnsignedByte(); + def.animayaScales[var51][var53] = var6.readUnsignedByte(); + } } } - var2.setOffset(position); - vertexZOffset = var2.readUnsignedByte(); - if (vertexZOffset != 0) + var2.setOffset(var38); + var3.setOffset(var58); + var4.setOffset(var31); + var5.setOffset(var34); + var6.setOffset(var32); + var7.setOffset(var36); + var8.setOffset(var37); + + for (var51 = 0; var51 < var10; ++var51) + { + def.faceColors[var51] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var51] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var51] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var51] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var51] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var51] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var51] != -1) + { + def.textureCoords[var51] = (byte) (var8.readUnsignedByte() - 1); + } + } + + var2.setOffset(var35); + var3.setOffset(var30); + var51 = 0; + var52 = 0; + var53 = 0; + var54 = 0; + + int var56; + for (var55 = 0; var55 < var10; ++var55) + { + var56 = var3.readUnsignedByte(); + if (var56 == 1) + { + var51 = var2.readShortSmart() + var54; + var52 = var2.readShortSmart() + var51; + var53 = var2.readShortSmart() + var52; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 2) + { + var52 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 3) + { + var51 = var53; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var52; + def.faceIndices3[var55] = var53; + } + + if (var56 == 4) + { + int var57 = var51; + var51 = var52; + var52 = var57; + var53 = var2.readShortSmart() + var54; + var54 = var53; + def.faceIndices1[var55] = var51; + def.faceIndices2[var55] = var57; + def.faceIndices3[var55] = var53; + } + } + + var2.setOffset(var42); + var3.setOffset(var43); + var4.setOffset(var44); + var5.setOffset(var45); + var6.setOffset(var46); + var7.setOffset(var47); + + for (var55 = 0; var55 < var11; ++var55) + { + var56 = def.textureRenderTypes[var55] & 255; + if (var56 == 0) + { + def.texIndices1[var55] = (short) var2.readUnsignedShort(); + def.texIndices2[var55] = (short) var2.readUnsignedShort(); + def.texIndices3[var55] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var28); + var55 = var2.readUnsignedByte(); + if (var55 != 0) { - //new Class41(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readUnsignedShort(); var2.readInt(); } + } - private void load2(ModelDefinition model, byte[] var1) + void decodeType2(ModelDefinition def, byte[] var1) { boolean var2 = false; - boolean var43 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); InputStream var5 = new InputStream(var1); - InputStream var39 = new InputStream(var1); - InputStream var26 = new InputStream(var1); - InputStream var9 = new InputStream(var1); - InputStream var3 = new InputStream(var1); - var5.setOffset(var1.length - 18); - int var10 = var5.readUnsignedShort(); - int var11 = var5.readUnsignedShort(); - int var12 = var5.readUnsignedByte(); - int var13 = var5.readUnsignedByte(); - int var14 = var5.readUnsignedByte(); - int var30 = var5.readUnsignedByte(); - int var15 = var5.readUnsignedByte(); - int var28 = var5.readUnsignedByte(); - int var27 = var5.readUnsignedShort(); - int var20 = var5.readUnsignedShort(); - int var36 = var5.readUnsignedShort(); - int var23 = var5.readUnsignedShort(); - byte var16 = 0; - int var46 = var16 + var10; - int var24 = var46; - var46 += var11; - int var25 = var46; - if (var14 == 255) + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 23); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedByte(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + int var21 = var4.readUnsignedShort(); + int var22 = var4.readUnsignedShort(); + byte var23 = 0; + int var24 = var23 + var9; + int var25 = var24; + var24 += var10; + int var26 = var24; + if (var13 == 255) { - var46 += var11; + var24 += var10; } - int var4 = var46; + int var27 = var24; if (var15 == 1) { - var46 += var11; + var24 += var10; } - int var42 = var46; - if (var13 == 1) + int var28 = var24; + if (var12 == 1) { - var46 += var11; + var24 += var10; } - int var37 = var46; - if (var28 == 1) + int var29 = var24; + var24 += var22; + int var30 = var24; + if (var14 == 1) { - var46 += var10; + var24 += var10; } - int var29 = var46; - if (var30 == 1) + int var31 = var24; + var24 += var21; + int var32 = var24; + var24 += var10 * 2; + int var33 = var24; + var24 += var11 * 6; + int var34 = var24; + var24 += var18; + int var35 = var24; + var24 += var19; + int var10000 = var24 + var20; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) { - var46 += var11; + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; } - int var44 = var46; - var46 += var23; - int var17 = var46; - var46 += var11 * 2; - int var32 = var46; - var46 += var12 * 6; - int var34 = var46; - var46 += var27; - int var35 = var46; - var46 += var20; - int var10000 = var46 + var36; - model.vertexCount = var10; - model.faceCount = var11; - model.textureTriangleCount = var12; - model.vertexPositionsX = new int[var10]; - model.vertexPositionsY = new int[var10]; - model.vertexPositionsZ = new int[var10]; - model.faceVertexIndices1 = new int[var11]; - model.faceVertexIndices2 = new int[var11]; - model.faceVertexIndices3 = new int[var11]; - if (var12 > 0) + if (var16 == 1) { - model.textureRenderTypes = new byte[var12]; - model.textureTriangleVertexIndices1 = new short[var12]; - model.textureTriangleVertexIndices2 = new short[var12]; - model.textureTriangleVertexIndices3 = new short[var12]; + def.packedVertexGroups = new int[var9]; } - if (var28 == 1) + if (var12 == 1) { - model.vertexSkins = new int[var10]; + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; } - if (var13 == 1) + if (var13 == 255) { - model.faceRenderTypes = new byte[var11]; - model.textureCoordinates = new byte[var11]; - model.faceTextures = new short[var11]; - } - - if (var14 == 255) - { - model.faceRenderPriorities = new byte[var11]; + def.faceRenderPriorities = new byte[var10]; } else { - model.priority = (byte) var14; + def.priority = (byte) var13; } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas = new byte[var11]; + def.faceTransparencies = new byte[var10]; } if (var15 == 1) { - model.faceSkins = new int[var11]; + def.packedTransparencyVertexGroups = new int[var10]; } - model.faceColors = new short[var11]; - var5.setOffset(var16); - var39.setOffset(var34); - var26.setOffset(var35); - var9.setOffset(var46); - var3.setOffset(var37); - int var41 = 0; - int var33 = 0; - int var19 = 0; - - int var6; - int var7; - int var8; - int var18; - int var31; - for (var18 = 0; var18 < var10; ++var18) + if (var17 == 1) { - var8 = var5.readUnsignedByte(); - var31 = 0; - if ((var8 & 1) != 0) + def.animayaGroups = new int[var9][]; + def.animayaScales = new int[var9][]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var23); + var5.setOffset(var34); + var6.setOffset(var35); + var7.setOffset(var24); + var8.setOffset(var29); + int var37 = 0; + int var38 = 0; + int var39 = 0; + + int var40; + int var41; + int var42; + int var43; + int var44; + for (var40 = 0; var40 < var9; ++var40) + { + var41 = var4.readUnsignedByte(); + var42 = 0; + if ((var41 & 1) != 0) { - var31 = var39.readShortSmart(); + var42 = var5.readShortSmart(); } - var6 = 0; - if ((var8 & 2) != 0) + var43 = 0; + if ((var41 & 2) != 0) { - var6 = var26.readShortSmart(); + var43 = var6.readShortSmart(); } - var7 = 0; - if ((var8 & 4) != 0) + var44 = 0; + if ((var41 & 4) != 0) { - var7 = var9.readShortSmart(); + var44 = var7.readShortSmart(); } - model.vertexPositionsX[var18] = var41 + var31; - model.vertexPositionsY[var18] = var33 + var6; - model.vertexPositionsZ[var18] = var19 + var7; - var41 = model.vertexPositionsX[var18]; - var33 = model.vertexPositionsY[var18]; - var19 = model.vertexPositionsZ[var18]; - if (var28 == 1) + def.vertexX[var40] = var37 + var42; + def.vertexY[var40] = var38 + var43; + def.vertexZ[var40] = var39 + var44; + var37 = def.vertexX[var40]; + var38 = def.vertexY[var40]; + var39 = def.vertexZ[var40]; + if (var16 == 1) { - model.vertexSkins[var18] = var3.readUnsignedByte(); + def.packedVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var17); - var39.setOffset(var42); - var26.setOffset(var25); - var9.setOffset(var29); - var3.setOffset(var4); - - for (var18 = 0; var18 < var11; ++var18) + if (var17 == 1) { - model.faceColors[var18] = (short) var5.readUnsignedShort(); - if (var13 == 1) + for (var40 = 0; var40 < var9; ++var40) { - var8 = var39.readUnsignedByte(); - if ((var8 & 1) == 1) + var41 = var8.readUnsignedByte(); + def.animayaGroups[var40] = new int[var41]; + def.animayaScales[var40] = new int[var41]; + + for (var42 = 0; var42 < var41; ++var42) { - model.faceRenderTypes[var18] = 1; + def.animayaGroups[var40][var42] = var8.readUnsignedByte(); + def.animayaScales[var40][var42] = var8.readUnsignedByte(); + } + } + } + + var4.setOffset(var32); + var5.setOffset(var28); + var6.setOffset(var26); + var7.setOffset(var30); + var8.setOffset(var27); + + for (var40 = 0; var40 < var10; ++var40) + { + def.faceColors[var40] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var41 = var5.readUnsignedByte(); + if ((var41 & 1) == 1) + { + def.faceRenderTypes[var40] = 1; var2 = true; } else { - model.faceRenderTypes[var18] = 0; + def.faceRenderTypes[var40] = 0; } - if ((var8 & 2) == 2) + if ((var41 & 2) == 2) { - model.textureCoordinates[var18] = (byte) (var8 >> 2); - model.faceTextures[var18] = model.faceColors[var18]; - model.faceColors[var18] = 127; - if (model.faceTextures[var18] != -1) + def.textureCoords[var40] = (byte) (var41 >> 2); + def.faceTextures[var40] = def.faceColors[var40]; + def.faceColors[var40] = 127; + if (def.faceTextures[var40] != -1) { - var43 = true; + var3 = true; } } else { - model.textureCoordinates[var18] = -1; - model.faceTextures[var18] = -1; + def.textureCoords[var40] = -1; + def.faceTextures[var40] = -1; } } - if (var14 == 255) + if (var13 == 255) { - model.faceRenderPriorities[var18] = var26.readByte(); + def.faceRenderPriorities[var40] = var6.readByte(); } - if (var30 == 1) + if (var14 == 1) { - model.faceAlphas[var18] = var9.readByte(); + def.faceTransparencies[var40] = var7.readByte(); } if (var15 == 1) { - model.faceSkins[var18] = var3.readUnsignedByte(); + def.packedTransparencyVertexGroups[var40] = var8.readUnsignedByte(); } } - var5.setOffset(var44); - var39.setOffset(var24); - var18 = 0; - var8 = 0; - var31 = 0; - var6 = 0; + var4.setOffset(var31); + var5.setOffset(var25); + var40 = 0; + var41 = 0; + var42 = 0; + var43 = 0; - int var21; - int var22; - for (var7 = 0; var7 < var11; ++var7) + int var45; + int var46; + for (var44 = 0; var44 < var10; ++var44) { - var22 = var39.readUnsignedByte(); - if (var22 == 1) + var45 = var5.readUnsignedByte(); + if (var45 == 1) { - var18 = var5.readShortSmart() + var6; - var8 = var5.readShortSmart() + var18; - var31 = var5.readShortSmart() + var8; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var4.readShortSmart() + var43; + var41 = var4.readShortSmart() + var40; + var42 = var4.readShortSmart() + var41; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 2) + if (var45 == 2) { - var8 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var41 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 3) + if (var45 == 3) { - var18 = var31; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var8; - model.faceVertexIndices3[var7] = var31; + var40 = var42; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var41; + def.faceIndices3[var44] = var42; } - if (var22 == 4) + if (var45 == 4) { - var21 = var18; - var18 = var8; - var8 = var21; - var31 = var5.readShortSmart() + var6; - var6 = var31; - model.faceVertexIndices1[var7] = var18; - model.faceVertexIndices2[var7] = var21; - model.faceVertexIndices3[var7] = var31; + var46 = var40; + var40 = var41; + var41 = var46; + var42 = var4.readShortSmart() + var43; + var43 = var42; + def.faceIndices1[var44] = var40; + def.faceIndices2[var44] = var46; + def.faceIndices3[var44] = var42; } } + var4.setOffset(var33); + + for (var44 = 0; var44 < var11; ++var44) + { + def.textureRenderTypes[var44] = 0; + def.texIndices1[var44] = (short) var4.readUnsignedShort(); + def.texIndices2[var44] = (short) var4.readUnsignedShort(); + def.texIndices3[var44] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) + { + boolean var47 = false; + + for (var45 = 0; var45 < var10; ++var45) + { + var46 = def.textureCoords[var45] & 255; + if (var46 != 255) + { + if (def.faceIndices1[var45] == (def.texIndices1[var46] & '\uffff') && def.faceIndices2[var45] == (def.texIndices2[var46] & '\uffff') && def.faceIndices3[var45] == (def.texIndices3[var46] & '\uffff')) + { + def.textureCoords[var45] = -1; + } + else + { + var47 = true; + } + } + } + + if (!var47) + { + def.textureCoords = null; + } + } + + if (!var3) + { + def.faceTextures = null; + } + + if (!var2) + { + def.faceRenderTypes = null; + } + + } + + void decodeType1(ModelDefinition def, byte[] var1) + { + InputStream var2 = new InputStream(var1); + InputStream var3 = new InputStream(var1); + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var2.setOffset(var1.length - 23); + int var9 = var2.readUnsignedShort(); + int var10 = var2.readUnsignedShort(); + int var11 = var2.readUnsignedByte(); + int var12 = var2.readUnsignedByte(); + int var13 = var2.readUnsignedByte(); + int var14 = var2.readUnsignedByte(); + int var15 = var2.readUnsignedByte(); + int var16 = var2.readUnsignedByte(); + int var17 = var2.readUnsignedByte(); + int var18 = var2.readUnsignedShort(); + int var19 = var2.readUnsignedShort(); + int var20 = var2.readUnsignedShort(); + int var21 = var2.readUnsignedShort(); + int var22 = var2.readUnsignedShort(); + int var23 = 0; + int var24 = 0; + int var25 = 0; + int var26; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + var2.setOffset(0); + + for (var26 = 0; var26 < var11; ++var26) + { + byte var27 = def.textureRenderTypes[var26] = var2.readByte(); + if (var27 == 0) + { + ++var23; + } + + if (var27 >= 1 && var27 <= 3) + { + ++var24; + } + + if (var27 == 2) + { + ++var25; + } + } + } + + var26 = var11 + var9; + int var56 = var26; + if (var12 == 1) + { + var26 += var10; + } + + int var28 = var26; + var26 += var10; + int var29 = var26; + if (var13 == 255) + { + var26 += var10; + } + + int var30 = var26; + if (var15 == 1) + { + var26 += var10; + } + + int var31 = var26; + if (var17 == 1) + { + var26 += var9; + } + + int var32 = var26; + if (var14 == 1) + { + var26 += var10; + } + + int var33 = var26; + var26 += var21; + int var34 = var26; + if (var16 == 1) + { + var26 += var10 * 2; + } + + int var35 = var26; + var26 += var22; + int var36 = var26; + var26 += var10 * 2; + int var37 = var26; + var26 += var18; + int var38 = var26; + var26 += var19; + int var39 = var26; + var26 += var20; + int var40 = var26; + var26 += var23 * 6; + int var41 = var26; + var26 += var24 * 6; + int var42 = var26; + var26 += var24 * 6; + int var43 = var26; + var26 += var24 * 2; + int var44 = var26; + var26 += var24; + int var45 = var26; + var26 = var26 + var24 * 2 + var25 * 2; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var17 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + if (var16 == 1) + { + def.faceTextures = new short[var10]; + } + + if (var16 == 1 && var11 > 0) + { + def.textureCoords = new byte[var10]; + } + + def.faceColors = new short[var10]; + if (var11 > 0) + { + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + var2.setOffset(var11); + var3.setOffset(var37); + var4.setOffset(var38); + var5.setOffset(var39); + var6.setOffset(var31); + int var46 = 0; + int var47 = 0; + int var48 = 0; + + int var49; + int var50; + int var51; + int var52; + int var53; + for (var49 = 0; var49 < var9; ++var49) + { + var50 = var2.readUnsignedByte(); + var51 = 0; + if ((var50 & 1) != 0) + { + var51 = var3.readShortSmart(); + } + + var52 = 0; + if ((var50 & 2) != 0) + { + var52 = var4.readShortSmart(); + } + + var53 = 0; + if ((var50 & 4) != 0) + { + var53 = var5.readShortSmart(); + } + + def.vertexX[var49] = var46 + var51; + def.vertexY[var49] = var47 + var52; + def.vertexZ[var49] = var48 + var53; + var46 = def.vertexX[var49]; + var47 = def.vertexY[var49]; + var48 = def.vertexZ[var49]; + if (var17 == 1) + { + def.packedVertexGroups[var49] = var6.readUnsignedByte(); + } + } + + var2.setOffset(var36); + var3.setOffset(var56); + var4.setOffset(var29); var5.setOffset(var32); + var6.setOffset(var30); + var7.setOffset(var34); + var8.setOffset(var35); - for (var7 = 0; var7 < var12; ++var7) + for (var49 = 0; var49 < var10; ++var49) { - model.textureRenderTypes[var7] = 0; - model.textureTriangleVertexIndices1[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices2[var7] = (short) var5.readUnsignedShort(); - model.textureTriangleVertexIndices3[var7] = (short) var5.readUnsignedShort(); + def.faceColors[var49] = (short) var2.readUnsignedShort(); + if (var12 == 1) + { + def.faceRenderTypes[var49] = var3.readByte(); + } + + if (var13 == 255) + { + def.faceRenderPriorities[var49] = var4.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var49] = var5.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var49] = var6.readUnsignedByte(); + } + + if (var16 == 1) + { + def.faceTextures[var49] = (short) (var7.readUnsignedShort() - 1); + } + + if (def.textureCoords != null && def.faceTextures[var49] != -1) + { + def.textureCoords[var49] = (byte) (var8.readUnsignedByte() - 1); + } } - if (model.textureCoordinates != null) + var2.setOffset(var33); + var3.setOffset(var28); + var49 = 0; + var50 = 0; + var51 = 0; + var52 = 0; + + int var54; + for (var53 = 0; var53 < var10; ++var53) + { + var54 = var3.readUnsignedByte(); + if (var54 == 1) + { + var49 = var2.readShortSmart() + var52; + var50 = var2.readShortSmart() + var49; + var51 = var2.readShortSmart() + var50; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 2) + { + var50 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 3) + { + var49 = var51; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var50; + def.faceIndices3[var53] = var51; + } + + if (var54 == 4) + { + int var55 = var49; + var49 = var50; + var50 = var55; + var51 = var2.readShortSmart() + var52; + var52 = var51; + def.faceIndices1[var53] = var49; + def.faceIndices2[var53] = var55; + def.faceIndices3[var53] = var51; + } + } + + var2.setOffset(var40); + var3.setOffset(var41); + var4.setOffset(var42); + var5.setOffset(var43); + var6.setOffset(var44); + var7.setOffset(var45); + + for (var53 = 0; var53 < var11; ++var53) + { + var54 = def.textureRenderTypes[var53] & 255; + if (var54 == 0) + { + def.texIndices1[var53] = (short) var2.readUnsignedShort(); + def.texIndices2[var53] = (short) var2.readUnsignedShort(); + def.texIndices3[var53] = (short) var2.readUnsignedShort(); + } + } + + var2.setOffset(var26); + var53 = var2.readUnsignedByte(); + if (var53 != 0) + { + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readUnsignedShort(); + var2.readInt(); + } + + } + + void decodeOldFormat(ModelDefinition def, byte[] var1) + { + boolean var2 = false; + boolean var3 = false; + InputStream var4 = new InputStream(var1); + InputStream var5 = new InputStream(var1); + InputStream var6 = new InputStream(var1); + InputStream var7 = new InputStream(var1); + InputStream var8 = new InputStream(var1); + var4.setOffset(var1.length - 18); + int var9 = var4.readUnsignedShort(); + int var10 = var4.readUnsignedShort(); + int var11 = var4.readUnsignedByte(); + int var12 = var4.readUnsignedByte(); + int var13 = var4.readUnsignedByte(); + int var14 = var4.readUnsignedByte(); + int var15 = var4.readUnsignedByte(); + int var16 = var4.readUnsignedByte(); + int var17 = var4.readUnsignedShort(); + int var18 = var4.readUnsignedShort(); + int var19 = var4.readUnsignedShort(); + int var20 = var4.readUnsignedShort(); + byte var21 = 0; + int var22 = var21 + var9; + int var23 = var22; + var22 += var10; + int var24 = var22; + if (var13 == 255) + { + var22 += var10; + } + + int var25 = var22; + if (var15 == 1) + { + var22 += var10; + } + + int var26 = var22; + if (var12 == 1) + { + var22 += var10; + } + + int var27 = var22; + if (var16 == 1) + { + var22 += var9; + } + + int var28 = var22; + if (var14 == 1) + { + var22 += var10; + } + + int var29 = var22; + var22 += var20; + int var30 = var22; + var22 += var10 * 2; + int var31 = var22; + var22 += var11 * 6; + int var32 = var22; + var22 += var17; + int var33 = var22; + var22 += var18; + int var10000 = var22 + var19; + def.vertexCount = var9; + def.faceCount = var10; + def.numTextureFaces = var11; + def.vertexX = new int[var9]; + def.vertexY = new int[var9]; + def.vertexZ = new int[var9]; + def.faceIndices1 = new int[var10]; + def.faceIndices2 = new int[var10]; + def.faceIndices3 = new int[var10]; + if (var11 > 0) + { + def.textureRenderTypes = new byte[var11]; + def.texIndices1 = new short[var11]; + def.texIndices2 = new short[var11]; + def.texIndices3 = new short[var11]; + } + + if (var16 == 1) + { + def.packedVertexGroups = new int[var9]; + } + + if (var12 == 1) + { + def.faceRenderTypes = new byte[var10]; + def.textureCoords = new byte[var10]; + def.faceTextures = new short[var10]; + } + + if (var13 == 255) + { + def.faceRenderPriorities = new byte[var10]; + } + else + { + def.priority = (byte) var13; + } + + if (var14 == 1) + { + def.faceTransparencies = new byte[var10]; + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups = new int[var10]; + } + + def.faceColors = new short[var10]; + var4.setOffset(var21); + var5.setOffset(var32); + var6.setOffset(var33); + var7.setOffset(var22); + var8.setOffset(var27); + int var35 = 0; + int var36 = 0; + int var37 = 0; + + int var38; + int var39; + int var40; + int var41; + int var42; + for (var38 = 0; var38 < var9; ++var38) + { + var39 = var4.readUnsignedByte(); + var40 = 0; + if ((var39 & 1) != 0) + { + var40 = var5.readShortSmart(); + } + + var41 = 0; + if ((var39 & 2) != 0) + { + var41 = var6.readShortSmart(); + } + + var42 = 0; + if ((var39 & 4) != 0) + { + var42 = var7.readShortSmart(); + } + + def.vertexX[var38] = var35 + var40; + def.vertexY[var38] = var36 + var41; + def.vertexZ[var38] = var37 + var42; + var35 = def.vertexX[var38]; + var36 = def.vertexY[var38]; + var37 = def.vertexZ[var38]; + if (var16 == 1) + { + def.packedVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var30); + var5.setOffset(var26); + var6.setOffset(var24); + var7.setOffset(var28); + var8.setOffset(var25); + + for (var38 = 0; var38 < var10; ++var38) + { + def.faceColors[var38] = (short) var4.readUnsignedShort(); + if (var12 == 1) + { + var39 = var5.readUnsignedByte(); + if ((var39 & 1) == 1) + { + def.faceRenderTypes[var38] = 1; + var2 = true; + } + else + { + def.faceRenderTypes[var38] = 0; + } + + if ((var39 & 2) == 2) + { + def.textureCoords[var38] = (byte) (var39 >> 2); + def.faceTextures[var38] = def.faceColors[var38]; + def.faceColors[var38] = 127; + if (def.faceTextures[var38] != -1) + { + var3 = true; + } + } + else + { + def.textureCoords[var38] = -1; + def.faceTextures[var38] = -1; + } + } + + if (var13 == 255) + { + def.faceRenderPriorities[var38] = var6.readByte(); + } + + if (var14 == 1) + { + def.faceTransparencies[var38] = var7.readByte(); + } + + if (var15 == 1) + { + def.packedTransparencyVertexGroups[var38] = var8.readUnsignedByte(); + } + } + + var4.setOffset(var29); + var5.setOffset(var23); + var38 = 0; + var39 = 0; + var40 = 0; + var41 = 0; + + int var43; + int var44; + for (var42 = 0; var42 < var10; ++var42) + { + var43 = var5.readUnsignedByte(); + if (var43 == 1) + { + var38 = var4.readShortSmart() + var41; + var39 = var4.readShortSmart() + var38; + var40 = var4.readShortSmart() + var39; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 2) + { + var39 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 3) + { + var38 = var40; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var39; + def.faceIndices3[var42] = var40; + } + + if (var43 == 4) + { + var44 = var38; + var38 = var39; + var39 = var44; + var40 = var4.readShortSmart() + var41; + var41 = var40; + def.faceIndices1[var42] = var38; + def.faceIndices2[var42] = var44; + def.faceIndices3[var42] = var40; + } + } + + var4.setOffset(var31); + + for (var42 = 0; var42 < var11; ++var42) + { + def.textureRenderTypes[var42] = 0; + def.texIndices1[var42] = (short) var4.readUnsignedShort(); + def.texIndices2[var42] = (short) var4.readUnsignedShort(); + def.texIndices3[var42] = (short) var4.readUnsignedShort(); + } + + if (def.textureCoords != null) { boolean var45 = false; - for (var22 = 0; var22 < var11; ++var22) + for (var43 = 0; var43 < var10; ++var43) { - var21 = model.textureCoordinates[var22] & 255; - if (var21 != 255) + var44 = def.textureCoords[var43] & 255; + if (var44 != 255) { - if ((model.textureTriangleVertexIndices1[var21] & '\uffff') == model.faceVertexIndices1[var22] && (model.textureTriangleVertexIndices2[var21] & '\uffff') == model.faceVertexIndices2[var22] && (model.textureTriangleVertexIndices3[var21] & '\uffff') == model.faceVertexIndices3[var22]) + if (def.faceIndices1[var43] == (def.texIndices1[var44] & '\uffff') && def.faceIndices2[var43] == (def.texIndices2[var44] & '\uffff') && def.faceIndices3[var43] == (def.texIndices3[var44] & '\uffff')) { - model.textureCoordinates[var22] = -1; + def.textureCoords[var43] = -1; } else { @@ -732,19 +1394,19 @@ public class ModelLoader if (!var45) { - model.textureCoordinates = null; + def.textureCoords = null; } } - if (!var43) + if (!var3) { - model.faceTextures = null; + def.faceTextures = null; } if (!var2) { - model.faceRenderTypes = null; + def.faceRenderTypes = null; } - } + } } diff --git a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java index dc8922535e..3898850920 100644 --- a/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java +++ b/cache/src/main/java/net/runelite/cache/item/ItemSpriteFactory.java @@ -227,22 +227,22 @@ public class ItemSpriteFactory litModel.field1856 = new int[def.faceCount]; litModel.field1854 = new int[def.faceCount]; litModel.field1823 = new int[def.faceCount]; - if (def.textureTriangleCount > 0 && def.textureCoordinates != null) + if (def.numTextureFaces > 0 && def.textureCoords != null) { - int[] var9 = new int[def.textureTriangleCount]; + int[] var9 = new int[def.numTextureFaces]; int var10; for (var10 = 0; var10 < def.faceCount; ++var10) { - if (def.textureCoordinates[var10] != -1) + if (def.textureCoords[var10] != -1) { - ++var9[def.textureCoordinates[var10] & 255]; + ++var9[def.textureCoords[var10] & 255]; } } litModel.field1852 = 0; - for (var10 = 0; var10 < def.textureTriangleCount; ++var10) + for (var10 = 0; var10 < def.numTextureFaces; ++var10) { if (var9[var10] > 0 && def.textureRenderTypes[var10] == 0) { @@ -256,13 +256,13 @@ public class ItemSpriteFactory var10 = 0; - for (int i = 0; i < def.textureTriangleCount; ++i) + for (int i = 0; i < def.numTextureFaces; ++i) { if (var9[i] > 0 && def.textureRenderTypes[i] == 0) { - litModel.field1844[var10] = def.textureTriangleVertexIndices1[i] & '\uffff'; - litModel.field1865[var10] = def.textureTriangleVertexIndices2[i] & '\uffff'; - litModel.field1846[var10] = def.textureTriangleVertexIndices3[i] & '\uffff'; + litModel.field1844[var10] = def.texIndices1[i] & '\uffff'; + litModel.field1865[var10] = def.texIndices2[i] & '\uffff'; + litModel.field1846[var10] = def.texIndices3[i] & '\uffff'; var9[i] = var10++; } else @@ -275,9 +275,9 @@ public class ItemSpriteFactory for (int i = 0; i < def.faceCount; ++i) { - if (def.textureCoordinates[i] != -1) + if (def.textureCoords[i] != -1) { - litModel.field1840[i] = (byte) var9[def.textureCoordinates[i] & 255]; + litModel.field1840[i] = (byte) var9[def.textureCoords[i] & 255]; } else { @@ -299,13 +299,13 @@ public class ItemSpriteFactory } byte faceAlpha; - if (def.faceAlphas == null) + if (def.faceTransparencies == null) { faceAlpha = 0; } else { - faceAlpha = def.faceAlphas[faceIdx]; + faceAlpha = def.faceTransparencies[faceIdx]; } short faceTexture; @@ -355,15 +355,15 @@ public class ItemSpriteFactory else { int var15 = def.faceColors[faceIdx] & '\uffff'; - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = method2608(var15, tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = method2608(var15, tmp); @@ -385,15 +385,15 @@ public class ItemSpriteFactory } else { - vertexNormal = def.vertexNormals[def.faceVertexIndices1[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices1[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1856[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices2[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices2[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1854[faceIdx] = bound2to126(tmp); - vertexNormal = def.vertexNormals[def.faceVertexIndices3[faceIdx]]; + vertexNormal = def.vertexNormals[def.faceIndices3[faceIdx]]; tmp = (y * vertexNormal.y + z * vertexNormal.z + x * vertexNormal.x) / (var7 * vertexNormal.magnitude) + ambient; litModel.field1823[faceIdx] = bound2to126(tmp); @@ -401,15 +401,15 @@ public class ItemSpriteFactory } litModel.verticesCount = def.vertexCount; - litModel.verticesX = def.vertexPositionsX; - litModel.verticesY = def.vertexPositionsY; - litModel.verticesZ = def.vertexPositionsZ; + litModel.verticesX = def.vertexX; + litModel.verticesY = def.vertexY; + litModel.verticesZ = def.vertexZ; litModel.indicesCount = def.faceCount; - litModel.indices1 = def.faceVertexIndices1; - litModel.indices2 = def.faceVertexIndices2; - litModel.indices3 = def.faceVertexIndices3; + litModel.indices1 = def.faceIndices1; + litModel.indices2 = def.faceIndices2; + litModel.indices3 = def.faceIndices3; litModel.field1838 = def.faceRenderPriorities; - litModel.field1882 = def.faceAlphas; + litModel.field1882 = def.faceTransparencies; litModel.field1842 = def.priority; litModel.field1841 = def.faceTextures; return litModel; diff --git a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java index fb65f99972..75b67f689f 100644 --- a/cache/src/main/java/net/runelite/cache/models/ObjExporter.java +++ b/cache/src/main/java/net/runelite/cache/models/ObjExporter.java @@ -53,9 +53,9 @@ public class ObjExporter for (int i = 0; i < model.vertexCount; ++i) { - objWriter.println("v " + model.vertexPositionsX[i] + " " - + model.vertexPositionsY[i] * -1 + " " - + model.vertexPositionsZ[i] * -1); + objWriter.println("v " + model.vertexX[i] + " " + + model.vertexY[i] * -1 + " " + + model.vertexZ[i] * -1); } if (model.faceTextures != null) @@ -78,9 +78,9 @@ public class ObjExporter for (int i = 0; i < model.faceCount; ++i) { - int x = model.faceVertexIndices1[i] + 1; - int y = model.faceVertexIndices2[i] + 1; - int z = model.faceVertexIndices3[i] + 1; + int x = model.faceIndices1[i] + 1; + int y = model.faceIndices2[i] + 1; + int z = model.faceIndices3[i] + 1; objWriter.println("usemtl m" + i); if (model.faceTextures != null) @@ -129,9 +129,9 @@ public class ObjExporter int alpha = 0; - if (model.faceAlphas != null) + if (model.faceTransparencies != null) { - alpha = model.faceAlphas[i] & 0xFF; + alpha = model.faceTransparencies[i] & 0xFF; } if (alpha != 0) diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java index 98326c0972..4fc7513a64 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/CheckCast.java @@ -47,6 +47,13 @@ public class CheckCast extends Instruction implements TypeInstruction super(instructions, InstructionType.CHECKCAST); } + public CheckCast(Instructions instructions, Type type) + { + super(instructions, InstructionType.CHECKCAST); + + this.type = type; + } + public CheckCast(Instructions instructions, InstructionType type) { super(instructions, type); diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java deleted file mode 100644 index c2ab3407a1..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2017. l2- - * 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.hiscore; - -import java.util.Objects; - -public class SingleHiscoreSkillResult -{ - private String player; - private String skillName; - private Skill skill; - - public String getPlayer() - { - return player; - } - - public void setPlayer(String player) - { - this.player = player; - } - - public String getSkillName() - { - return skillName; - } - - public void setSkillName(String skillName) - { - this.skillName = skillName; - } - - public Skill getSkill() - { - return skill; - } - - public void setSkill(Skill skill) - { - this.skill = skill; - } - - @Override - public int hashCode() - { - int hash = 7; - hash = 37 * hash + Objects.hashCode(this.player); - hash = 37 * hash + Objects.hashCode(this.skillName); - hash = 37 * hash + Objects.hashCode(this.skill); - return hash; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - final SingleHiscoreSkillResult other = (SingleHiscoreSkillResult) obj; - if (!Objects.equals(this.player, other.player)) - { - return false; - } - if (!Objects.equals(this.skillName, other.skillName)) - { - return false; - } - if (!Objects.equals(this.skill, other.skill)) - { - return false; - } - return true; - } - - @Override - public String toString() - { - return "SingleHiscoreSkillResult{" + "player=" + player + ", skillName=" + skillName + ", skill=" + skill + '}'; - } -} diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java b/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java deleted file mode 100644 index 7bd1706cf4..0000000000 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeClient.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018, AeonLucid - * 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.osbuddy; - -import com.google.gson.JsonParseException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -@Slf4j -@AllArgsConstructor -public class OSBGrandExchangeClient -{ - private final OkHttpClient client; - - public OSBGrandExchangeResult lookupItem(int itemId) throws IOException - { - final HttpUrl url = RuneLiteAPI.getApiBase().newBuilder() - .addPathSegment("osb") - .addPathSegment("ge") - .addQueryParameter("itemId", Integer.toString(itemId)) - .build(); - - log.debug("Built URI: {}", url); - - final Request request = new Request.Builder() - .url(url) - .build(); - - try (final Response response = client.newCall(request).execute()) - { - if (!response.isSuccessful()) - { - throw new IOException("Error looking up item id: " + response); - } - - final InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), OSBGrandExchangeResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } - } -} diff --git a/injector/src/main/java/com/openosrs/injector/InjectUtil.java b/injector/src/main/java/com/openosrs/injector/InjectUtil.java index d8c9fbd7c2..f4ff0ff3ac 100644 --- a/injector/src/main/java/com/openosrs/injector/InjectUtil.java +++ b/injector/src/main/java/com/openosrs/injector/InjectUtil.java @@ -13,6 +13,7 @@ import static com.openosrs.injector.rsapi.RSApi.RL_API_BASE; import com.openosrs.injector.rsapi.RSApiClass; import com.openosrs.injector.rsapi.RSApiMethod; import java.util.List; +import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -340,6 +341,11 @@ public interface InjectUtil } static Type apiToDeob(InjectData data, Type api) + { + return apiToDeob(data, api, null); + } + + static Type apiToDeob(InjectData data, Type api, Type deobType) { if (api.isPrimitive()) { @@ -354,29 +360,43 @@ public interface InjectUtil else if (internalName.startsWith(RL_API_BASE)) { Class rlApiC = new Class(internalName); - RSApiClass highestKnown = data.getRsApi().withInterface(rlApiC); + Set allClasses = data.getRsApi().withInterface(rlApiC); // Cheeky unchecked exception - assert highestKnown != null : "No rs api class implements rl api class " + rlApiC.toString(); + assert allClasses.size() > 0 : "No rs api class implements rl api class " + rlApiC.toString(); - boolean changed; - do + if (allClasses.size() == 1) { - changed = false; - - for (RSApiClass interf : highestKnown.getApiInterfaces()) + RSApiClass highestKnown = allClasses.stream().findFirst().get(); + boolean changed; + do { - if (interf.getInterfaces().contains(rlApiC)) + changed = false; + + for (RSApiClass interf : highestKnown.getApiInterfaces()) { - highestKnown = interf; - changed = true; - break; + if (interf.getInterfaces().contains(rlApiC)) + { + highestKnown = interf; + changed = true; + break; + } + } + } + while (changed); + + return apiToDeob(data, Type.getType(highestKnown.getName(), api.getDimensions())); + } + else + { + for (RSApiClass rsApiClass : allClasses) + { + if (rsApiClass.getName().contains(deobType.getInternalName())) + { + return apiToDeob(data, Type.getType(rsApiClass.getName(), api.getDimensions())); } } } - while (changed); - - return apiToDeob(data, Type.getType(highestKnown.getName(), api.getDimensions())); } return api; diff --git a/injector/src/main/java/com/openosrs/injector/Injector.java b/injector/src/main/java/com/openosrs/injector/Injector.java index 5216adae21..2264ff15f1 100644 --- a/injector/src/main/java/com/openosrs/injector/Injector.java +++ b/injector/src/main/java/com/openosrs/injector/Injector.java @@ -23,7 +23,8 @@ import com.openosrs.injector.injectors.raw.Occluder; import com.openosrs.injector.injectors.raw.RasterizerAlpha; import com.openosrs.injector.injectors.raw.RenderDraw; import com.openosrs.injector.injectors.raw.CopyRuneLiteClasses; -import com.openosrs.injector.injectors.raw.RuneLiteIterableHashTable; +import com.openosrs.injector.injectors.raw.RuneLiteIterables; +import com.openosrs.injector.injectors.raw.RuneliteMenuEntry; import com.openosrs.injector.injectors.raw.RuneliteObject; import com.openosrs.injector.injectors.raw.ScriptVM; import com.openosrs.injector.rsapi.RSApi; @@ -117,7 +118,7 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new CopyRuneLiteClasses(this)); - inject(new RuneLiteIterableHashTable(this)); + inject(new RuneLiteIterables(this)); inject(new RuneliteObject(this)); @@ -150,6 +151,8 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new AddPlayerToMenu(this)); + inject(new RuneliteMenuEntry(this)); + validate(new InjectorValidator(this)); transform(new SourceChanger(this)); diff --git a/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java b/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java index c469542463..fb02f3079e 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java @@ -131,7 +131,7 @@ public class RSApiInjector extends AbstractInjector } else if (sig.size() == 0) { - Type type = InjectUtil.apiToDeob(inject, sig.getReturnValue()); + Type type = InjectUtil.apiToDeob(inject, sig.getReturnValue(), deobType); if (deobType.equals(type)) { continue; diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java index 72fdf81ea4..9296d10b8f 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java @@ -19,6 +19,7 @@ import net.runelite.asm.Type; import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.CheckCast; import net.runelite.asm.attributes.code.instructions.GetField; import net.runelite.asm.attributes.code.instructions.GetStatic; import net.runelite.asm.attributes.code.instructions.InvokeSpecial; @@ -35,7 +36,10 @@ public class CopyRuneLiteClasses extends AbstractInjector { private static final List RUNELITE_OBJECTS = List.of( "RuneLiteObject", - "RuneLiteIterableHashTable" + "RuneLiteIterableLinkDeque", + "RuneLiteIterableNodeDeque", + "RuneLiteIterableNodeHashTable", + "RuneLiteMenuEntry" ); public CopyRuneLiteClasses(InjectData inject) @@ -226,6 +230,11 @@ public class CopyRuneLiteClasses extends AbstractInjector iterator.set(new New(ins, inject.toVanilla(deobClass))); } } + else if (i instanceof CheckCast) + { + CheckCast clazz = ((CheckCast) i); + iterator.set(new CheckCast(ins, getObfuscatedSignature(clazz.getType_()))); + } } } } diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java deleted file mode 100644 index a8c63dd97b..0000000000 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2021, Owain van Brakel - * All rights reserved. - * - * This code is licensed under GPL3, see the complete license in - * the LICENSE file in the root directory of this submodule. - */ -package com.openosrs.injector.injectors.raw; - -import com.openosrs.injector.injection.InjectData; -import com.openosrs.injector.injectors.AbstractInjector; -import java.util.List; -import net.runelite.asm.ClassFile; -import net.runelite.asm.Method; -import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.code.Instruction; -import net.runelite.asm.attributes.code.InstructionType; -import net.runelite.asm.attributes.code.Instructions; -import net.runelite.asm.attributes.code.instructions.ALoad; -import net.runelite.asm.attributes.code.instructions.Dup; -import net.runelite.asm.attributes.code.instructions.InvokeSpecial; -import net.runelite.asm.attributes.code.instructions.New; -import net.runelite.asm.attributes.code.instructions.Return; -import net.runelite.asm.signature.Signature; - -public class RuneLiteIterableHashTable extends AbstractInjector -{ - private static final String RUNELITE_ITERABLE_HASHTABLE = "RuneLiteIterableHashTable"; - - public RuneLiteIterableHashTable(InjectData inject) - { - super(inject); - } - - public void inject() - { - ClassFile runeliteIterableHashTableVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_HASHTABLE); - - final ClassFile nodeHashTableVanilla = inject.toVanilla( - inject.getDeobfuscated() - .findClass("NodeHashTable") - ); - - Method copy = new Method(nodeHashTableVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); - copy.setPublic(); - - final Code code = new Code(copy); - code.setMaxStack(3); - copy.setCode(code); - nodeHashTableVanilla.addMethod(copy); - - final Instructions instructions = code.getInstructions(); - final List ins = instructions.getInstructions(); - - ins.add(new New(instructions, runeliteIterableHashTableVanilla.getPoolClass())); - ins.add(new Dup(instructions)); - ins.add(new ALoad(instructions, 0)); - ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableHashTableVanilla.getPoolClass(), "", new Signature("(L" + nodeHashTableVanilla.getName() + ";)V")))); - ins.add(new Return(instructions, InstructionType.ARETURN)); - } -} diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java new file mode 100644 index 0000000000..42fc49f5da --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterables.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.InstructionType; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.ALoad; +import net.runelite.asm.attributes.code.instructions.Dup; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.Return; +import net.runelite.asm.signature.Signature; + +public class RuneLiteIterables extends AbstractInjector +{ + private static final String RUNELITE_ITERABLE_HASHTABLE = "RuneLiteIterableNodeHashTable"; + private static final String RUNELITE_ITERABLE_NODE_DEQUE = "RuneLiteIterableNodeDeque"; + private static final String RUNELITE_ITERABLE_LINK_DEQUE = "RuneLiteIterableLinkDeque"; + + public RuneLiteIterables(InjectData inject) + { + super(inject); + } + + public void inject() + { + injectHashTable(); + injectNodeDeque(); + injectLinkDeque(); + } + + public void injectHashTable() + { + ClassFile runeliteIterableHashTableVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_HASHTABLE); + + final ClassFile nodeHashTableVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass(RUNELITE_ITERABLE_HASHTABLE.replace("RuneLiteIterable", "")) + ); + + Method copy = new Method(nodeHashTableVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + nodeHashTableVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableHashTableVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableHashTableVanilla.getPoolClass(), "", new Signature("(L" + nodeHashTableVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + public void injectNodeDeque() + { + ClassFile runeliteIterableNodeDequeVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_NODE_DEQUE); + + final ClassFile nodeDequeVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass(RUNELITE_ITERABLE_NODE_DEQUE.replace("RuneLiteIterable", "")) + ); + + Method copy = new Method(nodeDequeVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + nodeDequeVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableNodeDequeVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableNodeDequeVanilla.getPoolClass(), "", new Signature("(L" + nodeDequeVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + public void injectLinkDeque() + { + ClassFile runeliteIterableLinkDequeVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_LINK_DEQUE); + + final ClassFile linkDequeVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass(RUNELITE_ITERABLE_LINK_DEQUE.replace("RuneLiteIterable", "")) + ); + + Method copy = new Method(linkDequeVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + linkDequeVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableLinkDequeVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableLinkDequeVanilla.getPoolClass(), "", new Signature("(L" + linkDequeVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } +} diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java new file mode 100644 index 0000000000..fe67fb85a3 --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteMenuEntry.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.InjectUtil; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import java.util.ListIterator; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.InstructionType; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.BAStore; +import net.runelite.asm.attributes.code.instructions.Dup; +import net.runelite.asm.attributes.code.instructions.ILoad; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.InvokeStatic; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.Return; +import net.runelite.asm.signature.Signature; + +public class RuneliteMenuEntry extends AbstractInjector +{ + private static final String RUNELITE_MENU_ENTRY = "RuneLiteMenuEntry"; + + public RuneliteMenuEntry(InjectData inject) + { + super(inject); + } + + public void inject() + { + addInvoke(); + addSwap(InjectUtil.findMethod(inject, "incrementMenuEntries")); + addSwap(InjectUtil.findMethod(inject, "decrementMenuEntries")); + } + + private void addInvoke() + { + ClassFile runeliteMenuEntryVanilla = inject.vanilla.findClass(RUNELITE_MENU_ENTRY); + + final ClassFile clientVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("Client") + ); + + Method copy = clientVanilla.findMethod("newRuneliteMenuEntry"); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteMenuEntryVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ILoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteMenuEntryVanilla.getPoolClass(), "", new Signature("(I)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } + + private void addSwap(Method method) + { + final ClassFile clientVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("Client") + ); + + Instructions ins = method.getCode().getInstructions(); + ListIterator iterator = ins.getInstructions().listIterator(); + while (iterator.hasNext()) + { + Instruction i = iterator.next(); + + if (!(i instanceof BAStore)) + { + continue; + } + + ILoad i1 = new ILoad(ins, 2); + InvokeStatic i2 = new InvokeStatic(ins, new net.runelite.asm.pool.Method(clientVanilla.getPoolClass(), "swapMenuEntries", new Signature("(I)V"))); + + iterator.add(i1); + iterator.add(i2); + + return; + } + } +} diff --git a/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java b/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java index def5997c75..cbcbdf9744 100644 --- a/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java +++ b/injector/src/main/java/com/openosrs/injector/rsapi/RSApi.java @@ -15,8 +15,10 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import lombok.Getter; import lombok.NoArgsConstructor; import net.runelite.asm.Type; @@ -111,23 +113,19 @@ public class RSApi implements Iterable return findClass(name) != null; } - public RSApiClass withInterface(Class interf) + public Set withInterface(Class interf) { - RSApiClass clazz = findClass(interf.getName()); - if (clazz != null) - { - return clazz; - } + Set classes = new HashSet<>(); for (RSApiClass apiC : this) { if (apiC.getInterfaces().contains(interf)) { - return apiC; + classes.add(apiC); } } - return null; + return classes; } @NotNull 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 080f6443a1..318deaf0f8 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -636,6 +636,13 @@ public interface Client extends GameEngine */ World[] getWorldList(); + /** + * Create a new menu entry + * @param idx the index to create the menu entry at. Accepts negative indexes eg. -1 inserts at the end. + * @return the newly created menu entry + */ + MenuEntry createMenuEntry(int idx); + /** * Gets an array of currently open right-click menu entries that can be * clicked and activated. @@ -1133,7 +1140,7 @@ public interface Client extends GameEngine * @param id the ID of the animation. Any int is allowed, but implementations in the client * should be defined in {@link AnimationID} */ - Sequence loadAnimation(int id); + Animation loadAnimation(int id); /** * Gets the music volume @@ -1341,7 +1348,7 @@ public interface Client extends GameEngine /** * Retrieve the nameable container containing friends */ - NameableContainer getFriendContainer(); + FriendContainer getFriendContainer(); /** * Retrieve the nameable container containing ignores @@ -2117,24 +2124,6 @@ public interface Client extends GameEngine */ void scaleSprite(int[] canvas, int[] pixels, int color, int pixelX, int pixelY, int canvasIdx, int canvasOffset, int newWidth, int newHeight, int pixelWidth, int pixelHeight, int oldWidth); - /** - * Get the MenuEntry at client.getMenuOptionCount() - 1 - *

- * This is useful so you don't have to use getMenuEntries, - * which will create a big array, when you only want to change - * the left click one. - */ - MenuEntry getLeftClickMenuEntry(); - - /** - * Set the MenuEntry at client.getMenuOptionCount() - 1 - *

- * This is useful so you don't have to use setMenuEntries, - * which will arraycopy a big array to several smaller arrays lol, - * when you only want to change the left click one. - */ - void setLeftClickMenuEntry(MenuEntry entry); - /** * If this field is set to true, getting 5 minute logged won't show * the "You have been disconnected." message anymore. diff --git a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java similarity index 80% rename from http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java rename to runelite-api/src/main/java/net/runelite/api/FriendContainer.java index 13e5f5e8e4..b288db028b 100644 --- a/http-api/src/main/java/net/runelite/http/api/osbuddy/OSBGrandExchangeResult.java +++ b/runelite-api/src/main/java/net/runelite/api/FriendContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, AeonLucid + * Copyright (c) 2021, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,17 +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.http.api.osbuddy; +package net.runelite.api; -import java.time.Instant; -import lombok.Data; - -@Data -public class OSBGrandExchangeResult +/** + * A nameable container of friends + */ +public interface FriendContainer extends NameableContainer { - private int item_id; - private int buy_average; - private int sell_average; - private int overall_average; - private Instant last_update; + /** + * Get the recent logins/logouts of friends from the last few seconds + * @return + */ + Deque getPendingLogins(); } 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 0e8673a66d..dcd48656ce 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -12206,11 +12206,11 @@ public final class ItemID public static final int NIHIL_SHARD = 26231; public static final int ANCIENT_GODSWORD = 26233; public static final int ZARYTE_VAMBRACES = 26235; - public static final int ZARYTE_BOW_UNCHARGED = 26237; - public static final int ZARYTE_BOW = 26239; + public static final int ZARYTE_BOW = 26237; + public static final int ZARYTE_BOW_26239 = 26239; public static final int VIRTUS_MASK = 26241; public static final int VIRTUS_ROBE_TOP = 26243; - public static final int VIRTUS_ROBE_LEGS = 26245; + public static final int VIRTUS_ROBE_BOTTOMS = 26245; public static final int PUMPKIN_PIE = 26247; public static final int JEREDS_EMPTY_WINE_BOTTLE = 26250; public static final int AD_COUPON = 26252; @@ -12222,5 +12222,67 @@ public final class ItemID public static final int STUDDED_BODY_26264 = 26264; public static final int CONDENSED_GOLD = 26266; public static final int GOLD_SINK = 26269; + public static final int FESTIVE_CINNAMON = 26270; + public static final int FESTIVE_HOLLY = 26272; + public static final int FESTIVE_WHITE_WINE = 26274; + public static final int NOTES_26276 = 26276; + public static final int MAGICAL_CLEANING_POTION = 26278; + public static final int PINK_STAINED_PLATEBODY = 26280; + public static final int PINK_STAINED_PLATELEGS = 26282; + public static final int PINK_STAINED_FULL_HELM = 26284; + public static final int CLEAN_PLATEBODY = 26286; + public static final int CLEAN_PLATELEGS = 26288; + public static final int CLEAN_FULL_HELM = 26290; + public static final int FESTIVE_GINGERBREAD_GNOMES = 26292; + public static final int FESTIVE_MULLED_WINE = 26294; + public static final int SNOW = 26296; + public static final int SECRET_SANTA_PRESENT = 26298; + public static final int SECRET_SANTA_PRESENT_26300 = 26300; + public static final int SECRET_SANTA_PRESENT_26302 = 26302; + public static final int CHOCOLATE_CHIPS = 26304; + public static final int CHOCOLATE_CHIPS_26306 = 26306; + public static final int A_BIG_PRESENT = 26308; + public static final int FESTIVE_ELF_SLIPPERS = 26310; + public static final int FESTIVE_ELF_HAT = 26312; + public static final int SNOWMAN_RING = 26314; + public static final int SECRET_SANTA_PRESENT_RED = 26316; + public static final int SECRET_SANTA_PRESENT_BLUE = 26318; + public static final int SECRET_SANTA_PRESENT_GREEN = 26320; + public static final int SECRET_SANTA_PRESENT_BLACK = 26322; + public static final int SECRET_SANTA_PRESENT_GOLD = 26324; + public static final int LITTLE_SNOWBALL = 26326; + public static final int SMALL_SNOWBALL = 26328; + public static final int NORMAL_SNOWBALL = 26330; + public static final int BIG_SNOWBALL = 26332; + public static final int LARGE_SNOWBALL = 26334; + public static final int HUGE_SNOWBALL = 26336; + public static final int HUMONGOUS_SNOWBALL = 26338; + public static final int ANCIENT_BREW4 = 26340; + public static final int ANCIENT_BREW3 = 26342; + public static final int ANCIENT_BREW2 = 26344; + public static final int ANCIENT_BREW1 = 26346; + public static final int NEXLING = 26348; + public static final int ANCIENT_MIX2 = 26350; + public static final int ANCIENT_MIX1 = 26353; + public static final int FROZEN_KEY_26356 = 26356; + public static final int FROZEN_KEY_PIECE_ARMADYL = 26358; + public static final int FROZEN_KEY_PIECE_BANDOS = 26360; + public static final int FROZEN_KEY_PIECE_ZAMORAK = 26362; + public static final int FROZEN_KEY_PIECE_SARADOMIN = 26364; + public static final int IMPORTANT_LETTER = 26366; + public static final int NIHIL_DUST = 26368; + public static final int ANCIENT_HILT = 26370; + public static final int NIHIL_HORN = 26372; + public static final int ZARYTE_CROSSBOW = 26374; + public static final int TORVA_FULL_HELM_DAMAGED = 26376; + public static final int TORVA_PLATEBODY_DAMAGED = 26378; + public static final int TORVA_PLATELEGS_DAMAGED = 26380; + public static final int TORVA_FULL_HELM = 26382; + public static final int TORVA_PLATEBODY = 26384; + public static final int TORVA_PLATELEGS = 26386; + public static final int ECUMENICAL_KEY_SHARD = 26388; + public static final int BLOOD_ESSENCE = 26390; + public static final int BLOOD_ESSENCE_ACTIVE = 26392; + public static final int BANDOSIAN_COMPONENTS = 26394; /* This file is automatically generated. Do not edit. */ } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 150d534de2..f0db11f095 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -24,141 +24,90 @@ */ package net.runelite.api; -import lombok.Data; -import lombok.NoArgsConstructor; +import java.util.function.Consumer; /** * A menu entry in a right-click menu. */ -@Data -@NoArgsConstructor -public class MenuEntry implements Cloneable +public interface MenuEntry { /** * The option text added to the menu. (ie. "Walk here", "Use") */ - private String option; + String getOption(); + MenuEntry setOption(String option); + /** * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. */ - private String target; + String getTarget(); + MenuEntry setTarget(String target); + /** * An identifier value for the target of the action. */ - private int identifier; + int getIdentifier(); + MenuEntry setIdentifier(int identifier); + /** * The action the entry will trigger. - * {@link MenuAction} */ - private int opcode; + MenuAction getType(); + MenuEntry setType(MenuAction type); + /** * An additional parameter for the action. */ - private int param0; + int getParam0(); + MenuEntry setParam0(int param0); + /** * A second additional parameter for the action. */ - private int param1; + int getParam1(); + MenuEntry setParam1(int param1); + /** - * If this field is true and you have single mouse button on and this entry is + * If this is true and you have single mouse button on and this entry is * the top entry the right click menu will not be opened when you left click * * This is used for shift click */ - private boolean forceLeftClick; - - public MenuEntry(String option, String target, int type, int opcode, int param0, int param1, boolean forceLeftClick) - { - this.option = option; - this.target = target; - this.identifier = type; - this.opcode = opcode; - this.param0 = param0; - this.param1 = param1; - this.forceLeftClick = forceLeftClick; - } - - @Override - public MenuEntry clone() - { - try - { - return (MenuEntry) super.clone(); - } - catch (CloneNotSupportedException ex) - { - throw new RuntimeException(ex); - } - } - - public void setActionParam0(int i) - { - this.param0 = i; - } - - public int getActionParam0() - { - return this.param0; - } - - public int getParam0() - { - return this.param0; - } - - public void setParam0(int i) - { - this.param0 = i; - } - - public void setParam1(int i) - { - this.param1 = i; - } - - public int getParam1() - { - return this.param1; - } - - public void setActionParam1(int i) - { - this.param1 = i; - } - - public int getActionParam1() - { - return this.param1; - } - - public void setType(int i) - { - this.opcode = i; - } - - public int getType() - { - return this.opcode; - } - - public void setId(int i) - { - this.identifier = i; - } - - public int getId() - { - return this.identifier; - } + boolean isForceLeftClick(); + MenuEntry setForceLeftClick(boolean forceLeftClick); /** - * Get opcode, but as it's enum counterpart + * Deprioritized menus are sorted in the menu to be below the other menu entries. + * @return */ - public MenuAction getMenuAction() - { - return MenuAction.of(getOpcode()); - } -} + boolean isDeprioritized(); + MenuEntry setDeprioritized(boolean deprioritized); + + /** + * Set a callback to be called when this menu option is clicked + * @param callback + * @return + */ + MenuEntry onClick(Consumer callback); + + @Deprecated + int getOpcode(); + @Deprecated + void setOpcode(int opcode); + + @Deprecated + int getActionParam0(); + @Deprecated + void setActionParam0(int param0); + + @Deprecated + int getActionParam1(); + @Deprecated + void setActionParam1(int param0); + + @Deprecated + MenuAction getMenuAction(); +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java index 871f7525cd..71338a968b 100644 --- a/runelite-api/src/main/java/net/runelite/api/Model.java +++ b/runelite-api/src/main/java/net/runelite/api/Model.java @@ -55,13 +55,13 @@ public interface Model extends Renderable int[] getVerticesZ(); - int getTrianglesCount(); + int getFaceCount(); - int[] getTrianglesX(); + int[] getFaceIndices1(); - int[] getTrianglesY(); + int[] getFaceIndices2(); - int[] getTrianglesZ(); + int[] getFaceIndices3(); int[] getFaceColors1(); @@ -69,7 +69,7 @@ public interface Model extends Renderable int[] getFaceColors3(); - byte[] getTriangleTransparencies(); + byte[] getFaceTransparencies(); int getSceneId(); void setSceneId(int sceneId); @@ -109,4 +109,9 @@ public interface Model extends Renderable int[] getVertexNormalsX(); int[] getVertexNormalsY(); int[] getVertexNormalsZ(); + + byte getOverrideAmount(); + byte getOverrideHue(); + byte getOverrideSaturation(); + byte getOverrideLuminance(); } 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 d07ffdbd55..cd8c383e63 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -9477,5 +9477,49 @@ public final class NpcID public static final int REGENT = 11229; public static final int GROUP_STORAGE_TUTOR = 11230; public static final int GROUP_IRON_TUTOR = 11231; + public static final int TINY_SNOWBALL = 11232; + public static final int MINI_SNOWBALL = 11233; + public static final int LITTLE_SNOWBALL = 11234; + public static final int SMALL_SNOWBALL = 11235; + public static final int NORMAL_SNOWBALL = 11236; + public static final int BIG_SNOWBALL = 11237; + public static final int LARGE_SNOWBALL = 11238; + public static final int HUGE_SNOWBALL = 11239; + public static final int HUMONGOUS_SNOWBALL = 11240; + public static final int BUOY = 11241; + public static final int GURL = 11242; + public static final int BUOY_11243 = 11243; + public static final int GURL_11244 = 11244; + public static final int HERQUIN_11245 = 11245; + public static final int CECILIA_11247 = 11247; + public static final int LARRY_11248 = 11248; + public static final int SANTAS_THRONE = 11249; + public static final int SANTA = 11250; + public static final int WAYNE_11251 = 11251; + public static final int WYSON_THE_GARDENER_11252 = 11252; + public static final int HAIRDRESSER_11254 = 11254; + public static final int SIR_VYVIN_11255 = 11255; + public static final int XI_PLZPETDOGZ_XIX = 11259; + public static final int DRAKE_11260 = 11260; + public static final int DUCK_11261 = 11261; + public static final int NEXLING = 11276; + public static final int NEXLING_11277 = 11277; + public static final int NEX = 11278; + public static final int NEX_11279 = 11279; + public static final int NEX_11280 = 11280; + public static final int NEX_11281 = 11281; + public static final int NEX_11282 = 11282; + public static final int FUMUS = 11283; + public static final int UMBRA = 11284; + public static final int CRUOR = 11285; + public static final int GLACIES = 11286; + public static final int MESSENGER = 11287; + public static final int ASHUELOT_REIS = 11288; + public static final int ASHUELOT_REIS_11289 = 11289; + public static final int SPIRITUAL_WARRIOR_11290 = 11290; + public static final int SPIRITUAL_RANGER_11291 = 11291; + public static final int SPIRITUAL_MAGE_11292 = 11292; + public static final int BLOOD_REAVER = 11293; + public static final int BLOOD_REAVER_11294 = 11294; /* 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 4ac8a346ad..3adbbe4a12 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -13837,5 +13837,69 @@ public final class NullItemID public static final int NULL_26265 = 26265; public static final int NULL_26267 = 26267; public static final int NULL_26268 = 26268; + public static final int NULL_26271 = 26271; + public static final int NULL_26273 = 26273; + public static final int NULL_26275 = 26275; + public static final int NULL_26277 = 26277; + public static final int NULL_26279 = 26279; + public static final int NULL_26281 = 26281; + public static final int NULL_26283 = 26283; + public static final int NULL_26285 = 26285; + public static final int NULL_26287 = 26287; + public static final int NULL_26289 = 26289; + public static final int NULL_26291 = 26291; + public static final int NULL_26293 = 26293; + public static final int NULL_26295 = 26295; + public static final int NULL_26297 = 26297; + public static final int NULL_26299 = 26299; + public static final int NULL_26301 = 26301; + public static final int NULL_26303 = 26303; + public static final int NULL_26305 = 26305; + public static final int NULL_26307 = 26307; + public static final int NULL_26309 = 26309; + public static final int NULL_26311 = 26311; + public static final int NULL_26313 = 26313; + public static final int NULL_26315 = 26315; + public static final int NULL_26317 = 26317; + public static final int NULL_26319 = 26319; + public static final int NULL_26321 = 26321; + public static final int NULL_26323 = 26323; + public static final int NULL_26325 = 26325; + public static final int NULL_26327 = 26327; + public static final int NULL_26329 = 26329; + public static final int NULL_26331 = 26331; + public static final int NULL_26333 = 26333; + public static final int NULL_26335 = 26335; + public static final int NULL_26337 = 26337; + public static final int NULL_26339 = 26339; + public static final int NULL_26341 = 26341; + public static final int NULL_26343 = 26343; + public static final int NULL_26345 = 26345; + public static final int NULL_26347 = 26347; + public static final int NULL_26349 = 26349; + public static final int NULL_26351 = 26351; + public static final int NULL_26352 = 26352; + public static final int NULL_26354 = 26354; + public static final int NULL_26355 = 26355; + public static final int NULL_26357 = 26357; + public static final int NULL_26359 = 26359; + public static final int NULL_26361 = 26361; + public static final int NULL_26363 = 26363; + public static final int NULL_26365 = 26365; + public static final int NULL_26367 = 26367; + public static final int NULL_26369 = 26369; + public static final int NULL_26371 = 26371; + public static final int NULL_26373 = 26373; + public static final int NULL_26375 = 26375; + public static final int NULL_26377 = 26377; + public static final int NULL_26379 = 26379; + public static final int NULL_26381 = 26381; + public static final int NULL_26383 = 26383; + public static final int NULL_26385 = 26385; + public static final int NULL_26387 = 26387; + public static final int NULL_26389 = 26389; + public static final int NULL_26391 = 26391; + public static final int NULL_26393 = 26393; + public static final int NULL_26395 = 26395; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java index 757da4d4a1..73396db288 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java @@ -1738,6 +1738,26 @@ public final class NullNpcID public static final int NULL_11222 = 11222; public static final int NULL_11223 = 11223; public static final int NULL_11224 = 11224; + public static final int NULL_11246 = 11246; public static final int NULL_11253 = 11253; + public static final int NULL_11256 = 11256; + public static final int NULL_11257 = 11257; + public static final int NULL_11258 = 11258; + public static final int NULL_11262 = 11262; + public static final int NULL_11263 = 11263; + public static final int NULL_11264 = 11264; + public static final int NULL_11265 = 11265; + public static final int NULL_11266 = 11266; + public static final int NULL_11267 = 11267; + public static final int NULL_11268 = 11268; + public static final int NULL_11269 = 11269; + public static final int NULL_11270 = 11270; + public static final int NULL_11271 = 11271; + public static final int NULL_11272 = 11272; + public static final int NULL_11273 = 11273; + public static final int NULL_11274 = 11274; + public static final int NULL_11275 = 11275; + public static final int NULL_11295 = 11295; + public static final int NULL_11296 = 11296; /* 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 ac7cff6b24..ae2f7ee931 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -21006,5 +21006,67 @@ public final class NullObjectID public static final int NULL_42849 = 42849; public static final int NULL_42850 = 42850; public static final int NULL_42851 = 42851; + public static final int NULL_42873 = 42873; + public static final int NULL_42874 = 42874; + public static final int NULL_42875 = 42875; + public static final int NULL_42876 = 42876; + public static final int NULL_42877 = 42877; + public static final int NULL_42882 = 42882; + public static final int NULL_42883 = 42883; + public static final int NULL_42884 = 42884; + public static final int NULL_42893 = 42893; + public static final int NULL_42894 = 42894; + public static final int NULL_42896 = 42896; + public static final int NULL_42897 = 42897; + public static final int NULL_42898 = 42898; + public static final int NULL_42899 = 42899; + public static final int NULL_42900 = 42900; + public static final int NULL_42901 = 42901; + public static final int NULL_42902 = 42902; + public static final int NULL_42903 = 42903; + public static final int NULL_42904 = 42904; + public static final int NULL_42905 = 42905; + public static final int NULL_42906 = 42906; + public static final int NULL_42909 = 42909; + public static final int NULL_42910 = 42910; + public static final int NULL_42911 = 42911; + public static final int NULL_42912 = 42912; + public static final int NULL_42913 = 42913; + public static final int NULL_42914 = 42914; + public static final int NULL_42915 = 42915; + public static final int NULL_42916 = 42916; + public static final int NULL_42917 = 42917; + public static final int NULL_42918 = 42918; + public static final int NULL_42919 = 42919; + public static final int NULL_42920 = 42920; + public static final int NULL_42921 = 42921; + public static final int NULL_42922 = 42922; + public static final int NULL_42923 = 42923; + public static final int NULL_42924 = 42924; + public static final int NULL_42925 = 42925; + public static final int NULL_42926 = 42926; + public static final int NULL_42927 = 42927; + public static final int NULL_42945 = 42945; + public static final int NULL_42946 = 42946; + public static final int NULL_42947 = 42947; + public static final int NULL_42948 = 42948; + public static final int NULL_42949 = 42949; + public static final int NULL_42950 = 42950; + public static final int NULL_42951 = 42951; + public static final int NULL_42952 = 42952; + public static final int NULL_42953 = 42953; + public static final int NULL_42954 = 42954; + public static final int NULL_42955 = 42955; + public static final int NULL_42956 = 42956; + public static final int NULL_42957 = 42957; + public static final int NULL_42958 = 42958; + public static final int NULL_42959 = 42959; + public static final int NULL_42960 = 42960; + public static final int NULL_42961 = 42961; + public static final int NULL_42962 = 42962; + public static final int NULL_42963 = 42963; + public static final int NULL_42964 = 42964; + public static final int NULL_42967 = 42967; + public static final int NULL_42968 = 42968; /* 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 832f553d9a..016f9487e5 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -21832,5 +21832,60 @@ public final class ObjectID public static final int FROZEN_DOOR = 42840; public static final int FROZEN_DOOR_42841 = 42841; public static final int GOLD_SINK_42852 = 42852; + public static final int SIGN_42853 = 42853; + public static final int SCUFFED_SNOW = 42854; + public static final int SNOWMAN = 42855; + public static final int SNOWMAN_42856 = 42856; + public static final int SNOWMAN_42857 = 42857; + public static final int SNOWMAN_42858 = 42858; + public static final int SNOWMAN_42859 = 42859; + public static final int SNOWMAN_42860 = 42860; + public static final int SNOWMAN_42861 = 42861; + public static final int SNOWMAN_42862 = 42862; + public static final int SNOWMAN_42863 = 42863; + public static final int SNOWMAN_42864 = 42864; + public static final int SPADE_42865 = 42865; + public static final int PILE_OF_SNOW = 42866; + public static final int BUSH_42867 = 42867; + public static final int PILE_OF_SNOW_42868 = 42868; + public static final int PILE_OF_SNOW_42869 = 42869; + public static final int CHRISTMAS_TREE = 42870; + public static final int CHRISTMAS_TREE_42871 = 42871; + public static final int CHRISTMAS_TREE_42872 = 42872; + public static final int PRESENTS = 42878; + public static final int PRESENTS_42879 = 42879; + public static final int PRESENTS_42880 = 42880; + public static final int PRESENTS_42881 = 42881; + public static final int POTTED_TREE = 42885; + public static final int POTTED_TREE_42886 = 42886; + public static final int MARKET_STALL_42887 = 42887; + public static final int MARKET_STALL_42888 = 42888; + public static final int MARKET_STALL_42889 = 42889; + public static final int MARKET_STALL_42890 = 42890; + public static final int MARKET_STALL_42891 = 42891; + public static final int MARKET_STALL_42892 = 42892; + public static final int ROBIN = 42895; + public static final int DEAD_TREE_42907 = 42907; + public static final int DEAD_OAK_42908 = 42908; + public static final int SANTAS_SLEIGH = 42928; + public static final int SANTAS_THRONE = 42929; + public static final int SANTAS_SACK = 42930; + public static final int FROZEN_DOOR_42931 = 42931; + public static final int FROZEN_DOOR_42932 = 42932; + public static final int DOOR_42933 = 42933; + public static final int DOOR_42934 = 42934; + public static final int ANCIENT_PLAQUE = 42935; + public static final int SCOREBOARD_42936 = 42936; + public static final int ANCIENT_BARRIER = 42937; + public static final int ANCIENT_BARRIER_42938 = 42938; + public static final int ANCIENT_BARRIER_42939 = 42939; + public static final int ANCIENT_BARRIER_42940 = 42940; + public static final int ANCIENT_BARRIER_42941 = 42941; + public static final int SHADOW = 42942; + public static final int STALAGMITE_42943 = 42943; + public static final int STALAGMITE_42944 = 42944; + public static final int ALTAR_42965 = 42965; + public static final int ANCIENT_FORGE = 42966; + public static final int BROKEN_CROSSBOW_42969 = 42969; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/PendingLogin.java b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java new file mode 100644 index 0000000000..c7c3a1d1a3 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/PendingLogin.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, 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; + +/** + * A pending friend login/out. This is used to suppress world hop notifications + * by buffering the pending logins to try to match a pending logout with a pending + * login and cancel both. + */ +public interface PendingLogin +{ + /** + * The name of the player + * @return + */ + String getName(); + + /** + * The world the player logged into, or 0 if a logout. + * @return + */ + short getWorld(); +} 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 2ddd236fd5..17360b5c5e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Perspective.java +++ b/runelite-api/src/main/java/net/runelite/api/Perspective.java @@ -782,9 +782,9 @@ public class Perspective final int radius = 5; int[][] tris = new int[][]{ - m.getTrianglesX(), - m.getTrianglesY(), - m.getTrianglesZ() + m.getFaceIndices1(), + m.getFaceIndices2(), + m.getFaceIndices3() }; int vpX1 = client.getViewportXOffset(); @@ -792,10 +792,10 @@ public class Perspective int vpX2 = vpX1 + client.getViewportWidth(); int vpY2 = vpY1 + client.getViewportHeight(); - List rects = new ArrayList<>(m.getTrianglesCount()); + List rects = new ArrayList<>(m.getFaceCount()); nextTri: - for (int tri = 0; tri < m.getTrianglesCount(); tri++) + for (int tri = 0; tri < m.getFaceCount(); tri++) { if (faceColors3[tri] == -2) { diff --git a/runelite-api/src/main/java/net/runelite/api/Quest.java b/runelite-api/src/main/java/net/runelite/api/Quest.java index 771cb64271..7acb5e4132 100644 --- a/runelite-api/src/main/java/net/runelite/api/Quest.java +++ b/runelite-api/src/main/java/net/runelite/api/Quest.java @@ -198,7 +198,9 @@ public enum Quest FAMILY_PEST(329, "Family Pest"), MAGE_ARENA_II(330, "Mage Arena II"), IN_SEARCH_OF_KNOWLEDGE(3143, "In Search of Knowledge"), - DADDYS_HOME(1688, "Daddy's Home"); + DADDYS_HOME(1688, "Daddy's Home"), + THE_FROZEN_DOOR(3768, "The Frozen Door"), +; @Getter private final int id; diff --git a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java index 20f2fb001e..5fcd50c3e3 100644 --- a/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java +++ b/runelite-api/src/main/java/net/runelite/api/RuneLiteObject.java @@ -41,7 +41,7 @@ public interface RuneLiteObject extends GraphicsObject * Sets the animation of the RuneLiteObject * If animation is null model will be static */ - void setAnimation(Sequence animation); + void setAnimation(Animation animation); /** * Sets whether the animation of the RuneLiteObject should loop when the animation ends. 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 5205871c64..aafe123a0f 100644 --- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java +++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java @@ -257,6 +257,12 @@ public final class ScriptID @ScriptArguments(integer = 15) public static final int FRIENDS_CHAT_CHANNEL_REBUILD = 1658; + /** + * Builds the widget that holds all of the players inside a clan chat + */ + @ScriptArguments(integer = 7) + public static final int CLAN_SIDEPANEL_DRAW = 4396; + /** * Builds the widget for making an offer in Grand Exchange */ diff --git a/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java b/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java index 6874f4145c..7c33371f94 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java +++ b/runelite-api/src/main/java/net/runelite/api/events/ClientTick.java @@ -31,7 +31,7 @@ public class ClientTick { public static final ClientTick INSTANCE = new ClientTick(); - private ClientTick() + public ClientTick() { // noop } diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java index c7be511bc1..faf369be56 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java @@ -25,24 +25,59 @@ package net.runelite.api.events; import lombok.Getter; -import net.runelite.api.MenuEntry; +import lombok.Setter; +import net.runelite.api.MenuAction; /** * An event when a new entry is added to a right-click menu. */ -public class MenuEntryAdded extends MenuEntry +public class MenuEntryAdded { // Here for RuneLite compatibility (different parameter order) public MenuEntryAdded(String option, String target, int type, int identifier, int actionParam0, int actionParam1) { - super(option, target, identifier, type, actionParam0, actionParam1, false); + this(option, target, identifier, type, actionParam0, actionParam1, false); } - public MenuEntryAdded(String option, String target, int identifier, int opcode, int param0, int param1, boolean forceLeftClick) + public MenuEntryAdded(String option, String target, int identifier, int type, int param0, int param1, boolean forceLeftClick) { - super(option, target, identifier, opcode, param0, param1, forceLeftClick); + this.option = option; + this.target = target; + this.identifier = identifier; + this.type = type; + this.actionParam0 = param0; + this.actionParam1 = param1; + this.forceLeftClick = forceLeftClick; } + @Getter + @Setter + private String option; + + @Getter + @Setter + private String target; + + @Getter + @Setter + private int type; + + @Getter + @Setter + private int identifier; + + @Getter + @Setter + private int actionParam0; + + @Getter + @Setter + private int actionParam1; + + @Getter + @Setter + private boolean forceLeftClick; + /** * If this is set to true client mixin will update * the menu entry with the modified values. @@ -51,10 +86,52 @@ public class MenuEntryAdded extends MenuEntry * been multiple changes */ @Getter + @Setter private boolean modified; public void setModified() { this.modified = true; } + + @Deprecated + public int getParam0() + { + return actionParam0; + } + + @Deprecated + public void setParam0(int param) + { + actionParam0 = param; + } + + @Deprecated + public int getParam1() + { + return actionParam1; + } + + @Deprecated + public void setParam1(int param) + { + actionParam1 = param; + } + @Deprecated + public int getOpcode() + { + return type; + } + + @Deprecated + public void setOpcode(int opcode) + { + type = opcode; + } + + @Deprecated + public MenuAction getMenuAction() + { + return MenuAction.of(type); + } } diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java index fe5b90edb2..d25ee0a34d 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java @@ -91,8 +91,8 @@ public class MenuOptionClicked { this.setMenuOption(entry.getOption()); this.setMenuTarget(entry.getTarget()); - this.setId(entry.getId()); - this.setMenuAction(MenuAction.of(entry.getOpcode())); + this.setId(entry.getIdentifier()); + this.setMenuAction(entry.getType()); this.setParam0(entry.getParam0()); this.setParam1(entry.getParam1()); } diff --git a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java index d3a4dda748..f6f55e89a8 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/WidgetMenuOptionClicked.java @@ -32,6 +32,7 @@ import net.runelite.api.widgets.WidgetInfo; * A MenuManager widget menu was clicked. This event is fired only for MenuManager managed custom menus. */ @Data +@Deprecated public class WidgetMenuOptionClicked { /** @@ -51,4 +52,4 @@ public class WidgetMenuOptionClicked * The widget id of the widget that was clicked. */ private int widgetId; -} +} \ No newline at end of file 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 a637f90919..1114c99147 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 @@ -185,6 +185,7 @@ public final class WidgetID public static final int GRAVESTONE_GROUP_ID = 672; public static final int POH_TREASURE_CHEST_INVENTORY_GROUP_ID = 674; public static final int GROUP_IRON_GROUP_ID = 726; + public static final int GROUP_STORAGE_GROUP_ID = 724; static class WorldMap { @@ -308,6 +309,11 @@ public final class WidgetID static final int EQUIPMENT_BUTTON = 113; } + static class GroupStorage + { + static final int ITEM_CONTAINER = 10; + } + static class GrandExchange { static final int WINDOW_CONTAINER = 0; @@ -1352,11 +1358,15 @@ public final class WidgetID static class Clan { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } static class ClanGuest { + static final int LAYER = 0; + static final int HEADER = 1; static final int MEMBERS = 6; } } 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 1bfd141dfd..aa5c7b17a6 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 @@ -153,6 +153,8 @@ public enum WidgetInfo BANK_SETTINGS_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.SETTINGS_BUTTON), BANK_TUTORIAL_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.TUTORIAL_BUTTON), + GROUP_STORAGE_ITEM_CONTAINER(WidgetID.GROUP_STORAGE_GROUP_ID, WidgetID.GroupStorage.ITEM_CONTAINER), + GRAND_EXCHANGE_WINDOW_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.WINDOW_CONTAINER), GRAND_EXCHANGE_OFFER_CONTAINER(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONTAINER), GRAND_EXCHANGE_OFFER_TEXT(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_DESCRIPTION), @@ -554,7 +556,12 @@ public enum WidgetInfo TEMPOROSS_STATUS_INDICATOR(WidgetID.TEMPOROSS_GROUP_ID, WidgetID.TemporossStatus.STATUS_INDICATOR), + CLAN_LAYER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.LAYER), + CLAN_HEADER(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.HEADER), CLAN_MEMBER_LIST(WidgetID.CLAN_GROUP_ID, WidgetID.Clan.MEMBERS), + + CLAN_GUEST_LAYER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.LAYER), + CLAN_GUEST_HEADER(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.HEADER), CLAN_GUEST_MEMBER_LIST(WidgetID.CLAN_GUEST_GROUP_ID, WidgetID.ClanGuest.MEMBERS), //OpenOSRS diff --git a/runelite-client/runelite-client.gradle.kts b/runelite-client/runelite-client.gradle.kts index 85a5efc236..5dc11f5703 100644 --- a/runelite-client/runelite-client.gradle.kts +++ b/runelite-client/runelite-client.gradle.kts @@ -75,6 +75,7 @@ dependencies { implementation(group = "net.sf.jopt-simple", name = "jopt-simple", version = "5.0.4") implementation(group = "org.madlonkay", name = "desktopsupport", version = "0.6.0") implementation(group = "org.apache.commons", name = "commons-text", version = "1.9") + implementation(group = "org.apache.commons", name = "commons-csv", version = "1.9.0") implementation(group = "commons-io", name = "commons-io", version = "2.8.0") implementation(group = "org.jetbrains", name = "annotations", version = "22.0.0") implementation(group = "com.github.zafarkhaja", name = "java-semver", version = "0.9.0") diff --git a/runelite-client/src/main/java/com/openosrs/client/game/PlayerContainer.java b/runelite-client/src/main/java/com/openosrs/client/game/PlayerContainer.java index ecfb0ce55a..781b86d66e 100644 --- a/runelite-client/src/main/java/com/openosrs/client/game/PlayerContainer.java +++ b/runelite-client/src/main/java/com/openosrs/client/game/PlayerContainer.java @@ -29,7 +29,7 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; import net.runelite.api.Player; -import net.runelite.http.api.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreResult; @Getter @Setter diff --git a/runelite-client/src/main/java/com/openosrs/client/game/PlayerManager.java b/runelite-client/src/main/java/com/openosrs/client/game/PlayerManager.java index 534a520c81..ea21d3e880 100644 --- a/runelite-client/src/main/java/com/openosrs/client/game/PlayerManager.java +++ b/runelite-client/src/main/java/com/openosrs/client/game/PlayerManager.java @@ -33,9 +33,9 @@ import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemMapping; +import net.runelite.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreResult; import net.runelite.client.util.PvPUtil; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreResult; import net.runelite.http.api.item.ItemEquipmentStats; import net.runelite.http.api.item.ItemStats; import okhttp3.OkHttpClient; 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 05a9f07ef4..857752fb1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -395,7 +395,6 @@ public class RuneLite // Add core overlays WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add); overlayManager.add(worldMapOverlay.get()); - eventBus.register(worldMapOverlay.get()); overlayManager.add(tooltipOverlay.get()); playerManager.get(); diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java index 3b14bc9da9..466bed401d 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigInvocationHandler.java @@ -99,11 +99,9 @@ class ConfigInvocationHandler implements InvocationHandler } // Convert value to return type - Class returnType = method.getReturnType(); - try { - Object objectValue = ConfigManager.stringToObject(value, returnType); + Object objectValue = manager.stringToObject(value, method.getGenericReturnType()); cache.put(method, objectValue == null ? NULL : objectValue); return objectValue; } @@ -155,7 +153,7 @@ class ConfigInvocationHandler implements InvocationHandler } else { - String newValueStr = ConfigManager.objectToString(newValue); + String newValueStr = manager.objectToString(newValue); manager.setConfiguration(group.value(), item.keyName(), newValueStr); } return null; diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java index d6ced58e18..922fb531a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItemDescriptor.java @@ -24,13 +24,14 @@ */ package net.runelite.client.config; +import java.lang.reflect.Type; import lombok.Value; @Value public class ConfigItemDescriptor implements ConfigObject { private final ConfigItem item; - private final Class type; + private final Type type; private final Range range; private final Alpha alpha; private final Units units; 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 6fbdb1011d..1b0e33560a 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 @@ -30,6 +30,7 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableSet; import com.google.common.hash.Hasher; import com.google.common.hash.Hashing; +import com.google.gson.Gson; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; @@ -44,6 +45,7 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.nio.channels.FileChannel; @@ -129,6 +131,7 @@ public class ConfigManager private final File settingsFileInput; private final EventBus eventBus; private final OkHttpClient okHttpClient; + private final Gson gson; private AccountSession session; private ConfigClient configClient; @@ -153,13 +156,15 @@ public class ConfigManager ScheduledExecutorService scheduledExecutorService, EventBus eventBus, OkHttpClient okHttpClient, - @Nullable Client client) + @Nullable Client client, + Gson gson) { this.settingsFileInput = config; this.eventBus = eventBus; this.okHttpClient = okHttpClient; this.client = client; this.propertiesFile = getPropertiesFile(); + this.gson = gson; scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); } @@ -413,17 +418,12 @@ public class ConfigManager return properties.getProperty(getWholeKey(groupName, profile, key)); } - public T getConfiguration(String groupName, String key, Class clazz) + public T getConfiguration(String groupName, String key, Type clazz) { return getConfiguration(groupName, null, key, clazz); } - public Object getConfiguration(String groupName, String key, Type clazz) - { - return getConfiguration(groupName, null, key, clazz); - } - - public T getRSProfileConfiguration(String groupName, String key, Class clazz) + public T getRSProfileConfiguration(String groupName, String key, Type clazz) { String rsProfileKey = this.rsProfileKey; if (rsProfileKey == null) @@ -434,31 +434,14 @@ public class ConfigManager return getConfiguration(groupName, rsProfileKey, key, clazz); } - public T getConfiguration(String groupName, String profile, String key, Type clazz) + public T getConfiguration(String groupName, String profile, String key, Type type) { String value = getConfiguration(groupName, profile, key); if (!Strings.isNullOrEmpty(value)) { try { - return (T) stringToObject(value, (Class) clazz); - } - catch (Exception e) - { - log.warn("Unable to unmarshal {} ", getWholeKey(groupName, profile, key), e); - } - } - return null; - } - - public T getConfiguration(String groupName, String profile, String key, Class clazz) - { - String value = getConfiguration(groupName, profile, key); - if (!Strings.isNullOrEmpty(value)) - { - try - { - return (T) stringToObject(value, clazz); + return (T) stringToObject(value, type); } catch (Exception e) { @@ -511,12 +494,12 @@ public class ConfigManager eventBus.post(configChanged); } - public void setConfiguration(String groupName, String profile, String key, Object value) + public void setConfiguration(String groupName, String profile, String key, T value) { setConfiguration(groupName, profile, key, objectToString(value)); } - public void setConfiguration(String groupName, String key, Object value) + public void setConfiguration(String groupName, String key, T value) { // do not save consumers for buttons, they cannot be changed anyway if (value instanceof Consumer) @@ -527,7 +510,7 @@ public class ConfigManager setConfiguration(groupName, null, key, value); } - public void setRSProfileConfiguration(String groupName, String key, Object value) + public void setRSProfileConfiguration(String groupName, String key, T value) { String rsProfileKey = this.rsProfileKey; if (rsProfileKey == null) @@ -673,7 +656,7 @@ public class ConfigManager .filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class)) .map(m -> new ConfigItemDescriptor( m.getDeclaredAnnotation(ConfigItem.class), - m.getReturnType(), + m.getGenericReturnType(), m.getDeclaredAnnotation(Range.class), m.getDeclaredAnnotation(Alpha.class), m.getDeclaredAnnotation(Units.class) @@ -748,7 +731,7 @@ public class ConfigManager { // This checks if it is set and is also unmarshallable to the correct type; so // we will overwrite invalid config values with the default - Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType()); + Object current = getConfiguration(group.value(), item.keyName(), method.getGenericReturnType()); if (current != null) { continue; // something else is already set @@ -783,7 +766,7 @@ public class ConfigManager } } - static Object stringToObject(String str, Class type) + Object stringToObject(String str, Type type) { if (type == boolean.class || type == Boolean.class) { @@ -824,7 +807,7 @@ public class ConfigManager int height = Integer.parseInt(splitStr[3]); return new Rectangle(x, y, width, height); } - if (type.isEnum()) + if (type instanceof Class && ((Class) type).isEnum()) { return Enum.valueOf((Class) type, str); } @@ -859,6 +842,14 @@ public class ConfigManager { return Base64.getUrlDecoder().decode(str); } + if (type instanceof ParameterizedType) + { + ParameterizedType parameterizedType = (ParameterizedType) type; + if (parameterizedType.getRawType() == Set.class) + { + return gson.fromJson(str, parameterizedType); + } + } if (type == EnumSet.class) { try @@ -898,7 +889,7 @@ public class ConfigManager } @Nullable - static String objectToString(Object object) + String objectToString(Object object) { if (object instanceof Color) { @@ -954,7 +945,10 @@ public class ConfigManager return ((EnumSet) object).toArray()[0].getClass().getCanonicalName() + "{" + object.toString() + "}"; } - + if (object instanceof Set) + { + return gson.toJson(object, Set.class); + } return object == null ? null : object.toString(); } diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreClient.java similarity index 86% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreClient.java index cad7b00094..58f7a6e950 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreClient.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.http.api.hiscore; +package net.runelite.client.hiscore; import java.io.IOException; import java.util.concurrent.CompletableFuture; @@ -64,28 +64,6 @@ public class HiscoreClient return lookup(username, HiscoreEndpoint.NORMAL); } - public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill, HiscoreEndpoint endpoint) throws IOException - { - HiscoreResult result = lookupSync(username, endpoint.getHiscoreURL()); - - if (result == null) - { - return null; - } - - Skill requested = result.getSkill(skill); - SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); - skillResult.setPlayer(username); - skillResult.setSkillName(skill.getName()); - skillResult.setSkill(requested); - return skillResult; - } - - public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException - { - return lookup(username, skill, HiscoreEndpoint.NORMAL); - } - private HiscoreResult lookupSync(String username, HttpUrl hiscoreUrl) throws IOException { try (Response response = client.newCall(buildRequest(username, hiscoreUrl)).execute()) @@ -109,7 +87,7 @@ public class HiscoreClient @Override public void onResponse(Call call, Response response) throws IOException { - try + try // NOPMD: UseTryWithResources { future.complete(processResponse(username, response)); } @@ -156,9 +134,7 @@ public class HiscoreClient { CSVParser parser = CSVParser.parse(responseStr, CSVFormat.DEFAULT); - HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder(); - hiscoreBuilder.setPlayer(username); - + HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder(username); int count = 0; for (CSVRecord record : parser.getRecords()) @@ -186,4 +162,4 @@ public class HiscoreClient return hiscoreBuilder.build(); } -} +} \ No newline at end of file diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreEndpoint.java similarity index 96% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreEndpoint.java index 6edfdda64b..df7146ad61 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreEndpoint.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreEndpoint.java @@ -23,8 +23,7 @@ * 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.hiscore; +package net.runelite.client.hiscore; import lombok.Getter; import okhttp3.HttpUrl; @@ -46,6 +45,6 @@ public enum HiscoreEndpoint HiscoreEndpoint(String name, String hiscoreURL) { this.name = name; - this.hiscoreURL = HttpUrl.parse(hiscoreURL); + this.hiscoreURL = HttpUrl.get(hiscoreURL); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/game/HiscoreLoader.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreLoader.java similarity index 90% rename from runelite-client/src/main/java/net/runelite/client/game/HiscoreLoader.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreLoader.java index 36b6024e35..97a1b26ee0 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/HiscoreLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreLoader.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.client.game; +package net.runelite.client.hiscore; import com.google.common.cache.CacheLoader; import com.google.common.util.concurrent.ListenableFuture; @@ -31,11 +31,8 @@ import com.google.common.util.concurrent.MoreExecutors; import java.io.IOException; import java.util.concurrent.ScheduledExecutorService; import lombok.extern.slf4j.Slf4j; -import static net.runelite.client.game.HiscoreManager.EMPTY; -import static net.runelite.client.game.HiscoreManager.NONE; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; +import static net.runelite.client.hiscore.HiscoreManager.EMPTY; +import static net.runelite.client.hiscore.HiscoreManager.NONE; @Slf4j class HiscoreLoader extends CacheLoader diff --git a/runelite-client/src/main/java/net/runelite/client/game/HiscoreManager.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreManager.java similarity index 93% rename from runelite-client/src/main/java/net/runelite/client/game/HiscoreManager.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreManager.java index 9e05b20373..cf8ef66bdd 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/HiscoreManager.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreManager.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.client.game; +package net.runelite.client.hiscore; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; @@ -33,9 +33,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.AllArgsConstructor; import lombok.Data; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; import okhttp3.OkHttpClient; @Singleton @@ -56,7 +53,7 @@ public class HiscoreManager private final HiscoreClient hiscoreClient; @Inject - public HiscoreManager(ScheduledExecutorService executor, OkHttpClient okHttpClient) + private HiscoreManager(ScheduledExecutorService executor, OkHttpClient okHttpClient) { hiscoreClient = new HiscoreClient(okHttpClient); hiscoreCache = CacheBuilder.newBuilder() diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResult.java similarity index 86% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResult.java index de52f5c5aa..bfc6d46b6e 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResult.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResult.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.http.api.hiscore; +package net.runelite.client.hiscore; import lombok.Data; @@ -93,6 +93,7 @@ public class HiscoreResult private Skill kreearra; private Skill krilTsutsaroth; private Skill mimic; + private Skill nex; private Skill nightmare; private Skill phosanisNightmare; private Skill obor; @@ -119,77 +120,77 @@ public class HiscoreResult switch (skill) { case ATTACK: - return getAttack(); + return attack; case DEFENCE: - return getDefence(); + return defence; case STRENGTH: - return getStrength(); + return strength; case HITPOINTS: - return getHitpoints(); + return hitpoints; case RANGED: - return getRanged(); + return ranged; case PRAYER: - return getPrayer(); + return prayer; case MAGIC: - return getMagic(); + return magic; case COOKING: - return getCooking(); + return cooking; case WOODCUTTING: - return getWoodcutting(); + return woodcutting; case FLETCHING: - return getFletching(); + return fletching; case FISHING: - return getFishing(); + return fishing; case FIREMAKING: - return getFiremaking(); + return firemaking; case CRAFTING: - return getCrafting(); + return crafting; case SMITHING: - return getSmithing(); + return smithing; case MINING: - return getMining(); + return mining; case HERBLORE: - return getHerblore(); + return herblore; case AGILITY: - return getAgility(); + return agility; case THIEVING: - return getThieving(); + return thieving; case SLAYER: - return getSlayer(); + return slayer; case FARMING: - return getFarming(); + return farming; case RUNECRAFT: - return getRunecraft(); + return runecraft; case HUNTER: - return getHunter(); + return hunter; case CONSTRUCTION: - return getConstruction(); + return construction; case LEAGUE_POINTS: - return getLeaguePoints(); + return leaguePoints; case OVERALL: - return getOverall(); + return overall; case BOUNTY_HUNTER_HUNTER: - return getBountyHunterHunter(); + return bountyHunterHunter; case BOUNTY_HUNTER_ROGUE: - return getBountyHunterRogue(); + return bountyHunterRogue; case CLUE_SCROLL_ALL: - return getClueScrollAll(); + return clueScrollAll; case CLUE_SCROLL_BEGINNER: - return getClueScrollBeginner(); + return clueScrollBeginner; case CLUE_SCROLL_EASY: - return getClueScrollEasy(); + return clueScrollEasy; case CLUE_SCROLL_MEDIUM: - return getClueScrollMedium(); + return clueScrollMedium; case CLUE_SCROLL_HARD: - return getClueScrollHard(); + return clueScrollHard; case CLUE_SCROLL_ELITE: - return getClueScrollElite(); + return clueScrollElite; case CLUE_SCROLL_MASTER: - return getClueScrollMaster(); + return clueScrollMaster; case LAST_MAN_STANDING: - return getLastManStanding(); + return lastManStanding; case SOUL_WARS_ZEAL: - return getSoulWarsZeal(); + return soulWarsZeal; case ABYSSAL_SIRE: return abyssalSire; case ALCHEMICAL_HYDRA: @@ -244,6 +245,8 @@ public class HiscoreResult return krilTsutsaroth; case MIMIC: return mimic; + case NEX: + return nex; case NIGHTMARE: return nightmare; case PHOSANIS_NIGHTMARE: diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResultBuilder.java similarity index 96% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResultBuilder.java index 6c88ebcd18..e5a7ec20eb 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreResultBuilder.java @@ -22,21 +22,18 @@ * (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.hiscore; +package net.runelite.client.hiscore; import java.util.ArrayList; import java.util.List; +import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor class HiscoreResultBuilder { - private String player; + private final String player; private final List skills = new ArrayList<>(); - public void setPlayer(String player) - { - this.player = player; - } - void setNextSkill(Skill skill) { skills.add(skill); @@ -118,6 +115,10 @@ class HiscoreResultBuilder hiscoreResult.setKreearra(skills.get(index++)); hiscoreResult.setKrilTsutsaroth(skills.get(index++)); hiscoreResult.setMimic(skills.get(index++)); + if (skills.size() > 83) + { + hiscoreResult.setNex(skills.get(index++)); + } hiscoreResult.setNightmare(skills.get(index++)); hiscoreResult.setPhosanisNightmare(skills.get(index++)); hiscoreResult.setObor(skills.get(index++)); diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkill.java similarity index 94% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkill.java index 698bd34e8e..6cf3dc94ca 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkill.java @@ -22,13 +22,13 @@ * (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.hiscore; +package net.runelite.client.hiscore; import lombok.AllArgsConstructor; import lombok.Getter; -import static net.runelite.http.api.hiscore.HiscoreSkillType.SKILL; -import static net.runelite.http.api.hiscore.HiscoreSkillType.ACTIVITY; -import static net.runelite.http.api.hiscore.HiscoreSkillType.BOSS; +import static net.runelite.client.hiscore.HiscoreSkillType.SKILL; +import static net.runelite.client.hiscore.HiscoreSkillType.ACTIVITY; +import static net.runelite.client.hiscore.HiscoreSkillType.BOSS; @AllArgsConstructor @Getter @@ -97,6 +97,7 @@ public enum HiscoreSkill KREEARRA("Kree'Arra", BOSS), KRIL_TSUTSAROTH("K'ril Tsutsaroth", BOSS), MIMIC("Mimic", BOSS), + NEX("Nex", BOSS), NIGHTMARE("Nightmare", BOSS), PHOSANIS_NIGHTMARE("Phosani's Nightmare", BOSS), OBOR("Obor", BOSS), diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkillType.java b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkillType.java similarity index 97% rename from http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkillType.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkillType.java index 67e695364b..55879981b9 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkillType.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/HiscoreSkillType.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.http.api.hiscore; +package net.runelite.client.hiscore; public enum HiscoreSkillType { @@ -30,4 +30,4 @@ public enum HiscoreSkillType SKILL, ACTIVITY, BOSS -} +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/Sequence.java b/runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java similarity index 88% rename from runelite-api/src/main/java/net/runelite/api/Sequence.java rename to runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java index e7e1c8fcb9..c742c0c86e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Sequence.java +++ b/runelite-client/src/main/java/net/runelite/client/hiscore/Skill.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Trevor + * Copyright (c) 2021, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,11 +22,14 @@ * (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; +package net.runelite.client.hiscore; -/** - * Represents an animation of a renderable - */ -public interface Sequence +import lombok.Value; + +@Value +public class Skill { -} + int rank; + int level; + long experience; +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index d6c9c79893..69e9dca77c 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -27,10 +27,10 @@ package net.runelite.client.menus; import com.google.common.base.Preconditions; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -67,6 +67,7 @@ public class MenuManager { this.client = client; this.eventBus = eventBus; + eventBus.register(this); } @@ -74,10 +75,12 @@ public class MenuManager * Adds a CustomMenuOption to the list of managed menu options. * * @param customMenuOption The custom menu to add + * @param callback callback to be called when the menu is clicked */ - public void addManagedCustomMenu(WidgetMenuOption customMenuOption) + public void addManagedCustomMenu(WidgetMenuOption customMenuOption, Consumer callback) { managedMenuOptions.put(customMenuOption.getWidgetId(), customMenuOption); + customMenuOption.callback = callback; } /** @@ -113,7 +116,7 @@ public class MenuManager return; } - int widgetId = event.getParam1(); + int widgetId = event.getActionParam1(); Collection options = managedMenuOptions.get(widgetId); if (options.isEmpty()) { @@ -122,11 +125,10 @@ public class MenuManager MenuEntry[] menuEntries = client.getMenuEntries(); - MenuEntry[] newMenuEntries = Arrays.copyOf(menuEntries, menuEntries.length + options.size()); // Menu entries are sorted with higher-index entries appearing toward the top of the minimenu, so insert older // managed menu entries at higher indices and work backward for newer entries so newly-added entries appear at // the bottom - int insertIdx = newMenuEntries.length - 1; + int insertIdx = -1; for (WidgetMenuOption currentMenu : options) { // Exit if we've inserted the managed menu entries already @@ -135,16 +137,42 @@ public class MenuManager return; } - MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(insertIdx--) + .setOption(currentMenu.getMenuOption()) + .setTarget(currentMenu.getMenuTarget()) + .setType(MenuAction.RUNELITE) + .setParam1(widgetId) + .onClick(currentMenu.callback); + } + } - newMenuEntries[insertIdx--] = menuEntry; + @Subscribe + public void onMenuOptionClicked(MenuOptionClicked event) + { + if (event.getMenuAction() != MenuAction.RUNELITE) + { + return; } - client.setMenuEntries(newMenuEntries); + int widgetId = event.getParam1(); + Collection options = managedMenuOptions.get(widgetId); + + for (WidgetMenuOption curMenuOption : options) + { + if (curMenuOption.getMenuTarget().equals(event.getMenuTarget()) + && curMenuOption.getMenuOption().equals(event.getMenuOption())) + { + WidgetMenuOptionClicked widgetMenuOptionClicked = new WidgetMenuOptionClicked(); + widgetMenuOptionClicked.setMenuOption(event.getMenuOption()); + widgetMenuOptionClicked.setMenuTarget(event.getMenuTarget()); + widgetMenuOptionClicked.setWidget(curMenuOption.getWidget()); + widgetMenuOptionClicked.setWidgetId(curMenuOption.getWidgetId()); + + eventBus.post(widgetMenuOptionClicked); + + return; + } + } } public void addPlayerMenuItem(String menuText) @@ -198,33 +226,6 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - int widgetId = event.getParam1(); - Collection options = managedMenuOptions.get(widgetId); - - for (WidgetMenuOption curMenuOption : options) - { - if (curMenuOption.getMenuTarget().equals(event.getMenuTarget()) - && curMenuOption.getMenuOption().equals(event.getMenuOption())) - { - WidgetMenuOptionClicked customMenu = new WidgetMenuOptionClicked(); - customMenu.setMenuOption(event.getMenuOption()); - customMenu.setMenuTarget(event.getMenuTarget()); - customMenu.setWidget(curMenuOption.getWidget()); - customMenu.setWidgetId(curMenuOption.getWidgetId()); - eventBus.post(customMenu); - return; - } - } - } - private void addPlayerMenuItem(int playerOptionIndex, String menuText) { client.getPlayerOptions()[playerOptionIndex] = menuText; diff --git a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java index 1f1a74606b..7727897f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java @@ -25,9 +25,11 @@ package net.runelite.client.menus; import java.awt.Color; +import java.util.function.Consumer; import javax.annotation.Nullable; import lombok.Getter; import lombok.Setter; +import net.runelite.api.MenuEntry; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; @@ -65,6 +67,8 @@ public final class WidgetMenuOption @Getter private final int widgetId; + Consumer callback; + /** * Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options * 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 6091fefb10..bacab9beae 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 @@ -341,9 +341,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - MenuEntry[] entries = client.getMenuEntries(); - - if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { Widget container = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER); @@ -357,87 +355,80 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener text += " (" + tagCount + ")"; } - MenuEntry editTags = new MenuEntry(); - editTags.setParam0(event.getActionParam0()); - editTags.setParam1(event.getParam1()); - editTags.setTarget(event.getTarget()); - editTags.setOption(text); - editTags.setType(MenuAction.RUNELITE.getId()); - editTags.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = editTags; - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(event.getTarget()) + .setOption(text) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(this::editTags); } tabInterface.handleAdd(event); } + private void editTags(MenuEntry entry) + { + int inventoryIndex = entry.getParam0(); + ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); + if (bankContainer == null) + { + return; + } + Item[] items = bankContainer.getItems(); + if (inventoryIndex < 0 || inventoryIndex >= items.length) + { + return; + } + Item item = bankContainer.getItems()[inventoryIndex]; + if (item == null) + { + return; + } + + int itemId = item.getId(); + ItemComposition itemComposition = itemManager.getItemComposition(itemId); + String name = itemComposition.getName(); + + // Get both tags and vartags and append * to end of vartags name + Collection tags = tagManager.getTags(itemId, false); + tagManager.getTags(itemId, true).stream() + .map(i -> i + "*") + .forEach(tags::add); + + String initialValue = Text.toCSV(tags); + + chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") + .addCharValidator(FILTERED_CHARS) + .value(initialValue) + .onDone((Consumer) (newValue) -> + clientThread.invoke(() -> + { + // Split inputted tags to vartags (ending with *) and regular tags + final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); + final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> + { + newTags.remove(s); + return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); + }).collect(Collectors.toList()); + + // And save them + tagManager.setTagString(itemId, Text.toCSV(newTags), false); + tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); + + // Check both previous and current tags in case the tag got removed in new tags or in case + // the tag got added in new tags + tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); + })) + .build(); + } + @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() - && event.getMenuAction() == MenuAction.RUNELITE - && event.getMenuOption().startsWith(EDIT_TAGS_MENU_OPTION)) - { - event.consume(); - int inventoryIndex = event.getParam0(); - ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK); - if (bankContainer == null) - { - return; - } - Item[] items = bankContainer.getItems(); - if (inventoryIndex < 0 || inventoryIndex >= items.length) - { - return; - } - Item item = bankContainer.getItems()[inventoryIndex]; - if (item == null) - { - return; - } - - int itemId = item.getId(); - ItemComposition itemComposition = itemManager.getItemComposition(itemId); - String name = itemComposition.getName(); - - // Get both tags and vartags and append * to end of vartags name - Collection tags = tagManager.getTags(itemId, false); - tagManager.getTags(itemId, true).stream() - .map(i -> i + "*") - .forEach(tags::add); - - String initialValue = Text.toCSV(tags); - - chatboxPanelManager.openTextInput(name + " tags:
(append " + VAR_TAG_SUFFIX + " for variation tag)") - .addCharValidator(FILTERED_CHARS) - .value(initialValue) - .onDone((Consumer) (newValue) -> - clientThread.invoke(() -> - { - // Split inputted tags to vartags (ending with *) and regular tags - final Collection newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase())); - final Collection newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s -> - { - newTags.remove(s); - return s.substring(0, s.length() - VAR_TAG_SUFFIX.length()); - }).collect(Collectors.toList()); - - // And save them - tagManager.setTagString(itemId, Text.toCSV(newTags), false); - tagManager.setTagString(itemId, Text.toCSV(newVarTags), true); - - // Check both previous and current tags in case the tag got removed in new tags or in case - // the tag got added in new tags - tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), ""))); - })) - .build(); - } - else - { - tabInterface.handleClick(event); - } + tabInterface.handleClick(event); } @Subscribe 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 05a3240f95..7a1954e656 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 @@ -618,38 +618,32 @@ public class TabInterface return; } - MenuEntry[] entries = client.getMenuEntries(); if (activeTab != null - && event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + && event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getOption().equals("Examine")) { - entries = createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget(), entries); - client.setMenuEntries(entries); + createMenuEntry(event, REMOVE_TAG + " (" + activeTab.getTag() + ")", event.getTarget()); } - else if (event.getParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() + else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getOption().equals("Deposit inventory")) { - entries = createMenuEntry(event, TAG_INVENTORY, event.getTarget(), entries); + createMenuEntry(event, TAG_INVENTORY, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_INVENTORY, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } - else if (event.getParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() + else if (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getOption().equals("Deposit worn items")) { - entries = createMenuEntry(event, TAG_GEAR, event.getTarget(), entries); + createMenuEntry(event, TAG_GEAR, event.getTarget()); if (activeTab != null) { - entries = createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR), entries); + createMenuEntry(event, TAG_GEAR, ColorUtil.wrapWithColorTag(activeTab.getTag(), HILIGHT_COLOR)); } - - client.setMenuEntries(entries); } } @@ -773,7 +767,6 @@ public class TabInterface { entry.setOption(TAG_SEARCH + Text.removeTags(entry.getTarget()) + (shiftDown ? VAR_TAG_SUFFIX : "")); entry.setTarget(draggedWidget.getName()); - client.setMenuEntries(entries); } if (entry.getOption().equals(SCROLL_UP)) @@ -1195,17 +1188,14 @@ public class TabInterface searchButtonBackground.setSpriteId(SpriteID.EQUIPMENT_SLOT_TILE); } - private static MenuEntry[] createMenuEntry(MenuEntryAdded event, String option, String target, MenuEntry[] entries) + private void createMenuEntry(MenuEntryAdded event, String option, String target) { - final MenuEntry entry = new MenuEntry(); - entry.setParam0(event.getActionParam0()); - entry.setParam1(event.getParam1()); - entry.setTarget(target); - entry.setOption(option); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setIdentifier(event.getIdentifier()); - entries = Arrays.copyOf(entries, entries.length + 1); - entries[entries.length - 1] = entry; - return entries; + client.createMenuEntry(-1) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setTarget(target) + .setOption(option) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java index dfb29e8950..21c495b603 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java @@ -294,7 +294,7 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener { for (MenuEntry menuEntry : menuEntries) { - MenuAction action = MenuAction.of(menuEntry.getType()); + MenuAction action = menuEntry.getType(); switch (action) { case CANCEL: diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java index eeffc30f4d..66739bf5a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelConfig.java @@ -206,6 +206,18 @@ public interface ChatChannelConfig extends Config return false; } + @ConfigItem( + keyName = "clanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online clan members at the end of the clan's name.", + position = 1, + section = clanChatSection + ) + default boolean clanChatShowOnlineMemberCount() + { + return false; + } + @ConfigItem( keyName = "guestClanChatShowJoinLeave", name = "Show Join/Leave", @@ -217,4 +229,16 @@ public interface ChatChannelConfig extends Config { return false; } + + @ConfigItem( + keyName = "guestClanChatShowOnlineMemberCount", + name = "Show Online Member Count", + description = "Shows the number of online guest clan members at the end of the clan's name.", + position = 1, + section = guestClanChatSection + ) + default boolean guestClanChatShowOnlineMemberCount() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 25ac07f449..d1277b981d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -145,6 +145,8 @@ public class ChatChannelPlugin extends Plugin { clientThread.invoke(() -> colorIgnoredPlayers(config.showIgnoresColor())); } + + rebuildClanTitle(); } @Override @@ -153,6 +155,7 @@ public class ChatChannelPlugin extends Plugin chats = null; clientThread.invoke(() -> colorIgnoredPlayers(Color.WHITE)); rebuildFriendsChat(); + rebuildClanTitle(); } @Subscribe @@ -167,6 +170,8 @@ public class ChatChannelPlugin extends Plugin Color ignoreColor = config.showIgnores() ? config.showIgnoresColor() : Color.WHITE; clientThread.invoke(() -> colorIgnoredPlayers(ignoreColor)); + + rebuildClanTitle(); } } @@ -606,6 +611,18 @@ public class ChatChannelPlugin extends Plugin chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); } } + else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW) + { + if (config.clanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_HEADER, client.getClanChannel()); + } + + if (config.guestClanChatShowOnlineMemberCount()) + { + updateClanTitle(WidgetInfo.CLAN_GUEST_HEADER, client.getGuestClanChannel()); + } + } } private void insertRankIcon(final ChatMessage message) @@ -740,4 +757,35 @@ public class ChatChannelPlugin extends Plugin listWidget.setTextColor(ignoreColor.getRGB()); } } + + private void rebuildClanTitle() + { + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + + clientThread.invokeLater(() -> + { + Widget w = client.getWidget(WidgetInfo.CLAN_GUEST_LAYER); + if (w != null) + { + client.runScript(w.getOnVarTransmitListener()); + } + }); + } + + private void updateClanTitle(WidgetInfo widget, ClanChannel channel) + { + Widget header = client.getWidget(widget); + if (header != null && channel != null) + { + Widget title = header.getChild(0); + title.setText(title.getText() + " (" + channel.getMembers().size() + ")"); + } + } } 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 b15cebb7e4..4105a926a5 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 @@ -82,6 +82,11 @@ import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; import net.runelite.client.game.ItemManager; +import net.runelite.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreSkill; +import net.runelite.client.hiscore.Skill; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -90,12 +95,6 @@ import net.runelite.client.util.QuantityFormatter; import net.runelite.client.util.Text; import net.runelite.http.api.chat.ChatClient; import net.runelite.http.api.chat.Duels; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; -import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; -import net.runelite.http.api.hiscore.Skill; import net.runelite.http.api.item.ItemPrice; import okhttp3.OkHttpClient; import org.apache.commons.text.WordUtils; @@ -1372,16 +1371,14 @@ public class ChatCommandsPlugin extends Plugin try { - final SingleHiscoreSkillResult result = hiscoreClient.lookup(lookup.getName(), skill, lookup.getEndpoint()); - + final HiscoreResult result = hiscoreClient.lookup(lookup.getName(), lookup.getEndpoint()); if (result == null) { log.warn("unable to look up skill {} for {}: not found", skill, search); return; } - final Skill hiscoreSkill = result.getSkill(); - + final Skill hiscoreSkill = result.getSkill(skill); ChatMessageBuilder chatMessageBuilder = new ChatMessageBuilder() .append(ChatColorType.NORMAL) .append("Level ") 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 index 39d736d4c5..a529800017 100644 --- 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 @@ -201,6 +201,9 @@ public class ChatFilterPlugin extends Plugin case NPC_EXAMINE: case OBJECT_EXAMINE: case SPAM: + case CLAN_MESSAGE: + case CLAN_GUEST_MESSAGE: + case CLAN_GIM_MESSAGE: if (config.filterGameChat()) { message = censorMessage(null, message); 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 ad6530a2e7..2b11c3318b 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,7 +25,6 @@ */ package net.runelite.client.plugins.chathistory; -import com.google.common.base.Strings; import com.google.common.collect.EvictingQueue; import com.google.inject.Provides; import java.awt.Toolkit; @@ -83,8 +82,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener private Queue messageQueue; private Deque friends; - private String currentMessage = null; - @Inject private Client client; @@ -121,7 +118,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener messageQueue = null; friends.clear(); friends = null; - currentMessage = null; keyManager.unregisterKeyListener(this); } @@ -195,7 +191,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener // Use second entry as first one can be walk here with transparent chatbox final MenuEntry entry = event.getMenuEntries()[event.getMenuEntries().length - 2]; - if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY.getId() && entry.getType() != MenuAction.RUNELITE.getId()) + if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY && entry.getType() != MenuAction.RUNELITE) { return; } @@ -236,16 +232,17 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - currentMessage = messageContents.getText(); + String currentMessage = messageContents.getText(); - final MenuEntry menuEntry = new MenuEntry(); - menuEntry.setOption(COPY_TO_CLIPBOARD); - menuEntry.setTarget(entry.getTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - menuEntry.setParam0(entry.getParam0()); - menuEntry.setParam1(entry.getParam1()); - menuEntry.setIdentifier(entry.getIdentifier()); - client.setMenuEntries(ArrayUtils.insert(1, client.getMenuEntries(), menuEntry)); + client.createMenuEntry(1) + .setOption(COPY_TO_CLIPBOARD) + .setTarget(entry.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + }); } @Subscribe @@ -258,11 +255,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener { clearChatboxHistory(ChatboxTab.of(event.getParam1())); } - else if (COPY_TO_CLIPBOARD.equals(menuOption) && !Strings.isNullOrEmpty(currentMessage)) - { - final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage)); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); - } } @Subscribe @@ -279,10 +271,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return; } - final MenuEntry clearEntry = new MenuEntry(); - clearEntry.setTarget(""); - clearEntry.setType(MenuAction.RUNELITE_HIGH_PRIORITY.getId()); - clearEntry.setParam0(entry.getActionParam0()); + final MenuEntry clearEntry = client.createMenuEntry(-2) + .setType(MenuAction.RUNELITE_HIGH_PRIORITY); clearEntry.setParam1(entry.getActionParam1()); final StringBuilder optionBuilder = new StringBuilder(); @@ -299,9 +289,6 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener optionBuilder.append(CLEAR_HISTORY); clearEntry.setOption(optionBuilder.toString()); - - final MenuEntry[] menuEntries = client.getMenuEntries(); - client.setMenuEntries(ArrayUtils.insert(menuEntries.length - 1, menuEntries, clearEntry)); } private void clearMessageQueue(ChatboxTab tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 3fc4c112d0..a2356c2676 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.config; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Sets; import com.google.common.primitives.Ints; import java.awt.BasicStroke; import java.awt.BorderLayout; @@ -46,13 +47,19 @@ import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.TreeMap; import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.swing.BorderFactory; import javax.swing.BoxLayout; @@ -60,8 +67,10 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -72,6 +81,7 @@ import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.JTextField; +import javax.swing.ListCellRenderer; import javax.swing.ScrollPaneConstants; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; @@ -84,8 +94,6 @@ import javax.swing.event.ChangeListener; import javax.swing.plaf.basic.BasicSpinnerUI; import javax.swing.text.JTextComponent; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.events.ConfigButtonClicked; -import net.runelite.client.config.Button; import net.runelite.client.config.ConfigDescriptor; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -100,7 +108,6 @@ import net.runelite.client.config.Keybind; import net.runelite.client.config.ModifierlessKeybind; import net.runelite.client.config.Range; import net.runelite.client.config.Units; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ExternalPluginsChanged; import net.runelite.client.events.PluginChanged; @@ -138,33 +145,6 @@ class ConfigPanel extends PluginPanel private static final Map sectionExpandStates = new HashMap<>(); - private final FixedWidthPanel mainPanel; - private final JLabel title; - private final PluginToggleButton pluginToggle; - - @Inject - private PluginListPanel pluginList; - - @Inject - private ConfigManager configManager; - - @Inject - private PluginManager pluginManager; - - @Inject - private ExternalPluginManager externalPluginManager; - - @Inject - private OPRSExternalPluginManager oprsExternalPluginManager; - - @Inject - private ColorPickerManager colorPickerManager; - - @Inject - private EventBus eventBus; - - private PluginConfigurationDescriptor pluginConfig = null; - static { final BufferedImage backIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_back_icon.png"); @@ -180,10 +160,36 @@ class ConfigPanel extends PluginPanel SECTION_RETRACT_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(sectionExpandIcon, -100)); } - public ConfigPanel() + private final PluginListPanel pluginList; + private final ConfigManager configManager; + private final PluginManager pluginManager; + private final ExternalPluginManager externalPluginManager; + private final ColorPickerManager colorPickerManager; + + private final ListCellRenderer> listCellRenderer = new ComboBoxListRenderer<>(); + + private final FixedWidthPanel mainPanel; + private final JLabel title; + private final PluginToggleButton pluginToggle; + + private PluginConfigurationDescriptor pluginConfig = null; + + @Inject + private OPRSExternalPluginManager oprsExternalPluginManager; + + @Inject + private ConfigPanel(PluginListPanel pluginList, ConfigManager configManager, PluginManager pluginManager, + ExternalPluginManager externalPluginManager, ColorPickerManager colorPickerManager, OPRSExternalPluginManager oprsExternalPluginManager) { super(false); + this.pluginList = pluginList; + this.configManager = configManager; + this.pluginManager = pluginManager; + this.externalPluginManager = externalPluginManager; + this.colorPickerManager = colorPickerManager; + this.oprsExternalPluginManager = oprsExternalPluginManager; + setLayout(new BorderLayout()); setBackground(ColorScheme.DARK_GRAY_COLOR); @@ -333,10 +339,10 @@ class ConfigPanel extends PluginPanel final Map sectionWidgets = new HashMap<>(); final Map titleWidgets = new HashMap<>(); final Map topLevelPanels = new TreeMap<>((a, b) -> - ComparisonChain.start() - .compare(a.position(), b.position()) - .compare(a.name(), b.name()) - .result()); + ComparisonChain.start() + .compare(a.position(), b.position()) + .compare(a.name(), b.name()) + .result()); for (ConfigSectionDescriptor csd : cd.getSections()) { @@ -353,8 +359,8 @@ class ConfigPanel extends PluginPanel // For whatever reason, the header extends out by a single pixel when closed. Adding a single pixel of // border on the right only affects the width when closed, fixing the issue. sectionHeader.setBorder(new CompoundBorder( - new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), - new EmptyBorder(0, 0, 3, 1))); + new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), + new EmptyBorder(0, 0, 3, 1))); section.add(sectionHeader, BorderLayout.NORTH); final JButton sectionToggle = new JButton(isOpen ? SECTION_RETRACT_ICON : SECTION_EXPAND_ICON); @@ -376,8 +382,8 @@ class ConfigPanel extends PluginPanel sectionContents.setLayout(new DynamicGridLayout(0, 1, 0, 5)); sectionContents.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); sectionContents.setBorder(new CompoundBorder( - new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), - new EmptyBorder(BORDER_OFFSET, 0, BORDER_OFFSET, 0))); + new MatteBorder(0, 0, 1, 0, ColorScheme.MEDIUM_GRAY_COLOR), + new EmptyBorder(BORDER_OFFSET, 0, BORDER_OFFSET, 0))); sectionContents.setVisible(isOpen); section.add(sectionContents, BorderLayout.SOUTH); @@ -462,250 +468,30 @@ class ConfigPanel extends PluginPanel configEntryName.setToolTipText("" + name + ":
" + cid.getItem().description() + ""); PluginListItem.addLabelPopupMenu(configEntryName, createResetMenuItem(pluginConfig, cid)); item.add(configEntryName, BorderLayout.CENTER); - item.setName(cid.getItem().keyName()); - - if (cid.getType() == Button.class) - { - try - { - ConfigItem cidItem = cid.getItem(); - JButton button = new JButton(cidItem.name()); - button.addActionListener((e) -> - { - ConfigButtonClicked event = new ConfigButtonClicked(); - event.setGroup(cd.getGroup().value()); - event.setKey(cid.getItem().keyName()); - eventBus.post(event); - }); - item.add(button); - } - catch (Exception ex) - { - log.error("Adding action listener failed: {}", ex.getMessage()); - ex.printStackTrace(); - } - } if (cid.getType() == boolean.class) { - JCheckBox checkbox = new ToggleButton(); - checkbox.setPreferredSize(new Dimension(26, 25)); - checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); - checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); - - item.add(checkbox, BorderLayout.EAST); + item.add(createCheckbox(cd, cid), BorderLayout.EAST); } - - if (cid.getType().isAssignableFrom(Consumer.class)) + else if (cid.getType() == int.class) { - item.remove(configEntryName); - - JButton button = new JButton(cid.getItem().name()); - button.addActionListener((e) -> - { - log.debug("Running consumer: {}.{}", cd.getGroup().value(), cid.getItem().keyName()); - configManager.getConsumer(cd.getGroup().value(), cid.getItem().keyName()).accept(pluginConfig.getPlugin()); - }); - - item.add(button, BorderLayout.CENTER); + item.add(createIntSpinner(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == int.class) - { - int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - - Units units = cid.getUnits(); - Range range = cid.getRange(); - int min = 0, max = Integer.MAX_VALUE; - if (range != null) - { - min = range.min(); - max = range.max(); - } - - // Config may previously have been out of range - value = Ints.constrainToRange(value, min, max); - - if (max < Integer.MAX_VALUE) - { - JLabel sliderValueLabel = new JLabel(); - JSlider slider = new JSlider(min, max, value); - slider.setBackground(ColorScheme.DARK_GRAY_COLOR); - if (units != null) - { - sliderValueLabel.setText(slider.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(slider.getValue())); - } - slider.setPreferredSize(new Dimension(80, 25)); - slider.addChangeListener((l) -> - { - if (units != null) - { - sliderValueLabel.setText(slider.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(slider.getValue())); - } - - if (!slider.getValueIsAdjusting()) - { - changeConfiguration(slider, cd, cid); - } - } - ); - - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.setUI(new BasicSpinnerUI() - { - protected Component createNextButton() - { - return null; - } - - protected Component createPreviousButton() - { - return null; - } - }); - - JPanel subPanel = new JPanel(); - subPanel.setPreferredSize(new Dimension(110, 25)); - subPanel.setLayout(new BorderLayout()); - - spinner.addChangeListener((ce) -> - { - changeConfiguration(spinner, cd, cid); - - if (units != null) - { - sliderValueLabel.setText(spinner.getValue() + units.value()); - } - else - { - sliderValueLabel.setText(String.valueOf(spinner.getValue())); - } - slider.setValue((Integer) spinner.getValue()); - - subPanel.add(sliderValueLabel, BorderLayout.WEST); - subPanel.add(slider, BorderLayout.EAST); - subPanel.remove(spinner); - - validate(); - repaint(); - }); - - sliderValueLabel.addMouseListener(new MouseAdapter() - { - public void mouseClicked(MouseEvent e) - { - spinner.setValue(slider.getValue()); - - subPanel.remove(sliderValueLabel); - subPanel.remove(slider); - subPanel.add(spinner, BorderLayout.EAST); - - validate(); - repaint(); - - final JTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); - tf.requestFocusInWindow(); - SwingUtilities.invokeLater(tf::selectAll); - } - }); - - subPanel.add(sliderValueLabel, BorderLayout.WEST); - subPanel.add(slider, BorderLayout.EAST); - - item.add(subPanel, BorderLayout.EAST); - } - else - { - SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - if (units != null) - { - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); - } - - item.add(spinner, BorderLayout.EAST); - } - } - else if (cid.getType() == double.class) { - double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); - - SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); - spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); - - item.add(spinner, BorderLayout.EAST); + item.add(createDoubleSpinner(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == String.class) + else if (cid.getType() == String.class) { - JTextComponent textField; - - if (cid.getItem().secret()) - { - textField = new JPasswordField(); - } - else - { - final JTextArea textArea = new JTextArea(); - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - textField = textArea; - } - - textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - - textField.addFocusListener(new FocusAdapter() - { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(textField, cd, cid); - } - }); + JTextComponent textField = createTextField(cd, cid); if (cid.getItem().parse()) { - JLabel parsingLabel = new JLabel(); - parsingLabel.setHorizontalAlignment(SwingConstants.CENTER); - parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15)); - - DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener(); - listener.addChangeListener(e -> - { - if (cid.getItem().parse()) - { - parseLabel(cid.getItem(), parsingLabel, textField.getText()); - } - }); - textField.getDocument().addDocumentListener(listener); + JLabel parsingLabel = createParseLabel(cid, textField); item.add(configEntryName, BorderLayout.NORTH); item.add(textField, BorderLayout.CENTER); - parseLabel(cid.getItem(), parsingLabel, textField.getText()); item.add(parsingLabel, BorderLayout.SOUTH); } @@ -714,168 +500,38 @@ class ConfigPanel extends PluginPanel item.add(textField, BorderLayout.SOUTH); } } - - if (cid.getType() == Color.class) + else if (cid.getType() == Color.class) { - Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); - - ColorJButton colorPickerBtn; - - boolean alphaHidden = cid.getAlpha() == null; - - if (existing == null) - { - colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK); - } - else - { - String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase(); - colorPickerBtn = new ColorJButton(colorHex, existing); - } - - colorPickerBtn.setFocusable(false); - colorPickerBtn.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - RuneliteColorPicker colorPicker = colorPickerManager.create( - SwingUtilities.windowForComponent(ConfigPanel.this), - colorPickerBtn.getColor(), - cid.getItem().name(), - alphaHidden); - colorPicker.setLocation(getLocationOnScreen()); - colorPicker.setOnColorChange(c -> - { - colorPickerBtn.setColor(c); - colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase()); - }); - colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid)); - colorPicker.setVisible(true); - } - }); - - item.add(colorPickerBtn, BorderLayout.EAST); + item.add(createColorPicker(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == Dimension.class) + else if (cid.getType() == Dimension.class) { - JPanel dimensionPanel = new JPanel(); - dimensionPanel.setLayout(new BorderLayout()); - - String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); - String[] splitStr = str.split("x"); - int width = Integer.parseInt(splitStr[0]); - int height = Integer.parseInt(splitStr[1]); - - SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1); - JSpinner widthSpinner = new JSpinner(widthModel); - Component widthEditor = widthSpinner.getEditor(); - JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField(); - widthSpinnerTextField.setColumns(4); - - SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); - JSpinner heightSpinner = new JSpinner(heightModel); - Component heightEditor = heightSpinner.getEditor(); - JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField(); - heightSpinnerTextField.setColumns(4); - - ChangeListener listener = e -> - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); - - widthSpinner.addChangeListener(listener); - heightSpinner.addChangeListener(listener); - - dimensionPanel.add(widthSpinner, BorderLayout.WEST); - dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER); - dimensionPanel.add(heightSpinner, BorderLayout.EAST); - - item.add(dimensionPanel, BorderLayout.EAST); + item.add(createDimension(cd, cid), BorderLayout.EAST); } - - if (cid.getType().isEnum()) + else if (cid.getType() instanceof Class && ((Class) cid.getType()).isEnum()) { - Class type = (Class) cid.getType(); - - JComboBox> box = new JComboBox>(type.getEnumConstants()); // NOPMD: UseDiamondOperator - // set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer - // to build components for each combobox element in order to compute the display size of the - // combobox - box.setRenderer(new ComboBoxListRenderer<>()); - box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); - box.setForeground(Color.WHITE); - box.setFocusable(false); - - try - { - Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); - box.setSelectedItem(selectedItem); - box.setToolTipText(Text.titleCase(selectedItem)); - } - catch (IllegalArgumentException ex) - { - log.debug("invalid seleced item", ex); - } - box.addItemListener(e -> - { - if (e.getStateChange() == ItemEvent.SELECTED) - { - changeConfiguration(box, cd, cid); - box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); - } - }); - item.add(box, BorderLayout.EAST); + item.add(createComboBox(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) + else if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class) { - Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), - (Class) cid.getType()); - - HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); - - button.addFocusListener(new FocusAdapter() - { - @Override - public void focusLost(FocusEvent e) - { - changeConfiguration(button, cd, cid); - } - }); - - item.add(button, BorderLayout.EAST); + item.add(createKeybind(cd, cid), BorderLayout.EAST); } - - if (cid.getType() == EnumSet.class) + else if (cid.getType() instanceof ParameterizedType) { - Class enumType = cid.getItem().enumClass(); - - EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), EnumSet.class); - if (enumSet == null || enumSet.contains(null)) + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + if (parameterizedType.getRawType() == Set.class) { - enumSet = EnumSet.noneOf(enumType); + item.add(createList(cd, cid), BorderLayout.SOUTH); } - - JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); - List jcheckboxes = new ArrayList<>(); - - for (Object obj : enumType.getEnumConstants()) + else if (parameterizedType.getRawType() == Consumer.class) { - String option = String.valueOf(obj).toLowerCase().replace("_", " "); - - JCheckBox checkbox = new ToggleButton(option); - checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); - checkbox.setSelected(enumSet.contains(obj)); - jcheckboxes.add(checkbox); - - enumsetLayout.add(checkbox); + item.remove(configEntryName); + item.add(createConsumer(cd, cid), BorderLayout.CENTER); + } + else if (parameterizedType.getRawType() == EnumSet.class) + { + item.add(createEnumSetLayout(cd, cid), BorderLayout.SOUTH); } - - jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); - - item.add(enumsetLayout, BorderLayout.SOUTH); } JPanel section = sectionWidgets.get(cid.getItem().section()); @@ -901,8 +557,8 @@ class ConfigPanel extends PluginPanel resetButton.addActionListener((e) -> { final int result = JOptionPane.showOptionDialog(resetButton, "Are you sure you want to reset this plugin's configuration?", - "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, new String[]{"Yes", "No"}, "No"); + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); if (result == JOptionPane.YES_OPTION) { @@ -927,6 +583,416 @@ class ConfigPanel extends PluginPanel revalidate(); } + private JButton createConsumer(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JButton button = new JButton(cid.getItem().name()); + button.addActionListener((e) -> + { + log.debug("Running consumer: {}.{}", cd.getGroup().value(), cid.getItem().keyName()); + configManager.getConsumer(cd.getGroup().value(), cid.getItem().keyName()).accept(pluginConfig.getPlugin()); + }); + + return button; + } + + private JCheckBox createCheckbox(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JCheckBox checkbox = new ToggleButton(); + checkbox.setPreferredSize(new Dimension(26, 25)); + checkbox.setSelected(Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()))); + checkbox.addActionListener(ae -> changeConfiguration(checkbox, cd, cid)); + return checkbox; + } + + private JComponent createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + int value = Integer.parseInt(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + + Units units = cid.getUnits(); + Range range = cid.getRange(); + int min = 0, max = Integer.MAX_VALUE; + if (range != null) + { + min = range.min(); + max = range.max(); + } + + // Config may previously have been out of range + value = Ints.constrainToRange(value, min, max); + + if (max < Integer.MAX_VALUE) + { + JLabel sliderValueLabel = new JLabel(); + JSlider slider = new JSlider(min, max, value); + slider.setBackground(ColorScheme.DARK_GRAY_COLOR); + if (units != null) + { + sliderValueLabel.setText(slider.getValue() + units.value()); + } + else + { + sliderValueLabel.setText(String.valueOf(slider.getValue())); + } + slider.setPreferredSize(new Dimension(80, 25)); + slider.addChangeListener((l) -> + { + if (units != null) + { + sliderValueLabel.setText(slider.getValue() + units.value()); + } + else + { + sliderValueLabel.setText(String.valueOf(slider.getValue())); + } + + if (!slider.getValueIsAdjusting()) + { + changeConfiguration(slider, cd, cid); + } + } + ); + + SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.setUI(new BasicSpinnerUI() + { + protected Component createNextButton() + { + return null; + } + + protected Component createPreviousButton() + { + return null; + } + }); + + JPanel subPanel = new JPanel(); + subPanel.setPreferredSize(new Dimension(110, 25)); + subPanel.setLayout(new BorderLayout()); + + spinner.addChangeListener((ce) -> + { + changeConfiguration(spinner, cd, cid); + + if (units != null) + { + sliderValueLabel.setText(spinner.getValue() + units.value()); + } + else + { + sliderValueLabel.setText(String.valueOf(spinner.getValue())); + } + slider.setValue((Integer) spinner.getValue()); + + subPanel.add(sliderValueLabel, BorderLayout.WEST); + subPanel.add(slider, BorderLayout.EAST); + subPanel.remove(spinner); + + validate(); + repaint(); + }); + + sliderValueLabel.addMouseListener(new MouseAdapter() + { + public void mouseClicked(MouseEvent e) + { + spinner.setValue(slider.getValue()); + + subPanel.remove(sliderValueLabel); + subPanel.remove(slider); + subPanel.add(spinner, BorderLayout.EAST); + + validate(); + repaint(); + + final JTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField(); + tf.requestFocusInWindow(); + SwingUtilities.invokeLater(tf::selectAll); + } + }); + + subPanel.add(sliderValueLabel, BorderLayout.WEST); + subPanel.add(slider, BorderLayout.EAST); + + return subPanel; + } + else + { + SpinnerModel model = new SpinnerNumberModel(value, min, max, 1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + + if (units != null) + { + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); + } + + return spinner; + } + } + + private JSpinner createDoubleSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + double value = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), double.class); + + SpinnerModel model = new SpinnerNumberModel(value, 0, Double.MAX_VALUE, 0.1); + JSpinner spinner = new JSpinner(model); + Component editor = spinner.getEditor(); + JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); + spinnerTextField.setColumns(SPINNER_FIELD_WIDTH); + spinner.addChangeListener(ce -> changeConfiguration(spinner, cd, cid)); + + return spinner; + } + + private JTextComponent createTextField(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JTextComponent textField; + + if (cid.getItem().secret()) + { + textField = new JPasswordField(); + } + else + { + final JTextArea textArea = new JTextArea(); + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + textField = textArea; + } + + textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + textField.setText(configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + + textField.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(textField, cd, cid); + } + }); + + return textField; + } + + private JLabel createParseLabel(ConfigItemDescriptor cid, JTextComponent textField) + { + JLabel parsingLabel = new JLabel(); + parsingLabel.setHorizontalAlignment(SwingConstants.CENTER); + parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15)); + + DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener(); + listener.addChangeListener(e -> + { + if (cid.getItem().parse()) + { + parseLabel(cid.getItem(), parsingLabel, textField.getText()); + } + }); + textField.getDocument().addDocumentListener(listener); + + return parsingLabel; + } + + private ColorJButton createColorPicker(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Color existing = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Color.class); + + ColorJButton colorPickerBtn; + + boolean alphaHidden = cid.getAlpha() == null; + + if (existing == null) + { + colorPickerBtn = new ColorJButton("Pick a color", Color.BLACK); + } + else + { + String colorHex = "#" + (alphaHidden ? ColorUtil.colorToHexCode(existing) : ColorUtil.colorToAlphaHexCode(existing)).toUpperCase(); + colorPickerBtn = new ColorJButton(colorHex, existing); + } + + colorPickerBtn.setFocusable(false); + colorPickerBtn.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + RuneliteColorPicker colorPicker = colorPickerManager.create( + SwingUtilities.windowForComponent(ConfigPanel.this), + colorPickerBtn.getColor(), + cid.getItem().name(), + alphaHidden); + colorPicker.setLocation(getLocationOnScreen()); + colorPicker.setOnColorChange(c -> + { + colorPickerBtn.setColor(c); + colorPickerBtn.setText("#" + (alphaHidden ? ColorUtil.colorToHexCode(c) : ColorUtil.colorToAlphaHexCode(c)).toUpperCase()); + }); + colorPicker.setOnClose(c -> changeConfiguration(colorPicker, cd, cid)); + colorPicker.setVisible(true); + } + }); + + return colorPickerBtn; + } + + private JPanel createDimension(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + JPanel dimensionPanel = new JPanel(); + dimensionPanel.setLayout(new BorderLayout()); + + String str = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); + String[] splitStr = str.split("x"); + int width = Integer.parseInt(splitStr[0]); + int height = Integer.parseInt(splitStr[1]); + + SpinnerModel widthModel = new SpinnerNumberModel(width, 0, Integer.MAX_VALUE, 1); + JSpinner widthSpinner = new JSpinner(widthModel); + Component widthEditor = widthSpinner.getEditor(); + JFormattedTextField widthSpinnerTextField = ((JSpinner.DefaultEditor) widthEditor).getTextField(); + widthSpinnerTextField.setColumns(4); + + SpinnerModel heightModel = new SpinnerNumberModel(height, 0, Integer.MAX_VALUE, 1); + JSpinner heightSpinner = new JSpinner(heightModel); + Component heightEditor = heightSpinner.getEditor(); + JFormattedTextField heightSpinnerTextField = ((JSpinner.DefaultEditor) heightEditor).getTextField(); + heightSpinnerTextField.setColumns(4); + + ChangeListener listener = e -> + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue()); + + widthSpinner.addChangeListener(listener); + heightSpinner.addChangeListener(listener); + + dimensionPanel.add(widthSpinner, BorderLayout.WEST); + dimensionPanel.add(new JLabel(" x "), BorderLayout.CENTER); + dimensionPanel.add(heightSpinner, BorderLayout.EAST); + + return dimensionPanel; + } + + private JComboBox> createComboBox(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Class type = (Class) cid.getType(); + + JComboBox> box = new JComboBox>(type.getEnumConstants()); // NOPMD: UseDiamondOperator + // set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer + // to build components for each combobox element in order to compute the display size of the + // combobox + box.setRenderer(listCellRenderer); + box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25)); + box.setForeground(Color.WHITE); + box.setFocusable(false); + + try + { + Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); + box.setSelectedItem(selectedItem); + box.setToolTipText(Text.titleCase(selectedItem)); + } + catch (IllegalArgumentException ex) + { + log.debug("invalid selected item", ex); + } + box.addItemListener(e -> + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + changeConfiguration(box, cd, cid); + box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); + } + }); + + return box; + } + + private HotkeyButton createKeybind(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(), + cid.getItem().keyName(), + (Class) cid.getType()); + + HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class); + + button.addFocusListener(new FocusAdapter() + { + @Override + public void focusLost(FocusEvent e) + { + changeConfiguration(button, cd, cid); + } + }); + + return button; + } + + private JPanel createList(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + ParameterizedType parameterizedType = (ParameterizedType) cid.getType(); + Class type = (Class) parameterizedType.getActualTypeArguments()[0]; + Set set = configManager.getConfiguration(cd.getGroup().value(), null, + cid.getItem().keyName(), parameterizedType); + + JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); + List jcheckboxes = new ArrayList<>(); + + Set selectedItems = new HashSet(Objects.requireNonNullElse(set, Collections.emptySet())); + + for (Object obj : type.getEnumConstants()) + { + ToggleButton checkbox = new ToggleButton(obj); + checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); + checkbox.setSelected(selectedItems.contains(obj)); + jcheckboxes.add(checkbox); + + enumsetLayout.add(checkbox); + } + + jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); + + return enumsetLayout; + } + + private JPanel createEnumSetLayout(ConfigDescriptor cd, ConfigItemDescriptor cid) + { + Class enumType = cid.getItem().enumClass(); + + EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), + cid.getItem().keyName(), EnumSet.class); + if (enumSet == null || enumSet.contains(null)) + { + enumSet = EnumSet.noneOf(enumType); + } + + JPanel enumsetLayout = new JPanel(new GridLayout(0, 2)); + List jcheckboxes = new ArrayList<>(); + + for (Object obj : enumType.getEnumConstants()) + { + String option = Text.titleCase((Enum) obj); + + ToggleButton checkbox = new ToggleButton(option); + checkbox.setBackground(ColorScheme.DARK_GRAY_COLOR); + checkbox.setSelected(enumSet.toString().contains(String.valueOf(obj))); + jcheckboxes.add(checkbox); + + enumsetLayout.add(checkbox); + } + + jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid))); + + return enumsetLayout; + } + private Boolean parse(ConfigItem item, String value) { try @@ -964,32 +1030,32 @@ class ConfigPanel extends PluginPanel } } - private void changeConfiguration(List components, ConfigDescriptor cd, ConfigItemDescriptor cid) + private void changeConfiguration(List components, ConfigDescriptor cd, ConfigItemDescriptor cid) { - Class enumType = cid.getItem().enumClass(); - EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(), - cid.getItem().keyName(), EnumSet.class); - if (enumSet == null) + if (cid.getItem().enumClass() != Enum.class) { + EnumSet enumSet = EnumSet.noneOf(cid.getItem().enumClass()); + //noinspection unchecked - enumSet = EnumSet.noneOf(enumType); - } - enumSet.clear(); - - EnumSet finalEnumSet = enumSet; - - //noinspection unchecked - components.forEach(value -> - { - if (value.isSelected()) + components.forEach(value -> { - finalEnumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_"))); - } - }); + if (value.isSelected()) + { + enumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_"))); + } + }); - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), finalEnumSet); - - rebuild(); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), enumSet); + } + else + { + Set values = components + .stream() + .filter(ToggleButton::isSelected) + .map(ToggleButton::getObject) + .collect(Collectors.toSet()); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), values); + } } private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid) @@ -999,8 +1065,8 @@ class ConfigPanel extends PluginPanel if (!Strings.isNullOrEmpty(configItem.warning())) { final int result = JOptionPane.showOptionDialog(component, configItem.warning(), - "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, new String[]{"Yes", "No"}, "No"); + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); if (result != JOptionPane.YES_OPTION) { @@ -1019,11 +1085,6 @@ class ConfigPanel extends PluginPanel JSpinner spinner = (JSpinner) component; configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), "" + spinner.getValue()); } - else if (component instanceof JSlider) - { - JSlider slider = (JSlider) component; - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), slider.getValue()); - } else if (component instanceof JTextComponent) { JTextComponent textField = (JTextComponent) component; @@ -1044,6 +1105,13 @@ class ConfigPanel extends PluginPanel HotkeyButton hotkeyButton = (HotkeyButton) component; configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), hotkeyButton.getValue()); } + else if (component instanceof JList) + { + JList list = (JList) component; + List selectedValues = list.getSelectedValuesList(); + + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Sets.newHashSet(selectedValues)); + } enableDisable(component, cid); rebuild(); @@ -1071,7 +1139,7 @@ class ConfigPanel extends PluginPanel private void onExternalPluginsChanged(ExternalPluginsChanged ev) { if (pluginManager.getPlugins().stream() - .noneMatch(p -> p == this.pluginConfig.getPlugin())) + .noneMatch(p -> p == this.pluginConfig.getPlugin())) { pluginList.getMuxer().popState(); } @@ -1108,10 +1176,10 @@ class ConfigPanel extends PluginPanel boolean show = false; List itemHide = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(String.format("%s || %s", cid.getItem().unhide(), cid.getItem().hide())); + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(String.format("%s || %s", cid.getItem().unhide(), cid.getItem().hide())); for (ConfigItemDescriptor cid2 : cd.getItems()) { @@ -1121,7 +1189,7 @@ class ConfigPanel extends PluginPanel { show = Boolean.parseBoolean(configManager.getConfiguration(cd.getGroup().value(), cid2.getItem().keyName())); } - else if (cid2.getType().isEnum()) + else if (cid2.getType() instanceof Class && ((Class) cid2.getType()).isEnum()) { Class type = (Class) cid2.getType(); try @@ -1130,20 +1198,20 @@ class ConfigPanel extends PluginPanel if (!cid.getItem().unhideValue().equals("")) { List unhideValue = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(cid.getItem().unhideValue()); + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(cid.getItem().unhideValue()); show = unhideValue.contains(selectedItem.toString()); } else if (!cid.getItem().hideValue().equals("")) { List hideValue = Splitter - .onPattern("\\|\\|") - .trimResults() - .omitEmptyStrings() - .splitToList(cid.getItem().hideValue()); + .onPattern("\\|\\|") + .trimResults() + .omitEmptyStrings() + .splitToList(cid.getItem().hideValue()); show = !hideValue.contains(selectedItem.toString()); } 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 64e12e7841..792e648f63 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 @@ -490,7 +490,6 @@ public class DevToolsPlugin extends Plugin } entry.setTarget(entry.getTarget() + " " + ColorUtil.prependColorTag("(" + info + ")", JagexColors.MENU_TARGET)); - client.setMenuEntries(entries); } } } 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 5e5e9a6011..ed99e6ef70 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 @@ -48,16 +48,16 @@ public class WidgetInfoTableModel extends AbstractTableModel private static final int COL_FIELD = 0; private static final int COL_VALUE = 1; - private final List fields = populateWidgetFields(); + private final List> fields = populateWidgetFields(); private Widget widget = null; - private Map values = null; + private Map, Object> values = null; public void setWidget(Widget w) { clientThread.invoke(() -> { - Map newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( + Map, Object> newValues = w == null ? null : fields.stream().collect(ImmutableMap.toImmutableMap( Function.identity(), i -> i.getValue(w) )); @@ -137,9 +137,9 @@ public class WidgetInfoTableModel extends AbstractTableModel }); } - private List populateWidgetFields() + private List> populateWidgetFields() { - List out = new ArrayList<>(); + List> out = new ArrayList<>(); out.add(new WidgetField<>("Id", Widget::getId)); out.add(new WidgetField<>("Type", Widget::getType, Widget::setType, Integer.class)); @@ -209,6 +209,11 @@ public class WidgetInfoTableModel extends AbstractTableModel } return null; })); + out.add(new WidgetField<>("OnOpListener", Widget::getOnOpListener)); + out.add(new WidgetField<>("OnKeyListener", Widget::getOnKeyListener)); + out.add(new WidgetField<>("OnLoadListener", Widget::getOnLoadListener)); + out.add(new WidgetField<>("OnInvTransmitListener", Widget::getOnInvTransmitListener)); + out.add(new WidgetField<>("OnVarTransmitListener", Widget::getOnVarTransmitListener)); return out; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java index 8bdc7baa00..592561219f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java @@ -487,7 +487,7 @@ class WidgetInspector extends DevToolsFrame client.setSpellSelected(false); ev.consume(); - Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction().getId(), ev.getParam0(), ev.getParam1()); + Object target = getWidgetOrWidgetItemForMenuOption(ev.getMenuAction(), ev.getParam0(), ev.getParam1()); if (target == null) { return; @@ -516,8 +516,8 @@ class WidgetInspector extends DevToolsFrame for (int i = 0; i < menuEntries.length; i++) { MenuEntry entry = menuEntries[i]; - if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET.getId() - && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() != MenuAction.ITEM_USE_ON_WIDGET + && entry.getType() != MenuAction.SPELL_CAST_ON_WIDGET) { continue; } @@ -532,8 +532,6 @@ class WidgetInspector extends DevToolsFrame entry.setTarget(ColorUtil.wrapWithColorTag(name, color)); } - - client.setMenuEntries(menuEntries); } Color colorForWidget(int index, int length) @@ -543,9 +541,9 @@ class WidgetInspector extends DevToolsFrame return Color.getHSBColor(h, 1, 1); } - Object getWidgetOrWidgetItemForMenuOption(int type, int param0, int param1) + Object getWidgetOrWidgetItemForMenuOption(MenuAction type, int param0, int param1) { - if (type == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (type == MenuAction.SPELL_CAST_ON_WIDGET) { Widget w = client.getWidget(param1); if (param0 != -1) @@ -555,7 +553,7 @@ class WidgetInspector extends DevToolsFrame return w; } - else if (type == MenuAction.ITEM_USE_ON_WIDGET.getId()) + else if (type == MenuAction.ITEM_USE_ON_WIDGET) { Widget w = client.getWidget(param1); return w.getWidgetItem(param0); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java index 8eb163ba53..8d64881631 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -93,6 +93,7 @@ enum Emoji XD("Xd"), SPOON("--o"), WEARY_FACE("Dx"), + ROCKETSHIP("=="), // >==> ; private static final Map emojiMap; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java index 441820c465..9c556c3dec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java @@ -28,9 +28,11 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("friendlist") +@ConfigGroup(FriendListConfig.GROUP) public interface FriendListConfig extends Config { + String GROUP = "friendlist"; + @ConfigItem( keyName = "showWorldOnLogin", name = "Show world on login", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index da5ebda38b..b3d85305ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -26,30 +26,40 @@ package net.runelite.client.plugins.friendlist; import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; +import java.util.Iterator; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ChatPlayer; import net.runelite.api.Client; import net.runelite.api.Friend; import net.runelite.api.Ignore; +import net.runelite.api.MenuAction; import net.runelite.api.MessageNode; import net.runelite.api.NameableContainer; +import net.runelite.api.PendingLogin; import net.runelite.api.ScriptID; import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptPostFired; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +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.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.task.Schedule; import net.runelite.client.util.Text; @PluginDescriptor( name = "Friend List", description = "Add extra information to the friend and ignore lists" ) +@Slf4j public class FriendListPlugin extends Plugin { private static final int MAX_FRIENDS_P2P = 400; @@ -58,12 +68,21 @@ public class FriendListPlugin extends Plugin private static final int MAX_IGNORES_P2P = 400; private static final int MAX_IGNORES_F2P = 100; + private static final String HIDE_NOTIFICATIONS = "Hide notifications"; + private static final String SHOW_NOTIFICATIONS = "Show notifications"; + @Inject private Client client; @Inject private FriendListConfig config; + @Inject + private ConfigManager configManager; + + @Inject + private ChatMessageManager chatMessageManager; + @Provides FriendListConfig getConfig(ConfigManager configManager) { @@ -144,6 +163,46 @@ public class FriendListPlugin extends Plugin } } + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); + + // Look for "Message" on friends list + if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) + { + String friend = Text.toJagexName(Text.removeTags(event.getTarget())); + + client.createMenuEntry(-1) + .setOption(isHideNotification(friend) ? SHOW_NOTIFICATIONS : HIDE_NOTIFICATIONS) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + boolean hidden = isHideNotification(friend); + setHideNotifications(friend, !hidden); + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .value("Login notifications for " + friend + " are now " + (hidden ? "shown." : "hidden.")) + .build()); + }); + } + } + + @Schedule(period = 5, unit = ChronoUnit.SECONDS) + public void setHideNotifications() + { + for (Iterator it = client.getFriendContainer().getPendingLogins().iterator(); it.hasNext(); ) + { + PendingLogin pendingLogin = it.next(); + if (isHideNotification(Text.toJagexName(pendingLogin.getName()))) + { + log.debug("Removing login notification for {}", pendingLogin.getName()); + it.remove(); + } + } + } + private void setFriendsListTitle(final String title) { Widget friendListTitleWidget = client.getWidget(WidgetInfo.FRIEND_CHAT_TITLE); @@ -173,4 +232,21 @@ public class FriendListPlugin extends Plugin return null; } + + private void setHideNotifications(String friend, boolean hide) + { + if (hide) + { + configManager.setConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, true); + } + else + { + configManager.unsetConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend); + } + } + + private boolean isHideNotification(String friend) + { + return configManager.getConfiguration(FriendListConfig.GROUP, "hidenotification_" + friend, Boolean.class) == Boolean.TRUE; + } } 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 088a782c9d..c274b74834 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 @@ -28,7 +28,6 @@ package net.runelite.client.plugins.friendnotes; import com.google.common.base.Strings; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.Color; import java.awt.image.BufferedImage; @@ -43,12 +42,10 @@ import net.runelite.api.GameState; import net.runelite.api.Ignore; import net.runelite.api.IndexedSprite; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Nameable; import net.runelite.api.ScriptID; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NameableNameChanged; import net.runelite.api.events.RemovedFriend; import net.runelite.api.events.ScriptCallbackEvent; @@ -235,7 +232,7 @@ public class FriendNotesPlugin extends Plugin @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - final int groupId = WidgetInfo.TO_GROUP(event.getParam1()); + final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); // Look for "Message" on friends list if ((groupId == WidgetInfo.FRIENDS_LIST.getGroupId() && event.getOption().equals("Message")) || @@ -245,16 +242,31 @@ public class FriendNotesPlugin extends Plugin setHoveredFriend(Text.toJagexName(Text.removeTags(event.getTarget()))); // Build "Add Note" or "Edit Note" menu entry - final MenuEntry addNote = new MenuEntry(); - addNote.setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE); - addNote.setType(MenuAction.RUNELITE.getId()); - addNote.setTarget(event.getTarget()); //Preserve color codes here - addNote.setParam0(event.getActionParam0()); - addNote.setParam1(event.getParam1()); + client.createMenuEntry(-1) + .setOption(hoveredFriend == null || hoveredFriend.getNote() == null ? ADD_NOTE : EDIT_NOTE) + .setType(MenuAction.RUNELITE) + .setTarget(event.getTarget()) //Preserve color codes here + .onClick(e -> + { + //Friends have color tags + final String sanitizedTarget = Text.toJagexName(Text.removeTags(e.getTarget())); + final String note = getFriendNote(sanitizedTarget); - // Add menu entry - final MenuEntry[] menuEntries = ObjectArrays.concat(client.getMenuEntries(), addNote); - client.setMenuEntries(menuEntries); + // Open the new chatbox input dialog + chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) + .value(Strings.nullToEmpty(note)) + .onDone((content) -> + { + if (content == null) + { + return; + } + + content = Text.removeTags(content).trim(); + log.debug("Set note for '{}': '{}'", sanitizedTarget, content); + setFriendNote(sanitizedTarget, content); + }).build(); + }); } else if (hoveredFriend != null) { @@ -262,46 +274,6 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - final int groupId = WidgetInfo.TO_GROUP(event.getParam1()); - - if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() || groupId == WidgetInfo.IGNORE_LIST.getGroupId()) - { - if (Strings.isNullOrEmpty(event.getMenuTarget())) - { - return; - } - - // 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 - chatboxPanelManager.openTextInput(String.format(NOTE_PROMPT_FORMAT, sanitizedTarget, CHARACTER_LIMIT)) - .value(Strings.nullToEmpty(note)) - .onDone((content) -> - { - if (content == null) - { - return; - } - - content = Text.removeTags(content).trim(); - log.debug("Set note for '{}': '{}'", sanitizedTarget, content); - setFriendNote(sanitizedTarget, content); - }).build(); - } - } - - } - @Subscribe public void onNameableNameChanged(NameableNameChanged event) { 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 b275fd7d4e..062c810ffa 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 @@ -1608,7 +1608,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks modelY = y + client.getCameraY2(); modelZ = z + client.getCameraZ2(); modelOrientation = orientation; - int triangleCount = model.getTrianglesCount(); + int triangleCount = model.getFaceCount(); vertexBuffer.ensureCapacity(12 * triangleCount); uvBuffer.ensureCapacity(12 * triangleCount); @@ -1632,7 +1632,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks model.calculateExtreme(orientation); client.checkClickbox(model, orientation, pitchSin, pitchCos, yawSin, yawCos, x, y, z, hash); - int tc = Math.min(MAX_TRIANGLE, model.getTrianglesCount()); + int tc = Math.min(MAX_TRIANGLE, model.getFaceCount()); int uvOffset = model.getUvBufferOffset(); GpuIntBuffer b = bufferForTriangles(tc); 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 910f8b3147..82f8676ce5 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 @@ -379,7 +379,7 @@ class SceneUploader public int pushModel(Model model, GpuIntBuffer vertexBuffer, GpuFloatBuffer uvBuffer) { - final int triangleCount = Math.min(model.getTrianglesCount(), GpuPlugin.MAX_TRIANGLE); + final int triangleCount = Math.min(model.getFaceCount(), GpuPlugin.MAX_TRIANGLE); vertexBuffer.ensureCapacity(triangleCount * 12); uvBuffer.ensureCapacity(triangleCount * 12); @@ -388,20 +388,25 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); float[] uv = model.getFaceTextureUVCoordinates(); + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int len = 0; for (int face = 0; face < triangleCount; ++face) { @@ -429,12 +434,22 @@ class SceneUploader len += 3; continue; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int packAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + int triangleA = indices1[face]; + int triangleB = indices2[face]; + int triangleC = indices3[face]; vertexBuffer.put(vertexX[triangleA], vertexY[triangleA], vertexZ[triangleA], packAlphaPriority | color1); vertexBuffer.put(vertexX[triangleB], vertexY[triangleB], vertexZ[triangleB], packAlphaPriority | color2); @@ -458,26 +473,31 @@ class SceneUploader final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] trianglesX = model.getTrianglesX(); - final int[] trianglesY = model.getTrianglesY(); - final int[] trianglesZ = model.getTrianglesZ(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); final int[] color1s = model.getFaceColors1(); final int[] color2s = model.getFaceColors2(); final int[] color3s = model.getFaceColors3(); - final byte[] transparencies = model.getTriangleTransparencies(); + final byte[] transparencies = model.getFaceTransparencies(); final short[] faceTextures = model.getFaceTextures(); final byte[] facePriorities = model.getFaceRenderPriorities(); - int triangleA = trianglesX[face]; - int triangleB = trianglesY[face]; - int triangleC = trianglesZ[face]; + final int triangleA = indices1[face]; + final int triangleB = indices2[face]; + final int triangleC = indices3[face]; int color1 = color1s[face]; int color2 = color2s[face]; int color3 = color3s[face]; + final byte overrideAmount = model.getOverrideAmount(); + final byte overrideHue = model.getOverrideHue(); + final byte overrideSat = model.getOverrideSaturation(); + final byte overrideLum = model.getOverrideLuminance(); + int packedAlphaPriority = packAlphaPriority(faceTextures, transparencies, facePriorities, face); int sin = 0, cos = 0; @@ -505,6 +525,16 @@ class SceneUploader } return 3; } + // HSL override is not applied to flat shade faces or to textured faces + else if (faceTextures == null || faceTextures[face] == -1) + { + if (overrideAmount > 0) + { + color1 = interpolateHSL(color1, overrideHue, overrideSat, overrideLum, overrideAmount); + color2 = interpolateHSL(color2, overrideHue, overrideSat, overrideLum, overrideAmount); + color3 = interpolateHSL(color3, overrideHue, overrideSat, overrideLum, overrideAmount); + } + } int a, b, c; @@ -605,4 +635,28 @@ class SceneUploader uvBuffer.put(0, 0, 0, 0); } } + + private static int interpolateHSL(int hsl, byte hue2, byte sat2, byte lum2, byte lerp) + { + int hue = hsl >> 10 & 63; + int sat = hsl >> 7 & 7; + int lum = hsl & 127; + int var9 = lerp & 255; + if (hue2 != -1) + { + hue += var9 * (hue2 - hue) >> 7; + } + + if (sat2 != -1) + { + sat += var9 * (sat2 - sat) >> 7; + } + + if (lum2 != -1) + { + lum += var9 * (lum2 - lum) >> 7; + } + + return (hue << 10 | sat << 7 | lum) & 65535; + } } 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 6075b23e11..c1c92c2f38 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 @@ -66,6 +66,7 @@ import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.ScriptID; import net.runelite.api.VarClientStr; +import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameStateChanged; @@ -74,7 +75,6 @@ import net.runelite.api.events.GrandExchangeSearched; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.ScriptPostFired; -import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; @@ -103,7 +103,6 @@ import net.runelite.client.util.Text; import net.runelite.http.api.ge.GrandExchangeClient; import net.runelite.http.api.ge.GrandExchangeTrade; import net.runelite.http.api.item.ItemStats; -import net.runelite.http.api.osbuddy.OSBGrandExchangeClient; import net.runelite.http.api.worlds.WorldType; import okhttp3.OkHttpClient; import org.apache.commons.lang3.time.DurationFormatUtils; @@ -120,10 +119,9 @@ public class GrandExchangePlugin extends Plugin @VisibleForTesting static final int GE_SLOTS = 8; private static final int GE_LOGIN_BURST_WINDOW = 2; // ticks - private static final int OFFER_CONTAINER_ITEM = 21; - private static final int OFFER_DEFAULT_ITEM_ID = 6512; + private static final int GE_MAX_EXAMINE_LEN = 100; - private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; + private static final String BUY_LIMIT_GE_TEXT = "Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); @@ -182,9 +180,6 @@ public class GrandExchangePlugin extends Plugin @Inject private RuneLiteConfig runeLiteConfig; - private Widget grandExchangeText; - private String grandExchangeExamine; - @Inject private GrandExchangeClient grandExchangeClient; private int lastLoginTick; @@ -264,12 +259,6 @@ public class GrandExchangePlugin extends Plugin return configManager.getConfig(GrandExchangeConfig.class); } - @Provides - OSBGrandExchangeClient provideOsbGrandExchangeClient(OkHttpClient okHttpClient) - { - return new OSBGrandExchangeClient(okHttpClient); - } - @Provides GrandExchangeClient provideGrandExchangeClient(OkHttpClient okHttpClient) { @@ -317,7 +306,6 @@ public class GrandExchangePlugin extends Plugin clientToolbar.removeNavigation(button); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); - grandExchangeText = null; lastUsername = machineUuid = null; tradeSeq = 0; } @@ -574,8 +562,7 @@ public class GrandExchangePlugin extends Plugin case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID: case WidgetID.SHOP_INVENTORY_GROUP_ID: menuEntry.setOption(SEARCH_GRAND_EXCHANGE); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(entries); + menuEntry.setType(MenuAction.RUNELITE); } } @@ -588,31 +575,10 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) - { - switch (event.getGroupId()) - { - // Grand exchange was opened. - case WidgetID.GRAND_EXCHANGE_GROUP_ID: - grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT); - break; - // Grand exchange was closed (if it was open before). - case WidgetID.INVENTORY_GROUP_ID: - grandExchangeText = null; - break; - } - } - @Subscribe public void onScriptPostFired(ScriptPostFired event) { - // GE offers setup init - if (event.getScriptId() == ScriptID.GE_OFFERS_SETUP_BUILD) - { - rebuildGeText(); - } - else if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) + if (event.getScriptId() == ScriptID.GE_ITEM_SEARCH && config.highlightSearchMatch()) { highlightSearchMatches(); } @@ -739,7 +705,30 @@ public class GrandExchangePlugin extends Plugin @Subscribe public void onScriptCallbackEvent(ScriptCallbackEvent event) { - if (!event.getEventName().equals("setGETitle") || !config.showTotal()) + switch (event.getEventName()) + { + case "setGETitle": + setGeTitle(); + break; + case "geExamineText": + { + String[] stack = client.getStringStack(); + int sz = client.getStringStackSize(); + String fee = stack[sz - 2]; + String examine = stack[sz - 3]; + String text = setExamineText(examine, fee); + if (text != null) + { + stack[sz - 1] = text; + } + break; + } + } + } + + private void setGeTitle() + { + if (!config.showTotal()) { return; } @@ -818,39 +807,10 @@ public class GrandExchangePlugin extends Plugin } } - private void rebuildGeText() + private String setExamineText(String examine, String fee) { - if (grandExchangeText == null) - { - return; - } - Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER); - if (grandExchangeOffer == null) - { - return; - } - Widget grandExchangeItem = grandExchangeOffer.getChild(OFFER_CONTAINER_ITEM); - if (grandExchangeItem == null || grandExchangeItem.isHidden()) - { - return; - } - - final Widget geText = grandExchangeText; - final int itemId = grandExchangeItem.getItemId(); - - if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1) - { - // This item is invalid/nothing has been searched for - return; - } - - if (geText.getText() == grandExchangeExamine) - { - // if we've already set the text, don't set it again - return; - } - - String text = geText.getText(); + final int itemId = client.getVar(VarPlayer.CURRENT_GE_ITEM); + StringBuilder sb = new StringBuilder(); if (config.enableGELimits()) { @@ -859,7 +819,7 @@ public class GrandExchangePlugin extends Plugin // If we have item buy limit, append it if (itemStats != null && itemStats.getGeLimit() > 0) { - text += BUY_LIMIT_GE_TEXT + QuantityFormatter.formatNumber(itemStats.getGeLimit()); + sb.append(BUY_LIMIT_GE_TEXT).append(QuantityFormatter.formatNumber(itemStats.getGeLimit())); } } @@ -869,7 +829,7 @@ public class GrandExchangePlugin extends Plugin if (resetTime != null) { Duration remaining = Duration.between(Instant.now(), resetTime); - text += " (" + DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm") + ")"; + sb.append(" (").append(DurationFormatUtils.formatDuration(remaining.toMillis(), "H:mm")).append(")"); } } @@ -878,12 +838,41 @@ public class GrandExchangePlugin extends Plugin final int price = itemManager.getItemPriceWithSource(itemId, true); if (price > 0) { - text += "
Actively traded price: " + QuantityFormatter.formatNumber(price); + if (sb.length() > 0) + { + sb.append(" / "); + } + sb.append("Actively traded price: ").append(QuantityFormatter.formatNumber(price)); } } - grandExchangeExamine = text; - geText.setText(text); + if (sb.length() == 0) + { + return null; + } + + return shortenExamine(examine) + "
" + sb + "
" + fee; + } + + private static String shortenExamine(String examine) + { + int from = 0; + int idx; + while (true) + { + idx = examine.indexOf(' ', from); + if (idx == -1) + { + return examine; + } + if (idx > GE_MAX_EXAMINE_LEN && from > 0) + { + break; // use from + } + from = idx + 1; + } + + return examine.substring(0, from - 1) + "..."; } void openGeLink(String name, int itemId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 22f74c2353..6490f4d8d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -115,14 +115,6 @@ public class GroundItemsPlugin extends Plugin static final int MAX_QUANTITY = 65535; // ItemID for coins private static final int COINS = ItemID.COINS_995; - // Ground item menu options - private static final int FIRST_OPTION = MenuAction.GROUND_ITEM_FIRST_OPTION.getId(); - private static final int SECOND_OPTION = MenuAction.GROUND_ITEM_SECOND_OPTION.getId(); - private static final int THIRD_OPTION = MenuAction.GROUND_ITEM_THIRD_OPTION.getId(); // this is Take - private static final int FOURTH_OPTION = MenuAction.GROUND_ITEM_FOURTH_OPTION.getId(); - private static final int FIFTH_OPTION = MenuAction.GROUND_ITEM_FIFTH_OPTION.getId(); - private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId(); - private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE); @@ -344,9 +336,10 @@ public class GroundItemsPlugin extends Plugin { MenuEntry menuEntry = menuEntries[i]; - int menuType = menuEntry.getType(); - if (menuType == FIRST_OPTION || menuType == SECOND_OPTION || menuType == THIRD_OPTION - || menuType == FOURTH_OPTION || menuType == FIFTH_OPTION || menuType == EXAMINE_ITEM) + MenuAction menuType = menuEntry.getType(); + if (menuType == MenuAction.GROUND_ITEM_FIRST_OPTION || menuType == MenuAction.GROUND_ITEM_SECOND_OPTION + || menuType == MenuAction.GROUND_ITEM_THIRD_OPTION || menuType == MenuAction.GROUND_ITEM_FOURTH_OPTION + || menuType == MenuAction.GROUND_ITEM_FIFTH_OPTION || menuType == MenuAction.SPELL_CAST_ON_GROUND_ITEM) { for (MenuEntryWithCount entryWCount : newEntries) { @@ -490,15 +483,15 @@ public class GroundItemsPlugin extends Plugin { if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH) { - final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM; - if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry) + final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); + if (!(event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) && !telegrabEntry) { return; } final int itemId = event.getIdentifier(); final int sceneX = event.getActionParam0(); - final int sceneY = event.getParam1(); + final int sceneY = event.getActionParam1(); MenuEntry[] menuEntries = client.getMenuEntries(); MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; @@ -548,8 +541,6 @@ public class GroundItemsPlugin extends Plugin { lastEntry.setTarget(lastEntry.getTarget() + " (" + quantity + ")"); } - - client.setMenuEntries(menuEntries); } } 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 850f383439..e8de79d73e 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 @@ -30,7 +30,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -44,13 +43,11 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Tile; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; @@ -243,48 +240,34 @@ public class GroundMarkerPlugin extends Plugin final GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), null, null); final boolean exists = getPoints(regionId).contains(point); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + (exists ? 2 : 1)); - - MenuEntry mark = menuEntries[menuEntries.length - 1] = new MenuEntry(); - mark.setOption(exists ? UNMARK : MARK); - mark.setTarget(event.getTarget()); - mark.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-1) + .setOption(exists ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + markTile(target.getLocalLocation()); + } + }); if (exists) { - MenuEntry label = menuEntries[menuEntries.length - 2] = new MenuEntry(); - label.setOption(LABEL); - label.setTarget(event.getTarget()); - label.setType(MenuAction.RUNELITE.getId()); + client.createMenuEntry(-2) + .setOption(LABEL) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + Tile target = client.getSelectedSceneTile(); + if (target != null) + { + labelTile(target); + } + }); } - - client.setMenuEntries(menuEntries); - } - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId()) - { - return; - } - - Tile target = client.getSelectedSceneTile(); - if (target == null) - { - return; - } - - final String option = event.getMenuOption(); - if (option.equals(MARK) || option.equals(UNMARK)) - { - markTile(target.getLocalLocation()); - } - else if (option.equals(LABEL)) - { - labelTile(target); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java index d311a51319..a7661ff202 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -45,11 +45,10 @@ import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.events.WidgetMenuOptionClicked; +import net.runelite.api.MenuEntry; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; @@ -82,13 +81,13 @@ class GroundMarkerSharingManager void addImportExportMenuOptions() { - menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); - menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); + menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION, this::exportGroundMarkers); + menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION, this::promptForImport); } void addClearMenuOption() { - menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION); + menuManager.addManagedCustomMenu(CLEAR_MARKERS_OPTION, this::promptForClear); } void removeMenuOptions() @@ -98,36 +97,7 @@ class GroundMarkerSharingManager menuManager.removeManagedCustomMenu(CLEAR_MARKERS_OPTION); } - private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) - { - return event.getMenuTarget().equals(target.getMenuTarget()) && - event.getMenuOption().equals(target.getMenuOption()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - // ensure that the option clicked is the export markers option - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (widgetMenuClickedEquals(event, EXPORT_MARKERS_OPTION)) - { - exportGroundMarkers(); - } - else if (widgetMenuClickedEquals(event, IMPORT_MARKERS_OPTION)) - { - promptForImport(); - } - else if (widgetMenuClickedEquals(event, CLEAR_MARKERS_OPTION)) - { - promptForClear(); - } - } - - private void exportGroundMarkers() + private void exportGroundMarkers(MenuEntry menuEntry) { int[] regions = client.getMapRegions(); if (regions == null) @@ -156,7 +126,7 @@ class GroundMarkerSharingManager sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); } - private void promptForImport() + private void promptForImport(MenuEntry menuEntry) { final String clipboardText; try @@ -244,7 +214,7 @@ class GroundMarkerSharingManager sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); } - private void promptForClear() + private void promptForClear(MenuEntry entry) { int[] regions = client.getMapRegions(); if (regions == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 56673629e4..8f529b7834 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -61,13 +61,13 @@ import net.runelite.client.ui.components.materialtabs.MaterialTab; import net.runelite.client.ui.components.materialtabs.MaterialTabGroup; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.QuantityFormatter; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; -import static net.runelite.http.api.hiscore.HiscoreSkill.*; -import net.runelite.http.api.hiscore.HiscoreSkillType; -import net.runelite.http.api.hiscore.Skill; +import net.runelite.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreSkill; +import static net.runelite.client.hiscore.HiscoreSkill.*; +import net.runelite.client.hiscore.HiscoreSkillType; +import net.runelite.client.hiscore.Skill; import okhttp3.OkHttpClient; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -105,13 +105,13 @@ public class HiscorePanel extends PluginPanel GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI, KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN, KREEARRA, KRIL_TSUTSAROTH, MIMIC, - NIGHTMARE, PHOSANIS_NIGHTMARE, OBOR, SARACHNIS, - SCORPIA, SKOTIZO, TEMPOROSS, - THE_GAUNTLET, THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, - THEATRE_OF_BLOOD_HARD_MODE, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, - TZTOK_JAD, VENENATIS, VETION, - VORKATH, WINTERTODT, ZALCANO, - ZULRAH + NEX, NIGHTMARE, PHOSANIS_NIGHTMARE, + OBOR, SARACHNIS, SCORPIA, + SKOTIZO, TEMPOROSS, THE_GAUNTLET, + THE_CORRUPTED_GAUNTLET, THEATRE_OF_BLOOD, THEATRE_OF_BLOOD_HARD_MODE, + THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK, TZTOK_JAD, + VENENATIS, VETION, VORKATH, + WINTERTODT, ZALCANO, ZULRAH ); private static final HiscoreEndpoint[] ENDPOINTS = { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index 95f12ec821..8e567d37d7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.hiscore; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.util.EnumSet; @@ -39,7 +38,6 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.IconID; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Player; import net.runelite.api.WorldType; import net.runelite.api.events.ChatMessage; @@ -58,8 +56,7 @@ import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import org.apache.commons.lang3.ArrayUtils; +import net.runelite.client.hiscore.HiscoreEndpoint; @PluginDescriptor( name = "HiScore", @@ -169,46 +166,37 @@ public class HiscorePlugin extends Plugin || groupId == WidgetID.GROUP_IRON_GROUP_ID && (option.equals("Add friend") || option.equals("Remove friend") || option.equals("Remove ignore")) ) { - final MenuEntry lookup = new MenuEntry(); - lookup.setOption(LOOKUP); - lookup.setTarget(event.getTarget()); - lookup.setType(MenuAction.RUNELITE.getId()); - lookup.setParam0(event.getActionParam0()); - lookup.setParam1(event.getActionParam1()); - lookup.setIdentifier(event.getIdentifier()); - - insertMenuEntry(lookup, client.getMenuEntries()); + client.createMenuEntry(-2) + .setOption(LOOKUP) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .setIdentifier(event.getIdentifier()) + .onClick(e -> + { + // Determine proper endpoint from player name. + // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. + HiscoreEndpoint endpoint = findHiscoreEndpointFromPlayerName(e.getTarget()); + String target = Text.removeTags(e.getTarget()); + lookupPlayer(target, endpoint); + }); } } @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) - && event.getMenuOption().equals(LOOKUP)) + if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER && event.getMenuOption().equals(LOOKUP)) { - final String target; - HiscoreEndpoint endpoint; - if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + // The player id is included in the event, so we can use that to get the player name, + // which avoids having to parse out the combat level and any icons preceding the name. + Player player = client.getCachedPlayers()[event.getId()]; + if (player == null) { - // The player id is included in the event, so we can use that to get the player name, - // which avoids having to parse out the combat level and any icons preceding the name. - Player player = client.getCachedPlayers()[event.getId()]; - if (player == null) - { - return; - } + return; + } - endpoint = getWorldEndpoint(); - target = player.getName(); - } - else - { - // Determine proper endpoint from player name. - // TODO: look at target's world and determine if tournament/dmm endpoint should be used instead. - endpoint = findHiscoreEndpointFromPlayerName(event.getMenuTarget()); - target = Text.removeTags(event.getMenuTarget()); - } + String target = player.getName(); + HiscoreEndpoint endpoint = getWorldEndpoint(); lookupPlayer(target, endpoint); } @@ -236,14 +224,6 @@ public class HiscorePlugin extends Plugin localHiscoreEndpoint = findHiscoreEndpointFromLocalPlayer(); } - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - client.setMenuEntries(newMenu); - } - private void lookupPlayer(String playerName, HiscoreEndpoint endpoint) { SwingUtilities.invokeLater(() -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java index 00cadc1e22..3870803490 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/NameAutocompleter.java @@ -242,6 +242,7 @@ class NameAutocompleter implements KeyListener autocompleteName = Arrays.stream(cachedPlayers) .filter(Objects::nonNull) .map(Player::getName) + .filter(Objects::nonNull) .filter(n -> pattern.matcher(n).matches()) .findFirst(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java index f5cc4b6a51..8ed901350a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.instancemap; import com.google.inject.Binder; import javax.inject.Inject; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.WidgetMenuOptionClicked; import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyManager; @@ -72,7 +71,17 @@ public class InstanceMapPlugin extends Plugin private void addCustomOptions() { - menuManager.addManagedCustomMenu(openMapOption); + menuManager.addManagedCustomMenu(openMapOption, entry -> + { + if (overlay.isMapShown()) + { + closeMap(); + } + else + { + showMap(); + } + }); } private void removeCustomOptions() @@ -107,32 +116,6 @@ public class InstanceMapPlugin extends Plugin overlay.onGameStateChange(event); } - private boolean clickedOptionEquals(WidgetMenuOptionClicked event, WidgetMenuOption widgetMenuOption) - { - return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget()); - } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() != MINIMAP_WORLDMAP_OPTIONS) - { - return; - } - - if (clickedOptionEquals(event, openMapOption)) - { - if (overlay.isMapShown()) - { - closeMap(); - } - else - { - showMap(); - } - } - } - public void showMap() { overlay.setShowMap(true); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java index a5dd9c95da..0a14053e36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interacthighlight/InteractHighlightOverlay.java @@ -79,7 +79,7 @@ class InteractHighlightOverlay extends Overlay } MenuEntry top = menuEntries[menuEntries.length - 1]; - MenuAction menuAction = MenuAction.of(top.getType()); + MenuAction menuAction = top.getType(); switch (menuAction) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index cdbf26a845..d588ed42aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -28,14 +28,13 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.inject.Provides; import java.awt.Color; +import java.util.Arrays; import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.events.MenuOpened; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -46,7 +45,6 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; -import net.runelite.client.util.Text; @PluginDescriptor( name = "Inventory Tags", @@ -157,44 +155,11 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - editorMode = event.getMenuOption().equals(CONFIGURE) && Text.removeTags(event.getMenuTarget()).equals(MENU_TARGET); - refreshInventoryMenuOptions(); - } - } - - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE) - { - return; - } - - final String selectedMenu = Text.removeTags(event.getMenuTarget()); - - if (event.getMenuOption().equals(MENU_SET)) - { - setTag(event.getId(), selectedMenu); - } - else if (event.getMenuOption().equals(MENU_REMOVE)) - { - unsetTag(event.getId()); - } - } - @Subscribe public void onMenuOpened(final MenuOpened event) { final MenuEntry firstEntry = event.getFirstEntry(); - - if (firstEntry == null) + if (firstEntry == null || !editorMode) { return; } @@ -202,7 +167,7 @@ public class InventoryTagsPlugin extends Plugin final int widgetId = firstEntry.getParam1(); // Inventory item menu - if (widgetId == WidgetInfo.INVENTORY.getId() && editorMode) + if (widgetId == WidgetInfo.INVENTORY.getId()) { int itemId = firstEntry.getIdentifier(); @@ -211,26 +176,30 @@ public class InventoryTagsPlugin extends Plugin return; } - MenuEntry[] menuList = new MenuEntry[GROUPS.size() + 1]; - int num = 0; - - // preserve the 'Cancel' option as the client will reuse the first entry for Cancel and only resets option/action - menuList[num++] = event.getMenuEntries()[0]; + // Set menu to only be Cancel + client.setMenuEntries(Arrays.copyOf(client.getMenuEntries(), 1)); for (final String groupName : GROUPS) { final String group = getTag(itemId); - final MenuEntry newMenu = new MenuEntry(); final Color color = getGroupNameColor(groupName); - newMenu.setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET); - newMenu.setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))); - newMenu.setIdentifier(itemId); - newMenu.setParam1(widgetId); - newMenu.setType(MenuAction.RUNELITE.getId()); - menuList[num++] = newMenu; - } - client.setMenuEntries(menuList); + client.createMenuEntry(-1) + .setOption(groupName.equals(group) ? MENU_REMOVE : MENU_SET) + .setTarget(ColorUtil.prependColorTag(groupName, MoreObjects.firstNonNull(color, Color.WHITE))) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (e.getOption().equals(MENU_SET)) + { + setTag(itemId, groupName); + } + else + { + unsetTag(itemId); + } + }); + } } } @@ -270,15 +239,27 @@ public class InventoryTagsPlugin extends Plugin removeInventoryMenuOptions(); if (editorMode) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE, this::save); } else { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE, this::configure); } } + + private void save(MenuEntry menuEntry) + { + editorMode = false; + refreshInventoryMenuOptions(); + } + + private void configure(MenuEntry menuEntry) + { + editorMode = true; + refreshInventoryMenuOptions(); + } } 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 ea33e614f8..bea5de5af5 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 @@ -90,7 +90,7 @@ class ItemPricesOverlay extends Overlay } final MenuEntry menuEntry = menuEntries[last]; - final MenuAction action = MenuAction.of(menuEntry.getType()); + final MenuAction action = menuEntry.getType(); final int widgetId = menuEntry.getParam1(); final int groupId = WidgetInfo.TO_GROUP(widgetId); final boolean isAlching = menuEntry.getOption().equals("Cast") && menuEntry.getTarget().contains("High Level Alchemy"); 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 6a457ce2b7..58c2a66a6a 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 @@ -56,7 +56,6 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.PostItemComposition; -import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; @@ -75,7 +74,6 @@ import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfi import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.MorytaniaLegsMode; import static net.runelite.client.plugins.menuentryswapper.MenuEntrySwapperConfig.RadasBlessingMode; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "Menu Entry Swapper", @@ -516,24 +514,6 @@ public class MenuEntrySwapperPlugin extends Plugin clientThread.invoke(this::resetItemCompositionCache); } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) - { - if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB - || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_TAB) - { - String option = event.getMenuOption(); - String target = Text.removeTags(event.getMenuTarget()); - if ((option.equals(CONFIGURE) || option.equals(SAVE)) && (target.equals(LEFT_CLICK_MENU_TARGET) || target.equals(SHIFT_CLICK_MENU_TARGET))) - { - configuringShiftClick = option.equals(CONFIGURE) && target.equals(SHIFT_CLICK_MENU_TARGET); - configuringLeftClick = option.equals(CONFIGURE) && target.equals(LEFT_CLICK_MENU_TARGET); - rebuildCustomizationMenus(); - } - } - } - @Subscribe public void onMenuOpened(MenuOpened event) { @@ -601,11 +581,11 @@ public class MenuEntrySwapperPlugin extends Plugin for (MenuEntry entry : entries) { - final MenuAction menuAction = MenuAction.of(entry.getType()); + final MenuAction menuAction = entry.getType(); if (ITEM_MENU_TYPES.contains(menuAction) && entry.getIdentifier() == itemId) { - entry.setType(MenuAction.RUNELITE.getId()); + entry.setType(MenuAction.RUNELITE); if (activeAction == menuAction) { @@ -614,13 +594,11 @@ public class MenuEntrySwapperPlugin extends Plugin } } - final MenuEntry resetShiftClickEntry = new MenuEntry(); - resetShiftClickEntry.setOption(RESET); - resetShiftClickEntry.setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET); - resetShiftClickEntry.setIdentifier(itemId); - resetShiftClickEntry.setParam1(widgetId); - resetShiftClickEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry)); + client.createMenuEntry(-1) + .setOption(RESET) + .setTarget(configuringShiftClick ? SHIFT_CLICK_MENU_TARGET : LEFT_CLICK_MENU_TARGET) + .setType(MenuAction.RUNELITE) + .onClick(e -> unsetSwapConfig(configuringShiftClick, itemId)); } @Subscribe @@ -646,8 +624,8 @@ public class MenuEntrySwapperPlugin extends Plugin final int opId = isDepositBoxPlayerInventory ? shiftDepositMode.getIdentifierDepositBox() : isChambersOfXericStorageUnitPlayerInventory ? shiftDepositMode.getIdentifierChambersStorageUnit() : shiftDepositMode.getIdentifier(); - final int actionId = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY.getId() : MenuAction.CC_OP.getId(); - bankModeSwap(actionId, opId); + final MenuAction action = opId >= 6 ? MenuAction.CC_OP_LOW_PRIORITY : MenuAction.CC_OP; + bankModeSwap(action, opId); } // Swap to shift-click withdraw behavior @@ -657,22 +635,23 @@ public class MenuEntrySwapperPlugin extends Plugin && menuEntryAdded.getOption().startsWith("Withdraw")) { ShiftWithdrawMode shiftWithdrawMode = config.bankWithdrawShiftClick(); - final int actionId, opId; + final MenuAction action; + final int opId; if (widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_PRIVATE_GROUP_ID || widgetGroupId == WidgetID.CHAMBERS_OF_XERIC_STORAGE_UNIT_SHARED_GROUP_ID) { - actionId = MenuAction.CC_OP.getId(); + action = MenuAction.CC_OP; opId = shiftWithdrawMode.getIdentifierChambersStorageUnit(); } else { - actionId = shiftWithdrawMode.getMenuAction().getId(); + action = shiftWithdrawMode.getMenuAction(); opId = shiftWithdrawMode.getIdentifier(); } - bankModeSwap(actionId, opId); + bankModeSwap(action, opId); } } - private void bankModeSwap(int entryTypeId, int entryIdentifier) + private void bankModeSwap(MenuAction entryType, int entryIdentifier) { MenuEntry[] menuEntries = client.getMenuEntries(); @@ -680,10 +659,10 @@ public class MenuEntrySwapperPlugin extends Plugin { MenuEntry entry = menuEntries[i]; - if (entry.getType() == entryTypeId && entry.getIdentifier() == entryIdentifier) + if (entry.getType() == entryType && entry.getIdentifier() == entryIdentifier) { // Raise the priority of the op so it doesn't get sorted later - entry.setType(MenuAction.CC_OP.getId()); + entry.setType(MenuAction.CC_OP); menuEntries[i] = menuEntries[menuEntries.length - 1]; menuEntries[menuEntries.length - 1] = entry; @@ -713,17 +692,6 @@ public class MenuEntrySwapperPlugin extends Plugin String target = event.getMenuTarget(); ItemComposition itemComposition = itemManager.getItemComposition(itemId); - if (option.equals(RESET) && target.equals(SHIFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(true, itemId); - return; - } - if (option.equals(RESET) && target.equals(LEFT_CLICK_MENU_TARGET)) - { - unsetSwapConfig(false, itemId); - return; - } - if (!itemComposition.getName().equals(Text.removeTags(target))) { return; @@ -751,7 +719,7 @@ public class MenuEntrySwapperPlugin extends Plugin private void swapMenuEntry(MenuEntry[] menuEntries, int index, MenuEntry menuEntry) { final int eventId = menuEntry.getIdentifier(); - final MenuAction menuAction = MenuAction.of(menuEntry.getType()); + final MenuAction menuAction = menuEntry.getType(); final String option = Text.removeTags(menuEntry.getOption()).toLowerCase(); final String target = Text.removeTags(menuEntry.getTarget()).toLowerCase(); final NPC hintArrowNpc = client.getHintArrowNpc(); @@ -978,31 +946,31 @@ public class MenuEntrySwapperPlugin extends Plugin removeCusomizationMenus(); if (configuringLeftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_LC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_LC, this::save); } else if (configuringShiftClick) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_SAVE_SC, this::save); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_SAVE_SC, this::save); } else { // Left click if (config.leftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_LC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_LC, this::configure); } // Shift click if (config.shiftClickCustomization()) { - menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC); - menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC); + menuManager.addManagedCustomMenu(FIXED_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_INVENTORY_TAB_CONFIGURE_SC, this::configure); + menuManager.addManagedCustomMenu(RESIZABLE_INVENTORY_TAB_CONFIGURE_SC, this::configure); } } } @@ -1011,4 +979,18 @@ public class MenuEntrySwapperPlugin extends Plugin { return client.isKeyPressed(KeyCode.KC_SHIFT); } + + private void save(MenuEntry menuEntry) + { + configuringLeftClick = configuringShiftClick = false; + rebuildCustomizationMenus(); + } + + private void configure(MenuEntry menuEntry) + { + String target = Text.removeTags(menuEntry.getTarget()); + configuringShiftClick = target.equals(SHIFT_CLICK_MENU_TARGET); + configuringLeftClick = target.equals(LEFT_CLICK_MENU_TARGET); + rebuildCustomizationMenus(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java index 1e56b743eb..f9355f0aa5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightOverlay.java @@ -108,7 +108,7 @@ class MouseHighlightOverlay extends Overlay MenuEntry menuEntry = menuEntries[last]; String target = menuEntry.getTarget(); String option = menuEntry.getOption(); - MenuAction type = MenuAction.of(menuEntry.getType()); + MenuAction type = menuEntry.getType(); if (type == MenuAction.RUNELITE_OVERLAY || type == MenuAction.CC_OP_LOW_PRIORITY) { 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 679f773913..4ad21005b2 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 @@ -91,13 +91,6 @@ class NightmareZoneOverlay extends OverlayPanel return null; } - Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); - - if (nmzWidget != null) - { - nmzWidget.setHidden(true); - } - renderAbsorptionCounter(); final int currentPoints = client.getVar(Varbits.NMZ_POINTS); 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 ccd2a775c0..f95e2ab8a6 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,7 @@ import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Varbits; +import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ChatMessage; import net.runelite.client.events.ConfigChanged; import net.runelite.api.events.GameTick; @@ -121,6 +122,21 @@ public class NightmareZonePlugin extends Plugin return configManager.getConfig(NightmareZoneConfig.class); } + @Subscribe + public void onBeforeRender(BeforeRender beforeRender) + { + if (!isInNightmareZone() || !config.moveOverlay()) + { + return; + } + + Widget nmzWidget = client.getWidget(WidgetInfo.NIGHTMARE_ZONE); + if (nmzWidget != null) + { + nmzWidget.setHidden(true); + } + } + @Subscribe public void onGameTick(GameTick event) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 7efaa91640..4ee62c2545 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -31,7 +31,6 @@ import com.google.inject.Provides; import java.awt.Color; import java.time.Instant; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -57,7 +56,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; @@ -271,7 +269,6 @@ public class NpcIndicatorsPlugin extends Plugin final MenuEntry menuEntry = menuEntries[menuEntries.length - 1]; final String target = ColorUtil.prependColorTag(Text.removeTags(event.getTarget()), color); menuEntry.setTarget(target); - client.setMenuEntries(menuEntries); } } else if (menuAction == MenuAction.EXAMINE_NPC && client.isKeyPressed(KeyCode.KC_SHIFT)) @@ -291,48 +288,29 @@ public class NpcIndicatorsPlugin extends Plugin .filter(highlight -> !highlight.equalsIgnoreCase(npcName)) .anyMatch(highlight -> WildcardMatcher.matches(highlight, npcName)); - MenuEntry[] menuEntries = client.getMenuEntries(); - // Only add Untag-All option to npcs not highlighted by a wildcard entry, because untag-all will not remove wildcards if (!matchesList) { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 2); - final MenuEntry tagAllEntry = menuEntries[menuEntries.length - 2] = new MenuEntry(); - tagAllEntry.setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL); - tagAllEntry.setTarget(event.getTarget()); - tagAllEntry.setParam0(event.getActionParam0()); - tagAllEntry.setParam1(event.getParam1()); - tagAllEntry.setIdentifier(event.getIdentifier()); - tagAllEntry.setType(MenuAction.RUNELITE.getId()); - } - else - { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + client.createMenuEntry(-1) + .setOption(highlights.stream().anyMatch(npcName::equalsIgnoreCase) ? UNTAG_ALL : TAG_ALL) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag); } - final MenuEntry tagEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - tagEntry.setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG); - tagEntry.setTarget(event.getTarget()); - tagEntry.setParam0(event.getActionParam0()); - tagEntry.setParam1(event.getParam1()); - tagEntry.setIdentifier(event.getIdentifier()); - tagEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + MenuEntry i = client.createMenuEntry(-1) + .setOption(npcTags.contains(npc.getIndex()) ? UNTAG : TAG) + .setTarget(event.getTarget()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::tag); } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked click) + private void tag(MenuEntry entry) { - if (click.getMenuAction() != MenuAction.RUNELITE || - !(click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG) || - click.getMenuOption().equals(TAG_ALL) || click.getMenuOption().equals(UNTAG_ALL))) - { - return; - } - - final int id = click.getId(); + final int id = entry.getIdentifier(); final NPC[] cachedNPCs = client.getCachedNPCs(); final NPC npc = cachedNPCs[id]; @@ -341,7 +319,7 @@ public class NpcIndicatorsPlugin extends Plugin return; } - if (click.getMenuOption().equals(TAG) || click.getMenuOption().equals(UNTAG)) + if (entry.getOption().equals(TAG) || entry.getOption().equals(UNTAG)) { final boolean removed = npcTags.remove(id); @@ -371,8 +349,6 @@ public class NpcIndicatorsPlugin extends Plugin // this trips a config change which triggers the overlay rebuild updateNpcsToHighlight(name); } - - click.consume(); } @Subscribe 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 403a19fe04..526ffe7f91 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 @@ -31,7 +31,6 @@ import com.google.gson.reflect.TypeToken; import com.google.inject.Provides; import java.awt.Color; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -65,7 +64,6 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; @@ -222,7 +220,7 @@ public class ObjectIndicatorsPlugin extends Plugin return; } - final Tile tile = client.getScene().getTiles()[client.getPlane()][event.getActionParam0()][event.getParam1()]; + final Tile tile = client.getScene().getTiles()[client.getPlane()][event.getActionParam0()][event.getActionParam1()]; final TileObject tileObject = findTileObject(tile, event.getIdentifier()); if (tileObject == null) @@ -230,35 +228,26 @@ public class ObjectIndicatorsPlugin extends Plugin return; } - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK); - menuEntry.setTarget(event.getTarget()); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(event.getParam1()); - menuEntry.setIdentifier(event.getIdentifier()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setOption(objects.stream().anyMatch(o -> o.getTileObject() == tileObject) ? UNMARK : MARK) + .setTarget(event.getTarget()) + .setParam0(event.getActionParam0()) + .setParam1(event.getActionParam1()) + .setIdentifier(event.getIdentifier()) + .setType(MenuAction.RUNELITE) + .onClick(this::markObject); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void markObject(MenuEntry entry) { - if (event.getMenuAction() != MenuAction.RUNELITE - || !(event.getMenuOption().equals(MARK) || event.getMenuOption().equals(UNMARK))) - { - return; - } - Scene scene = client.getScene(); Tile[][][] tiles = scene.getTiles(); - final int x = event.getParam0(); - final int y = event.getParam1(); + final int x = entry.getParam0(); + final int y = entry.getParam1(); final int z = client.getPlane(); final Tile tile = tiles[z][x][y]; - TileObject object = findTileObject(tile, event.getId()); + TileObject object = findTileObject(tile, entry.getIdentifier()); if (object == null) { return; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java index 672ab50e16..48989d2d29 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoOverlay.java @@ -42,7 +42,7 @@ import net.runelite.api.ParamID; import net.runelite.api.Player; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; -import net.runelite.client.game.HiscoreManager; +import net.runelite.client.hiscore.HiscoreManager; import net.runelite.client.game.NPCManager; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; @@ -53,7 +53,7 @@ import net.runelite.client.ui.overlay.components.ComponentConstants; import net.runelite.client.ui.overlay.components.ProgressBarComponent; import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.util.Text; -import net.runelite.http.api.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreResult; class OpponentInfoOverlay extends OverlayPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index 4d58b924d1..855ac8953c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -49,7 +49,7 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreEndpoint; @PluginDescriptor( name = "Opponent Information", @@ -184,7 +184,6 @@ public class OpponentInfoPlugin extends Plugin { MenuEntry[] menuEntries = client.getMenuEntries(); menuEntries[menuEntries.length - 1].setTarget("*" + menuEntries[menuEntries.length - 1].getTarget()); - client.setMenuEntries(menuEntries); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java index 840e4cae0e..03dc34f883 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/PlayerComparisonOverlay.java @@ -34,7 +34,7 @@ import net.runelite.api.Client; import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.api.Player; import net.runelite.api.Skill; -import net.runelite.client.game.HiscoreManager; +import net.runelite.client.hiscore.HiscoreManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; @@ -44,8 +44,8 @@ import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.util.Text; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.HiscoreSkill; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.HiscoreSkill; class PlayerComparisonOverlay extends Overlay { @@ -153,7 +153,7 @@ class PlayerComparisonOverlay extends Overlay final HiscoreSkill hiscoreSkill = HISCORE_COMBAT_SKILLS[i]; final Skill skill = COMBAT_SKILLS[i]; - final net.runelite.http.api.hiscore.Skill opponentSkill = opponentSkills.getSkill(hiscoreSkill); + final net.runelite.client.hiscore.Skill opponentSkill = opponentSkills.getSkill(hiscoreSkill); if (opponentSkill == null || opponentSkill.getLevel() == -1) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java index 5d38da1b3d..4d484f4cdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyConfig.java @@ -99,4 +99,23 @@ public interface PartyConfig extends Config { return false; } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + default String previousPartyId() + { + return ""; + } + + @ConfigItem( + keyName = "previousPartyId", + name = "", + description = "", + hidden = true + ) + void setPreviousPartyId(String id); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java index 3c3c1bba95..52d4799e95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java @@ -26,6 +26,12 @@ package net.runelite.client.plugins.party; import com.google.inject.Inject; import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -55,6 +61,9 @@ class PartyPanel extends PluginPanel private final Map memberBoxes = new HashMap<>(); private final JButton startButton = new JButton(); + private final JButton joinPartyButton = new JButton(); + private final JButton rejoinPartyButton = new JButton(); + private final JButton copyPartyIdButton = new JButton(); private final PluginErrorPanel noPartyPanel = new PluginErrorPanel(); private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel(); @@ -79,10 +88,29 @@ class PartyPanel extends PluginPanel final JPanel topPanel = new JPanel(); - topPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); - topPanel.setLayout(new BorderLayout()); + topPanel.setBorder(new EmptyBorder(0, 0, 4, 0)); + topPanel.setLayout(new GridBagLayout()); - topPanel.add(startButton, BorderLayout.CENTER); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(0, 2, 4, 2); + + c.gridx = 0; + c.gridy = 0; + topPanel.add(startButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(joinPartyButton, c); + + c.gridx = 1; + c.gridy = 0; + topPanel.add(copyPartyIdButton, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 2; + topPanel.add(rejoinPartyButton, c); layoutPanel.add(topPanel); layoutPanel.add(requestBoxPanel); @@ -91,7 +119,14 @@ class PartyPanel extends PluginPanel startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); startButton.setFocusable(false); - topPanel.add(startButton); + joinPartyButton.setText("Join party"); + joinPartyButton.setFocusable(false); + + rejoinPartyButton.setText("Join previous party"); + rejoinPartyButton.setFocusable(false); + + copyPartyIdButton.setText("Copy party id"); + copyPartyIdButton.setFocusable(false); startButton.addActionListener(e -> { @@ -115,6 +150,63 @@ class PartyPanel extends PluginPanel } }); + joinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + String s = (String) JOptionPane.showInputDialog( + joinPartyButton, + "Please enter the party id:", + "Party Id", + JOptionPane.PLAIN_MESSAGE, + null, + null, + ""); + + if (s == null) + { + return; + } + + try + { + party.changeParty(UUID.fromString(s)); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + rejoinPartyButton.addActionListener(e -> + { + if (!party.isInParty()) + { + try + { + party.changeParty(UUID.fromString(config.previousPartyId())); + } + catch (IllegalArgumentException ex) + { + JOptionPane.showMessageDialog(rejoinPartyButton, + "Failed to join your previous party, create a new party or join a new one.", + "Failed to Join Party", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + copyPartyIdButton.addActionListener(e -> + { + if (party.isInParty()) + { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null); + } + }); + noPartyPanel.setContent("Not in a party", "Create a party to begin."); partyEmptyPanel.setContent("Party created", "You can now invite friends!"); @@ -127,6 +219,9 @@ class PartyPanel extends PluginPanel remove(partyEmptyPanel); startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT); + joinPartyButton.setVisible(!party.isInParty()); + rejoinPartyButton.setVisible(!party.isInParty()); + copyPartyIdButton.setVisible(party.isInParty()); if (!party.isInParty()) { 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 e9287210a8..ae13a4a22f 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 @@ -66,8 +66,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.discord.events.DiscordJoinRequest; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; import net.runelite.client.plugins.Plugin; @@ -585,6 +585,11 @@ public class PartyPlugin extends Plugin pendingTilePings.clear(); worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); + if (event.getPartyId() != null) + { + config.setPreviousPartyId(String.valueOf(event.getPartyId())); + } + SwingUtilities.invokeLater(() -> { panel.removeAllMembers(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index df72925bb8..eaa841a620 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -31,8 +31,8 @@ import lombok.Value; import net.runelite.api.Client; import net.runelite.api.FriendsChatRank; import static net.runelite.api.FriendsChatRank.UNRANKED; +import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; -import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; @@ -118,29 +118,23 @@ public class PlayerIndicatorsPlugin extends Plugin } MenuEntry[] menuEntries = client.getMenuEntries(); - boolean modified = false; for (MenuEntry entry : menuEntries) { - int type = entry.getType(); + MenuAction type = entry.getType(); - if (type >= MENU_ACTION_DEPRIORITIZE_OFFSET) - { - type -= MENU_ACTION_DEPRIORITIZE_OFFSET; - } - - if (type == WALK.getId() - || type == SPELL_CAST_ON_PLAYER.getId() - || type == ITEM_USE_ON_PLAYER.getId() - || type == PLAYER_FIRST_OPTION.getId() - || type == PLAYER_SECOND_OPTION.getId() - || type == PLAYER_THIRD_OPTION.getId() - || type == PLAYER_FOURTH_OPTION.getId() - || type == PLAYER_FIFTH_OPTION.getId() - || type == PLAYER_SIXTH_OPTION.getId() - || type == PLAYER_SEVENTH_OPTION.getId() - || type == PLAYER_EIGTH_OPTION.getId() - || type == RUNELITE_PLAYER.getId()) + if (type == WALK + || type == SPELL_CAST_ON_PLAYER + || type == ITEM_USE_ON_PLAYER + || type == PLAYER_FIRST_OPTION + || type == PLAYER_SECOND_OPTION + || type == PLAYER_THIRD_OPTION + || type == PLAYER_FOURTH_OPTION + || type == PLAYER_FIFTH_OPTION + || type == PLAYER_SIXTH_OPTION + || type == PLAYER_SEVENTH_OPTION + || type == PLAYER_EIGTH_OPTION + || type == RUNELITE_PLAYER) { Player[] players = client.getCachedPlayers(); Player player = null; @@ -149,7 +143,7 @@ public class PlayerIndicatorsPlugin extends Plugin // 'Walk here' identifiers are offset by 1 because the default // identifier for this option is 0, which is also a player index. - if (type == WALK.getId()) + if (type == WALK) { identifier--; } @@ -175,14 +169,8 @@ public class PlayerIndicatorsPlugin extends Plugin String newTarget = decorateTarget(oldTarget, decorations); entry.setTarget(newTarget); - modified = true; } } - - if (modified) - { - client.setMenuEntries(menuEntries); - } } private Decorations getDecorations(Player player) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java index 1cb0a21044..8572cacbe7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java @@ -58,13 +58,13 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.game.HiscoreManager; +import net.runelite.client.hiscore.HiscoreManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.Skill; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.Skill; @PluginDescriptor( name = "Player-owned House", 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 index 2e8297c83a..9ac225d4ba 100644 --- 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 @@ -70,7 +70,7 @@ import okhttp3.HttpUrl; ) public class WikiPlugin extends Plugin { - static final HttpUrl WIKI_BASE = HttpUrl.parse("https://oldschool.runescape.wiki"); + static final HttpUrl WIKI_BASE = HttpUrl.get("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"; @@ -335,20 +335,6 @@ public class WikiPlugin extends Plugin LinkBrowser.browse(url.toString()); return; } - - if (ev.getMenuAction() == MenuAction.RUNELITE) - { - switch (ev.getMenuOption()) - { - case MENUOP_WIKI: - LinkBrowser.browse(WIKI_BASE.newBuilder() - .addPathSegment("w") - .addPathSegment(Text.removeTags(ev.getMenuTarget())) - .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) - .build().toString()); - - } - } } private void openSearchInput() @@ -371,18 +357,18 @@ public class WikiPlugin extends Plugin public void onMenuEntryAdded(MenuEntryAdded event) { int widgetIndex = event.getActionParam0(); - int widgetID = event.getParam1(); - MenuEntry[] menuEntries = client.getMenuEntries(); + int widgetID = event.getActionParam1(); if (wikiSelected && event.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) { + MenuEntry[] menuEntries = client.getMenuEntries(); Widget w = getWidget(widgetID, widgetIndex); if (w.getType() == WidgetType.GRAPHIC && w.getItemId() != -1) { for (int ourEntry = menuEntries.length - 1;ourEntry >= 0; ourEntry--) { MenuEntry entry = menuEntries[ourEntry]; - if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET.getId()) + if (entry.getType() == MenuAction.SPELL_CAST_ON_WIDGET) { int id = itemManager.canonicalize(w.getItemId()); String name = itemManager.getItemComposition(id).getName(); @@ -390,7 +376,6 @@ public class WikiPlugin extends Plugin break; } } - client.setMenuEntries(menuEntries); } else { @@ -400,7 +385,7 @@ public class WikiPlugin extends Plugin MenuEntry[] oldEntries = menuEntries; menuEntries = Arrays.copyOf(menuEntries, menuEntries.length - 1); for (int ourEntry = oldEntries.length - 1; - ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET.getId(); + ourEntry >= 2 && oldEntries[oldEntries.length - 1].getType() != MenuAction.SPELL_CAST_ON_WIDGET; ourEntry--) { menuEntries[ourEntry - 1] = oldEntries[ourEntry]; @@ -425,16 +410,15 @@ public class WikiPlugin extends Plugin return; } - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(action.replace("View ", "").replace(" guide", "")); - menuEntry.setOption(MENUOP_WIKI); - menuEntry.setParam0(widgetIndex); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + client.createMenuEntry(-1) + .setTarget(action.replace("View ", "").replace(" guide", "")) + .setOption(MENUOP_WIKI) + .setType(MenuAction.RUNELITE) + .onClick(ev -> LinkBrowser.browse(WIKI_BASE.newBuilder() + .addPathSegment("w") + .addPathSegment(Text.removeTags(ev.getTarget())) + .addQueryParameter(UTM_SORUCE_KEY, UTM_SORUCE_VALUE) + .build().toString())); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index f6cc53254f..f87bcaeef3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -53,26 +53,27 @@ import static net.runelite.api.ObjectID.WILLOW_10833; import static net.runelite.api.ObjectID.YEW; import static net.runelite.api.NullObjectID.NULL_10823; import static net.runelite.api.ObjectID.YEW_36683; +import static net.runelite.client.util.RSTimeUnit.GAME_TICKS; @Getter enum Tree { REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280), - OAK_TREE(Duration.ofMillis(8500), OAK_TREE_4540, OAK_10820), - WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), - MAPLE_TREE(Duration.ofSeconds(35), MAPLE_TREE_10832, MAPLE_TREE_36681) + OAK_TREE(Duration.of(14, GAME_TICKS), OAK_TREE_4540, OAK_10820), + WILLOW_TREE(Duration.of(14, GAME_TICKS), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833), + MAPLE_TREE(Duration.of(59, GAME_TICKS), MAPLE_TREE_10832, MAPLE_TREE_36681) { @Override Duration getRespawnTime(int region) { - return region == MISCELLANIA_REGION ? Duration.ofMillis(8500) : super.respawnTime; + return region == MISCELLANIA_REGION ? Duration.of(14, GAME_TICKS) : super.respawnTime; } }, - TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686), - MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688), - YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683), - MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835), - REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670); + TEAK_TREE(Duration.of(15, GAME_TICKS), TEAK, TEAK_36686), + MAHOGANY_TREE(Duration.of(14, GAME_TICKS), MAHOGANY, MAHOGANY_36688), + YEW_TREE(Duration.of(99, GAME_TICKS), YEW, NULL_10823, YEW_36683), + MAGIC_TREE(Duration.of(199, GAME_TICKS), MAGIC_TREE_10834, NULL_10835), + REDWOOD(Duration.of(199, GAME_TICKS), ObjectID.REDWOOD, REDWOOD_29670); @Nullable private final Duration respawnTime; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java index dccd9d499c..32713a7b17 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/RegionFilterMode.java @@ -24,16 +24,13 @@ */ package net.runelite.client.plugins.worldhopper; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import net.runelite.http.api.worlds.WorldRegion; -@NoArgsConstructor -@AllArgsConstructor -public enum RegionFilterMode +@RequiredArgsConstructor +enum RegionFilterMode { - NONE, AUSTRALIA(WorldRegion.AUSTRALIA), GERMANY(WorldRegion.GERMANY), UNITED_KINGDOM(WorldRegion.UNITED_KINGDOM) @@ -54,5 +51,22 @@ public enum RegionFilterMode }; @Getter - private WorldRegion region; + private final WorldRegion region; + + static RegionFilterMode of(WorldRegion region) + { + switch (region) + { + case UNITED_STATES_OF_AMERICA: + return UNITED_STATES; + case UNITED_KINGDOM: + return UNITED_KINGDOM; + case AUSTRALIA: + return AUSTRALIA; + case GERMANY: + return GERMANY; + default: + throw new IllegalStateException(); + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java index 11db14d55a..0c087993cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperConfig.java @@ -27,6 +27,8 @@ package net.runelite.client.plugins.worldhopper; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.util.Collections; +import java.util.Set; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -76,9 +78,9 @@ public interface WorldHopperConfig extends Config description = "Limit quick-hopping to worlds of a specific region", position = 3 ) - default RegionFilterMode quickHopRegionFilter() + default Set quickHopRegionFilter() { - return RegionFilterMode.NONE; + return Collections.emptySet(); } @ConfigItem( @@ -142,9 +144,9 @@ public interface WorldHopperConfig extends Config description = "Restrict sidebar worlds to one region", position = 8 ) - default RegionFilterMode regionFilter() + default Set regionFilter() { - return RegionFilterMode.NONE; + return Collections.emptySet(); } @ConfigItem( 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 dcb8d5e560..82d44972e2 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 @@ -28,7 +28,6 @@ package net.runelite.client.plugins.worldhopper; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ObjectArrays; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.Instant; @@ -36,6 +35,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -53,7 +53,6 @@ import net.runelite.api.FriendsChatManager; import net.runelite.api.FriendsChatMember; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NameableContainer; import net.runelite.api.Varbits; import net.runelite.api.clan.ClanChannel; @@ -62,7 +61,6 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; @@ -91,7 +89,6 @@ import net.runelite.client.util.WorldUtil; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.api.worlds.WorldType; -import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "World Hopper", @@ -355,7 +352,7 @@ public class WorldHopperPlugin extends Plugin return; } - final int componentId = event.getParam1(); + final int componentId = event.getActionParam1(); int groupId = WidgetInfo.TO_GROUP(componentId); String option = event.getOption(); @@ -396,43 +393,19 @@ public class WorldHopperPlugin extends Plugin return; } - final MenuEntry hopTo = new MenuEntry(); - hopTo.setOption(HOP_TO); - hopTo.setTarget(event.getTarget()); - hopTo.setType(MenuAction.RUNELITE.getId()); - hopTo.setParam0(event.getActionParam0()); - hopTo.setParam1(event.getParam1()); + client.createMenuEntry(after ? -2 : -1) + .setOption(HOP_TO) + .setTarget(event.getTarget()) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + ChatPlayer p = getChatPlayerFromName(e.getTarget()); - insertMenuEntry(hopTo, client.getMenuEntries(), after); - } - } - - private void insertMenuEntry(MenuEntry newEntry, MenuEntry[] entries, boolean after) - { - MenuEntry[] newMenu = ObjectArrays.concat(entries, newEntry); - - if (after) - { - int menuEntryCount = newMenu.length; - ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2); - } - - client.setMenuEntries(newMenu); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction() != MenuAction.RUNELITE || !event.getMenuOption().equals(HOP_TO)) - { - return; - } - - ChatPlayer player = getChatPlayerFromName(event.getMenuTarget()); - - if (player != null) - { - hop(player.getWorld()); + if (p != null) + { + hop(p.getWorld()); + } + }); } } @@ -533,6 +506,8 @@ public class WorldHopperPlugin extends Plugin int worldIdx = worlds.indexOf(currentWorld); int totalLevel = client.getTotalLevel(); + final Set regionFilter = config.quickHopRegionFilter(); + World world; do { @@ -564,7 +539,7 @@ public class WorldHopperPlugin extends Plugin world = worlds.get(worldIdx); // Check world region if filter is enabled - if (config.quickHopRegionFilter() != RegionFilterMode.NONE && world.getRegion() != config.quickHopRegionFilter().getRegion()) + if (!regionFilter.isEmpty() && !regionFilter.contains(RegionFilterMode.of(world.getRegion()))) { continue; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index e1e541d1bf..d446204884 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -34,6 +34,7 @@ import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import javax.swing.JPanel; import javax.swing.SwingUtilities; @@ -68,7 +69,7 @@ class WorldSwitcherPanel extends PluginPanel @Setter(AccessLevel.PACKAGE) private SubscriptionFilterMode subscriptionFilterMode; @Setter(AccessLevel.PACKAGE) - private RegionFilterMode regionFilterMode; + private Set regionFilterMode; WorldSwitcherPanel(WorldHopperPlugin plugin) { @@ -249,7 +250,7 @@ class WorldSwitcherPanel extends PluginPanel break; } - if (regionFilterMode.getRegion() != null && !regionFilterMode.getRegion().equals(world.getRegion())) + if (!regionFilterMode.isEmpty() && !regionFilterMode.contains(RegionFilterMode.of(world.getRegion()))) { continue; } 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 026b8980ac..5407226a99 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 @@ -32,7 +32,6 @@ import com.google.inject.Binder; import com.google.inject.Provides; import java.awt.image.BufferedImage; import java.time.temporal.ChronoUnit; -import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Objects; @@ -45,7 +44,6 @@ import net.runelite.api.Client; import net.runelite.api.Experience; import net.runelite.api.GameState; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.Skill; @@ -54,7 +52,6 @@ import net.runelite.api.WorldType; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.StatChanged; import net.runelite.api.widgets.WidgetID; @@ -508,7 +505,7 @@ public class XpTrackerPlugin extends Plugin @Subscribe public void onMenuEntryAdded(final MenuEntryAdded event) { - int widgetID = event.getParam1(); + int widgetID = event.getActionParam1(); if (TO_GROUP(widgetID) != WidgetID.SKILLS_GROUP_ID || !event.getOption().startsWith("View") @@ -521,48 +518,21 @@ public class XpTrackerPlugin extends Plugin final String skillText = event.getOption().split(" ")[1]; final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase()); - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setTarget(skillText); - menuEntry.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER); - menuEntry.setParam0(event.getActionParam0()); - menuEntry.setParam1(widgetID); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); - } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId() - || TO_GROUP(event.getParam1()) != WidgetID.SKILLS_GROUP_ID) - { - return; - } - - final Skill skill; - try - { - skill = Skill.valueOf(Text.removeTags(event.getMenuTarget()).toUpperCase()); - } - catch (IllegalArgumentException ex) - { - log.debug(null, ex); - return; - } - - switch (event.getMenuOption()) - { - case MENUOP_ADD_CANVAS_TRACKER: - addOverlay(skill); - break; - case MENUOP_REMOVE_CANVAS_TRACKER: - removeOverlay(skill); - break; - } + client.createMenuEntry(-1) + .setTarget(skillText) + .setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER) + .setType(MenuAction.RUNELITE) + .onClick(e -> + { + if (hasOverlay(skill)) + { + removeOverlay(skill); + } + else + { + addOverlay(skill); + } + }); } XpStateSingle getSkillState(Skill skill) 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 aca456df93..7b9d3f6091 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 @@ -78,7 +78,7 @@ import okhttp3.Response; public class ClientLoader implements Supplier { private static final String INJECTED_CLIENT_NAME = "/injected-client.oprs"; - private static final int NUM_ATTEMPTS = 6; + private static final int NUM_ATTEMPTS = 0; private static File LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock"); private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache"); private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache"); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java index f6a7007d26..d0c028b2ff 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ToggleButton.java @@ -31,6 +31,7 @@ import javax.swing.JCheckBox; import net.runelite.client.ui.ColorScheme; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.SwingUtil; +import net.runelite.client.util.Text; public class ToggleButton extends JCheckBox { @@ -38,6 +39,8 @@ public class ToggleButton extends JCheckBox private static final ImageIcon OFF_SWITCHER; private static final ImageIcon DISABLED_SWITCHER; + private final Object object; + static { BufferedImage onSwitcher = ImageUtil.loadImageResource(ToggleButton.class, "switcher_on.png"); @@ -63,6 +66,8 @@ public class ToggleButton extends JCheckBox public ToggleButton() { super(OFF_SWITCHER); + this.object = null; + setSelectedIcon(ON_SWITCHER); setDisabledIcon(DISABLED_SWITCHER); SwingUtil.removeButtonDecorations(this); @@ -71,8 +76,25 @@ public class ToggleButton extends JCheckBox public ToggleButton(String text) { super(text, OFF_SWITCHER, false); + this.object = null; + setSelectedIcon(ON_SWITCHER); setDisabledIcon(DISABLED_SWITCHER); SwingUtil.removeButtonDecorations(this); } + + public ToggleButton(Object object) + { + super(Text.titleCase((Enum) object), OFF_SWITCHER, false); + this.object = object; + + setSelectedIcon(ON_SWITCHER); + setDisabledIcon(DISABLED_SWITCHER); + SwingUtil.removeButtonDecorations(this); + } + + public Object getObject() + { + return this.object; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index bea3f9d280..31d428ceed 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -40,17 +40,13 @@ import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; -import net.runelite.api.MenuAction; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PluginChanged; /** @@ -108,14 +104,12 @@ public class OverlayManager private ArrayListMultimap overlayMap = ArrayListMultimap.create(); private final ConfigManager configManager; - private final EventBus eventBus; private final RuneLiteConfig runeLiteConfig; @Inject - private OverlayManager(final ConfigManager configManager, final EventBus eventBus, final RuneLiteConfig runeLiteConfig) + private OverlayManager(final ConfigManager configManager, final RuneLiteConfig runeLiteConfig) { this.configManager = configManager; - this.eventBus = eventBus; this.runeLiteConfig = runeLiteConfig; } @@ -137,32 +131,6 @@ public class OverlayManager rebuildOverlayLayers(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) - { - MenuAction menuAction = event.getMenuAction(); - if (menuAction != MenuAction.RUNELITE_OVERLAY && menuAction != MenuAction.RUNELITE_OVERLAY_CONFIG) - { - return; - } - - event.consume(); - - Overlay overlay = overlays.get(event.getId()); - if (overlay != null) - { - List menuEntries = overlay.getMenuEntries(); - OverlayMenuEntry overlayMenuEntry = menuEntries.stream() - .filter(me -> me.getOption().equals(event.getMenuOption())) - .findAny() - .orElse(null); - if (overlayMenuEntry != null) - { - eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay)); - } - } - } - /** * Gets all of the overlays on a layer sorted by priority and position * diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index c658c6944a..7bd2d7cbad 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -49,7 +49,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.KeyCode; -import net.runelite.api.MenuEntry; import net.runelite.api.Varbits; import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ClientTick; @@ -60,6 +59,7 @@ import net.runelite.api.widgets.WidgetItem; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; @@ -93,6 +93,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private final TooltipManager tooltipManager; private final RuneLiteConfig runeLiteConfig; private final ClientUI clientUI; + private final EventBus eventBus; // Overlay movement variables private final Point overlayOffset = new Point(); @@ -104,7 +105,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener private boolean inOverlayResizingMode; private boolean inOverlayDraggingMode; private boolean startedMovingOverlay; - private MenuEntry[] menuEntries; + private Overlay hoveredOverlay; // for building menu entries // Overlay state validation private Rectangle viewportBounds; @@ -133,6 +134,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener this.runeLiteConfig = runeLiteConfig; this.clientUI = clientUI; this.tooltipManager = tooltipManager; + this.eventBus = eventBus; keyManager.registerKeyListener(this); mouseManager.registerMouseListener(this); eventBus.register(this); @@ -149,14 +151,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener resetOverlayManagementMode(); } - menuEntries = null; + hoveredOverlay = null; } } @Subscribe protected void onClientTick(ClientTick t) { - if (menuEntries == null) + final Overlay overlay = hoveredOverlay; + if (overlay == null || client.isMenuOpen()) { return; } @@ -167,24 +170,29 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener return; } - if (client.isMenuOpen()) + List menuEntries = overlay.getMenuEntries(); + if (menuEntries.isEmpty()) { return; } - MenuEntry[] clientMenuEntries = client.getMenuEntries(); - MenuEntry[] newEntries = new MenuEntry[clientMenuEntries.length + menuEntries.length]; + // Add in reverse order so they display correctly in the right-click menu + for (int i = menuEntries.size() - 1; i >= 0; --i) + { + OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - newEntries[0] = clientMenuEntries[0]; // Keep cancel at 0 - System.arraycopy(menuEntries, 0, newEntries, 1, menuEntries.length); // Add overlay menu entries - System.arraycopy(clientMenuEntries, 1, newEntries, menuEntries.length + 1, clientMenuEntries.length - 1); // Add remaining menu entries - client.setMenuEntries(newEntries); + client.createMenuEntry(-1) + .setOption(overlayMenuEntry.getOption()) + .setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)) + .setType(overlayMenuEntry.getMenuAction()) + .onClick(e -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))); + } } @Subscribe public void onBeforeRender(BeforeRender event) { - menuEntries = null; + hoveredOverlay = null; if (focusedOverlay == null && prevFocusedOverlay != null) { @@ -366,10 +374,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener if (!client.isMenuOpen() && !client.getSpellSelected() && bounds.contains(mouse)) { - if (menuEntries == null) - { - menuEntries = createRightClickMenuEntries(overlay); - } + hoveredOverlay = overlay; if (inOverlayManagingMode) { @@ -940,33 +945,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener new Rectangle(canvasTopRightPoint, SNAP_CORNER_SIZE)); } - private MenuEntry[] createRightClickMenuEntries(Overlay overlay) - { - List menuEntries = overlay.getMenuEntries(); - if (menuEntries.isEmpty()) - { - return null; - } - - final MenuEntry[] entries = new MenuEntry[menuEntries.size()]; - - // Add in reverse order so they display correctly in the right-click menu - for (int i = menuEntries.size() - 1; i >= 0; --i) - { - OverlayMenuEntry overlayMenuEntry = menuEntries.get(i); - - final MenuEntry entry = new MenuEntry(); - entry.setOption(overlayMenuEntry.getOption()); - entry.setTarget(ColorUtil.wrapWithColorTag(overlayMenuEntry.getTarget(), JagexColors.MENU_TARGET)); - entry.setType(overlayMenuEntry.getMenuAction().getId()); - entry.setIdentifier(overlayManager.getOverlays().indexOf(overlay)); // overlay id - - entries[i] = entry; - } - - return entries; - } - /** * Adjust the given overlay position to be within its parent's bounds. * diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java index 0233b3856a..5151b60e42 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetItemOverlay.java @@ -135,6 +135,7 @@ public abstract class WidgetItemOverlay extends Overlay protected void showOnBank() { drawAfterLayer(WidgetInfo.BANK_ITEM_CONTAINER); + drawAfterLayer(WidgetInfo.GROUP_STORAGE_ITEM_CONTAINER); } protected void showOnEquipment() diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java index e3528433cb..3047086dda 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/outline/ModelOutlineRenderer.java @@ -564,11 +564,11 @@ public class ModelOutlineRenderer */ private void simulateModelRasterizationForOutline(Model model) { - final int triangleCount = model.getTrianglesCount(); - final int[] indices1 = model.getTrianglesX(); - final int[] indices2 = model.getTrianglesY(); - final int[] indices3 = model.getTrianglesZ(); - final byte[] triangleTransparencies = model.getTriangleTransparencies(); + final int triangleCount = model.getFaceCount(); + final int[] indices1 = model.getFaceIndices1(); + final int[] indices2 = model.getFaceIndices2(); + final int[] indices3 = model.getFaceIndices3(); + final byte[] triangleTransparencies = model.getFaceTransparencies(); for (int i = 0; i < triangleCount; i++) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 2f2beb0c62..16ca444f8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -24,6 +24,7 @@ */ package net.runelite.client.ui.overlay.worldmap; +import com.google.common.base.MoreObjects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import java.awt.Dimension; @@ -32,23 +33,18 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import net.runelite.api.MenuEntry; import net.runelite.api.Point; import net.runelite.api.RenderOverview; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.ui.overlay.Overlay; @@ -73,7 +69,7 @@ public class WorldMapOverlay extends Overlay private final WorldMapPointManager worldMapPointManager; private final Client client; - private final List mapMenuEntries = new ArrayList<>(); + private WorldMapPoint hoveredPoint; @Inject private WorldMapOverlay( @@ -107,19 +103,18 @@ public class WorldMapOverlay extends Overlay bottomBar.setOnTimerListener((JavaScriptCallback) ev -> { - if (client.isMenuOpen() || mapMenuEntries.isEmpty()) + WorldMapPoint worldPoint = hoveredPoint; + if (client.isMenuOpen() || worldPoint == null) { return; } - MenuEntry[] entries = client.getMenuEntries(); - int end = entries.length; - entries = Arrays.copyOf(entries, end + mapMenuEntries.size()); - for (int i = 0; i < mapMenuEntries.size(); i++) - { - entries[end + i] = mapMenuEntries.get(i); - } - client.setMenuEntries(entries); + client.createMenuEntry(-1) + .setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)) + .setOption(FOCUS_ON) + .setType(MenuAction.RUNELITE) + .onClick(m -> client.getRenderOverview().setWorldMapPositionTarget( + MoreObjects.firstNonNull(worldPoint.getTarget(), worldPoint.getWorldPoint()))); }); bottomBar.setHasListener(true); @@ -135,7 +130,7 @@ public class WorldMapOverlay extends Overlay mousePos = null; } - mapMenuEntries.clear(); + hoveredPoint = null; WorldMapPoint tooltipPoint = null; @@ -227,19 +222,7 @@ public class WorldMapOverlay extends Overlay if (worldPoint.isJumpOnClick()) { assert worldPoint.getName() != null; - - WorldPoint target = worldPoint.getTarget(); - if (target == null) - { - target = worldPoint.getWorldPoint(); - } - - MenuEntry entry = new MenuEntry(); - entry.setType(MenuAction.RUNELITE.getId()); - entry.setOption(FOCUS_ON); - entry.setTarget(ColorUtil.wrapWithColorTag(worldPoint.getName(), JagexColors.MENU_TARGET)); - entry.setIdentifier(target.getPlane() << 28 | target.getX() << 14 | target.getY()); - mapMenuEntries.add(entry); + hoveredPoint = worldPoint; } } } @@ -259,21 +242,6 @@ public class WorldMapOverlay extends Overlay return null; } - @Subscribe - private void onMenuOptionClicked(MenuOptionClicked ev) - { - if (ev.getMenuAction() == MenuAction.RUNELITE && FOCUS_ON.equals(ev.getMenuOption())) - { - int pxy = ev.getId(); - WorldPoint wp = new WorldPoint( - pxy >> 14 & 0x3fff, - pxy & 0x3fff, - pxy >> 28); - - client.getRenderOverview().setWorldMapPositionTarget(wp); - } - } - /** * Get the screen coordinates for a WorldPoint on the world map * diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 083b901710..6a56701fb7 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -244,7 +244,8 @@ 20772, 21056, 21057, - 21058 + 21058, + 26276 ], "glarials urn": [ 296, @@ -3254,6 +3255,10 @@ 3739, 3740 ], + "frozen key": [ + 3741, + 26356 + ], "archer helm": [ 3749, 20572 @@ -10189,5 +10194,51 @@ "ugly halloween jumper": [ 26256, 26258 + ], + "secret santa present": [ + 26298, + 26300, + 26302, + 26316, + 26318, + 26320, + 26322, + 26324 + ], + "chocolate chips": [ + 26304, + 26306 + ], + "ancient brew": [ + 26340, + 26342, + 26344, + 26346 + ], + "ancient mix": [ + 26350, + 26353 + ], + "frozen key piece": [ + 26358, + 26360, + 26362, + 26364 + ], + "torva helm": [ + 26376, + 26382 + ], + "torva platebody": [ + 26378, + 26384 + ], + "torva platelegs": [ + 26380, + 26386 + ], + "blood essence": [ + 26390, + 26392 ] } \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png new file mode 100644 index 0000000000..62bb05ace9 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rocketship.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png new file mode 100644 index 0000000000..eaaa147d0f Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nex.png differ diff --git a/runelite-client/src/main/scripts/ChatSend.hash b/runelite-client/src/main/scripts/ChatSend.hash index 03fd850497..1e7ae9ee97 100644 --- a/runelite-client/src/main/scripts/ChatSend.hash +++ b/runelite-client/src/main/scripts/ChatSend.hash @@ -1 +1 @@ -77B41EBBD7A825A8AC984B282115ED636C9F32A4FA777B1B58169E9C6FF103E0 \ No newline at end of file +95E7960E289ECA35DEADD35BC5A34AEBAA1C9F367AC42A71A5F3EFCCA0600D10 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatSend.rs2asm b/runelite-client/src/main/scripts/ChatSend.rs2asm index 7ce4fa5d9a..e4e8725cbf 100644 --- a/runelite-client/src/main/scripts/ChatSend.rs2asm +++ b/runelite-client/src/main/scripts/ChatSend.rs2asm @@ -30,28 +30,41 @@ LABEL16: join_string 5 mes LABEL23: - iload 3 - iconst -1 - if_icmpne LABEL27 - jump LABEL60 + invoke 5262 + iconst 0 + if_icmpeq LABEL27 + jump LABEL33 LABEL27: iload 3 iconst 4 - if_icmple LABEL31 - jump LABEL60 + if_icmpeq LABEL31 + jump LABEL33 LABEL31: + get_varc_int 945 + istore 3 +LABEL33: + iload 3 + iconst -1 + if_icmpne LABEL37 + jump LABEL70 +LABEL37: + iload 3 + iconst 4 + if_icmple LABEL41 + jump LABEL70 +LABEL41: iload 3 get_varc_int 945 - if_icmpne LABEL35 - jump LABEL60 -LABEL35: + if_icmpne LABEL45 + jump LABEL70 +LABEL45: iload 3 set_varc_int 945 iload 3 iconst 0 - if_icmpne LABEL41 - jump LABEL51 -LABEL41: + if_icmpne LABEL51 + jump LABEL61 +LABEL51: sconst "Your chatbox mode is now set to " iconst 105 iconst 115 @@ -61,8 +74,8 @@ LABEL41: sconst " chat, to reset your mode type /@p" join_string 3 mes - jump LABEL60 -LABEL51: + jump LABEL70 +LABEL61: sconst "Your chatbox mode has been reset to " iconst 105 iconst 115 @@ -72,28 +85,28 @@ LABEL51: sconst " chat." join_string 3 mes -LABEL60: +LABEL70: iload 2 iconst 1 - if_icmpeq LABEL64 - jump LABEL102 -LABEL64: + if_icmpeq LABEL74 + jump LABEL112 +LABEL74: get_varc_int 945 switch - 1: LABEL67 - 2: LABEL88 - 3: LABEL93 - 4: LABEL98 - jump LABEL102 -LABEL67: + 1: LABEL77 + 2: LABEL98 + 3: LABEL103 + 4: LABEL108 + jump LABEL112 +LABEL77: iconst 2 istore 0 sload 0 string_length iconst 0 - if_icmpgt LABEL74 - jump LABEL87 -LABEL74: + if_icmpgt LABEL84 + jump LABEL97 +LABEL84: sload 0 iconst 0 iconst 1 @@ -101,33 +114,33 @@ LABEL74: sconst "/" compare iconst 0 ; - if_icmpne LABEL83 - jump LABEL87 -LABEL83: + if_icmpne LABEL93 + jump LABEL97 +LABEL93: sconst "/" sload 0 append sstore 0 -LABEL87: - jump LABEL102 -LABEL88: +LABEL97: + jump LABEL112 +LABEL98: iconst 3 iconst 0 istore 1 istore 0 - jump LABEL102 -LABEL93: + jump LABEL112 +LABEL103: iconst 4 iconst 0 istore 1 istore 0 - jump LABEL102 -LABEL98: + jump LABEL112 +LABEL108: iconst 3 iconst 1 istore 1 istore 0 -LABEL102: +LABEL112: sload 0 ; load input iload 0 ; load chat type iload 1 ; load clan target @@ -144,31 +157,31 @@ CONTINUE: sstore 1 iload 0 iconst 2 - if_icmpeq LABEL114 + if_icmpeq LABEL124 iload 0 iconst 3 - if_icmpeq LABEL114 + if_icmpeq LABEL124 iload 0 iconst 4 - if_icmpeq LABEL114 - jump LABEL154 -LABEL114: + if_icmpeq LABEL124 + jump LABEL164 +LABEL124: sload 0 invoke 5501 iconst 1 - if_icmpeq LABEL119 - jump LABEL123 -LABEL119: + if_icmpeq LABEL129 + jump LABEL133 +LABEL129: sload 0 invoke 632 sstore 0 sstore 1 -LABEL123: +LABEL133: iload 1 iconst 1 - if_icmpeq LABEL127 - jump LABEL143 -LABEL127: + if_icmpeq LABEL137 + jump LABEL153 +LABEL137: sload 0 iconst 0 iconst 1 @@ -185,33 +198,33 @@ LABEL127: sload 0 append sstore 0 -LABEL143: +LABEL153: sload 0 string_length iconst 0 - if_icmple LABEL148 - jump LABEL149 -LABEL148: + if_icmple LABEL158 + jump LABEL159 +LABEL158: return -LABEL149: +LABEL159: sload 0 iload 0 iload 1 chat_sendclan - jump LABEL163 -LABEL154: + jump LABEL173 +LABEL164: sload 0 string_length iconst 0 - if_icmple LABEL159 - jump LABEL160 -LABEL159: + if_icmple LABEL169 + jump LABEL170 +LABEL169: return -LABEL160: +LABEL170: sload 0 iload 0 chat_sendpublic -LABEL163: +LABEL173: clientclock set_varc_int 61 return diff --git a/runelite-client/src/main/scripts/ChatTimestamp.hash b/runelite-client/src/main/scripts/ChatTimestamp.hash new file mode 100644 index 0000000000..0fca71cb43 --- /dev/null +++ b/runelite-client/src/main/scripts/ChatTimestamp.hash @@ -0,0 +1 @@ +6943EE91A5B24C1E3C43274E34A6207A981EE9DDF1F8CBB2129666CF70DC955F \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatTimestamp.rs2asm b/runelite-client/src/main/scripts/ChatTimestamp.rs2asm new file mode 100644 index 0000000000..7ebc00dbde --- /dev/null +++ b/runelite-client/src/main/scripts/ChatTimestamp.rs2asm @@ -0,0 +1,56 @@ +; used by TimestampPlugin via Chat(Split)Builder to display timestamps +; add a timestamp to a message +; string0 = timestamp +; string1 = message +; string2 = timestamp color +.id 4742 +.int_stack_count 0 +.string_stack_count 3 +.int_var_count 0 +.string_var_count 3 + jump ENABLED ; jump over ~on_enhanced_any = 0 | chat_gettimestamps = 0 + invoke 100 + iconst 0 + if_icmpeq LABEL11 + 5025 + iconst 0 + if_icmpeq LABEL11 +ENABLED: + sload 0 + invoke 5529 + iconst 1 + if_icmpeq LABEL11 + jump LABEL13 +LABEL11: + sload 1 + return +LABEL13: + sload 1 + invoke 5530 + invoke 5529 + iconst 1 + if_icmpeq LABEL19 + jump LABEL21 +LABEL19: + sload 1 + return +LABEL21: + sload 2 + invoke 5529 + iconst 0 + if_icmpeq LABEL26 + jump LABEL31 +LABEL26: + sload 2 + sload 0 + sconst "" + join_string 3 + sstore 0 +LABEL31: + sload 0 + sconst " " + sload 1 + join_string 3 + return + sconst "" + return diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.hash b/runelite-client/src/main/scripts/GeExamineInfoText.hash new file mode 100644 index 0000000000..e920ac8015 --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.hash @@ -0,0 +1 @@ +703C181C0453F22483854DC20D14FCBDE79E9DEC0400F9DB5404A7E299AA5CD8 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm new file mode 100644 index 0000000000..07eb5a9c1a --- /dev/null +++ b/runelite-client/src/main/scripts/GeExamineInfoText.rs2asm @@ -0,0 +1,183 @@ +; script used to position the ge buy offer "Convenience fee" info icon as well as set the +; examine text +; component0 = text component for the examine text +; component1 = parent of the info icon +; string0 = item examine +; string1 = Convenience fee text +.id 5730 +.int_stack_count 2 +.string_stack_count 2 +.int_var_count 5 +.string_var_count 3 + sconst "" + sstore 2 + iconst 0 + istore 2 + iconst 0 + istore 3 + iconst 0 + istore 4 + sload 1 + string_length + iconst 0 + if_icmpgt LABEL13 + jump LABEL131 +LABEL13: + iload 0 + if_getwidth + istore 2 + sload 0 + iload 2 + iconst 494 + paraheight + iconst 2 + if_icmple LABEL23 + jump LABEL30 +LABEL23: + sload 0 + sconst "
" + sconst "
" + sload 1 + join_string 4 + sstore 2 + jump LABEL35 +LABEL30: + sload 0 + sconst "
" + sload 1 + join_string 3 + sstore 2 +LABEL35: + + sload 0 ; examine + sload 1 ; Convenience fee + sload 2 ; "<$string0>

<$string1>" + sconst "geExamineText" + runelite_callback + sstore 2 ; final text + pop_string ; Convenience fee + pop_string ; examine + + iload 0 + if_getx + sload 1 + iload 2 + iconst 494 + parawidth + add + iconst 5 + add + iload 0 + if_gety + sload 2 + iload 2 + iconst 494 + paraheight + iconst 15 + multiply + add + iconst 2 + add + istore 4 + istore 3 + iload 3 + iload 1 + if_getwidth + iconst 15 + sub + iconst 2 + div + sub + iload 4 + iconst 11 + iload 1 + if_getheight + iconst 2 + div + add + sub + istore 4 + istore 3 + iload 3 + iload 4 + iconst 0 + iconst 0 + iload 1 + if_setposition + iconst 0 + iload 1 + if_sethide + iload 1 + cc_deleteall + iload 1 + iconst 5 + iconst 0 + cc_create + iconst 15 + iconst 15 + iconst 0 + iconst 0 + cc_setsize + iconst 0 + iconst 0 + iconst 1 + iconst 1 + cc_setposition + iconst 1094 + cc_setgraphic + iconst 50 + cc_settrans + iconst 244 + iconst -2147483645 + cc_getid + iconst 0 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouserepeat + iconst 244 + iconst -2147483645 + cc_getid + iconst 50 + iconst -1 + sconst "IiiI" + iload 1 + if_setonmouseleave + iconst 489 + iconst -2147483644 + iconst 2 + sconst "ii" + iload 1 + if_setonop + iconst 1 + sconst "Info" + iload 1 + if_setop + jump LABEL152 +LABEL131: + sload 0 + sstore 2 + iconst 1 + iload 1 + if_sethide + iload 1 + cc_deleteall + iconst -1 + sconst "" + iload 1 + if_setonmouserepeat + iconst -1 + sconst "" + iload 1 + if_setonmouseleave + iconst -1 + sconst "" + iload 1 + if_setonop + iload 1 + if_clearops +LABEL152: + sload 2 + iload 0 + if_settext + return diff --git a/runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java b/runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java new file mode 100644 index 0000000000..fbc2e7b48f --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/hiscore/HiscoreClientTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021, 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.hiscore; + +import java.io.IOException; +import net.runelite.http.api.RuneLiteAPI; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class HiscoreClientTest +{ + private static final String RESPONSE = "654683,705,1304518\n" + + "679419,50,107181\n" + + "550667,48,85764\n" + + "861497,50,101366\n" + + "891591,48,87843\n" + + "-1,1,4\n" + + "840255,27,10073\n" + + "1371912,10,1310\n" + + "432193,56,199795\n" + + "495638,56,198304\n" + + "514466,37,27502\n" + + "456981,54,159727\n" + + "459159,49,93010\n" + + "1028855,8,823\n" + + "862906,29,12749\n" + + "795020,31,16097\n" + + "673591,5,495\n" + + "352676,51,112259\n" + + "428419,40,37235\n" + + "461887,43,51971\n" + + "598582,1,10\n" + + "638177,1,0\n" + + "516239,9,1000\n" + + "492790,1,0\n" + + "2,2460\n" // leagues + + "-1,-1\n" + + "73,1738\n" + + "531,1432\n" + + "324,212\n" + + "8008,131\n" + + "1337,911\n" + + "42,14113\n" + + "1,777\n" + + "254,92\n" + + "-1,-1\n" // lms + + "1,241\n" // soul wars + + "24870,37\n" + + "15020,388\n" + + "50463,147\n" + + "-1,-1\n" + + "92357,1\n" + + "22758,637\n" + + "22744,107\n" + + "-1,-1\n" + + "20150,17\n" + + "29400,18\n" + + "13465,172\n" + + "1889,581\n" + + "42891,11\n" + + "1624,1957\n" + + "1243,2465\n" + + "1548,2020\n" + + "-1,-1\n" + + "16781,327\n" + + "19004,149\n" + + "-1,-1\n" + + "72046,5\n" + + "5158,374\n" + + "20902,279\n" + + "702,6495\n" + + "10170,184\n" + + "8064,202\n" + + "6936,2\n" // Mimic + + "1,4920\n" // Nex + + "2335,9\n" // Nightmare + + "2336,10\n" // Phosanis Nightmare + + "-1,-1\n" + + "-1,-1\n" + + "19779,22\n" + + "58283,10\n" + + "1234,5678\n" // Tempoross + + "-1,-1\n" + + "-1,-1\n" + + "-1,-1\n" // TOB + + "42,42\n" // TOB: Hard Mode + + "29347,130\n" + + "723,4\n" + + "1264,38\n" + + "44595,4\n" + + "24820,4\n" + + "12116,782\n" + + "2299,724\n" + + "19301,62\n" + + "1498,5847\n"; + + @Rule + public final MockWebServer server = new MockWebServer(); + + @Before + public void before() throws IOException + { + server.enqueue(new MockResponse().setBody(RESPONSE)); + } + + @Test + public void testNormalLookup() throws Exception + { + HiscoreClient hiscoreClient = new HiscoreClient(RuneLiteAPI.CLIENT); + + HiscoreResult result = hiscoreClient.lookup("zezima", server.url("/")); + + assertEquals(50, result.getAttack().getLevel()); + assertEquals(159727L, result.getFishing().getExperience()); + assertEquals(492790, result.getConstruction().getRank()); + assertEquals(1432, result.getClueScrollAll().getLevel()); + assertEquals(324, result.getClueScrollBeginner().getRank()); + assertEquals(8008, result.getClueScrollEasy().getRank()); + assertEquals(911, result.getClueScrollMedium().getLevel()); + assertEquals(42, result.getClueScrollHard().getRank()); + assertEquals(777, result.getClueScrollElite().getLevel()); + assertEquals(254, result.getClueScrollMaster().getRank()); + assertEquals(-1, result.getLastManStanding().getLevel()); + assertEquals(241, result.getSoulWarsZeal().getLevel()); + assertEquals(2460, result.getLeaguePoints().getLevel()); + assertEquals(37, result.getAbyssalSire().getLevel()); + assertEquals(92357, result.getCallisto().getRank()); + assertEquals(4920, result.getNex().getLevel()); + assertEquals(2336, result.getPhosanisNightmare().getRank()); + assertEquals(5678, result.getTempoross().getLevel()); + assertEquals(42, result.getTheatreOfBloodHardMode().getLevel()); + assertEquals(5847, result.getZulrah().getLevel()); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java index 30ca3dfeda..cd33ded89b 100644 --- a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java @@ -24,9 +24,12 @@ */ package net.runelite.client.menus; +import com.google.common.collect.Lists; import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.MenuAction; @@ -38,24 +41,18 @@ import static net.runelite.api.widgets.WidgetInfo.MINIMAP_WORLDMAP_OPTIONS; import net.runelite.client.util.Text; import static org.junit.Assert.assertArrayEquals; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; +import static org.mockito.ArgumentMatchers.anyInt; import org.mockito.Mock; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) public class MenuManagerTest { - private static final MenuEntry CANCEL = new MenuEntry(); - @Inject private MenuManager menuManager; @@ -63,14 +60,18 @@ public class MenuManagerTest @Bind private Client client; - private MenuEntry[] clientMenuEntries = {CANCEL}; + private final MenuEntry CANCEL = createMenuEntry("Cancel", "", MenuAction.CANCEL, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - @BeforeClass - public static void beforeClass() + private final List createdMenuEntries = new ArrayList<>(); + + private static MenuEntry createMenuEntry(String option, String target, MenuAction type, int param1) { - CANCEL.setOption("Cancel"); - CANCEL.setType(MenuAction.CANCEL.getId()); - CANCEL.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + MenuEntry menuEntry = new TestMenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setType(type); + menuEntry.setParam1(param1); + return menuEntry; } @Before @@ -78,35 +79,25 @@ public class MenuManagerTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - doAnswer((Answer) invocationOnMock -> - { - clientMenuEntries = invocationOnMock.getArgument(0, MenuEntry[].class); - return null; - }).when(client).setMenuEntries(ArgumentMatchers.any(MenuEntry[].class)); - when(client.getMenuEntries()).thenAnswer((Answer) invocationMock -> clientMenuEntries); + when(client.createMenuEntry(anyInt())) + .thenAnswer(a -> + { + MenuEntry e = new TestMenuEntry(); + createdMenuEntries.add(e); + return e; + }); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{CANCEL}); } @Test public void testManagedMenuOrder() { - final MenuEntry first = new MenuEntry(); - final MenuEntry second = new MenuEntry(); - final MenuEntry third = new MenuEntry(); - first.setOption("Test"); - first.setTarget("First Entry"); - first.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - first.setType(RUNELITE.getId()); - second.setOption("Test"); - second.setTarget("Second Entry"); - second.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - second.setType(RUNELITE.getId()); - third.setOption("Test"); - third.setTarget("Third Entry"); - third.setParam1(MINIMAP_WORLDMAP_OPTIONS.getPackedId()); - third.setType(RUNELITE.getId()); - menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); - menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS)); + final MenuEntry first = createMenuEntry("Test", "First Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry second = createMenuEntry("Test", "Second Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + final MenuEntry third = createMenuEntry("Test", "Third Entry", RUNELITE, MINIMAP_WORLDMAP_OPTIONS.getPackedId()); + menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); + menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), MINIMAP_WORLDMAP_OPTIONS), null); menuManager.onMenuEntryAdded(new MenuEntryAdded( CANCEL.getOption(), @@ -116,12 +107,10 @@ public class MenuManagerTest CANCEL.getParam0(), CANCEL.getParam1())); - ArgumentCaptor captor = ArgumentCaptor.forClass(MenuEntry[].class); - verify(client, atLeastOnce()).setMenuEntries(captor.capture()); + verify(client, times(3)).createMenuEntry(anyInt()); - final MenuEntry[] resultMenuEntries = captor.getValue(); // Strip color tags from menu options before array comparison - for (MenuEntry resultEntry : resultMenuEntries) + for (MenuEntry resultEntry : createdMenuEntries) { final String resultTarget = resultEntry.getTarget(); if (resultTarget != null) @@ -130,6 +119,7 @@ public class MenuManagerTest } } - assertArrayEquals(new MenuEntry[]{CANCEL, third, second, first}, resultMenuEntries); + assertArrayEquals(new MenuEntry[]{third, second, first}, + Lists.reverse(createdMenuEntries).toArray(new MenuEntry[0])); } } diff --git a/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java new file mode 100644 index 0000000000..fc337e7376 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/menus/TestMenuEntry.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2021, 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.menus; + +import java.util.function.Consumer; +import lombok.EqualsAndHashCode; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +@EqualsAndHashCode(callSuper = false) +public class TestMenuEntry implements MenuEntry +{ + private String option; + private String target; + private int identifier; + private int type; + private int param0; + private int param1; + private boolean forceLeftClick; + + @Override + public String getOption() + { + return option; + } + + @Override + public MenuEntry setOption(String option) + { + this.option = option; + return this; + } + + @Override + public String getTarget() + { + return target; + } + + @Override + public MenuEntry setTarget(String target) + { + this.target = target; + return this; + } + + @Override + public int getIdentifier() + { + return this.identifier; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + this.identifier = identifier; + return this; + } + + @Override + public MenuAction getType() + { + return MenuAction.of(this.type); + } + + @Override + public MenuEntry setType(MenuAction type) + { + this.type = type.getId(); + return this; + } + + @Override + public int getParam0() + { + return this.param0; + } + + @Override + public MenuEntry setParam0(int param0) + { + this.param0 = param0; + return this; + } + + @Override + public int getParam1() + { + return this.param1; + } + + @Override + public MenuEntry setParam1(int param1) + { + this.param1 = param1; + return this; + } + + @Override + public boolean isForceLeftClick() + { + return this.forceLeftClick; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + this.forceLeftClick = forceLeftClick; + return this; + } + + @Override + public boolean isDeprioritized() + { + return type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + + @Override + public MenuEntry setDeprioritized(boolean deprioritized) + { + if (deprioritized) + { + if (type < MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type += MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + else + { + if (type >= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET) + { + type -= MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; + } + } + + return this; + } + + @Override + public MenuEntry onClick(Consumer callback) + { + return this; + } + + @Override + public int getOpcode() + { + return this.type; + } + + @Override + public void setOpcode(int opcode) + { + this.type = opcode; + } + + @Override + public int getActionParam0() + { + return this.param0; + } + + @Override + public void setActionParam0(int param0) + { + this.param0 = param0; + } + + @Override + public int getActionParam1() + { + return this.param1; + } + + @Override + public void setActionParam1(int param1) + { + this.param1 = param1; + } + + @Override + public MenuAction getMenuAction() + { + return MenuAction.of(this.type); + } +} 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 ab2ec35046..8ac44d3a6a 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 @@ -54,17 +54,19 @@ import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; +import net.runelite.client.hiscore.HiscoreClient; +import net.runelite.client.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreResult; +import net.runelite.client.hiscore.Skill; import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.chat.ChatClient; -import net.runelite.http.api.hiscore.HiscoreClient; -import net.runelite.http.api.hiscore.HiscoreSkill; -import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; -import net.runelite.http.api.hiscore.Skill; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; import org.mockito.Mock; import static org.mockito.Mockito.any; import static org.mockito.Mockito.atLeastOnce; @@ -545,11 +547,11 @@ public class ChatCommandsPluginTest { when(chatCommandsConfig.lvl()).thenReturn(true); - SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); - skillResult.setPlayer(PLAYER_NAME); - skillResult.setSkill(new Skill(10, 1000, -1)); + HiscoreResult hiscoreResult = new HiscoreResult(); + hiscoreResult.setPlayer(PLAYER_NAME); + hiscoreResult.setZulrah(new Skill(10, 1000, -1)); - when(hiscoreClient.lookup(PLAYER_NAME, HiscoreSkill.ZULRAH, null)).thenReturn(skillResult); + when(hiscoreClient.lookup(eq(PLAYER_NAME), nullable(HiscoreEndpoint.class))).thenReturn(hiscoreResult); MessageNode messageNode = mock(MessageNode.class); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java index 4b3fd12f32..ee8b485b6a 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java @@ -31,9 +31,11 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.Friend; +import net.runelite.api.FriendContainer; import net.runelite.api.MessageNode; -import net.runelite.api.NameableContainer; import net.runelite.api.events.ChatMessage; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.config.ConfigManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +56,14 @@ public class FriendListPluginTest @Bind private FriendListConfig config; + @Mock + @Bind + private ConfigManager configManager; + + @Mock + @Bind + private ChatMessageManager chatMessageManager; + @Inject private FriendListPlugin friendListPlugin; @@ -78,7 +88,7 @@ public class FriendListPluginTest Friend friend = mock(Friend.class); when(friend.getWorld()).thenReturn(311); - NameableContainer friendContainer = mock(NameableContainer.class); + FriendContainer friendContainer = mock(FriendContainer.class); when(friendContainer.findByName("test\u00a0rsn")).thenReturn(friend); when(client.getFriendContainer()).thenReturn(friendContainer); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java index 8624a9017a..b6139cc265 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java @@ -53,7 +53,6 @@ import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.find import static net.runelite.http.api.RuneLiteAPI.GSON; import net.runelite.http.api.ge.GrandExchangeClient; import net.runelite.http.api.ge.GrandExchangeTrade; -import net.runelite.http.api.osbuddy.OSBGrandExchangeClient; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -112,10 +111,6 @@ public class GrandExchangePluginTest @Bind private GrandExchangeClient grandExchangeClient; - @Mock - @Bind - private OSBGrandExchangeClient osbGrandExchangeClient; - @Mock @Bind private Client client; 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 5cd56d3669..bc0ced11c6 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 @@ -25,7 +25,7 @@ package net.runelite.client.plugins.hiscore; import static net.runelite.client.plugins.hiscore.HiscorePanel.formatLevel; -import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.client.hiscore.HiscoreEndpoint; import okhttp3.OkHttpClient; import static org.junit.Assert.assertEquals; import org.junit.Test; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java new file mode 100644 index 0000000000..4fa03023a1 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPluginTest.java @@ -0,0 +1,430 @@ +/* + * 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.menuentryswapper; + +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.Arrays; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.KeyCode; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.menus.TestMenuEntry; +import static org.junit.Assert.assertArrayEquals; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import static org.mockito.ArgumentMatchers.any; +import org.mockito.Mock; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; + +@RunWith(MockitoJUnitRunner.class) +public class MenuEntrySwapperPluginTest +{ + @Mock + @Bind + Client client; + + @Mock + @Bind + ConfigManager configManager; + + @Mock + @Bind + ItemManager itemManager; + + @Mock + @Bind + MenuEntrySwapperConfig config; + + @Inject + MenuEntrySwapperPlugin menuEntrySwapperPlugin; + + private MenuEntry[] entries; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getGameState()).thenReturn(GameState.LOGGED_IN); + + when(client.getMenuEntries()).thenAnswer((Answer) invocationOnMock -> + { + // The menu implementation returns a copy of the array, which causes swap() to not + // modify the same array being iterated in onClientTick + return Arrays.copyOf(entries, entries.length); + }); + doAnswer((Answer) invocationOnMock -> + { + Object argument = invocationOnMock.getArguments()[0]; + entries = (MenuEntry[]) argument; + return null; + }).when(client).setMenuEntries(any(MenuEntry[].class)); + + menuEntrySwapperPlugin.setupSwaps(); + } + + private static MenuEntry menu(String option, String target, MenuAction menuAction) + { + return menu(option, target, menuAction, 0); + } + + private static MenuEntry menu(String option, String target, MenuAction menuAction, int identifier) + { + MenuEntry menuEntry = new TestMenuEntry(); + menuEntry.setOption(option); + menuEntry.setTarget(target); + menuEntry.setType(menuAction); + menuEntry.setIdentifier(identifier); + return menuEntry; + } + + @Test + public void testSlayerMaster() + { + lenient().when(config.swapTrade()).thenReturn(true); + when(config.swapAssignment()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Rewards", "Duradel", MenuAction.NPC_FIFTH_OPTION), + menu("Trade", "Duradel", MenuAction.NPC_FOURTH_OPTION), + menu("Assignment", "Duradel", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Duradel", MenuAction.NPC_FIRST_OPTION), + }; + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + // check the assignment swap is hit first instead of trade + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Rewards", "Duradel", MenuAction.NPC_FIFTH_OPTION), + menu("Trade", "Duradel", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Duradel", MenuAction.NPC_FIRST_OPTION), + menu("Assignment", "Duradel", MenuAction.NPC_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testBankers() + { + when(config.swapBank()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + // Banker 2 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + + // Banker 1 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client, times(2)).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Examine", "Gnome banker", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + // Banker 2 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + + // Banker 1 + menu("Collect", "Gnome banker", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Gnome banker", MenuAction.NPC_FIRST_OPTION), + menu("Bank", "Gnome banker", MenuAction.NPC_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testContains() + { + when(config.swapPay()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Kragen", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + menu("Pay (south)", "Kragen", MenuAction.NPC_FOURTH_OPTION), + menu("Pay (north)", "Kragen", MenuAction.NPC_THIRD_OPTION), + menu("Talk-to", "Kragen", MenuAction.NPC_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Kragen", MenuAction.EXAMINE_NPC), + menu("Walk here", "", MenuAction.WALK), + + menu("Pay (south)", "Kragen", MenuAction.NPC_FOURTH_OPTION), + menu("Talk-to", "Kragen", MenuAction.NPC_FIRST_OPTION), + menu("Pay (north)", "Kragen", MenuAction.NPC_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testTeleport() + { + when(config.swapTeleportSpell()).thenReturn(true); + when(client.isKeyPressed(KeyCode.KC_SHIFT)).thenReturn(true); + + // Cast -> Grand Exchange + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + }, argumentCaptor.getValue()); + + clearInvocations(client); + + // Grand Exchange -> Cast + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + + menu("Configure", "Varrock Teleport", MenuAction.WIDGET_THIRD_OPTION), + menu("Grand Exchange", "Varrock Teleport", MenuAction.WIDGET_FIRST_OPTION), + menu("Cast", "Varrock Teleport", MenuAction.WIDGET_SECOND_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testTobDoor() + { + when(config.swapQuick()).thenReturn(true); + + //Quick-enter, Enter + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Formidable Passage", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Quick-Enter", "Formidable Passage", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Enter", "Formidable Passage", MenuAction.GAME_OBJECT_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Formidable Passage", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Enter", "Formidable Passage", MenuAction.GAME_OBJECT_FIRST_OPTION), + menu("Quick-Enter", "Formidable Passage", MenuAction.GAME_OBJECT_SECOND_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testShiftWithdraw() + { + when(config.bankDepositShiftClick()).thenReturn(ShiftDepositMode.EXTRA_OP); + when(client.isKeyPressed(KeyCode.KC_SHIFT)).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Wield", "Abyssal whip", MenuAction.CC_OP_LOW_PRIORITY, 9), + menu("Deposit-1", "Abyssal whip", MenuAction.CC_OP, 2), + }; + + menuEntrySwapperPlugin.onMenuEntryAdded(new MenuEntryAdded( + "Deposit-1", + "Abyssal whip", + MenuAction.CC_OP.getId(), + 2, + -1, + -1 + )); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Deposit-1", "Abyssal whip", MenuAction.CC_OP, 2), + menu("Wield", "Abyssal whip", MenuAction.CC_OP, 9), + }, argumentCaptor.getValue()); + } + + @Test + public void testShiftDeposit() + { + when(config.bankDepositShiftClick()).thenReturn(ShiftDepositMode.DEPOSIT_ALL); + when(client.isKeyPressed(KeyCode.KC_SHIFT)).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Wield", "Rune arrow", MenuAction.CC_OP_LOW_PRIORITY, 9), + menu("Deposit-All", "Rune arrow", MenuAction.CC_OP_LOW_PRIORITY, 8), + menu("Deposit-1", "Rune arrow", MenuAction.CC_OP, 2), + }; + + menuEntrySwapperPlugin.onMenuEntryAdded(new MenuEntryAdded( + "Deposit-1", + "Rune arrow", + MenuAction.CC_OP.getId(), + 2, + -1, + -1 + )); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Wield", "Rune arrow", MenuAction.CC_OP_LOW_PRIORITY, 9), + menu("Deposit-1", "Rune arrow", MenuAction.CC_OP, 2), + menu("Deposit-All", "Rune arrow", MenuAction.CC_OP, 8), + }, argumentCaptor.getValue()); + } + + @Test + public void testBirdhouse() + { + when(config.swapBirdhouseEmpty()).thenReturn(true); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Redwood birdhouse", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Empty", "Redwood birdhouse", MenuAction.GAME_OBJECT_THIRD_OPTION), + menu("Seeds", "Redwood birdhouse", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Interact", "Redwood birdhouse", MenuAction.GAME_OBJECT_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Redwood birdhouse", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Interact", "Redwood birdhouse", MenuAction.GAME_OBJECT_FIRST_OPTION), + menu("Seeds", "Redwood birdhouse", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Empty", "Redwood birdhouse", MenuAction.GAME_OBJECT_THIRD_OPTION), + }, argumentCaptor.getValue()); + } + + @Test + public void testZanarisFairyRing() + { + when(config.swapFairyRing()).thenReturn(FairyRingMode.ZANARIS); + + entries = new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Fairy ring", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Last-destination (AIQ)", "Fairy ring", MenuAction.GAME_OBJECT_SECOND_OPTION), + menu("Configure", "Fairy ring", MenuAction.GAME_OBJECT_FIRST_OPTION), + }; + + menuEntrySwapperPlugin.onClientTick(new ClientTick()); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client).setMenuEntries(argumentCaptor.capture()); + + assertArrayEquals(new MenuEntry[]{ + menu("Cancel", "", MenuAction.CANCEL), + menu("Examine", "Fairy ring", MenuAction.EXAMINE_OBJECT), + menu("Walk here", "", MenuAction.WALK), + + menu("Configure", "Fairy ring", MenuAction.GAME_OBJECT_FIRST_OPTION), + menu("Last-destination (AIQ)", "Fairy ring", MenuAction.GAME_OBJECT_SECOND_OPTION), + }, argumentCaptor.getValue()); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java index 13c42671f7..1179f3e48c 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java @@ -39,6 +39,7 @@ import net.runelite.api.NPC; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.NpcChanged; import net.runelite.api.events.NpcSpawned; +import net.runelite.client.menus.TestMenuEntry; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -49,7 +50,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -111,13 +111,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // red - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // red } @Test @@ -136,13 +135,12 @@ public class NpcIndicatorsPluginTest when(client.getCachedNPCs()).thenReturn(new NPC[]{npc}); // id 0 - when(client.getMenuEntries()).thenReturn(new MenuEntry[]{new MenuEntry()}); + MenuEntry entry = new TestMenuEntry(); + when(client.getMenuEntries()).thenReturn(new MenuEntry[]{entry}); MenuEntryAdded menuEntryAdded = new MenuEntryAdded("", "Goblin", MenuAction.NPC_FIRST_OPTION.getId(), 0, -1, -1); npcIndicatorsPlugin.onMenuEntryAdded(menuEntryAdded); - MenuEntry target = new MenuEntry(); - target.setTarget("Goblin"); // blue - verify(client).setMenuEntries(new MenuEntry[]{target}); + assertEquals("Goblin", entry.getTarget()); // blue } @Test diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java index 30854ef800..86e44fc473 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/ClickboxMixin.java @@ -59,15 +59,15 @@ public abstract class ClickboxMixin implements RSClient // otherwise we must check if the mouse is in a triangle final int vertexCount = model.getVerticesCount(); - final int triangleCount = model.getTrianglesCount(); + final int triangleCount = model.getFaceCount(); final int[] vertexX = model.getVerticesX(); final int[] vertexY = model.getVerticesY(); final int[] vertexZ = model.getVerticesZ(); - final int[] triangleX = model.getTrianglesX(); - final int[] triangleY = model.getTrianglesY(); - final int[] triangleZ = model.getTrianglesZ(); + final int[] triangleX = model.getFaceIndices1(); + final int[] triangleY = model.getFaceIndices2(); + final int[] triangleZ = model.getFaceIndices3(); final int[] color3 = model.getFaceColors3(); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java index 6fb4d17233..21a59cd3fa 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/MenuMixin.java @@ -163,36 +163,6 @@ public abstract class MenuMixin implements RSClient } } - @Inject - @Override - public MenuEntry getLeftClickMenuEntry() - { - final int i = getMenuOptionCount() - 1; - return new MenuEntry( - getMenuOptions()[i], - getMenuTargets()[i], - getMenuIdentifiers()[i], - getMenuOpcodes()[i], - getMenuArguments1()[i], - getMenuArguments2()[i], - getMenuForceLeftClick()[i] - ); - } - - @Inject - @Override - public void setLeftClickMenuEntry(final MenuEntry entry) - { - final int i = getMenuOptionCount() - 1; - getMenuOptions()[i] = entry.getOption(); - getMenuTargets()[i] = entry.getTarget(); - getMenuIdentifiers()[i] = entry.getIdentifier(); - getMenuOpcodes()[i] = entry.getOpcode(); - getMenuArguments1()[i] = entry.getParam0(); - getMenuArguments2()[i] = entry.getParam1(); - getMenuForceLeftClick()[i] = entry.isForceLeftClick(); - } - @Inject @FieldHook("tempMenuAction") public static void onTempMenuActionChanged(int idx) @@ -213,7 +183,7 @@ public abstract class MenuMixin implements RSClient } tempMenuAction.setOption(entry.getOption()); - tempMenuAction.setOpcode(entry.getOpcode()); + tempMenuAction.setOpcode(entry.getType().getId()); tempMenuAction.setIdentifier(entry.getIdentifier()); tempMenuAction.setParam0(entry.getParam0()); tempMenuAction.setParam1(entry.getParam1()); 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 1885cb949f..b1f1d79763 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -39,9 +39,10 @@ import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import net.runelite.api.Animation; import net.runelite.api.ChatMessageType; import net.runelite.api.EnumComposition; -import net.runelite.api.Friend; +import net.runelite.api.FriendContainer; import net.runelite.api.GameState; import net.runelite.api.GrandExchangeOffer; import net.runelite.api.GraphicsObject; @@ -79,7 +80,6 @@ import net.runelite.api.Point; import net.runelite.api.Prayer; import net.runelite.api.Projectile; import net.runelite.api.ScriptEvent; -import net.runelite.api.Sequence; import net.runelite.api.Skill; import net.runelite.api.SpritePixels; import net.runelite.api.StructComposition; @@ -156,6 +156,7 @@ import net.runelite.rs.api.RSNodeDeque; import net.runelite.rs.api.RSNodeHashTable; import net.runelite.rs.api.RSPacketBuffer; import net.runelite.rs.api.RSPlayer; +import net.runelite.rs.api.RSRuneLiteMenuEntry; import net.runelite.rs.api.RSScene; import net.runelite.rs.api.RSScriptEvent; import net.runelite.rs.api.RSSpritePixels; @@ -294,6 +295,12 @@ public abstract class RSClientMixin implements RSClient @Inject private static ArrayList hiddenWidgets = new ArrayList<>(); + @Inject + private static final RSRuneLiteMenuEntry[] rl$menuEntries = new RSRuneLiteMenuEntry[500]; + + @Inject + private static int tmpMenuOptionsCount; + @Inject @Override public void setPrintMenuActions(boolean yes) @@ -790,109 +797,209 @@ public abstract class RSClientMixin implements RSClient } @Inject - @Override - public MenuEntry[] getMenuEntries() + public static RSRuneLiteMenuEntry newRuneliteMenuEntry(int idx) { - int count = getMenuOptionCount(); - String[] menuOptions = getMenuOptions(); - String[] menuTargets = getMenuTargets(); - int[] menuIdentifiers = getMenuIdentifiers(); - int[] menuTypes = getMenuOpcodes(); - int[] params0 = getMenuArguments1(); - int[] params1 = getMenuArguments2(); - boolean[] leftClick = getMenuForceLeftClick(); - - MenuEntry[] entries = new MenuEntry[count]; - for (int i = 0; i < count; ++i) - { - MenuEntry entry = entries[i] = new MenuEntry(); - entry.setOption(menuOptions[i]); - entry.setTarget(menuTargets[i]); - entry.setIdentifier(menuIdentifiers[i]); - entry.setOpcode(menuTypes[i]); - entry.setParam0(params0[i]); - entry.setParam1(params1[i]); - entry.setForceLeftClick(leftClick[i]); - } - return entries; + return null; } @Inject @Override - public void setMenuEntries(MenuEntry[] entries) + public MenuEntry createMenuEntry(int idx) { - int count = 0; - String[] menuOptions = getMenuOptions(); - String[] menuTargets = getMenuTargets(); - int[] menuIdentifiers = getMenuIdentifiers(); - int[] menuTypes = getMenuOpcodes(); - int[] params0 = getMenuArguments1(); - int[] params1 = getMenuArguments2(); - boolean[] leftClick = getMenuForceLeftClick(); - - for (MenuEntry entry : entries) + if (client.getMenuOptionCount() >= 500) { - if (entry == null) + throw new IllegalStateException(); + } + else + { + if (idx < 0) { - continue; + idx = client.getMenuOptionCount() + idx + 1; + if (idx < 0) + { + throw new IllegalArgumentException(); + } } - menuOptions[count] = entry.getOption(); - menuTargets[count] = entry.getTarget(); - menuIdentifiers[count] = entry.getIdentifier(); - menuTypes[count] = entry.getOpcode(); - params0[count] = entry.getParam0(); - params1[count] = entry.getParam1(); - leftClick[count] = entry.isForceLeftClick(); - ++count; + RSRuneLiteMenuEntry menuEntry; + if (idx < client.getMenuOptionCount()) + { + RSRuneLiteMenuEntry tmpEntry = rl$menuEntries[client.getMenuOptionCount()]; + if (tmpEntry == null) + { + tmpEntry = rl$menuEntries[client.getMenuOptionCount()] = newRuneliteMenuEntry(client.getMenuOptionCount()); + } + + for (int i = client.getMenuOptionCount(); i > idx; rl$menuEntries[i].setIdx(i--)) + { + client.getMenuOptions()[i] = client.getMenuOptions()[i - 1]; + client.getMenuTargets()[i] = client.getMenuTargets()[i - 1]; + client.getMenuIdentifiers()[i] = client.getMenuIdentifiers()[i - 1]; + client.getMenuOpcodes()[i] = client.getMenuOpcodes()[i - 1]; + client.getMenuArguments1()[i] = client.getMenuArguments1()[i - 1]; + client.getMenuArguments2()[i] = client.getMenuArguments2()[i - 1]; + client.getMenuForceLeftClick()[i] = client.getMenuForceLeftClick()[i - 1]; + + rl$menuEntries[i] = rl$menuEntries[i - 1]; + } + + client.setMenuOptionCount(client.getMenuOptionCount() + 1); + tmpMenuOptionsCount = client.getMenuOptionCount(); + + menuEntry = tmpEntry; + rl$menuEntries[idx] = tmpEntry; + + tmpEntry.setIdx(idx); + } + else + { + if (idx != client.getMenuOptionCount()) + { + throw new IllegalArgumentException(); + } + + menuEntry = rl$menuEntries[client.getMenuOptionCount()]; + + if (menuEntry == null) + { + menuEntry = rl$menuEntries[client.getMenuOptionCount()] = newRuneliteMenuEntry(client.getMenuOptionCount()); + } + + client.setMenuOptionCount(client.getMenuOptionCount() + 1); + tmpMenuOptionsCount = client.getMenuOptionCount(); + } + + menuEntry.setOption(""); + menuEntry.setTarget(""); + menuEntry.setIdentifier(0); + menuEntry.setType(MenuAction.RUNELITE); + menuEntry.setParam0(0); + menuEntry.setParam1(0); + menuEntry.setConsumer(null); + + return menuEntry; + } + } + + @Inject + @Override + public MenuEntry[] getMenuEntries() + { + return Arrays.copyOf(rl$menuEntries, client.getMenuOptionCount()); + } + + @Inject + @Override + public void setMenuEntries(MenuEntry[] menuEntries) + { + for (int i = 0; i < menuEntries.length; ++i) + { + RSRuneLiteMenuEntry menuEntry = (RSRuneLiteMenuEntry) menuEntries[i]; + if (menuEntry.getIdx() != i) + { + sortMenuEntries(menuEntry.getIdx(), i); + } } - setMenuOptionCount(count); - oldMenuEntryCount = count; + client.setMenuOptionCount(menuEntries.length); + tmpMenuOptionsCount = menuEntries.length; + } + + @Inject + public static void sortMenuEntries(int left, int right) + { + String menuOption = client.getMenuOptions()[left]; + client.getMenuOptions()[left] = client.getMenuOptions()[right]; + client.getMenuOptions()[right] = menuOption; + + String menuTarget = client.getMenuTargets()[left]; + client.getMenuTargets()[left] = client.getMenuTargets()[right]; + client.getMenuTargets()[right] = menuTarget; + + int menuIdentifier = client.getMenuIdentifiers()[left]; + client.getMenuIdentifiers()[left] = client.getMenuIdentifiers()[right]; + client.getMenuIdentifiers()[right] = menuIdentifier; + + int menuOpcode = client.getMenuOpcodes()[left]; + client.getMenuOpcodes()[left] = client.getMenuOpcodes()[right]; + client.getMenuOpcodes()[right] = menuOpcode; + + int menuArguments1 = client.getMenuArguments1()[left]; + client.getMenuArguments1()[left] = client.getMenuArguments1()[right]; + client.getMenuArguments1()[right] = menuArguments1; + + int menuArgument2 = client.getMenuArguments2()[left]; + client.getMenuArguments2()[left] = client.getMenuArguments2()[right]; + client.getMenuArguments2()[right] = menuArgument2; + + boolean menuForceLeftClick = client.getMenuForceLeftClick()[left]; + client.getMenuForceLeftClick()[left] = client.getMenuForceLeftClick()[right]; + client.getMenuForceLeftClick()[right] = menuForceLeftClick; + + RSRuneLiteMenuEntry tmpEntry = rl$menuEntries[left]; + rl$menuEntries[left] = rl$menuEntries[right]; + rl$menuEntries[right] = tmpEntry; + + rl$menuEntries[left].setIdx(left); + rl$menuEntries[right].setIdx(right); + } + + @Inject + public static void swapMenuEntries(int var0) + { + RSRuneLiteMenuEntry var1 = rl$menuEntries[var0]; + RSRuneLiteMenuEntry var2 = rl$menuEntries[var0 + 1]; + + rl$menuEntries[var0] = var2; + rl$menuEntries[var0 + 1] = var1; + + var1.setIdx(var0 + 1); + var2.setIdx(var0); } @FieldHook("menuOptionsCount") @Inject public static void onMenuOptionsChanged(int idx) { - int oldCount = oldMenuEntryCount; - int newCount = client.getMenuOptionCount(); + int tmpOptionsCount = tmpMenuOptionsCount; + int optionCount = client.getMenuOptionCount(); - oldMenuEntryCount = newCount; + tmpMenuOptionsCount = optionCount; - final String[] options = client.getMenuOptions(); - final String[] targets = client.getMenuTargets(); - final int[] identifiers = client.getMenuIdentifiers(); - final int[] opcodes = client.getMenuOpcodes(); - final int[] arguments1 = client.getMenuArguments1(); - final int[] arguments2 = client.getMenuArguments2(); - final boolean[] forceLeftClick = client.getMenuForceLeftClick(); - - if (newCount == oldCount + 1) + if (optionCount < tmpOptionsCount) { - MenuEntryAdded event = new MenuEntryAdded( - options[oldCount], - targets[oldCount], - identifiers[oldCount], - opcodes[oldCount], - arguments1[oldCount], - arguments2[oldCount], - forceLeftClick[oldCount] - ); - - client.getCallbacks().post(event); - - if (event.isModified() && client.getMenuOptionCount() == newCount) + for (int i = optionCount; i < tmpOptionsCount; ++i) { - options[oldCount] = event.getOption(); - targets[oldCount] = event.getTarget(); - identifiers[oldCount] = event.getIdentifier(); - opcodes[oldCount] = event.getOpcode(); - arguments1[oldCount] = event.getParam0(); - arguments2[oldCount] = event.getParam1(); - forceLeftClick[oldCount] = event.isForceLeftClick(); + rl$menuEntries[i].setConsumer(null); } } + else if (optionCount == tmpOptionsCount + 1) + { + String menuOption = client.getMenuOptions()[tmpOptionsCount]; + String menuTarget = client.getMenuTargets()[tmpOptionsCount]; + int menuOpcode = client.getMenuOpcodes()[tmpOptionsCount]; + int menuIdentifier = client.getMenuIdentifiers()[tmpOptionsCount]; + int menuArgument1 = client.getMenuArguments1()[tmpOptionsCount]; + int menuArgument2 = client.getMenuArguments2()[tmpOptionsCount]; + if (rl$menuEntries[tmpOptionsCount] == null) + { + rl$menuEntries[tmpOptionsCount] = newRuneliteMenuEntry(tmpOptionsCount); + } + else + { + rl$menuEntries[tmpOptionsCount].setConsumer(null); + } + + MenuEntryAdded menuEntryAdded = new MenuEntryAdded( + menuOption, + menuTarget, + menuOpcode, + menuIdentifier, + menuArgument1, + menuArgument2 + ); + client.getCallbacks().post(menuEntryAdded); + } } @Inject @@ -999,7 +1106,7 @@ public abstract class RSClientMixin implements RSClient @Inject @Override - public NameableContainer getFriendContainer() + public FriendContainer getFriendContainer() { return getFriendManager().getFriendContainer(); } @@ -1470,6 +1577,17 @@ public abstract class RSClientMixin implements RSClient @Replace("menuAction") static void copy$menuAction(int param0, int param1, int opcode, int id, String option, String target, int canvasX, int canvasY) { + RSRuneLiteMenuEntry menuEntry = null; + + for (int i = client.getMenuOptionCount() - 1; i >= 0; --i) + { + if (client.getMenuOptions()[i] == option && client.getMenuTargets()[i] == target && client.getMenuIdentifiers()[i] == id && client.getMenuOpcodes()[i] == opcode) + { + menuEntry = rl$menuEntries[i]; + break; + } + } + /* * The RuneScape client may deprioritize an action in the menu by incrementing the opcode with 2000, * undo it here so we can get the correct opcode @@ -1492,6 +1610,11 @@ public abstract class RSClientMixin implements RSClient client.getCallbacks().post(menuOptionClicked); + if (menuEntry != null && menuEntry.getConsumer() != null) + { + menuEntry.getConsumer().accept(menuEntry); + } + if (menuOptionClicked.isConsumed()) { return; @@ -2427,7 +2550,7 @@ public abstract class RSClientMixin implements RSClient } @Inject - public Sequence loadAnimation(int id) + public Animation loadAnimation(int id) { return client.getSequenceDefinition(id); } diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java similarity index 53% rename from http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java rename to runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java index fa779381bc..8df78b44c4 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/Skill.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendLoginUpdatesMixin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Adam + * Copyright (c) 2016-2017, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,80 +22,34 @@ * (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.hiscore; +package net.runelite.mixins; -public class Skill +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSFriendLoginUpdate; +import net.runelite.rs.api.RSUsername; + +@Mixin(RSFriendLoginUpdate.class) +public abstract class RSFriendLoginUpdatesMixin implements RSFriendLoginUpdate { - private final int rank; - private final int level; - private final long experience; - - public Skill(int rank, int level, long experience) - { - this.rank = rank; - this.level = level; - this.experience = experience; - } - - public int getRank() - { - return rank; - } - - public int getLevel() - { - return level; - } - - public long getExperience() - { - return experience; - } - + @Inject @Override - public int hashCode() + public String getName() { - int hash = 3; - hash = 59 * hash + this.rank; - hash = 59 * hash + this.level; - hash = 59 * hash + (int) (this.experience ^ (this.experience >>> 32)); - return hash; - } + final RSUsername rsName = getRsName(); - @Override - public boolean equals(Object obj) - { - if (this == obj) + if (rsName == null) { - return true; + return null; } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - final Skill other = (Skill) obj; - if (this.rank != other.rank) - { - return false; - } - if (this.level != other.level) - { - return false; - } - if (this.experience != other.experience) - { - return false; - } - return true; - } - @Override - public String toString() - { - return "Skill{" + "rank=" + rank + ", level=" + level + ", experience=" + experience + '}'; + String name = rsName.getName(); + + if (name == null) + { + return null; + } + + return name.replace('\u00A0', ' '); } -} +} \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java new file mode 100644 index 0000000000..1ab3935574 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSLinkDequeMixin.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-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.mixins; + +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSLink; +import net.runelite.rs.api.RSLinkDeque; + +@Mixin(RSLinkDeque.class) +public abstract class RSLinkDequeMixin implements RSLinkDeque +{ + @Inject + @Override + public void clear() + { + while (true) + { + RSLink rsLink = getSentinel().getPrevious(); + if (rsLink == getSentinel()) + { + setCurrent(null); + return; + } + + rsLink.remove(); + } + } +} \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java index f17215d244..c18e32c59d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSModelMixin.java @@ -78,7 +78,7 @@ public abstract class RSModelMixin implements RSModel { if (getFaceTextures() != null) { - int count = getTrianglesCount(); + int count = getFaceCount(); float[] uv = new float[count * 6]; int idx = 0; @@ -91,10 +91,10 @@ public abstract class RSModelMixin implements RSModel if (modelUV != null) { - System.arraycopy(modelUV, 0, uv, idx, model.getTrianglesCount() * 6); + System.arraycopy(modelUV, 0, uv, idx, model.getFaceCount() * 6); } - idx += model.getTrianglesCount() * 6; + idx += model.getFaceCount() * 6; } } @@ -131,14 +131,14 @@ public abstract class RSModelMixin implements RSModel @Inject public List getTriangles() { - int[] trianglesX = getTrianglesX(); - int[] trianglesY = getTrianglesY(); - int[] trianglesZ = getTrianglesZ(); + int[] trianglesX = getFaceIndices1(); + int[] trianglesY = getFaceIndices2(); + int[] trianglesZ = getFaceIndices3(); List vertices = getVertices(); - List triangles = new ArrayList<>(getTrianglesCount()); + List triangles = new ArrayList<>(getFaceCount()); - for (int i = 0; i < getTrianglesCount(); ++i) + for (int i = 0; i < getFaceCount(); ++i) { int triangleX = trianglesX[i]; int triangleY = trianglesY[i]; @@ -408,14 +408,14 @@ public abstract class RSModelMixin implements RSModel rl$vertexNormalsY = new int[verticesCount]; rl$vertexNormalsZ = new int[verticesCount]; - int[] trianglesX = getTrianglesX(); - int[] trianglesY = getTrianglesY(); - int[] trianglesZ = getTrianglesZ(); + int[] trianglesX = getFaceIndices1(); + int[] trianglesY = getFaceIndices2(); + int[] trianglesZ = getFaceIndices3(); int[] verticesX = getVerticesX(); int[] verticesY = getVerticesY(); int[] verticesZ = getVerticesZ(); - for (int i = 0; i < getTrianglesCount(); ++i) + for (int i = 0; i < getFaceCount(); ++i) { int var9 = trianglesX[i]; int var10 = trianglesY[i]; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java index 2fd8f9b6a4..661f076b0c 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java @@ -181,13 +181,13 @@ public abstract class RSPlayerMixin implements RSPlayer final int tileHeight = Perspective.getTileHeight(client, new LocalPoint(localX, localY), client.getPlane()); Perspective.modelToCanvas(client, model.getVerticesCount(), localX, localY, tileHeight, getOrientation(), model.getVerticesX(), model.getVerticesZ(), model.getVerticesY(), x2d, y2d); - ArrayList polys = new ArrayList(model.getTrianglesCount()); + ArrayList polys = new ArrayList(model.getFaceCount()); - int[] trianglesX = model.getTrianglesX(); - int[] trianglesY = model.getTrianglesY(); - int[] trianglesZ = model.getTrianglesZ(); + int[] trianglesX = model.getFaceIndices1(); + int[] trianglesY = model.getFaceIndices2(); + int[] trianglesZ = model.getFaceIndices3(); - for (int triangle = 0; triangle < model.getTrianglesCount(); ++triangle) + for (int triangle = 0; triangle < model.getFaceCount(); ++triangle) { int[] xx = { diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java index b4db85cf4e..788eeaf7f5 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java @@ -24,9 +24,9 @@ */ package net.runelite.mixins; +import net.runelite.api.Animation; import net.runelite.api.Model; import net.runelite.api.Perspective; -import net.runelite.api.Sequence; import net.runelite.api.coords.LocalPoint; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; @@ -55,7 +55,7 @@ public abstract class RuneLiteObjectMixin implements RSRuneLiteObject } @Inject - public void setAnimation(Sequence var1) + public void setAnimation(Animation var1) { setFrame(0); setFrameCycle(0); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java index b8de44e8a9..2a7721cdf3 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendLoginUpdate.java @@ -1,3 +1,13 @@ package net.runelite.rs.api; -public interface RSFriendLoginUpdate {} +import net.runelite.api.PendingLogin; +import net.runelite.mapping.Import; + +public interface RSFriendLoginUpdate extends PendingLogin +{ + @Import("username") + RSUsername getRsName(); + + @Import("world") + short getWorld(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java index 87bd7ed14e..ad77d41299 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java @@ -1,11 +1,12 @@ package net.runelite.rs.api; +import net.runelite.api.FriendContainer; import net.runelite.mapping.Import; public interface RSFriendSystem { @Import("friendsList") - RSFriendsList getFriendContainer(); + FriendContainer getFriendContainer(); @Import("ignoreList") RSIgnoreList getIgnoreContainer(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java index 68eddcc8a1..25666db7ff 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendsList.java @@ -1,6 +1,12 @@ package net.runelite.rs.api; -import net.runelite.api.Friend; -import net.runelite.api.NameableContainer; +import net.runelite.api.Deque; +import net.runelite.api.FriendContainer; +import net.runelite.api.PendingLogin; +import net.runelite.mapping.Import; -public interface RSFriendsList extends NameableContainer {} +public interface RSFriendsList extends FriendContainer +{ + @Import("friendLoginUpdates") + Deque getPendingLogins(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java b/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java index 3ff6db1a48..800b172b12 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSLink.java @@ -1,3 +1,15 @@ package net.runelite.rs.api; -public interface RSLink {} +import net.runelite.mapping.Import; + +public interface RSLink +{ + @Import("previous") + RSLink getPrevious(); + + @Import("next") + RSLink next(); + + @Import("remove") + void remove(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java b/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java index b55e7e1632..8610c54b61 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSLinkDeque.java @@ -1,3 +1,25 @@ package net.runelite.rs.api; -public interface RSLinkDeque {} +import net.runelite.api.Deque; +import net.runelite.mapping.Import; + +public interface RSLinkDeque extends Deque +{ + @Import("current") + RSLink getCurrent(); + + @Import("current") + void setCurrent(RSLink link); + + @Import("sentinel") + RSLink getSentinel(); + + @Import("last") + RSLink last(); + + @Import("previous") + RSLink previous(); + + @Import("addFirst") + void addFirst(RSLink val); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java b/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java index de2835e5f2..afeacaabe9 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSModel.java @@ -48,19 +48,19 @@ public interface RSModel extends RSRenderable, Model @Import("indicesCount") @Override - int getTrianglesCount(); + int getFaceCount(); @Import("indices1") @Override - int[] getTrianglesX(); + int[] getFaceIndices1(); @Import("indices2") @Override - int[] getTrianglesY(); + int[] getFaceIndices2(); @Import("indices3") @Override - int[] getTrianglesZ(); + int[] getFaceIndices3(); @Import("faceColors1") @Override @@ -76,7 +76,7 @@ public interface RSModel extends RSRenderable, Model @Import("faceAlphas") @Override - byte[] getTriangleTransparencies(); + byte[] getFaceTransparencies(); @Import("faceRenderPriorities") @Override @@ -184,4 +184,20 @@ public interface RSModel extends RSRenderable, Model int[] getVertexNormalsZ(); void setVertexNormalsZ(int[] vertexNormalsZ); + + @Import("overrideAmount") + @Override + byte getOverrideAmount(); + + @Import("overrideHue") + @Override + byte getOverrideHue(); + + @Import("overrideSaturation") + @Override + byte getOverrideSaturation(); + + @Import("overrideLuminance") + @Override + byte getOverrideLuminance(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java b/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java index 3be4aba4d0..68e2aa226b 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSObjectSound.java @@ -1,8 +1,9 @@ package net.runelite.rs.api; +import net.runelite.api.AmbientSoundEffect; import net.runelite.mapping.Import; -public interface RSObjectSound +public interface RSObjectSound extends AmbientSoundEffect { @Import("x") int getX(); diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java deleted file mode 100644 index 29833ca736..0000000000 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.runelite.rs.api; - -public interface RSRuneLiteIterableHashTable -{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java new file mode 100644 index 0000000000..0d63db74fe --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableLinkDeque.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableLinkDeque +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java new file mode 100644 index 0000000000..9816004c85 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeDeque.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableNodeDeque +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java new file mode 100644 index 0000000000..6337285901 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableNodeHashTable.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableNodeHashTable +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java new file mode 100644 index 0000000000..ba16a2c48d --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteMenuEntry.java @@ -0,0 +1,13 @@ +package net.runelite.rs.api; + +import java.util.function.Consumer; +import net.runelite.api.MenuEntry; + +public interface RSRuneLiteMenuEntry extends MenuEntry +{ + Consumer getConsumer(); + void setConsumer(Consumer consumer); + + int getIdx(); + void setIdx(int idx); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java b/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java index 8436ba4d11..79e4ef0ace 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSSequenceDefinition.java @@ -1,26 +1,11 @@ package net.runelite.rs.api; -import net.runelite.api.Sequence; +import net.runelite.api.Animation; import net.runelite.api.SequenceDefinition; import net.runelite.mapping.Import; -public interface RSSequenceDefinition extends RSNode, SequenceDefinition, Sequence +public interface RSSequenceDefinition extends RSNode, SequenceDefinition, Animation { -// @Import("stretches") -// boolean getStretches(); -// -// @Import("maxLoops") -// int getMaxLoops(); -// -// @Import("precedenceAnimating") --- All unused -// int getPrecedenceAnimating(); -// -// @Import("replyMode") -// int getReplyMode(); -// -// @Import("interleaveLeave") -// int[] getInterleaveLeave(); - @Import("frameCount") @Override int getFrameCount(); diff --git a/runescape-client/runescape-client.gradle.kts b/runescape-client/runescape-client.gradle.kts index fe52c6c012..5fc7078743 100644 --- a/runescape-client/runescape-client.gradle.kts +++ b/runescape-client/runescape-client.gradle.kts @@ -27,6 +27,8 @@ group = "com.openosrs.rs" description = "RuneScape Client" dependencies { + api(project(":runelite-api")) + implementation(project(":injection-annotations")) implementation(group = "org.bouncycastle", name = "bcprov-jdk15on", version = "1.52") diff --git a/runescape-client/src/main/java/ChatChannel.java b/runescape-client/src/main/java/ChatChannel.java index 4ff9e9bd1b..9bd2622d45 100644 --- a/runescape-client/src/main/java/ChatChannel.java +++ b/runescape-client/src/main/java/ChatChannel.java @@ -161,7 +161,7 @@ public class ChatChannel { Client.meslayerContinueWidget = null; } - FileSystem.method3084(); + FileSystem.decrementMenuEntries(); class115.revalidateWidgetScroll(MouseRecorder.Widget_interfaceComponents[var0 >> 16], var4, false); class33.runWidgetOnLoadListener(var1); if (Client.rootInterface != -1) { diff --git a/runescape-client/src/main/java/Client.java b/runescape-client/src/main/java/Client.java index 40e1149835..42e7d5c191 100644 --- a/runescape-client/src/main/java/Client.java +++ b/runescape-client/src/main/java/Client.java @@ -6401,7 +6401,7 @@ public final class Client extends GameEngine implements Usernamed, OAuthTokens { ) @Export("menu") final void menu() { - Message.method1115(); + Message.incrementMenuEntries(); if (class143.dragInventoryWidget == null) { if (clickedWidget == null) { int var1 = MouseHandler.MouseHandler_lastButton; diff --git a/runescape-client/src/main/java/FileSystem.java b/runescape-client/src/main/java/FileSystem.java index 8dd33ebc91..d26b04189b 100644 --- a/runescape-client/src/main/java/FileSystem.java +++ b/runescape-client/src/main/java/FileSystem.java @@ -30,7 +30,8 @@ public class FileSystem { descriptor = "(I)V", garbageValue = "497428397" ) - static void method3084() { + @Export("decrementMenuEntries") + static void decrementMenuEntries() { for (int var0 = 0; var0 < Client.menuOptionsCount; ++var0) { if (InvDefinition.method3157(Client.menuOpcodes[var0])) { if (var0 < Client.menuOptionsCount - 1) { diff --git a/runescape-client/src/main/java/Message.java b/runescape-client/src/main/java/Message.java index a6b0243341..fda1fa3c4b 100644 --- a/runescape-client/src/main/java/Message.java +++ b/runescape-client/src/main/java/Message.java @@ -166,7 +166,8 @@ public class Message extends DualNode { descriptor = "(I)V", garbageValue = "1989735073" ) - static final void method1115() { + @Export("incrementMenuEntries") + static final void incrementMenuEntries() { boolean var0 = false; while (!var0) { diff --git a/runescape-client/src/main/java/Model.java b/runescape-client/src/main/java/Model.java index 9a27115261..04d186a751 100644 --- a/runescape-client/src/main/java/Model.java +++ b/runescape-client/src/main/java/Model.java @@ -200,13 +200,17 @@ public class Model extends Renderable { @Export("zMidOffset") int zMidOffset; @ObfuscatedName("bo") - public byte field2494; + @Export("overrideHue") + public byte overrideHue; @ObfuscatedName("bf") - public byte field2495; + @Export("overrideSaturation") + public byte overrideSaturation; @ObfuscatedName("be") - public byte field2479; + @Export("overrideLuminance") + public byte overrideLuminance; @ObfuscatedName("ce") - public byte field2474; + @Export("overrideAmount") + public byte overrideAmount; static { Model_sharedSequenceModel = new Model(); @@ -574,7 +578,7 @@ public class Model extends Renderable { var2.field2449 = this.field2449; var2.isSingleTile = this.isSingleTile; var2.resetBounds(); - var2.field2474 = 0; + var2.overrideAmount = 0; return var2; } @@ -1569,10 +1573,10 @@ public class Model extends Renderable { } } else if (this.faceColors3[var1] == -1) { Rasterizer3D.method3856(modelViewportYs[var2], modelViewportYs[var3], modelViewportYs[var4], modelViewportXs[var2], modelViewportXs[var3], modelViewportXs[var4], Model_colorPalette[this.faceColors1[var1]]); - } else if (this.field2474 > 0) { - var5 = this.method4216(this.faceColors1[var1], this.field2494, this.field2495, this.field2479, this.field2474); - var6 = this.method4216(this.faceColors2[var1], this.field2494, this.field2495, this.field2479, this.field2474); - var7 = this.method4216(this.faceColors3[var1], this.field2494, this.field2495, this.field2479, this.field2474); + } else if (this.overrideAmount > 0) { + var5 = this.method4216(this.faceColors1[var1], this.overrideHue, this.overrideSaturation, this.overrideLuminance, this.overrideAmount); + var6 = this.method4216(this.faceColors2[var1], this.overrideHue, this.overrideSaturation, this.overrideLuminance, this.overrideAmount); + var7 = this.method4216(this.faceColors3[var1], this.overrideHue, this.overrideSaturation, this.overrideLuminance, this.overrideAmount); Rasterizer3D.method3854(modelViewportYs[var2], modelViewportYs[var3], modelViewportYs[var4], modelViewportXs[var2], modelViewportXs[var3], modelViewportXs[var4], var5, var6, var7); } else { Rasterizer3D.method3854(modelViewportYs[var2], modelViewportYs[var3], modelViewportYs[var4], modelViewportXs[var2], modelViewportXs[var3], modelViewportXs[var4], this.faceColors1[var1], this.faceColors2[var1], this.faceColors3[var1]); diff --git a/runescape-client/src/main/java/NPC.java b/runescape-client/src/main/java/NPC.java index 0507cf325a..54bc07a1b2 100644 --- a/runescape-client/src/main/java/NPC.java +++ b/runescape-client/src/main/java/NPC.java @@ -129,12 +129,12 @@ public final class NPC extends Actor { } if (super.field1146 != 0 && Client.cycle >= super.field1141 && Client.cycle < super.field1140) { - var3.field2494 = super.field1143; - var3.field2495 = super.field1144; - var3.field2479 = super.field1095; - var3.field2474 = super.field1146; + var3.overrideHue = super.field1143; + var3.overrideSaturation = super.field1144; + var3.overrideLuminance = super.field1095; + var3.overrideAmount = super.field1146; } else { - var3.field2474 = 0; + var3.overrideAmount = 0; } return var3; diff --git a/runescape-client/src/main/java/Player.java b/runescape-client/src/main/java/Player.java index 0866f9e41e..b0e15a332a 100644 --- a/runescape-client/src/main/java/Player.java +++ b/runescape-client/src/main/java/Player.java @@ -381,12 +381,12 @@ public final class Player extends Actor { var3.isSingleTile = true; if (super.field1146 != 0 && Client.cycle >= super.field1141 && Client.cycle < super.field1140) { - var3.field2494 = super.field1143; - var3.field2495 = super.field1144; - var3.field2479 = super.field1095; - var3.field2474 = super.field1146; + var3.overrideHue = super.field1143; + var3.overrideSaturation = super.field1144; + var3.overrideLuminance = super.field1095; + var3.overrideAmount = super.field1146; } else { - var3.field2474 = 0; + var3.overrideAmount = 0; } return var3; diff --git a/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java b/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java new file mode 100644 index 0000000000..b315836771 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteIterableLinkDeque.java @@ -0,0 +1,49 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class RuneLiteIterableLinkDeque implements Iterator +{ + public final LinkDeque linkDeque; + public Link link; + + public RuneLiteIterableLinkDeque(LinkDeque linkDeque) + { + this.linkDeque = linkDeque; + this.link = this.linkDeque.sentinel.previous; + } + + @Override + public boolean hasNext() + { + return this.link != this.linkDeque.sentinel; + } + + @Override + public FriendLoginUpdate next() + { + if (this.link == this.linkDeque.sentinel) + { + throw new NoSuchElementException(); + } + else + { + FriendLoginUpdate friendLoginUpdate = (FriendLoginUpdate) this.link; + this.link = this.link.previous; + + return friendLoginUpdate; + } + } + + public void remove() + { + Link link = this.link.next; + if (link == this.linkDeque.sentinel) + { + throw new IllegalStateException(); + } + else + { + link.remove(); + } + } +} diff --git a/runescape-client/src/main/java/RuneLiteIterableNodeDeque.java b/runescape-client/src/main/java/RuneLiteIterableNodeDeque.java new file mode 100644 index 0000000000..b6bfb495e4 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteIterableNodeDeque.java @@ -0,0 +1,49 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class RuneLiteIterableNodeDeque implements Iterator +{ + public final NodeDeque nodeDeque; + public Node node; + + public RuneLiteIterableNodeDeque(NodeDeque nodeDeque) + { + this.nodeDeque = nodeDeque; + this.node = this.nodeDeque.sentinel.previous; + } + + @Override + public boolean hasNext() + { + return this.node != this.nodeDeque.sentinel; + } + + @Override + public Node next() + { + if (this.node == this.nodeDeque.sentinel) + { + throw new NoSuchElementException(); + } + else + { + Node node = this.node; + this.node = this.node.previous; + + return node; + } + } + + public void remove() + { + Node node = this.node.next; + if (node == this.nodeDeque.sentinel) + { + throw new IllegalStateException(); + } + else + { + node.remove(); + } + } +} diff --git a/runescape-client/src/main/java/RuneLiteIterableHashTable.java b/runescape-client/src/main/java/RuneLiteIterableNodeHashTable.java similarity index 89% rename from runescape-client/src/main/java/RuneLiteIterableHashTable.java rename to runescape-client/src/main/java/RuneLiteIterableNodeHashTable.java index ca4f181efb..5fd93eaee1 100644 --- a/runescape-client/src/main/java/RuneLiteIterableHashTable.java +++ b/runescape-client/src/main/java/RuneLiteIterableNodeHashTable.java @@ -1,13 +1,13 @@ import java.util.Iterator; import java.util.NoSuchElementException; -public class RuneLiteIterableHashTable implements Iterator +public class RuneLiteIterableNodeHashTable implements Iterator { public Node node; public final NodeHashTable nodeHashTable; public int it; - public RuneLiteIterableHashTable(NodeHashTable nodeHashTable) + public RuneLiteIterableNodeHashTable(NodeHashTable nodeHashTable) { this.nodeHashTable = nodeHashTable; } diff --git a/runescape-client/src/main/java/RuneLiteMenuEntry.java b/runescape-client/src/main/java/RuneLiteMenuEntry.java new file mode 100644 index 0000000000..d47d3d9927 --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteMenuEntry.java @@ -0,0 +1,340 @@ +import java.util.function.Consumer; +import net.runelite.api.MenuAction; +import net.runelite.api.MenuEntry; + +public class RuneLiteMenuEntry implements MenuEntry +{ + public Consumer consumer; + public int idx; + + public RuneLiteMenuEntry(int idx) + { + this.idx = idx; + } + + public Consumer getConsumer() + { + return consumer; + } + + public void setConsumer(Consumer consumer) + { + this.consumer = consumer; + } + + public int getIdx() + { + return idx; + } + + public void setIdx(int idx) + { + this.idx = idx; + } + + @Override + public String getOption() + { + return Client.menuActions[this.idx]; + } + + @Override + public MenuEntry setOption(String option) + { + Client.menuActions[this.idx] = option; + return this; + } + + @Override + public String getTarget() + { + return Client.menuTargets[this.idx]; + } + + @Override + public MenuEntry setTarget(String target) + { + Client.menuTargets[this.idx] = target; + return this; + } + + @Override + public MenuAction getType() + { + int opcode = Client.menuOpcodes[this.idx]; + if (opcode >= 2000) + { + opcode -= 2000; + } + + return MenuAction.of(opcode); + } + + @Override + public MenuAction getMenuAction() + { + return this.getType(); + } + + @Override + public MenuEntry setType(MenuAction menuAction) + { + int opcode = Client.menuOpcodes[this.idx]; + short mod = 0; + if (opcode >= 2000) + { + mod = 2000; + } + + Client.menuOpcodes[this.idx] = menuAction.getId() + mod; + return this; + } + + @Override + public int getOpcode() + { + int opcode = Client.menuOpcodes[this.idx]; + if (opcode >= 2000) + { + opcode -= 2000; + } + + return opcode; + } + + @Override + public void setOpcode(int code) + { + int opcode = Client.menuOpcodes[this.idx]; + short mod = 0; + if (opcode >= 2000) + { + mod = 2000; + } + + Client.menuOpcodes[this.idx] = code + mod; + } + + @Override + public int getIdentifier() + { + return Client.menuIdentifiers[this.idx]; + } + + @Override + public MenuEntry setIdentifier(int identifier) + { + Client.menuIdentifiers[this.idx] = identifier; + return this; + } + + @Override + public int getParam0() + { + return Client.menuArguments1[this.idx]; + } + + @Override + public MenuEntry setParam0(int param0) + { + Client.menuArguments1[this.idx] = param0; + return this; + } + + @Override + public int getActionParam0() + { + return this.getParam0(); + } + + @Override + public void setActionParam0(int param0) + { + this.setParam0(param0); + } + + @Override + public int getParam1() + { + return Client.menuArguments2[this.idx]; + } + + @Override + public MenuEntry setParam1(int param1) + { + Client.menuArguments2[this.idx] = param1; + return this; + } + + @Override + public int getActionParam1() + { + return this.getParam1(); + } + + @Override + public void setActionParam1(int param1) + { + this.setParam1(param1); + } + + @Override + public boolean isDeprioritized() + { + return Client.menuOpcodes[this.idx] >= 2000; + } + + @Override + public MenuEntry setDeprioritized(boolean deprioritize) + { + int[] opcodes; + + if (deprioritize) + { + if (Client.menuOpcodes[this.idx] < 2000) + { + opcodes = Client.menuOpcodes; + opcodes[this.idx] += 2000; + } + } + else if (Client.menuOpcodes[this.idx] >= 2000) + { + opcodes = Client.menuOpcodes; + opcodes[this.idx] -= 2000; + } + + return this; + } + + @Override + public boolean isForceLeftClick() + { + return Client.menuShiftClick[this.idx]; + } + + @Override + public MenuEntry setForceLeftClick(boolean forceLeftClick) + { + Client.menuShiftClick[this.idx] = forceLeftClick; + return this; + } + + @Override + public MenuEntry onClick(Consumer consumer) + { + this.consumer = consumer; + return this; + } + + public boolean instanceOf(Object o) + { + return o instanceof RuneLiteMenuEntry; + } + + @Override + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + else if (!(o instanceof RuneLiteMenuEntry)) + { + return false; + } + else + { + RuneLiteMenuEntry menuEntry = (RuneLiteMenuEntry) o; + if (!menuEntry.instanceOf(this)) + { + return false; + } + else if (this.getIdentifier() != menuEntry.getIdentifier()) + { + return false; + } + else if (this.getParam0() != menuEntry.getParam0()) + { + return false; + } + else if (this.getParam1() != menuEntry.getParam1()) + { + return false; + } + else if (this.isForceLeftClick() != menuEntry.isForceLeftClick()) + { + return false; + } + else if (this.isDeprioritized() != menuEntry.isDeprioritized()) + { + return false; + } + else + { + String option = this.getOption(); + String menuEntryOption = menuEntry.getOption(); + if (option == null) + { + if (menuEntryOption != null) + { + return false; + } + } + else if (!option.equals(menuEntryOption)) + { + return false; + } + + String target = this.getTarget(); + String menuEntryTarget = menuEntry.getTarget(); + if (target == null) + { + if (menuEntryTarget != null) + { + return false; + } + } + else if (!target.equals(menuEntryTarget)) + { + return false; + } + + MenuAction type = this.getType(); + MenuAction menuEntryType = menuEntry.getType(); + if (type == null) + { + if (menuEntryType == null) + { + return true; + } + } + else if (type.equals(menuEntryType)) + { + return true; + } + + return false; + } + } + } + + @Override + public int hashCode() + { + byte b = 1; + + int hash = b * 59 + this.getIdentifier(); + hash = hash * 59 + this.getParam0(); + hash = hash * 59 + this.getParam1(); + hash = hash * 59 + (this.isForceLeftClick() ? 79 : 97); + hash = hash * 59 + (this.isDeprioritized() ? 79 : 97); + String option = this.getOption(); + hash = hash * 59 + (option == null ? 43 : option.hashCode()); + String target = this.getTarget(); + hash = hash * 59 + (target == null ? 43 : target.hashCode()); + MenuAction type = this.getType(); + hash = hash * 59 + (type == null ? 43 : type.hashCode()); + + return hash; + } +} diff --git a/runescape-client/src/main/java/class10.java b/runescape-client/src/main/java/class10.java index 211323be03..6ec5f93e9e 100644 --- a/runescape-client/src/main/java/class10.java +++ b/runescape-client/src/main/java/class10.java @@ -320,7 +320,7 @@ public class class10 { SecureRandomCallable.invalidateWidget(var4); } - FileSystem.method3084(); + FileSystem.decrementMenuEntries(); if (Client.rootInterface != -1) { Message.runIntfCloseListeners(Client.rootInterface, 1); }