diff --git a/Client/src/main/java/org/runite/client/AudioHandler.java b/Client/src/main/java/org/runite/client/AudioHandler.java
index fb7cf39a1..6ac7860d2 100644
--- a/Client/src/main/java/org/runite/client/AudioHandler.java
+++ b/Client/src/main/java/org/runite/client/AudioHandler.java
@@ -20,7 +20,7 @@ public final class AudioHandler {
try {
if (-1 == var1 && !musicEffectPlaying) {
GameObject.method1870();
- } else if (var1 != -1 && (currentTrack != var1 || Class79.method1391(-1)) && musicVolume != 0 && !musicEffectPlaying) {
+ } else if (var1 != -1 && (currentTrack != var1 || CSConfigCachefile.method1391(-1)) && musicVolume != 0 && !musicEffectPlaying) {
method2099(var1, CacheIndex.musicIndex, musicVolume);
}
currentTrack = var1;
@@ -117,13 +117,13 @@ public final class AudioHandler {
}
}
- if (musicEffectPlaying && Class79.method1391(-1)) {
+ if (musicEffectPlaying && CSConfigCachefile.method1391(-1)) {
if (0 != musicVolume && currentTrack != -1) {
Class70.method1285(CacheIndex.musicIndex, currentTrack, musicVolume);
}
musicEffectPlaying = false;
- } else if (musicVolume != 0 && currentTrack != -1 && Class79.method1391((byte) -92 + 91)) {
+ } else if (musicVolume != 0 && currentTrack != -1 && CSConfigCachefile.method1391((byte) -92 + 91)) {
TextureOperation12.outgoingBuffer.putOpcode(137);
TextureOperation12.outgoingBuffer.writeInt(currentTrack);
currentTrack = -1;
diff --git a/Client/src/main/java/org/runite/client/CS2Script.java b/Client/src/main/java/org/runite/client/CS2Script.java
index 7645d30d2..5544b1896 100644
--- a/Client/src/main/java/org/runite/client/CS2Script.java
+++ b/Client/src/main/java/org/runite/client/CS2Script.java
@@ -27,7 +27,6 @@ public final class CS2Script extends Linkable {
static int anInt3775 = 0;
static int anInt2440 = 0;
static ReferenceCache aReferenceCache_2442 = new ReferenceCache(50);
- static ReferenceCache aReferenceCache_2450 = new ReferenceCache(64);
static byte[][][] aByteArrayArrayArray2452;
RSInterface aClass11_2438;
RSString aClass94_2439;
@@ -58,30 +57,6 @@ public final class CS2Script extends Linkable {
}
}
- static Class79 method378(int var0, byte var1) {
- try {
- Class79 var2 = (Class79) aReferenceCache_2450.get(var0);
- if (var2 == null) {
- if (var1 < 126) {
- return null;
- } else {
- byte[] var3 = Class101.aClass153_1420.getFile(Class140_Sub7.method2032(var0), var0 & 1023);
- var2 = new Class79();
- if (var3 != null) {
- var2.method1387(new DataBuffer(var3));
- }
-
- aReferenceCache_2450.put(var2, var0);
- return var2;
- }
- } else {
- return var2;
- }
- } catch (RuntimeException var4) {
- throw ClientErrorException.clientError(var4, "jl.A(" + var0 + ',' + var1 + ')');
- }
- }
-
static void method379() {
try {
int var2 = Class146.anInt1904 * 128 - -64;
diff --git a/Client/src/main/java/org/runite/client/Class79.java b/Client/src/main/java/org/runite/client/CSConfigCachefile.java
similarity index 83%
rename from Client/src/main/java/org/runite/client/Class79.java
rename to Client/src/main/java/org/runite/client/CSConfigCachefile.java
index 043e62add..b07173151 100644
--- a/Client/src/main/java/org/runite/client/Class79.java
+++ b/Client/src/main/java/org/runite/client/CSConfigCachefile.java
@@ -1,14 +1,16 @@
package org.runite.client;
+import org.rs09.SystemLogger;
+
import java.awt.event.KeyEvent;
-final class Class79 {
+final class CSConfigCachefile {
static int anInt1124 = -1;
static int anInt1127 = 0;
- int anInt1123;
- int anInt1125;
- int anInt1128;
+ int lowerBound;
+ int upperBound;
+ int parentVarpIndex;
static void method1385(int var0, int var1) {
@@ -182,31 +184,44 @@ final class Class79 {
}
}
- final void method1387(DataBuffer var1) {
+ static CSConfigCachefile getCSConfigFileFromVarbitID(int varbitID) {
try {
- while (true) {
- int var3 = var1.readUnsignedByte();
- if (var3 == 0) {
- return;
+ CSConfigCachefile cacheFile = (CSConfigCachefile) VarpHelpers.varbitLookup.get(varbitID);
+ if (cacheFile == null) {
+ byte[] fileData = Class101.csConfigFileRAM.getFile(varbitID >>> 10, varbitID & 1023);
+ cacheFile = new CSConfigCachefile();
+ if (fileData != null) {
+ cacheFile.tryParseConfigFile(new DataBuffer(fileData));
}
- this.method1389(var1, var3);
+ VarpHelpers.varbitLookup.put(cacheFile, varbitID);
}
+ return cacheFile;
} catch (RuntimeException var4) {
- throw ClientErrorException.clientError(var4, "kk.G(" + (var1 != null ? "{...}" : "null") + ',' + -111 + ')');
+ throw ClientErrorException.clientError(var4, "jl.A(" + varbitID + ',' + (byte) 127 + ')');
}
}
- private void method1389(DataBuffer var1, int var3) {
+ final void tryParseConfigFile(DataBuffer fileData) {
try {
- if (1 == var3) {
- this.anInt1128 = var1.readUnsignedShort();
- this.anInt1123 = var1.readUnsignedByte();
- this.anInt1125 = var1.readUnsignedByte();
+ boolean end = fileData.readUnsignedByte() == 0;
+ while (!end) {
+ this.parseConfigFile(fileData);
+ end = fileData.readUnsignedByte() == 0;
}
+ } catch (RuntimeException var4) {
+ throw ClientErrorException.clientError(var4, "kk.G(" + (fileData != null ? "{...}" : "null") + ',' + -111 + ')');
+ }
+ }
+
+ private void parseConfigFile(DataBuffer fileData) {
+ try {
+ this.parentVarpIndex = fileData.readUnsignedShort();
+ this.lowerBound = fileData.readUnsignedByte();
+ this.upperBound = fileData.readUnsignedByte();
} catch (RuntimeException var5) {
- throw ClientErrorException.clientError(var5, "kk.B(" + (var1 != null ? "{...}" : "null") + ',' + 1 + ',' + var3 + ')');
+ throw ClientErrorException.clientError(var5, "kk.B(" + (fileData != null ? "{...}" : "null") + ',' + 1 + ')');
}
}
diff --git a/Client/src/main/java/org/runite/client/Class101.java b/Client/src/main/java/org/runite/client/Class101.java
index 4b1c1272c..bb1cad4d8 100644
--- a/Client/src/main/java/org/runite/client/Class101.java
+++ b/Client/src/main/java/org/runite/client/Class101.java
@@ -2,7 +2,7 @@ package org.runite.client;
final class Class101 {
- static CacheIndex aClass153_1420;
+ static CacheIndex csConfigFileRAM;
static Class3_Sub24_Sub4 aClass3_Sub24_Sub4_1421;
static Class30 aClass30_1422;
static CacheIndex aClass153_1423;
@@ -65,7 +65,7 @@ final class Class101 {
method1607(46, 78, true, null, null);
}
- aClass153_1420 = null;
+ csConfigFileRAM = null;
} catch (RuntimeException var2) {
throw ClientErrorException.clientError(var2, "nj.A(" + var0 + ')');
}
diff --git a/Client/src/main/java/org/runite/client/Class107.java b/Client/src/main/java/org/runite/client/Class107.java
index 9723ccd87..8ca5995aa 100644
--- a/Client/src/main/java/org/runite/client/Class107.java
+++ b/Client/src/main/java/org/runite/client/Class107.java
@@ -34,7 +34,7 @@ final class Class107 {
static void method1648(CacheIndex var0) {
try {
- Class101.aClass153_1420 = var0;
+ Class101.csConfigFileRAM = var0;
} catch (RuntimeException var3) {
throw ClientErrorException.clientError(var3, "og.B(" + (var0 != null ? "{...}" : "null") + ',' + 255 + ')');
diff --git a/Client/src/main/java/org/runite/client/Class108.java b/Client/src/main/java/org/runite/client/Class108.java
index 58dc2a50f..639db0458 100644
--- a/Client/src/main/java/org/runite/client/Class108.java
+++ b/Client/src/main/java/org/runite/client/Class108.java
@@ -51,7 +51,7 @@ final class Class108 {
int var2 = Class140_Sub7.canvasHeight;
int var3 = var2 * 956 / 503;
Objects.requireNonNull(Class40.aAbstractSprite_680).method639((Class23.canvasWidth + -var3) / 2, 0, var3, var2);
- SequenceDefinition.aClass109_1856 = InterfaceWidget.a(Class79.anInt1124, var0);
+ SequenceDefinition.aClass109_1856 = InterfaceWidget.a(CSConfigCachefile.anInt1124, var0);
Objects.requireNonNull(SequenceDefinition.aClass109_1856).method1667(Class23.canvasWidth / 2 + -(SequenceDefinition.aClass109_1856.width / 2), 18);
Class140_Sub2.aBoolean2713 = true;
if (var1 > -50) {
diff --git a/Client/src/main/java/org/runite/client/Class140_Sub7.java b/Client/src/main/java/org/runite/client/Class140_Sub7.java
index 8dd7f8e2c..2e05ab0a2 100644
--- a/Client/src/main/java/org/runite/client/Class140_Sub7.java
+++ b/Client/src/main/java/org/runite/client/Class140_Sub7.java
@@ -32,7 +32,7 @@ public final class Class140_Sub7 extends GameObject {
static boolean method2031(byte var0, boolean var1, int var2, int var3, Class3_Sub2[][][] var4, int var5) {
try {
- byte var6 = !var1?(byte)(255 & Class79.anInt1127):1;
+ byte var6 = !var1?(byte)(255 & CSConfigCachefile.anInt1127):1;
if(Class158.aByteArrayArrayArray2008[WorldListCountry.localPlane][var2][var3] == var6) {
return false;
} else if((Unsorted.aByteArrayArrayArray113[WorldListCountry.localPlane][var2][var3] & 4) == 0) {
diff --git a/Client/src/main/java/org/runite/client/Class163.java b/Client/src/main/java/org/runite/client/Class163.java
index d3774b46f..3d9a32fe3 100644
--- a/Client/src/main/java/org/runite/client/Class163.java
+++ b/Client/src/main/java/org/runite/client/Class163.java
@@ -1,5 +1,6 @@
package org.runite.client;
+import org.rs09.SystemLogger;
import org.rs09.client.data.NodeCache;
import java.util.Objects;
@@ -11,26 +12,4 @@ public class Class163 {
public static int localNPCCount = 0;
- static void method2209(byte var0, int var1, int var2) {
- try {
- if (var0 >= -99) {
- method2209((byte) 57, -14, 120);
- }
-
- Class79 var3 = CS2Script.method378(var2, (byte) 127);
- int var4 = Objects.requireNonNull(var3).anInt1128;
- int var6 = var3.anInt1125;
- int var5 = var3.anInt1123;
- int var7 = Class3_Sub6.anIntArray2288[var6 - var5];
- if (var1 < 0 || var7 < var1) {
- var1 = 0;
- }
-
- var7 <<= var5;
- TextureOperation39.method281(var1 << var5 & var7 | ~var7 & Class57.varpArray[var4], var4);
- } catch (RuntimeException var8) {
- throw ClientErrorException.clientError(var8, "wd.K(" + var0 + ',' + var1 + ',' + var2 + ')');
- }
- }
-
}
diff --git a/Client/src/main/java/org/runite/client/Class25.java b/Client/src/main/java/org/runite/client/Class25.java
index dacd09986..ed231bd4f 100644
--- a/Client/src/main/java/org/runite/client/Class25.java
+++ b/Client/src/main/java/org/runite/client/Class25.java
@@ -115,7 +115,7 @@ final class Class25 {
static void method959() {
try {
- CS2Script.aReferenceCache_2450.clear();
+ VarpHelpers.varbitLookup.clear();
} catch (RuntimeException var2) {
throw ClientErrorException.clientError(var2, "ec.B(" + 0 + ')');
diff --git a/Client/src/main/java/org/runite/client/Class3_Sub28_Sub20.java b/Client/src/main/java/org/runite/client/Class3_Sub28_Sub20.java
index 89fa25610..05de01b0b 100644
--- a/Client/src/main/java/org/runite/client/Class3_Sub28_Sub20.java
+++ b/Client/src/main/java/org/runite/client/Class3_Sub28_Sub20.java
@@ -289,8 +289,8 @@ final class Class3_Sub28_Sub20 extends Node {
static void method725() {
try {
if(Class137.method1817() == 2) {
- byte var2 = (byte)(255 & Class79.anInt1127 + -4);
- int var3 = Class79.anInt1127 % 104;
+ byte var2 = (byte)(255 & CSConfigCachefile.anInt1127 + -4);
+ int var3 = CSConfigCachefile.anInt1127 % 104;
int var4;
int var5;
diff --git a/Client/src/main/java/org/runite/client/Class3_Sub6.java b/Client/src/main/java/org/runite/client/Class3_Sub6.java
index d03ccd93d..da647c14f 100644
--- a/Client/src/main/java/org/runite/client/Class3_Sub6.java
+++ b/Client/src/main/java/org/runite/client/Class3_Sub6.java
@@ -6,15 +6,15 @@ final class Class3_Sub6 extends Linkable {
static byte[][] softReferenceTestArray;
- static int[] anIntArray2288 = new int[32];
+ static int[] expectedMinimumValues = new int[32];
static int anInt2291;
static {
- int var0 = 2;
+ int accumulator = 2;
- for (int var1 = 0; var1 < 32; ++var1) {
- anIntArray2288[var1] = -1 + var0;
- var0 += var0;
+ for (int i = 0; i < 32; ++i) {
+ expectedMinimumValues[i] = -1 + accumulator;
+ accumulator += accumulator;
}
anInt2291 = 1;
diff --git a/Client/src/main/java/org/runite/client/Class75_Sub3.java b/Client/src/main/java/org/runite/client/Class75_Sub3.java
index a9ed520cd..a0164ca0b 100644
--- a/Client/src/main/java/org/runite/client/Class75_Sub3.java
+++ b/Client/src/main/java/org/runite/client/Class75_Sub3.java
@@ -46,7 +46,7 @@ final class Class75_Sub3 extends Class75 {
Class67.aReferenceCache_1013.sweep(5);
Texture.aReferenceCache_1146.sweep(5);
Class159.aReferenceCache_2016.sweep(5);
- CS2Script.aReferenceCache_2450.sweep(5);
+ VarpHelpers.varbitLookup.sweep(5);
Class136.aReferenceCache_1772.sweep(5);
RenderAnimationDefinition.aReferenceCache_1955.sweep(5);
TextureOperation25.aReferenceCache_3412.sweep(5);
diff --git a/Client/src/main/java/org/runite/client/Class97.java b/Client/src/main/java/org/runite/client/Class97.java
index cfcb1f1cd..6469e23f3 100644
--- a/Client/src/main/java/org/runite/client/Class97.java
+++ b/Client/src/main/java/org/runite/client/Class97.java
@@ -67,7 +67,7 @@ public final class Class97 {
static void method1593(int var0, CacheIndex var1) {
try {
Class154.anInt1966 = var1.getArchiveForName(TextCore.aClass94_3574);
- Class79.anInt1124 = var1.getArchiveForName(TextCore.aClass94_1341);
+ CSConfigCachefile.anInt1124 = var1.getArchiveForName(TextCore.aClass94_1341);
if (var0 <= 108) {
method1593(14, null);
}
diff --git a/Client/src/main/java/org/runite/client/Client.java b/Client/src/main/java/org/runite/client/Client.java
index 3630de869..477138b8e 100644
--- a/Client/src/main/java/org/runite/client/Client.java
+++ b/Client/src/main/java/org/runite/client/Client.java
@@ -1349,8 +1349,8 @@ public final class Client extends GameShell {
} else {
try {
if (PacketParser.anInt80 == 0) {
- System.out.println("Trying " + GameConfig.Companion.getJS5_SERVER_PORT());
- Class17.aClass64_413 = Class38.gameSignlink.method1441((byte) 8, Class38_Sub1.accRegistryIp, GameConfig.Companion.getJS5_SERVER_PORT());
+ System.out.println("Trying " + GameConfig.JS5_SERVER_PORT);
+ Class17.aClass64_413 = Class38.gameSignlink.method1441((byte) 8, Class38_Sub1.accRegistryIp, GameConfig.JS5_SERVER_PORT);
++PacketParser.anInt80;
}
@@ -1358,7 +1358,7 @@ public final class Client extends GameShell {
/* If the connection is null we reset the JS5 port to the backup server JS5 for compatibility reasons */
if (2 == Objects.requireNonNull(Class17.aClass64_413).anInt978) {
- GameConfig.Companion.setJS5_SERVER_PORT(GameConfig.SERVER_PORT + ObjectDefinition.paramWorldID);
+ GameConfig.JS5_SERVER_PORT = GameConfig.SERVER_PORT + ObjectDefinition.paramWorldID;
this.method46(1000);
return;
}
diff --git a/Client/src/main/java/org/runite/client/ClientCommands.java b/Client/src/main/java/org/runite/client/ClientCommands.java
index ede2c12af..61ef6273c 100644
--- a/Client/src/main/java/org/runite/client/ClientCommands.java
+++ b/Client/src/main/java/org/runite/client/ClientCommands.java
@@ -1,7 +1,11 @@
package org.runite.client;
+import org.rs09.SystemLogger;
+
import java.awt.*;
+import java.io.File;
+import java.io.FileWriter;
import java.net.URI;
public class ClientCommands {
@@ -192,6 +196,29 @@ public class ClientCommands {
if (command.equalsStringIgnoreCase(TextCore.COMMAND_SHIFT_DROP_CLICK)) {
shiftClickEnabled = !shiftClickEnabled;
}
+
+ if (command.startsWith(TextCore.COMMAND_GETBITS)) {
+ System.out.println("Trying to write file...");
+ try {
+ int index = command.substring(10).parseInt();
+ File file = new File("FILE_BITS.txt");
+ FileWriter writer = new FileWriter(file);
+ for(int i = 0; i < 200000; i++){
+ CSConfigCachefile cachefile = CSConfigCachefile.getCSConfigFileFromVarbitID(i);
+ if(cachefile.parentVarpIndex == index){
+ writer.write("ID: " + i + " lowerBound = " + cachefile.lowerBound + " upperBound = " + cachefile.upperBound + " size = " + ((cachefile.upperBound - cachefile.lowerBound) + 1));
+ writer.write("\n");
+ }
+ }
+ writer.flush();
+ writer.close();
+ BufferedDataStream.addChatMessage(null, 0, RSString.parse("Wrote bits to " + file.getAbsolutePath()), -1);
+ } catch (Exception e){
+ SystemLogger.logInfo("Whoopsie");
+ e.printStackTrace();
+ }
+ }
+
TextureOperation12.outgoingBuffer.putOpcode(44);
TextureOperation12.outgoingBuffer.writeByte(command.length() + -1);
TextureOperation12.outgoingBuffer.writeString(command.substring(2));
@@ -220,7 +247,7 @@ public class ClientCommands {
Class159.aReferenceCache_2016.clearSoftReferences();//Originally Class133.method1803();
Class3_Sub31.aReferenceCache_2604.clearSoftReferences();//Class38.method1025();
Class27.aReferenceCache_511.clearSoftReferences();//Class38.method1025();
- CS2Script.aReferenceCache_2450.clearSoftReferences();//Class40.method1044();
+ VarpHelpers.varbitLookup.clearSoftReferences();//Class40.method1044();
Class136.aReferenceCache_1772.clearSoftReferences();
RenderAnimationDefinition.aReferenceCache_1955.clearSoftReferences();//Originally: Class158_Sub1.method2192();
TextureOperation25.aReferenceCache_3412.clearSoftReferences();//Originally: Class159.method2196();
diff --git a/Client/src/main/java/org/runite/client/KeyboardListener.java b/Client/src/main/java/org/runite/client/KeyboardListener.java
index afa10ca95..7d63daad9 100644
--- a/Client/src/main/java/org/runite/client/KeyboardListener.java
+++ b/Client/src/main/java/org/runite/client/KeyboardListener.java
@@ -188,7 +188,7 @@ final class KeyboardListener implements KeyListener, FocusListener {
try {
if(TextureOperation33.aClass148_3049 != null) {
- int var2 = Class79.method1386(var1);
+ int var2 = CSConfigCachefile.method1386(var1);
if(var2 >= 0) {
int var3 = 1 + Class25.anInt491 & 127;
if(var3 != Class3_Sub28_Sub9.anInt3620) {
diff --git a/Client/src/main/java/org/runite/client/NPCDefinition.java b/Client/src/main/java/org/runite/client/NPCDefinition.java
index 8e04e2b09..7f043ada4 100644
--- a/Client/src/main/java/org/runite/client/NPCDefinition.java
+++ b/Client/src/main/java/org/runite/client/NPCDefinition.java
@@ -902,11 +902,11 @@ public final class NPCDefinition {
static int method1484(int var1) {
try {
- Class79 var2 = CS2Script.method378(var1, (byte)127);
- int var3 = Objects.requireNonNull(var2).anInt1128;
- int var5 = var2.anInt1125;
- int var4 = var2.anInt1123;
- int var6 = Class3_Sub6.anIntArray2288[var5 + -var4];
+ CSConfigCachefile var2 = CSConfigCachefile.getCSConfigFileFromVarbitID(var1);
+ int var3 = Objects.requireNonNull(var2).parentVarpIndex;
+ int var5 = var2.upperBound;
+ int var4 = var2.lowerBound;
+ int var6 = Class3_Sub6.expectedMinimumValues[var5 + -var4];
return ItemDefinition.ram[var3] >> var4 & var6;
} catch (RuntimeException var7) {
throw ClientErrorException.clientError(var7, "me.B(" + 64835055 + ',' + var1 + ')');
diff --git a/Client/src/main/java/org/runite/client/PacketParser.java b/Client/src/main/java/org/runite/client/PacketParser.java
index 5c1ae1418..4b929db00 100644
--- a/Client/src/main/java/org/runite/client/PacketParser.java
+++ b/Client/src/main/java/org/runite/client/PacketParser.java
@@ -77,7 +77,7 @@ public final class PacketParser {
if (60 == Unsorted.incomingOpcode) {
nodeModelId = BufferedDataStream.incomingBuffer.readUnsignedShort128();
byte var69 = BufferedDataStream.incomingBuffer.readSignedNegativeByte();
- TextureOperation39.method281(var69, nodeModelId);
+ VarpHelpers.setVarp(var69, nodeModelId);
Unsorted.incomingOpcode = -1;
return true;
} else {
@@ -442,7 +442,7 @@ public final class PacketParser {
} else if (Unsorted.incomingOpcode == 226) {
nodeModelId = BufferedDataStream.incomingBuffer.readInt();
var19 = BufferedDataStream.incomingBuffer.readUnsignedShort128();
- TextureOperation39.method281(nodeModelId, var19);
+ VarpHelpers.setVarp(nodeModelId, var19);
Unsorted.incomingOpcode = -1;
return true;
} else if (Unsorted.incomingOpcode == 21) {
@@ -1027,7 +1027,7 @@ public final class PacketParser {
var19 = BufferedDataStream.incomingBuffer.readUnsignedShort128();
modelId = BufferedDataStream.incomingBuffer.readUnsignedShortLE128();
Class146.updateInterfacePacketCounter(var19);
- Class79.method1385(modelId, nodeModelId);
+ CSConfigCachefile.method1385(modelId, nodeModelId);
Unsorted.incomingOpcode = -1;
return true;
@@ -1123,7 +1123,7 @@ public final class PacketParser {
} else if (37 == Unsorted.incomingOpcode) {
nodeModelId = BufferedDataStream.incomingBuffer.readUnsignedByte128();
var19 = BufferedDataStream.incomingBuffer.readUnsignedShortLE();
- Class163.method2209((byte) -122, nodeModelId, var19);
+ VarpHelpers.setVarbit((byte) -122, nodeModelId, var19);
Unsorted.incomingOpcode = -1;
return true;
} else if (Unsorted.incomingOpcode == 155) {
@@ -1400,7 +1400,7 @@ public final class PacketParser {
} else if (Unsorted.incomingOpcode == 84) {
nodeModelId = BufferedDataStream.incomingBuffer.readIntLE();
var19 = BufferedDataStream.incomingBuffer.readUnsignedShortLE128();
- Class163.method2209((byte) -106, nodeModelId, var19);
+ VarpHelpers.setVarbit((byte) -106, nodeModelId, var19);
Unsorted.incomingOpcode = -1;
return true;
} else {
diff --git a/Client/src/main/java/org/runite/client/TextCore.java b/Client/src/main/java/org/runite/client/TextCore.java
index 338c84eb9..622de97cf 100644
--- a/Client/src/main/java/org/runite/client/TextCore.java
+++ b/Client/src/main/java/org/runite/client/TextCore.java
@@ -196,6 +196,7 @@ public class TextCore {
*/
static RSString COMMAND_HIGHRES_GRAPHICS_RESIZE = RSString.parse("::wm2");
static RSString COMMAND_SHIFT_DROP_CLICK = RSString.parse("::shiftclick");
+ static RSString COMMAND_GETBITS = RSString.parse("::getbits");
static RSString COMMAND_REPLACE_CANVAS = RSString.parse("::replacecanvas");
static RSString COMMAND_HIGHRES_GRAPHICS_WINDOW = RSString.parse("::wm1");
static RSString COMMAND_QA_OP_TEST = RSString.parse("::qa_op_test");
diff --git a/Client/src/main/java/org/runite/client/Texture.java b/Client/src/main/java/org/runite/client/Texture.java
index b73291c51..e3c8c3674 100644
--- a/Client/src/main/java/org/runite/client/Texture.java
+++ b/Client/src/main/java/org/runite/client/Texture.java
@@ -346,15 +346,15 @@ public final class Texture {
}
if (6 == anIntArray3331[var7]) {
- var32 = 10 <= Class79.anInt1127 % 20 ? 16776960 : 16711680;
+ var32 = 10 <= CSConfigCachefile.anInt1127 % 20 ? 16776960 : 16711680;
}
if (anIntArray3331[var7] == 7) {
- var32 = Class79.anInt1127 % 20 < 10 ? 255 : 65535;
+ var32 = CSConfigCachefile.anInt1127 % 20 < 10 ? 255 : 65535;
}
if (8 == anIntArray3331[var7]) {
- var32 = Class79.anInt1127 % 20 >= 10 ? 8454016 : '\ub000';
+ var32 = CSConfigCachefile.anInt1127 % 20 >= 10 ? 8454016 : '\ub000';
}
if (9 == anIntArray3331[var7]) {
@@ -405,15 +405,15 @@ public final class Texture {
}
if (1 == anIntArray3336[var7]) {
- FontType.bold.method696(var33, var2 - -Class32.anInt590, anInt2208 + var0, var32, Class79.anInt1127);
+ FontType.bold.method696(var33, var2 - -Class32.anInt590, anInt2208 + var0, var32, CSConfigCachefile.anInt1127);
}
if (anIntArray3336[var7] == 2) {
- FontType.bold.method695(var33, var2 - -Class32.anInt590, var0 - -anInt2208, var32, Class79.anInt1127);
+ FontType.bold.method695(var33, var2 - -Class32.anInt590, var0 - -anInt2208, var32, CSConfigCachefile.anInt1127);
}
if (anIntArray3336[var7] == 3) {
- FontType.bold.method692(var33, var2 + Class32.anInt590, anInt2208 + var0, var32, Class79.anInt1127, 150 - anIntArray3318[var7]);
+ FontType.bold.method692(var33, var2 + Class32.anInt590, anInt2208 + var0, var32, CSConfigCachefile.anInt1127, 150 - anIntArray3318[var7]);
}
if (4 == anIntArray3336[var7]) {
diff --git a/Client/src/main/java/org/runite/client/TextureOperation3.java b/Client/src/main/java/org/runite/client/TextureOperation3.java
index 292db387b..ecf12d88d 100644
--- a/Client/src/main/java/org/runite/client/TextureOperation3.java
+++ b/Client/src/main/java/org/runite/client/TextureOperation3.java
@@ -1,5 +1,6 @@
package org.runite.client;
+import org.rs09.SystemLogger;
import org.rs09.client.util.ArrayUtils;
import org.rs09.client.filestore.resources.configs.cursors.CursorDefinition;
@@ -114,12 +115,13 @@ final class TextureOperation3 extends TextureOperation {
static void method306(int var0, int var2) {
try {
- Class79 var3 = CS2Script.method378(var0, (byte)127);
- int var6 = Objects.requireNonNull(var3).anInt1125;
- int var5 = var3.anInt1123;
- int var4 = var3.anInt1128;
- int var7 = Class3_Sub6.anIntArray2288[var6 - var5];
+ CSConfigCachefile var3 = CSConfigCachefile.getCSConfigFileFromVarbitID(var0);
+ int var6 = Objects.requireNonNull(var3).upperBound;
+ int var5 = var3.lowerBound;
+ int var4 = var3.parentVarpIndex;
+ int var7 = Class3_Sub6.expectedMinimumValues[var6 - var5];
if(var2 < 0 || var7 < var2) {
+ SystemLogger.logInfo(var7 + " < " + var2);
var2 = 0;
}
diff --git a/Client/src/main/java/org/runite/client/TextureOperation39.java b/Client/src/main/java/org/runite/client/TextureOperation39.java
index 0998afd5f..1eedc6e60 100644
--- a/Client/src/main/java/org/runite/client/TextureOperation39.java
+++ b/Client/src/main/java/org/runite/client/TextureOperation39.java
@@ -166,25 +166,6 @@ class TextureOperation39 extends TextureOperation {
}
}
- static void method281(int var1, int var2) {
- try {
- Class57.varpArray[var2] = var1;
- if(CustomVars.parse(var2,var1)){
- return;
- }
- Class3_Sub7 var3 = (Class3_Sub7) AtmosphereParser.aHashTable_3679.get(var2);
- if(null == var3) {
- var3 = new Class3_Sub7(4611686018427387905L);
- AtmosphereParser.aHashTable_3679.put(var2, var3);
- } else if (var3.aLong2295 != 4611686018427387905L) {
- var3.aLong2295 = TimeUtils.time() + 500L | 4611686018427387904L;
- }
-
- } catch (RuntimeException var4) {
- throw ClientErrorException.clientError(var4, "nh.W(" + (byte) 99 + ',' + var1 + ',' + var2 + ')');
- }
- }
-
final void method161(byte var1) {
try {
super.method161(var1);
diff --git a/Client/src/main/java/org/runite/client/Unsorted.java b/Client/src/main/java/org/runite/client/Unsorted.java
index 81f90befc..747b5fbb2 100644
--- a/Client/src/main/java/org/runite/client/Unsorted.java
+++ b/Client/src/main/java/org/runite/client/Unsorted.java
@@ -12,8 +12,6 @@ import org.rs09.client.util.ArrayUtils;
import org.runite.client.drawcalls.*;
import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@@ -1964,7 +1962,7 @@ public class Unsorted {
Class136.method1816(512, -7);
TextureOperation19.method257();
} else {
- Class3_Sub5.method112((byte) (-4 + Class79.anInt1127 & 0xFF));
+ Class3_Sub5.method112((byte) (-4 + CSConfigCachefile.anInt1127 & 0xFF));
Class136.method1816(2, -7);
}
@@ -2646,7 +2644,7 @@ public class Unsorted {
++var2;
}
- if (var1.retrieveSpriteFile(Class79.anInt1124)) {
+ if (var1.retrieveSpriteFile(CSConfigCachefile.anInt1124)) {
++var2;
}
@@ -4720,7 +4718,7 @@ public class Unsorted {
}
}
- Class79.method1390(new DataBuffer(var4));
+ CSConfigCachefile.method1390(new DataBuffer(var4));
}
} catch (Exception var8) {
}
@@ -4913,7 +4911,7 @@ public class Unsorted {
static void method338(int var1, boolean var2, int var3, int var4, int var5) {
try {
- ++Class79.anInt1127;
+ ++CSConfigCachefile.anInt1127;
Class124.method1745();
if(!var2) {
Class3_Sub5.method116(true);
@@ -5022,7 +5020,7 @@ public class Unsorted {
}
Class58.method1194();
- byte var19 = Class137.method1817() != 2 ?1:(byte)Class79.anInt1127;
+ byte var19 = Class137.method1817() != 2 ?1:(byte) CSConfigCachefile.anInt1127;
if(HDToolKit.highDetail) {
HDToolKit.method1846();
HDToolKit.method1831(true);
diff --git a/Client/src/main/java/org/runite/client/VarpHelpers.java b/Client/src/main/java/org/runite/client/VarpHelpers.java
new file mode 100644
index 000000000..6fdfa25e1
--- /dev/null
+++ b/Client/src/main/java/org/runite/client/VarpHelpers.java
@@ -0,0 +1,58 @@
+package org.runite.client;
+
+import org.rs09.CustomVars;
+import org.rs09.SystemLogger;
+import org.rs09.client.data.ReferenceCache;
+
+import java.util.Objects;
+
+public class VarpHelpers {
+
+ static ReferenceCache varbitLookup = new ReferenceCache(64);
+
+ static void setVarbit(byte var0, int valueToSet, int varbitID) {
+ try {
+ if (var0 >= -99) {
+ setVarbit((byte) 57, -14, 120);
+ }
+
+ CSConfigCachefile cacheFile = CSConfigCachefile.getCSConfigFileFromVarbitID(varbitID);
+ int parentVarp = Objects.requireNonNull(cacheFile).parentVarpIndex;
+ int upperBound = cacheFile.upperBound;
+ int lowerBound = cacheFile.lowerBound;
+ int varbitSize = upperBound - lowerBound;
+ SystemLogger.logInfo(parentVarp + " - bitStart: " + lowerBound + " bitEnd: " + upperBound + " bitSize = " + (varbitSize + 1));
+ int expectedMinimumValue = Class3_Sub6.expectedMinimumValues[varbitSize];
+ SystemLogger.logInfo("emv: " + expectedMinimumValue + " || vs: " + (127 + valueToSet));
+ if (valueToSet < 0|| expectedMinimumValue < valueToSet) {
+ SystemLogger.logInfo(expectedMinimumValue + " < " + valueToSet);
+ valueToSet = 0;
+ }
+
+ expectedMinimumValue <<= lowerBound;
+ int modifiedVarpValue = valueToSet << lowerBound & expectedMinimumValue | ~expectedMinimumValue & Class57.varpArray[parentVarp];
+ setVarp(modifiedVarpValue, parentVarp);
+ } catch (RuntimeException var8) {
+ throw ClientErrorException.clientError(var8, "wd.K(" + var0 + ',' + valueToSet + ',' + varbitID + ')');
+ }
+ }
+
+ static void setVarp(int valueToSet, int varpIndex) {
+ try {
+ Class57.varpArray[varpIndex] = valueToSet;
+ if(CustomVars.parse(varpIndex,valueToSet)){
+ return;
+ }
+ Class3_Sub7 var3 = (Class3_Sub7) AtmosphereParser.aHashTable_3679.get(varpIndex);
+ if(null == var3) {
+ var3 = new Class3_Sub7(4611686018427387905L);
+ AtmosphereParser.aHashTable_3679.put(varpIndex, var3);
+ } else if (var3.aLong2295 != 4611686018427387905L) {
+ var3.aLong2295 = TimeUtils.time() + 500L | 4611686018427387904L;
+ }
+
+ } catch (RuntimeException var4) {
+ throw ClientErrorException.clientError(var4, "nh.W(" + (byte) 99 + ',' + valueToSet + ',' + varpIndex + ')');
+ }
+ }
+}
diff --git a/Client/src/main/java/org/runite/client/drawcalls/ContextMenu.java b/Client/src/main/java/org/runite/client/drawcalls/ContextMenu.java
index cb99d8a62..64ef0deb0 100644
--- a/Client/src/main/java/org/runite/client/drawcalls/ContextMenu.java
+++ b/Client/src/main/java/org/runite/client/drawcalls/ContextMenu.java
@@ -12,13 +12,13 @@ public final class ContextMenu {
int width = Class21.anInt3552;
int height = Class21.anInt3537;
int contextMenuColor = 6116423; //Context Menu RGB || 6116423 Classic || Old var5 || ColorCore.getHexColors()
- Toolkit.getActiveToolkit().fillRect(1 + x, y + 18, width + -2, -19 + height, GameConfig.RCM_BG_COLOR, GameConfig.RCM_BG_OPACITY);
+ Toolkit.getActiveToolkit().fillRect(1 + x, y + 18, width + -2, -19 + height, GameConfig.RCM_BG_COLOR, GameConfig.getRCM_BG_OPACITY());
if (GameConfig.RS3_CONTEXT_STYLE) {
- Toolkit.getActiveToolkit().fillRect(1 + x, 2 + y, width + -2, 16, GameConfig.RCM_TITLE_COLOR, GameConfig.RCM_TITLE_OPACITY);
- Toolkit.getActiveToolkit().drawRect(1 + x, 1 + y, width + -2, height, GameConfig.RCM_BORDER_COLOR, GameConfig.RCM_BORDER_OPACITY);
+ Toolkit.getActiveToolkit().fillRect(1 + x, 2 + y, width + -2, 16, GameConfig.RCM_TITLE_COLOR, GameConfig.getRCM_TITLE_OPACITY());
+ Toolkit.getActiveToolkit().drawRect(1 + x, 1 + y, width + -2, height, GameConfig.RCM_BORDER_COLOR, GameConfig.getRCM_BORDER_OPACITY());
} else {
- Toolkit.getActiveToolkit().fillRect(1 + x, 2 + y, width + -2, 16, GameConfig.RCM_TITLE_COLOR, GameConfig.RCM_TITLE_OPACITY);
- Toolkit.getActiveToolkit().drawRect(1 + x, y + 18, width + -2, -19 + height, GameConfig.RCM_BORDER_COLOR, GameConfig.RCM_BORDER_OPACITY);
+ Toolkit.getActiveToolkit().fillRect(1 + x, 2 + y, width + -2, 16, GameConfig.RCM_TITLE_COLOR, GameConfig.getRCM_TITLE_OPACITY());
+ Toolkit.getActiveToolkit().drawRect(1 + x, y + 18, width + -2, -19 + height, GameConfig.RCM_BORDER_COLOR, GameConfig.getRCM_BORDER_OPACITY());
}
FontType.bold.method681(RSString.parse(GameConfig.RCM_TITLE), x - -3, y + 14, contextMenuColor, -1);
diff --git a/Client/src/main/kotlin/org/rs09/client/config/GameConfig.kt b/Client/src/main/kotlin/org/rs09/client/config/GameConfig.kt
index 971a87e32..3979edb6e 100644
--- a/Client/src/main/kotlin/org/rs09/client/config/GameConfig.kt
+++ b/Client/src/main/kotlin/org/rs09/client/config/GameConfig.kt
@@ -11,384 +11,382 @@ import java.util.*
* Handles the client's config loading
* @author Ceikry
*/
-class GameConfig {
- companion object {
+object GameConfig {
+ /**
+ * Debug Booleans
+ */
+ @JvmField
+ var ITEM_DEBUG_ENABLED = false
- /**
- * Debug Booleans
- */
- @JvmField
- var ITEM_DEBUG_ENABLED = false
+ @JvmField
+ var OBJECT_DEBUG_ENABLED = false
- @JvmField
- var OBJECT_DEBUG_ENABLED = false
+ @JvmField
+ var NPC_DEBUG_ENABLED = false
- @JvmField
- var NPC_DEBUG_ENABLED = false
+ @JvmField
+ var HD_LOGIN_DEBUG = false
- @JvmField
- var HD_LOGIN_DEBUG = false
+ @JvmField
+ var HD_LOGIN_VERBOSE = false
- @JvmField
- var HD_LOGIN_VERBOSE = false
+ @JvmField
+ var CACHE_DEBUG = false
- @JvmField
- var CACHE_DEBUG = false
+ @JvmField
+ var WORLD_MAP_DEBUG = false
- @JvmField
- var WORLD_MAP_DEBUG = false
+ /**
+ * Context Menu Presets
+ */
+ @JvmField
+ var RCM_STYLE_PRESET = "classic"
- /**
- * Context Menu Presets
- */
- @JvmField
- var RCM_STYLE_PRESET = "classic"
+ /**
+ * Context Menu Customization
+ */
+ @JvmField
+ var RCM_BG_COLOR = 6116423
- /**
- * Context Menu Customization
- */
- @JvmField
- var RCM_BG_COLOR = 6116423
-
- @JvmStatic
- var RCM_BG_OPACITY = 255
- set(value) {
- if(value > 255 || value < 0) field = 255
- else field = value
- }
-
- @JvmField
- var RCM_TITLE_COLOR = 0
-
- @JvmStatic
- var RCM_TITLE_OPACITY = 255
- set(value) {
- if(value > 255 || value < 0) field = 255
- else field = value
- }
-
- @JvmField
- var RCM_BORDER_COLOR = 0
-
- @JvmStatic
- var RCM_BORDER_OPACITY = 255
- set(value) {
- if(value > 255 || value < 0) field = 255
- else field = value
- }
-
- @JvmField
- var RCM_TITLE = "
Choose Option"
-
- @JvmField
- var RS3_CONTEXT_STYLE = false
-
- /**
- * Render distance
- */
- @JvmField
- var RENDER_DISTANCE_INCREASE = false
-
- @JvmField
- var RENDER_DISTANCE_VALUE = 3584f
-
- @JvmField
- var RENDER_DISTANCE_TILE_VALUE = 28
-
- @JvmField
- var RENDER_DISTANCE_FOG_FIX = 3328.0f
-
- @JvmField
- var SKYBOX_COLOR = "float"
-
- /**
- * Client Info
- * Editable
- */
- @JvmField
- var IP_ADDRESS = "localhost"
-
- @JvmField
- var IP_MANAGEMENT = "localhost"
-
- var JS5_SERVER_PORT = 43593
-
- @JvmField
- var SERVER_PORT = 43594
-
- @JvmField
- var WL_PORT = 5555
-
- @JvmField
- var WORLD = 1
-
- @JvmField
- var WORLD_OVERRIDE = -1
-
- @JvmField
- var LOGIN_THEME = "scape main"
-
- @JvmField
- var xpDropsEnabled = true
-
- @JvmField
- var xpDropMode = 0
-
- @JvmField
- var xpTrackMode = 0
-
- @JvmField
- var slayerCountEnabled = true
-
- @JvmField
- var slayerTrackerColor = "#635a38"
-
- @JvmStatic
- var slayerTrackerOpacity = 180
+ @JvmStatic
+ var RCM_BG_OPACITY = 255
set(value) {
if(value > 255 || value < 0) field = 255
else field = value
}
- @JvmField
- var slayerTaskID = 0
+ @JvmField
+ var RCM_TITLE_COLOR = 0
- @JvmField
- var slayerTaskAmount = 0
-
- @JvmField
- var VERBOSE_LOGGING = false
-
- @JvmStatic
- fun setSlayerAmount(amount : Int){
- slayerTaskAmount = amount
- if(slayerTaskAmount < 0) slayerTaskAmount = 0
- SlayerTracker.lastUpdate = System.currentTimeMillis()
+ @JvmStatic
+ var RCM_TITLE_OPACITY = 255
+ set(value) {
+ if(value > 255 || value < 0) field = 255
+ else field = value
}
+ @JvmField
+ var RCM_BORDER_COLOR = 0
+
+ @JvmStatic
+ var RCM_BORDER_OPACITY = 255
+ set(value) {
+ if(value > 255 || value < 0) field = 255
+ else field = value
+ }
+
+ @JvmField
+ var RCM_TITLE = "Choose Option"
+
+ @JvmField
+ var RS3_CONTEXT_STYLE = false
+
+ /**
+ * Render distance
+ */
+ @JvmField
+ var RENDER_DISTANCE_INCREASE = false
+
+ @JvmField
+ var RENDER_DISTANCE_VALUE = 3584f
+
+ @JvmField
+ var RENDER_DISTANCE_TILE_VALUE = 28
+
+ @JvmField
+ var RENDER_DISTANCE_FOG_FIX = 3328.0f
+
+ @JvmField
+ var SKYBOX_COLOR = "float"
+
+ /**
+ * Client Info
+ * Editable
+ */
+ @JvmField
+ var IP_ADDRESS = "localhost"
+
+ @JvmField
+ var IP_MANAGEMENT = "localhost"
+
+ @JvmField
+ var JS5_SERVER_PORT = 43593
+
+ @JvmField
+ var SERVER_PORT = 43594
+
+ @JvmField
+ var WL_PORT = 5555
+
+ @JvmField
+ var WORLD = 1
+
+ @JvmField
+ var WORLD_OVERRIDE = -1
+
+ @JvmField
+ var LOGIN_THEME = "scape main"
+
+ @JvmField
+ var xpDropsEnabled = true
+
+ @JvmField
+ var xpDropMode = 0
+
+ @JvmField
+ var xpTrackMode = 0
+
+ @JvmField
+ var slayerCountEnabled = true
+
+ @JvmField
+ var slayerTrackerColor = "#635a38"
+
+ @JvmStatic
+ var slayerTrackerOpacity = 180
+ set(value) {
+ if(value > 255 || value < 0) field = 255
+ else field = value
+ }
+
+ @JvmField
+ var slayerTaskID = 0
+
+ @JvmField
+ var slayerTaskAmount = 0
+
+ @JvmField
+ var VERBOSE_LOGGING = false
+
+ @JvmStatic
+ fun setSlayerAmount(amount : Int){
+ slayerTaskAmount = amount
+ if(slayerTaskAmount < 0) slayerTaskAmount = 0
+ SlayerTracker.lastUpdate = System.currentTimeMillis()
+ }
+
+ /**
+ * Json config Parser
+ */
+ @JvmStatic
+ fun parse(path: String){
+ val reader = FileReader(path)
+ val parser = JSONParser()
+ val data = parser.parse(reader) as JSONObject
+
+ //Networking
+ if(data.containsKey("ip_address")) IP_ADDRESS = data["ip_address"].toString() else IP_ADDRESS = "play.2009scape.org"
+ if(data.containsKey("ip_management")) IP_MANAGEMENT = data["ip_management"].toString() else IP_MANAGEMENT = IP_ADDRESS
+ if(data.containsKey("wl_port")) WL_PORT = data["wl_port"].toString().toInt()
+ if(data.containsKey("server_port")) SERVER_PORT = data["server_port"].toString().toInt()
+ if(data.containsKey("js5_port")) JS5_SERVER_PORT = data["js5_port"].toString().toInt()
+ if(data.containsKey("world")) WORLD = data["world"].toString().toInt()
+
+ //Parse customization options
+ if(data.containsKey("customization")){
+ val custom = data["customization"] as JSONObject
+ if(custom.containsKey("login_theme")) LOGIN_THEME = custom["login_theme"].toString()
+
+ //Right-click menu customizations
+ if(custom.containsKey("right_click_menu")){
+ val rcm = custom["right_click_menu"] as JSONObject
+
+ //background
+ if(rcm.containsKey("background")){
+ val bg = rcm["background"] as JSONObject
+ if(bg.containsKey("color")) RCM_BG_COLOR = bg["color"].toString().replace("#", "").toIntOrNull(16) ?: 6116423//convert hex -> deci
+ if(bg.containsKey("opacity")) RCM_BG_OPACITY = bg["opacity"].toString().toInt()
+ }
+
+ //title bar
+ if(rcm.containsKey("title_bar")){
+ val tb = rcm["title_bar"] as JSONObject
+ if(tb.containsKey("font_color")) RCM_TITLE = RCM_TITLE.replace("0", tb["font_color"].toString().replace("#", ""))
+ if(tb.containsKey("color")) RCM_TITLE_COLOR = tb["color"].toString().replace("#", "").toIntOrNull(16) ?: 6116423//convert hex -> deci
+ if(tb.containsKey("opacity")) RCM_TITLE_OPACITY = tb["opacity"].toString().toInt()
+ }
+
+ //border
+ if(rcm.containsKey("border")){
+ val border = rcm["border"] as JSONObject
+ if(border.containsKey("color")) RCM_BORDER_COLOR = border["color"].toString().replace("#", "").toIntOrNull(16) ?: 6116423 //convert hex -> deci
+ if(border.containsKey("opacity")) RCM_BORDER_OPACITY = border["opacity"].toString().toInt()
+ }
+
+ //styles (changes how things are drawn)
+ if(rcm.containsKey("styles")){
+ val style = rcm["styles"] as JSONObject
+ if(style.containsKey("presets")) RCM_STYLE_PRESET = style["presets"].toString()
+ if(style.containsKey("rs3border")) RS3_CONTEXT_STYLE = style["rs3border"] as Boolean
+ }
+ }
+
+ if(custom.containsKey("xpdrops")){
+ val xpd = custom["xpdrops"] as JSONObject
+ if(xpd.containsKey("enabled")) xpDropsEnabled = xpd["enabled"] as Boolean
+ if(xpd.containsKey("drop_mode")) xpDropMode = xpd["drop_mode"].toString().toInt()
+ if(xpd.containsKey("track_mode")) xpTrackMode = xpd["track_mode"].toString().toInt()
+ }
+
+ if(custom.containsKey("slayer")){
+ val slayer = custom["slayer"] as JSONObject
+ if(slayer.containsKey("enabled")) slayerCountEnabled = slayer["enabled"] as Boolean
+ if(slayer.containsKey("color")) slayerTrackerColor = slayer["color"].toString().replace("#", "")
+ if(slayer.containsKey("opacity")) slayerTrackerOpacity = slayer["opacity"].toString().toInt()
+ }
+
+ if(custom.containsKey("rendering_options")) {
+ val hdoptions = custom["rendering_options"] as JSONObject
+
+ if(hdoptions.containsKey("technical")) {
+ val renderIncrease = hdoptions["technical"] as JSONObject
+ if(renderIncrease.containsKey("render_distance_increase")) RENDER_DISTANCE_INCREASE = renderIncrease["render_distance_increase"] as Boolean
+ }
+ if(hdoptions.containsKey("skybox")) {
+ val skyboxColor = hdoptions["skybox"] as JSONObject
+ if(skyboxColor.containsKey("skybox_color")) SKYBOX_COLOR
+ }
+ }
+ }
+
+ //Parse debug options
+ if(data.containsKey("debug")){
+ val debug = data["debug"] as JSONObject
+ if(debug.containsKey("item_debug")) ITEM_DEBUG_ENABLED = debug["item_debug"] as Boolean
+ if(debug.containsKey("npc_debug")) NPC_DEBUG_ENABLED = debug["npc_debug"] as Boolean
+ if(debug.containsKey("object_debug")) OBJECT_DEBUG_ENABLED = debug["object_debug"] as Boolean
+ if(debug.containsKey("hd_login_region_debug")) HD_LOGIN_DEBUG = debug["hd_login_region_debug"] as Boolean
+ if(debug.containsKey("hd_login_region_debug_verbose")) HD_LOGIN_VERBOSE = debug["hd_login_region_debug_verbose"] as Boolean
+ if(debug.containsKey("cache_debug")) CACHE_DEBUG = debug["cache_debug"] as Boolean
+ if(debug.containsKey("world_map_debug")) WORLD_MAP_DEBUG = debug["world_map_debug"] as Boolean
+ }
+
+
/**
- * Json config Parser
+ * Style Overrides (Still working on this system. We should allow for maximum creativity
+ * The way that it will be setup is a style type 1st
+ * ie, classicbox, rs3, rounded, rounded2
+ * Then we introduce color schemes that a user could select
+ * ie, classic, rs3, alternate, alternate2, custom
+ * @author Woah
*/
- @JvmStatic
- fun parse(path: String){
- val reader = FileReader(path)
- val parser = JSONParser()
- val data = parser.parse(reader) as JSONObject
-
- //Networking
- if(data.containsKey("ip_address")) IP_ADDRESS = data["ip_address"].toString() else IP_ADDRESS = "play.2009scape.org"
- if(data.containsKey("ip_management")) IP_MANAGEMENT = data["ip_management"].toString() else IP_MANAGEMENT = IP_ADDRESS
- if(data.containsKey("wl_port")) WL_PORT = data["wl_port"].toString().toInt()
- if(data.containsKey("server_port")) SERVER_PORT = data["server_port"].toString().toInt()
- if(data.containsKey("js5_port")) JS5_SERVER_PORT = data["js5_port"].toString().toInt()
- if(data.containsKey("world")) WORLD = data["world"].toString().toInt()
-
- //Parse customization options
- if(data.containsKey("customization")){
- val custom = data["customization"] as JSONObject
- if(custom.containsKey("login_theme")) LOGIN_THEME = custom["login_theme"].toString()
-
- //Right-click menu customizations
- if(custom.containsKey("right_click_menu")){
- val rcm = custom["right_click_menu"] as JSONObject
-
- //background
- if(rcm.containsKey("background")){
- val bg = rcm["background"] as JSONObject
- if(bg.containsKey("color")) RCM_BG_COLOR = bg["color"].toString().replace("#", "").toIntOrNull(16) ?: 6116423//convert hex -> deci
- if(bg.containsKey("opacity")) RCM_BG_OPACITY = bg["opacity"].toString().toInt()
- }
-
- //title bar
- if(rcm.containsKey("title_bar")){
- val tb = rcm["title_bar"] as JSONObject
- if(tb.containsKey("font_color")) RCM_TITLE = RCM_TITLE.replace("0", tb["font_color"].toString().replace("#", ""))
- if(tb.containsKey("color")) RCM_TITLE_COLOR = tb["color"].toString().replace("#", "").toIntOrNull(16) ?: 6116423//convert hex -> deci
- if(tb.containsKey("opacity")) RCM_TITLE_OPACITY = tb["opacity"].toString().toInt()
- }
-
- //border
- if(rcm.containsKey("border")){
- val border = rcm["border"] as JSONObject
- if(border.containsKey("color")) RCM_BORDER_COLOR = border["color"].toString().replace("#", "").toIntOrNull(16) ?: 6116423 //convert hex -> deci
- if(border.containsKey("opacity")) RCM_BORDER_OPACITY = border["opacity"].toString().toInt()
- }
-
- //styles (changes how things are drawn)
- if(rcm.containsKey("styles")){
- val style = rcm["styles"] as JSONObject
- if(style.containsKey("presets")) RCM_STYLE_PRESET = style["presets"].toString()
- if(style.containsKey("rs3border")) RS3_CONTEXT_STYLE = style["rs3border"] as Boolean
- }
- }
-
- if(custom.containsKey("xpdrops")){
- val xpd = custom["xpdrops"] as JSONObject
- if(xpd.containsKey("enabled")) xpDropsEnabled = xpd["enabled"] as Boolean
- if(xpd.containsKey("drop_mode")) xpDropMode = xpd["drop_mode"].toString().toInt()
- if(xpd.containsKey("track_mode")) xpTrackMode = xpd["track_mode"].toString().toInt()
- }
-
- if(custom.containsKey("slayer")){
- val slayer = custom["slayer"] as JSONObject
- if(slayer.containsKey("enabled")) slayerCountEnabled = slayer["enabled"] as Boolean
- if(slayer.containsKey("color")) slayerTrackerColor = slayer["color"].toString().replace("#", "")
- if(slayer.containsKey("opacity")) slayerTrackerOpacity = slayer["opacity"].toString().toInt()
- }
-
- if(custom.containsKey("rendering_options")) {
- val hdoptions = custom["rendering_options"] as JSONObject
-
- if(hdoptions.containsKey("technical")) {
- val renderIncrease = hdoptions["technical"] as JSONObject
- if(renderIncrease.containsKey("render_distance_increase")) RENDER_DISTANCE_INCREASE = renderIncrease["render_distance_increase"] as Boolean
- }
- if(hdoptions.containsKey("skybox")) {
- val skyboxColor = hdoptions["skybox"] as JSONObject
- if(skyboxColor.containsKey("skybox_color")) SKYBOX_COLOR
- }
- }
+ when (RCM_STYLE_PRESET) {
+ "classic" -> {
+ RS3_CONTEXT_STYLE = false
+ RCM_BG_COLOR = 6116423
+ RCM_BG_OPACITY = 255
+ RCM_TITLE = "Choose Option"
+ RCM_TITLE_COLOR = 0
+ RCM_TITLE_OPACITY = 255
+ RCM_BORDER_COLOR = 0
+ RCM_BORDER_OPACITY = 255
}
-
- //Parse debug options
- if(data.containsKey("debug")){
- val debug = data["debug"] as JSONObject
- if(debug.containsKey("item_debug")) ITEM_DEBUG_ENABLED = debug["item_debug"] as Boolean
- if(debug.containsKey("npc_debug")) NPC_DEBUG_ENABLED = debug["npc_debug"] as Boolean
- if(debug.containsKey("object_debug")) OBJECT_DEBUG_ENABLED = debug["object_debug"] as Boolean
- if(debug.containsKey("hd_login_region_debug")) HD_LOGIN_DEBUG = debug["hd_login_region_debug"] as Boolean
- if(debug.containsKey("hd_login_region_debug_verbose")) HD_LOGIN_VERBOSE = debug["hd_login_region_debug_verbose"] as Boolean
- if(debug.containsKey("cache_debug")) CACHE_DEBUG = debug["cache_debug"] as Boolean
- if(debug.containsKey("world_map_debug")) WORLD_MAP_DEBUG = debug["world_map_debug"] as Boolean
+ "rs3" -> {
+ RS3_CONTEXT_STYLE = true
+ RCM_BG_COLOR = 662822
+ RCM_BG_OPACITY = 255
+ RCM_TITLE = "Choose Option"
+ RCM_TITLE_COLOR = 1512718
+ RCM_TITLE_OPACITY = 165
+ RCM_BORDER_COLOR = 16777215
+ RCM_BORDER_OPACITY = 255
}
+ }
- /**
- * Style Overrides (Still working on this system. We should allow for maximum creativity
- * The way that it will be setup is a style type 1st
- * ie, classicbox, rs3, rounded, rounded2
- * Then we introduce color schemes that a user could select
- * ie, classic, rs3, alternate, alternate2, custom
- * @author Woah
+ }
+
+ fun extendRenderDistance() {
+ if (RENDER_DISTANCE_INCREASE) {
+ /** **DO NOT CHANGE THESE NUMBERS UNLESS YOU KNOW WHAT YOU ARE DOING**
+ * Render Distance Overrides
+ *
+ * (Simple formula) Tile amount * 512
+ * Default: 7 * 512 = 3584
+ * Extended(max): 56 * 512 = 28672
+ *
+ * Files + methods effected by these values:
+ * HDToolKit METHOD viewport
+ * Class140_Sub1_Sub1 METHOD animate
+ * Class3_Sub22 METHOD method398 * value as short
+ * Class40 METHOD method1046 * using RENDER_DISTANCE_TILE_VALUE
*/
- when (RCM_STYLE_PRESET) {
- "classic" -> {
- RS3_CONTEXT_STYLE = false
- RCM_BG_COLOR = 6116423
- RCM_BG_OPACITY = 255
- RCM_TITLE = "Choose Option"
- RCM_TITLE_COLOR = 0
- RCM_TITLE_OPACITY = 255
- RCM_BORDER_COLOR = 0
- RCM_BORDER_OPACITY = 255
- }
- "rs3" -> {
- RS3_CONTEXT_STYLE = true
- RCM_BG_COLOR = 662822
- RCM_BG_OPACITY = 255
- RCM_TITLE = "Choose Option"
- RCM_TITLE_COLOR = 1512718
- RCM_TITLE_OPACITY = 165
- RCM_BORDER_COLOR = 16777215
- RCM_BORDER_OPACITY = 255
- }
- }
-
-
+ RENDER_DISTANCE_VALUE = if (RENDER_DISTANCE_INCREASE) 28672F else 3584.0f
+ RENDER_DISTANCE_TILE_VALUE = if (RENDER_DISTANCE_INCREASE) 56 else 28
+ RENDER_DISTANCE_FOG_FIX = if (RENDER_DISTANCE_INCREASE) 28672F else 3328.0f
}
+ }
- fun extendRenderDistance() {
- if (RENDER_DISTANCE_INCREASE) {
- /** **DO NOT CHANGE THESE NUMBERS UNLESS YOU KNOW WHAT YOU ARE DOING**
- * Render Distance Overrides
- *
- * (Simple formula) Tile amount * 512
- * Default: 7 * 512 = 3584
- * Extended(max): 56 * 512 = 28672
- *
- * Files + methods effected by these values:
- * HDToolKit METHOD viewport
- * Class140_Sub1_Sub1 METHOD animate
- * Class3_Sub22 METHOD method398 * value as short
- * Class40 METHOD method1046 * using RENDER_DISTANCE_TILE_VALUE
- */
- RENDER_DISTANCE_VALUE = if (RENDER_DISTANCE_INCREASE) 28672F else 3584.0f
- RENDER_DISTANCE_TILE_VALUE = if (RENDER_DISTANCE_INCREASE) 56 else 28
- RENDER_DISTANCE_FOG_FIX = if (RENDER_DISTANCE_INCREASE) 28672F else 3328.0f
- }
- }
+ /**
+ * Client Info
+ * Not Editable
+ */
+ @JvmField
+ var CLIENT_BUILD = 530
- /**
- * Client Info
- * Not Editable
- */
- @JvmField
- var CLIENT_BUILD = 530
+ @JvmField
+ var CLIENT_VERSION = 1
- @JvmField
- var CLIENT_VERSION = 1
+ @JvmField
+ var PACKAGE_NAME = "org.runite.client"
- @JvmField
- var PACKAGE_NAME = "org.runite.client"
+ @JvmField
+ var RSA = true
- @JvmField
- var RSA = true
+ @JvmField
+ var ISAAC = false
- @JvmField
- var ISAAC = false
+ @JvmField
+ var EXPONENT = BigInteger("65537")
- @JvmField
- var EXPONENT = BigInteger("65537")
+ @JvmField
+ var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051")
- @JvmField
- var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051")
+ @JvmField
+ var SERVER_NAME = "2009scape"
- @JvmField
- var SERVER_NAME = "2009scape"
+ /**
+ * Path to config
+ */
+ @JvmField
+ var configLocation = "config.json"
- /**
- * Path to config
- */
- @JvmField
- var configLocation = "config.json"
+ /**
+ * Holiday Event Toggles
+ */
+ @JvmField
+ var HOLIDAYS_ENABLED = true
- /**
- * Holiday Event Toggles
- */
- @JvmField
- var HOLIDAYS_ENABLED = true
+ @JvmField
+ var EASTER_EVENT_ENABLED = false
+ /**
+ * Halloween event NPC Definitions are handled inside of NPCDefinition.java
+ */
+ @JvmField
+ var HALLOWEEN_EVENT_ENABLED = false
- @JvmField
- var EASTER_EVENT_ENABLED = false
- /**
- * Halloween event NPC Definitions are handled inside of NPCDefinition.java
- */
- @JvmField
- var HALLOWEEN_EVENT_ENABLED = false
+ @JvmField
+ var THANKSGIVING_EVENT_ENABLED = false
- @JvmField
- var THANKSGIVING_EVENT_ENABLED = false
+ @JvmField
+ var CHRISTMAS_EVENT_ENABLED = false
- @JvmField
- var CHRISTMAS_EVENT_ENABLED = false
+ private val calendar: Calendar = Calendar.getInstance()
+ private val month = calendar.get(Calendar.MONTH)
+ private val day = calendar.get(Calendar.DAY_OF_MONTH)
- private val calendar: Calendar = Calendar.getInstance()
- private val month = calendar.get(Calendar.MONTH)
- private val day = calendar.get(Calendar.DAY_OF_MONTH)
-
- @JvmStatic
- fun implementHoliday() {
- if (HOLIDAYS_ENABLED) {
- when (month) {
- 3 -> {
- if (day <= 8) {
- EASTER_EVENT_ENABLED = true
- }
+ @JvmStatic
+ fun implementHoliday() {
+ if (HOLIDAYS_ENABLED) {
+ when (month) {
+ 3 -> {
+ if (day <= 8) {
+ EASTER_EVENT_ENABLED = true
}
- 9 -> HALLOWEEN_EVENT_ENABLED = true
- 10 -> THANKSGIVING_EVENT_ENABLED = true
- 11 -> CHRISTMAS_EVENT_ENABLED = true
}
+ 9 -> HALLOWEEN_EVENT_ENABLED = true
+ 10 -> THANKSGIVING_EVENT_ENABLED = true
+ 11 -> CHRISTMAS_EVENT_ENABLED = true
}
}
}
diff --git a/Management-Server/managementprops/properties.json b/Management-Server/managementprops/properties.json
index 85bbcfb28..e081156a1 100644
--- a/Management-Server/managementprops/properties.json
+++ b/Management-Server/managementprops/properties.json
@@ -10,6 +10,6 @@
"WorldTechnicalInformation": {
"world_limit": "10",
"worldhop_delay": "20000"
- }
-
+ },
+ "secret_key": "2009scape_development"
}
\ No newline at end of file
diff --git a/Management-Server/src/main/java/ms/Management.java b/Management-Server/src/main/java/ms/Management.java
index 2c9863111..5d44a4e37 100644
--- a/Management-Server/src/main/java/ms/Management.java
+++ b/Management-Server/src/main/java/ms/Management.java
@@ -1,7 +1,8 @@
package ms;
-import ms.classloader.ClassLoadServer;
import ms.net.NioReactor;
+import ms.net.packet.IoBuffer;
+import ms.net.packet.PacketHeader;
import ms.net.packet.WorldPacketRepository;
import ms.system.ShutdownSequence;
import ms.system.mysql.SQLManager;
@@ -100,7 +101,6 @@ public final class Management {
new Command("-rlcache", "Reloads launcher/client resource cache") {
@Override
public void run(String... args) {
- ClassLoadServer.resetResourceCache();
System.out.println("Reloaded resource cache!");
}
},
@@ -118,6 +118,27 @@ public final class Management {
player.setWorldId(0);
System.out.println("Kicked player " + name + "!");
}
+ },
+
+ new Command("-say", "Send a message to all worlds") {
+ @Override
+ public void run(String... args) {
+ String message = String.join(" ", args);
+ message = message.substring(4);
+ for(GameServer server : WorldDatabase.getWorlds()){
+ if(server == null) continue;
+ String finalMessage = message;
+ server.getPlayers().forEach((String uname, PlayerSession p) -> {
+ IoBuffer buffer = new IoBuffer(5, PacketHeader.BYTE);
+ buffer.putString(p.getUsername());
+ buffer.putString("Server");
+ buffer.put(2);
+ buffer.put(2);
+ buffer.putString(finalMessage);
+ p.getWorld().getSession().write(buffer);
+ });
+ }
+ }
}
};
@@ -136,7 +157,6 @@ public final class Management {
SQLManager.init();
//NioReactor.configure(ServerConstants.PORT).start();
NioReactor.configure(5555).start();
- new ClassLoadServer().start();
Runtime.getRuntime().addShutdownHook(new ShutdownSequence());
System.out.println("Status: ready.");
System.out.println("Use -commands for a list of commands!");
diff --git a/Management-Server/src/main/java/ms/ServerConstants.java b/Management-Server/src/main/java/ms/ServerConstants.java
index dab98279f..60d4af36d 100644
--- a/Management-Server/src/main/java/ms/ServerConstants.java
+++ b/Management-Server/src/main/java/ms/ServerConstants.java
@@ -29,18 +29,6 @@ public final class ServerConstants {
*/
public static final OperatingSystem OS = System.getProperty("os.name").toUpperCase().contains("WIN") ? OperatingSystem.WINDOWS : OperatingSystem.UNIX;
- /**
- * The administrators.
- */
- public static final String[] ADMINISTRATORS = {
- "redsparr0w",
- };
-
- public static final String[] DATABASE_NAMES = {
- "server",
- "global",
- };
-
/**
* Stops from instantiating.
*/
diff --git a/Management-Server/src/main/java/ms/classloader/ClassLoadServer.java b/Management-Server/src/main/java/ms/classloader/ClassLoadServer.java
deleted file mode 100644
index ef35db3eb..000000000
--- a/Management-Server/src/main/java/ms/classloader/ClassLoadServer.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package ms.classloader;
-
-import ms.Management;
-import ms.ServerConstants;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.nio.file.Files;
-import java.util.HashMap;
-
-/**
- * ClassLoadServer
- * @author Clayton Williams (Hope)
- */
-public class ClassLoadServer extends Thread {
-
- /**
- * Listening port
- */
- private static final int PORT = 5050;
-
- /**
- * serverSocket for incoming connections
- */
- private ServerSocket serverSocket = null;
-
- /**
- * Holds classes and resources already added in the server
- */
- protected final static HashMap resourceCache = new HashMap();
-
- /**
- * New socket
- * @throws UnknownHostException
- * @throws IOException
- */
- public ClassLoadServer() {
- try {
- serverSocket = new ServerSocket(PORT);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
-
- /**
- * Listen for incoming connections
- */
- @Override
- public void run() {
- resetResourceCache();
- // System.out.println("Listening on port " + PORT + "...");
- while (Management.active) {
- Socket clientSocket = null;
- try {
- clientSocket = serverSocket.accept();
- //System.out.println("New Connection from : " + clientSocket.getInetAddress());
- WorkerThread wcs = new WorkerThread(clientSocket);
- wcs.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- /**
- * Loads resources recursively from a starting root directory and adds the file bytes to our cache
- * @param path
- * @param pathRoot
- */
- private static void loadResources(String path, String pathRoot) {
- try {
- path = ServerConstants.fixPath(null, path);
- pathRoot = ServerConstants.fixPath(null, pathRoot);
- File root = new File(path);
- File[] list = root.listFiles();
- if (list == null) return;
- for (File f : list) {
- if (f.isDirectory()) {
- loadResources(f.getAbsolutePath(), pathRoot);
- } else {
- if (f.exists()) {
- if (!f.getName().startsWith(".")) {
- byte[] bytes = Files.readAllBytes(f.toPath());
- String name = ServerConstants.fixPath(null, f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf(pathRoot)));
- //System.out.println("[ClassLoadServer] Loaded resource '" + f.getName() +
- // "' Size: " + NumberFormat.getInstance().format(bytes.length) + " bytes");
- resourceCache.put(name, bytes);
- }
- }
- }
- }
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Empties the class cache and loads resources
- */
- public static void resetResourceCache() {
- resourceCache.clear();
- //loadResources("bin/org/keldagrim/launcher/", "org/arios/launcher/");
- //loadResources("resources/", "org/keldagrim/launcher/");
- //System.out.println("Loaded all resources!");
- }
-
-}
diff --git a/Management-Server/src/main/java/ms/classloader/WorkerThread.java b/Management-Server/src/main/java/ms/classloader/WorkerThread.java
deleted file mode 100644
index c9af27f6a..000000000
--- a/Management-Server/src/main/java/ms/classloader/WorkerThread.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package ms.classloader;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.net.Socket;
-import java.util.Map;
-
-import ms.ServerConstants;
-import ms.system.OperatingSystem;
-
-/**
- * Worker thread for launcher connections
- * @author Clayton Williams (Hope)
- *
- */
-public class WorkerThread extends Thread {
-
- /**
- * Our launcher connection
- */
- private Socket launcher = null;
-
- /**
- * Input stream from launcher
- */
- private ObjectInputStream is = null;
-
- /**
- * Output stream to launcher
- */
- private ObjectOutputStream os = null;
-
- /**
- * The user's operating system type
- */
- private OperatingSystem operatingSystem = OperatingSystem.WINDOWS;
-
- /**
- * Creates a new worker thread to handle the launcher requests
- * @param socket
- * @param classesCache
- * @throws IOException
- */
- public WorkerThread(Socket launcher) throws IOException {
- super();
- this.launcher = launcher;
- try {
- os = new ObjectOutputStream(new BufferedOutputStream(this.launcher.getOutputStream()));
- os.flush();
- is = new ObjectInputStream(new BufferedInputStream(launcher.getInputStream()));
- } catch (IOException ioe) {
- this.launcher.close();
- }
- }
-
- /**
- * Input Stream handler
- */
- @SuppressWarnings("unused") //saving resource type for later
- public void run() {
- byte opcode = -1;
- try {
- while (true) {
- opcode = is.readByte();
- switch(opcode) {
- case 1: //requests revision
- operatingSystem = is.readUTF().contains("UNIX") ? OperatingSystem.UNIX : OperatingSystem.WINDOWS;
- os.reset();
- os.writeInt(ClassLoadServer.resourceCache.size());//#customresources
- for (Map.Entry hm : ClassLoadServer.resourceCache.entrySet()) {
- os.writeUTF(ServerConstants.fixPath(operatingSystem, (String) hm.getKey()));
- os.writeInt(hm.getValue().length);
- }
- os.writeByte(1); //number of custom resources
- //followed by 2 strings
- //System.err.println(operatingSystem.name());
- os.writeUTF(ServerConstants.fixPath(operatingSystem, "ms/launcher/arios-gamepack-530.jar"));
- os.writeUTF("BINARY");
- os.flush();
- break;
- case 2: //resource request
- String resourceName = ServerConstants.fixPath(null, is.readUTF());
- String resourceType = is.readUTF();
- if (ClassLoadServer.resourceCache.containsKey(resourceName)) {
- sendResource(ClassLoadServer.resourceCache.get(resourceName));
- //System.out.println("Sent Resource: " + resourceName);
- } else {
- sendOpcode(-1);
- //System.out.println("Could not send resource '" + resourceName + "'");
- }
- break;
- default:
- System.out.println("Unhandled opcode=" + opcode);
- break;
- }
- }
- } catch(Exception e) {
- //System.out.println("Client force disconnect.");
- } finally {
- try {
- is.close();
- os.close();
- launcher.close();
- } catch (Exception e) {}
- }
- }
-
- /**
- * send a byte array packet to the client
- * @exception IOException file read error.
- */
- protected void sendResource(byte [] bytes) throws IOException {
- os.reset();
- os.writeByte(2);
- os.writeInt(bytes.length);
- for (int i = 0; i < bytes.length; i++) {
- os.writeByte(bytes[i]);
- }
- os.flush();
- }
-
- /**
- * Send no data opcodes
- * @param opcode
- * @throws IOException
- */
- protected void sendOpcode(int opcode) throws IOException {
- os.reset();
- os.writeByte(opcode);
- os.flush();
- }
-
-}
diff --git a/Management-Server/src/main/java/ms/net/IoEventHandler.java b/Management-Server/src/main/java/ms/net/IoEventHandler.java
index 907ad9bbf..1971fffa7 100644
--- a/Management-Server/src/main/java/ms/net/IoEventHandler.java
+++ b/Management-Server/src/main/java/ms/net/IoEventHandler.java
@@ -67,6 +67,10 @@ public final class IoEventHandler {
ByteBuffer buffer = ByteBuffer.allocate(100_000);
IoSession session = (IoSession) key.attachment();
if (channel.read(buffer) == -1) {
+ if(session == null){
+ key.cancel();
+ return;
+ }
if(session.getGameServer() != null){
WorldDatabase.unRegister(session.getGameServer());
}
@@ -87,8 +91,10 @@ public final class IoEventHandler {
*/
public void write(SelectionKey key) {
IoSession session = (IoSession) key.attachment();
- key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
- session.write();
+ if(session != null) {
+ key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
+ session.write();
+ }
}
/**
diff --git a/Management-Server/src/main/java/ms/net/IoSession.java b/Management-Server/src/main/java/ms/net/IoSession.java
index dd722db17..5fc70344f 100644
--- a/Management-Server/src/main/java/ms/net/IoSession.java
+++ b/Management-Server/src/main/java/ms/net/IoSession.java
@@ -168,9 +168,9 @@ public class IoSession {
}
writingQueue.remove(0);
}
- writingLock.unlock();
} catch (IOException e) {
disconnect();
+ } finally {
writingLock.unlock();
}
}
diff --git a/Management-Server/src/main/java/ms/net/NioReactor.java b/Management-Server/src/main/java/ms/net/NioReactor.java
index 8c28177ad..21a17ec65 100644
--- a/Management-Server/src/main/java/ms/net/NioReactor.java
+++ b/Management-Server/src/main/java/ms/net/NioReactor.java
@@ -96,6 +96,7 @@ public final class NioReactor implements Runnable {
SelectionKey key = keys.next();
keys.remove();
try {
+ if(key == null) continue;
if (!key.isValid() || !key.channel().isOpen()) {
key.cancel();
continue;
diff --git a/Management-Server/src/main/java/ms/net/event/HSReadEvent.java b/Management-Server/src/main/java/ms/net/event/HSReadEvent.java
index ac12befc0..d92f5dbc7 100644
--- a/Management-Server/src/main/java/ms/net/event/HSReadEvent.java
+++ b/Management-Server/src/main/java/ms/net/event/HSReadEvent.java
@@ -4,6 +4,7 @@ import java.nio.ByteBuffer;
import ms.net.IoReadEvent;
import ms.net.IoSession;
+import ms.system.util.ManagementConstants;
import ms.world.WorldDatabase;
import ms.system.util.ByteBufferUtils;
@@ -12,11 +13,6 @@ import ms.system.util.ByteBufferUtils;
* @author Emperor
*/
public final class HSReadEvent extends IoReadEvent {
-
- /**
- * The password used to verify
- */
- private static final String PASSWORD = "0x14ari0SSbh98989910";
/**
* Constructs a new {@code HSReadEvent}.
@@ -33,7 +29,7 @@ public final class HSReadEvent extends IoReadEvent {
switch (opcode) {
case 88:
String password = ByteBufferUtils.getString(buffer);
- if (!password.equals(PASSWORD)) {
+ if (!password.equals(ManagementConstants.getSECRET_KEY())) {
System.out.println("Password mismatch (attempt=" + password + ")!");
session.disconnect();
break;
diff --git a/Management-Server/src/main/java/ms/net/packet/IoBuffer.java b/Management-Server/src/main/java/ms/net/packet/IoBuffer.java
index 8bd8199b7..c35fb5ab6 100644
--- a/Management-Server/src/main/java/ms/net/packet/IoBuffer.java
+++ b/Management-Server/src/main/java/ms/net/packet/IoBuffer.java
@@ -547,7 +547,7 @@ public class IoBuffer {
long second = getIntB();
if (second < 0)
second = second & 0xffffffffL;
- return (first << -41780448) + second;
+ return (first << 32) + second;
}
/**
@@ -567,7 +567,7 @@ public class IoBuffer {
if (peek <= Short.MAX_VALUE) {
return buf.getShort() & 0xFFFF;
}
- return (buf.getInt() & 0xFFFFFFFF) - 32768;
+ return buf.getInt() - 32768;
}
/**
diff --git a/Management-Server/src/main/java/ms/net/packet/WorldPacketRepository.kt b/Management-Server/src/main/java/ms/net/packet/WorldPacketRepository.kt
index 6b9233cae..b72f731e1 100644
--- a/Management-Server/src/main/java/ms/net/packet/WorldPacketRepository.kt
+++ b/Management-Server/src/main/java/ms/net/packet/WorldPacketRepository.kt
@@ -5,7 +5,7 @@ import ms.system.PunishmentStorage
import ms.system.communication.ClanRank
import ms.system.communication.ClanRepository
import ms.system.communication.CommunicationInfo
-import ms.system.util.ManagementConstants.Companion.WORLD_HOP_DELAY
+import ms.system.util.ManagementConstants.WORLD_HOP_DELAY
import ms.world.GameServer
import ms.world.PlayerSession
import ms.world.WorldDatabase
diff --git a/Management-Server/src/main/java/ms/system/PunishmentStorage.java b/Management-Server/src/main/java/ms/system/PunishmentStorage.java
index a82dad781..3fd0b00a5 100644
--- a/Management-Server/src/main/java/ms/system/PunishmentStorage.java
+++ b/Management-Server/src/main/java/ms/system/PunishmentStorage.java
@@ -49,7 +49,7 @@ public final class PunishmentStorage {
return;
}
long end = Long.MAX_VALUE;
- if (duration != -1l && duration != 0L) {
+ if (duration != -1L && duration != 0L) {
end = System.currentTimeMillis() + duration;
} else if (duration == 0L) {
end = 0L;
diff --git a/Management-Server/src/main/java/ms/system/communication/CommunicationInfo.java b/Management-Server/src/main/java/ms/system/communication/CommunicationInfo.java
index 1fd106fd3..86afae5ec 100644
--- a/Management-Server/src/main/java/ms/system/communication/CommunicationInfo.java
+++ b/Management-Server/src/main/java/ms/system/communication/CommunicationInfo.java
@@ -12,10 +12,7 @@ import java.nio.ByteBuffer;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
/**
@@ -184,9 +181,7 @@ public final class CommunicationInfo {
String bl = set.getString("blocked");
if (bl != null && !bl.isEmpty()) {
tokens = bl.split(",");
- for (String name : tokens) {
- blocked.add(name);
- }
+ blocked.addAll(Arrays.asList(tokens));
}
clanName = set.getString("clanName");
currentClan = set.getString("currentClan");
@@ -236,6 +231,9 @@ public final class CommunicationInfo {
case 2:
tradeSetting = Integer.parseInt(tokens[2]);
break;
+ default:
+ System.out.println("Illegal arg count in chatsetting string: " + chatSettings);
+ break;
}
}
}
diff --git a/Management-Server/src/main/java/ms/system/mysql/SQLManager.kt b/Management-Server/src/main/java/ms/system/mysql/SQLManager.kt
index e4704ea29..05affcacc 100644
--- a/Management-Server/src/main/java/ms/system/mysql/SQLManager.kt
+++ b/Management-Server/src/main/java/ms/system/mysql/SQLManager.kt
@@ -1,11 +1,11 @@
package ms.system.mysql
import ms.system.util.ManagementConstants
-import ms.system.util.ManagementConstants.Companion.DATABASE_HOST_ADDRESS
-import ms.system.util.ManagementConstants.Companion.DATABASE_NAME
-import ms.system.util.ManagementConstants.Companion.DATABASE_PASSWORD
-import ms.system.util.ManagementConstants.Companion.DATABASE_PORT
-import ms.system.util.ManagementConstants.Companion.DATABASE_USERNAME
+import ms.system.util.ManagementConstants.DATABASE_HOST_ADDRESS
+import ms.system.util.ManagementConstants.DATABASE_NAME
+import ms.system.util.ManagementConstants.DATABASE_PASSWORD
+import ms.system.util.ManagementConstants.DATABASE_PORT
+import ms.system.util.ManagementConstants.DATABASE_USERNAME
import java.sql.Connection
import java.sql.DriverManager
import java.sql.SQLException
diff --git a/Management-Server/src/main/java/ms/system/util/ManagementConfigParser.kt b/Management-Server/src/main/java/ms/system/util/ManagementConfigParser.kt
index 5cc872e9e..7aba7f237 100644
--- a/Management-Server/src/main/java/ms/system/util/ManagementConfigParser.kt
+++ b/Management-Server/src/main/java/ms/system/util/ManagementConfigParser.kt
@@ -30,19 +30,20 @@ class ManagementConfigParser(path: String) {
data = parser.parse(reader) as JSONObject
parseDatabaseInformation()
parseWorldTechnicalSettings()
+ ManagementConstants.SECRET_KEY = data!!["secret_key"].toString()
}
}
private fun parseDatabaseInformation(){
data ?: return
val dbData = data!!["DatabaseInformation"] as JSONObject
- ManagementConstants().parseDBProp(dbData)
+ ManagementConstants.parseDBProp(dbData)
}
private fun parseWorldTechnicalSettings(){
data ?: return
val wtiData = data!!["WorldTechnicalInformation"] as JSONObject
- ManagementConstants().parseWTIProp(wtiData)
+ ManagementConstants.parseWTIProp(wtiData)
}
/**
diff --git a/Management-Server/src/main/java/ms/system/util/ManagementConstants.kt b/Management-Server/src/main/java/ms/system/util/ManagementConstants.kt
index 5f07849c4..01d40fb5a 100644
--- a/Management-Server/src/main/java/ms/system/util/ManagementConstants.kt
+++ b/Management-Server/src/main/java/ms/system/util/ManagementConstants.kt
@@ -2,32 +2,31 @@ package ms.system.util
import org.json.simple.JSONObject
-class ManagementConstants {
+object ManagementConstants {
- companion object {
+ //MySQL main database name
+ var DATABASE_NAME: String = "global"
- //MySQL main database name
- var DATABASE_NAME: String = "global"
+ //MySQL database username
+ var DATABASE_USERNAME: String = "root"
- //MySQL database username
- var DATABASE_USERNAME: String = "root"
+ //MySQL database password
+ var DATABASE_PASSWORD: String = ""
- //MySQL database password
- var DATABASE_PASSWORD: String = ""
+ //MySQL host
+ var DATABASE_HOST_ADDRESS: String = "127.0.0.1"
- //MySQL host
- var DATABASE_HOST_ADDRESS: String = "127.0.0.1"
+ //MySQL port
+ var DATABASE_PORT: Int = 3306
- //MySQL port
- var DATABASE_PORT: Int = 3306
+ //Max amount of worlds supported on the world list
+ var MAX_WORLD_AMOUNT: Int = 10
- //Max amount of worlds supported on the world list
- var MAX_WORLD_AMOUNT: Int = 10
+ //User world hop delay in seconds
+ var WORLD_HOP_DELAY: Long = 20_000L
- //User world hop delay in seconds
- var WORLD_HOP_DELAY: Long = 20_000L
-
- }
+ @JvmStatic
+ var SECRET_KEY: String = ""
fun parseDBProp(data: JSONObject) {
DATABASE_NAME = data["database_name"].toString()
diff --git a/Management-Server/src/main/java/ms/system/util/StringUtils.java b/Management-Server/src/main/java/ms/system/util/StringUtils.java
index 2d997bb9a..2a85aea8f 100644
--- a/Management-Server/src/main/java/ms/system/util/StringUtils.java
+++ b/Management-Server/src/main/java/ms/system/util/StringUtils.java
@@ -409,8 +409,9 @@ public final class StringUtils {
}
}
}
- return -i_26_ + ((7 + i_30_) >> -662855293);
+ return -i_26_ + ((7 + i_30_) >> 3);
} catch (RuntimeException runtimeexception) {
+ runtimeexception.printStackTrace();
}
return 0;
}
diff --git a/Management-Server/src/main/java/ms/world/PlayerSession.java b/Management-Server/src/main/java/ms/world/PlayerSession.java
index cccb91cf1..09c4682d5 100644
--- a/Management-Server/src/main/java/ms/world/PlayerSession.java
+++ b/Management-Server/src/main/java/ms/world/PlayerSession.java
@@ -66,7 +66,7 @@ public final class PlayerSession {
/**
* The time stamp of last disconnection.
*/
- private long disconnectionTime = 0l;
+ private long disconnectionTime = 0L;
/**
* How long the player is banned for.
@@ -463,11 +463,8 @@ public final class PlayerSession {
this.disconnectionTime = time;
}
- @Override
- public boolean equals(Object o) {
- if(o instanceof PlayerSession) {
- return username.equals(((PlayerSession) o).username);
- } else return false;
+ public boolean equalsSession(PlayerSession o){
+ return username.equals(o.username);
}
@Override
diff --git a/Management-Server/src/main/kotlin/ms09/MSLogger.kt b/Management-Server/src/main/kotlin/ms09/MSLogger.kt
index b629b1595..5bd7a7b7f 100644
--- a/Management-Server/src/main/kotlin/ms09/MSLogger.kt
+++ b/Management-Server/src/main/kotlin/ms09/MSLogger.kt
@@ -9,12 +9,12 @@ import java.util.*
object MSLogger {
val t = Terminal()
- val formatter = SimpleDateFormat("HH:mm:ss")
var tradeLog: Writer? = null
var tradeLogWriter: BufferedWriter? = null
fun getTime(): String{
+ val formatter = SimpleDateFormat("HH:mm:ss")
return "[" + formatter.format(Date(System.currentTimeMillis())) +"]"
}
diff --git a/Server/data/configs/drop_tables.json b/Server/data/configs/drop_tables.json
index c1777d621..288dad9d1 100644
--- a/Server/data/configs/drop_tables.json
+++ b/Server/data/configs/drop_tables.json
@@ -62771,7 +62771,7 @@
{
"default": [],
"charm": [],
- "ids": "428, 429",
+ "ids": "428,429",
"description": "Shade (Stronghold of Security) (So Shade Robes can drop)",
"main": [
{
diff --git a/Server/server.jar b/Server/server.jar
deleted file mode 100644
index 7c1a8ef48..000000000
Binary files a/Server/server.jar and /dev/null differ
diff --git a/Server/src/main/java/core/game/content/activity/CutscenePlugin.java b/Server/src/main/java/core/game/content/activity/CutscenePlugin.java
index 4a999361f..bc9a214a1 100644
--- a/Server/src/main/java/core/game/content/activity/CutscenePlugin.java
+++ b/Server/src/main/java/core/game/content/activity/CutscenePlugin.java
@@ -100,6 +100,7 @@ public abstract class CutscenePlugin extends ActivityPlugin {
unpause();
}
player.unlock();
+ player.getInterfaceManager().openDefaultTabs();
player.getWalkingQueue().reset();
player.getLocks().unlockMovement();
}
diff --git a/Server/src/main/java/core/game/content/activity/guild/WizardGuildPlugin.java b/Server/src/main/java/core/game/content/activity/guild/WizardGuildPlugin.java
index 9f94f10f3..3dfd6ad90 100644
--- a/Server/src/main/java/core/game/content/activity/guild/WizardGuildPlugin.java
+++ b/Server/src/main/java/core/game/content/activity/guild/WizardGuildPlugin.java
@@ -1,5 +1,6 @@
package core.game.content.activity.guild;
+import api.ContentAPI;
import core.cache.def.impl.NPCDefinition;
import core.cache.def.impl.SceneryDefinition;
import core.game.content.dialogue.DialoguePlugin;
@@ -60,7 +61,7 @@ public final class WizardGuildPlugin extends OptionHandler {
switch (id) {
case 1600:
case 1601:
- if (player.getSkills().getStaticLevel(Skills.MAGIC) < 66) {
+ if (ContentAPI.getDynLevel(player, Skills.MAGIC) < 66) {
player.getDialogueInterpreter().sendDialogue("You need a Magic level of at least 66 to enter.");
return true;
}
diff --git a/Server/src/main/java/core/game/content/dialogue/BillTeachDialogue.java b/Server/src/main/java/core/game/content/dialogue/BillTeachDialogue.java
deleted file mode 100644
index 8ec4998bc..000000000
--- a/Server/src/main/java/core/game/content/dialogue/BillTeachDialogue.java
+++ /dev/null
@@ -1,219 +0,0 @@
-package core.game.content.dialogue;
-
-import core.game.node.entity.npc.NPC;
-import core.game.node.entity.player.Player;
-import core.plugin.Initializable;
-import core.game.world.map.Location;
-
-/**
- * Represents the dialogue plugin used for Bill Teach
- * @author Charlie
- * @version 1.0
- */
-@Initializable
-public final class BillTeachDialogue extends DialoguePlugin {
-
- /**
- * Constructs a new {@code BarfyBill} {@code Object}.
- */
- public BillTeachDialogue() {
- /**
- * empty.
- */
- }
-
- /**
- * Constructs a new {@code BarfyBill} {@code Object}.
- * @param player the player.
- */
- public BillTeachDialogue(Player player) {
- super(player);
- }
-
- @Override
- public DialoguePlugin newInstance(Player player) {
- return new BillTeachDialogue(player);
- }
-
- @Override
- public boolean open(Object... args) {
- npc = new NPC(3155);
- player("Hello there.");
- stage = 0;
- return true;
- }
-
- @Override
- public boolean handle(int interfaceId, int buttonId) {
- switch (stage) {
- case 0:
- npc("Arr'! Avast ye' scallywag!", "You be lookin' to get somewhere " + (player.isMale() ? "lad?" : "lass?"));
- stage = 1;
- break;
- case 1:
- interpreter.sendOptions("Select an Option", "Yes", "No, thank you");
- stage = 2;
- break;
- case 2:
- switch (buttonId) {
- case 1:
- player("Yes, where can you take me?");
- stage = 1000;
- break;
- case 2:
- npc("Arr'! You be wastin' my time again..");
- stage = 7;
- break;
- }
- break;
- case 1000:
- npc("Aye, take a browse through me options.");
- stage++;
- break;
- case 1001:
- interpreter.sendOptions("Select an Option", "Slayer Tower", "Zanaris Fairy Ring", "Gnome Stronghold", "Rellekka", "More");
- stage = 2000;
- break;
- case 2000:
- switch (buttonId) {
- case 1:
- if(!player.getQuestRepository().isComplete("Priest in Peril")) {
- npc("Aye, sorry there " + pirateGender() + ", but you'll be needing to ", "help King Roald with something first.");
- stage = 7;
- } else {
- end();
- player.teleport(new Location(3429, 3526, 0));
- }
- break;
- case 2:
- if(!player.getQuestRepository().isComplete("Lost City")) {
- npc("Aye, sorry there " + pirateGender() + ", but you'll be needing to ", "discover Zanaris first.");
- stage = 7;
- } else {
- end();
- player.teleport(new Location(2412, 4433, 0));
- }
- break;
- case 3:
- end();
- player.teleport(new Location(2461, 3444, 0));
- break;
- case 4:
- end();
- player.teleport(new Location(2669, 3631, 0));
- break;
- case 5:
- interpreter.sendOptions("Select an Option", "Kalphite Lair", "Asgarnian Ice Dungeon", "Fremmenik Dungeon", "Taverley Dungeon", "More");
- stage = 3000;
- break;
- }
- break;
- case 3000:
- switch (buttonId) {
- case 1:
- end();
- player.teleport(new Location(3227, 3107, 0));
- break;
- case 2:
- end();
- player.teleport(new Location(3007, 9550, 0));
- break;
- case 3:
- end();
- player.teleport(new Location(2808, 10002, 0));
- break;
- case 4:
- end();
- player.teleport(new Location(2884, 9798, 0));
- break;
- case 5:
- interpreter.sendOptions("Select an Option", "Waterfall Dungeon", "Brimhaven Dungeon", "Ape Atoll Dungeon", "God Wars Dungeon", "More");
- stage = 4000;
- break;
- }
- break;
- case 4000:
- switch (buttonId) {
- case 1:
- end();
- player.teleport(new Location(2575, 9861, 0));
- break;
- case 2:
- end();
- player.teleport(new Location(2713, 9564, 0));
- break;
- case 3:
- end();
- player.teleport(new Location(2715, 9184, 0));
- break;
- case 4:
- end();
- player.teleport(new Location(2898, 3710, 0));
- break;
- case 5:
- interpreter.sendOptions("Select an Option", "Shilo Village", "Yanille", "Zul-Andra", "Piscatoris Fishing Colony", "More");
- stage = 5000;
- break;
- }
- break;
- case 5000:
- switch (buttonId) {
- case 1:
- end();
- player.teleport(new Location(2867, 2952, 0));
- break;
- case 2:
- end();
- player.teleport(new Location(2544, 3096, 0));
- break;
- case 3:
- end();
- player.teleport(new Location(2193, 3055, 0));
- break;
- case 4:
- end();
- player.teleport(new Location(2343, 3663, 0));
- break;
- case 5:
- interpreter.sendOptions("Select an Option", "Bandit Camp", "Miscellenia", "Mort'ton", "Feldip Hills", "Back");
- stage = 6000;
- break;
- }
- break;
- case 6000:
- switch (buttonId) {
- case 1:
- end();
- player.teleport(new Location(3176, 2987, 0));
- break;
- case 2:
- end();
- player.teleport(new Location(2581, 3845, 0));
- break;
- case 3:
- end();
- player.teleport(new Location(3488, 3296, 0));
- break;
- case 4:
- end();
- player.teleport(new Location(2525, 2915, 0));
- break;
- case 5:
- interpreter.sendOptions("Select an Option", "Slayer Tower", "Zanaris Fairy Ring", "Gnome Stronghold", "Rellekka", "More");
- stage = 2000;
- break;
- }
- break;
- case 7:
- end();
- break;
- }
- return true;
- }
-
- @Override
- public int[] getIds() {
- return new int[] { 3155 };
- }
-
-}
diff --git a/Server/src/main/java/core/game/content/dialogue/HansDialoguePlugin.java b/Server/src/main/java/core/game/content/dialogue/HansDialoguePlugin.java
index 2639d98a0..2b2010c97 100644
--- a/Server/src/main/java/core/game/content/dialogue/HansDialoguePlugin.java
+++ b/Server/src/main/java/core/game/content/dialogue/HansDialoguePlugin.java
@@ -137,7 +137,7 @@ public final class HansDialoguePlugin extends DialoguePlugin {
case 12:
switch(buttonId){
case 1:
- options("1.0x","2.5x","10x","20x");
+ options("1.0x","2.5x","Stay 5.0x");
stage++;
break;
case 2:
@@ -166,13 +166,9 @@ public final class HansDialoguePlugin extends DialoguePlugin {
}
break;
case 3:
- player.getSkills().experienceMutiplier = 10.0;
- stage = 14;
- break;
- case 4:
- player.getSkills().experienceMutiplier = 20.0;
- stage = 14;
- break;
+ playerl(FacialExpression.FRIENDLY, "I'd rather stay 5x, thank you.");
+ stage = END_DIALOGUE;
+ return true;
}
npc("One moment, please...");
break;
diff --git a/Server/src/main/java/core/game/content/dialogue/SimonTempleton.java b/Server/src/main/java/core/game/content/dialogue/SimonTempleton.java
index abe12c03e..47ea1a4c4 100644
--- a/Server/src/main/java/core/game/content/dialogue/SimonTempleton.java
+++ b/Server/src/main/java/core/game/content/dialogue/SimonTempleton.java
@@ -38,7 +38,6 @@ public final class SimonTempleton extends DialoguePlugin{
return true;
}
}
- player.getPacketDispatch().sendMessage("" + args.length);
npc("G'day, mate!. Got any new", "pyramid artefacts for me?");
return true;
}
diff --git a/Server/src/main/java/core/game/content/global/shop/Shop.java b/Server/src/main/java/core/game/content/global/shop/Shop.java
deleted file mode 100644
index 5b44cfc1c..000000000
--- a/Server/src/main/java/core/game/content/global/shop/Shop.java
+++ /dev/null
@@ -1,913 +0,0 @@
-package core.game.content.global.shop;
-
-import api.ContentAPI;
-import core.cache.def.impl.ItemDefinition;
-import core.game.container.Container;
-import core.game.container.ContainerType;
-import org.rs09.consts.Items;
-import core.game.node.entity.player.Player;
-import core.game.node.entity.player.link.diary.DiaryType;
-import core.game.node.item.Item;
-import rs09.game.system.SystemLogger;
-import rs09.game.system.config.ItemConfigParser;
-import rs09.game.world.GameWorld;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A class representing a shop.
- *
- * @author 'Vexia
- * @author Jamix77
- */
-public class Shop {
-
- /**
- * Represents the general store items.
- */
- public final static Item[] GENERAL_STORE_ITEMS = new Item[]{
- new Item(Items.EMPTY_POT_1931,5),
- new Item(Items.JUG_1935,5),
- new Item(Items.SHEARS_1735,2),
- new Item(Items.BUCKET_1925,3),
- new Item(Items.BOWL_1923,2),
- new Item(Items.CAKE_TIN_1887,2),
- new Item(Items.TINDERBOX_590,2),
- new Item(Items.CHISEL_1755,2),
- new Item(Items.HAMMER_2347,5),
- new Item(Items.NEWCOMER_MAP_550,5),
- new Item(Items.SECURITY_BOOK_9003,5)
- };
- /**
- * Represents the coins item.
- */
- private static final int COINS = 995;
- /**
- * Represents the tokkul item id.
- */
- private static final int TOKKUL = 6529;
-
- /**
- * Represents the archery ticket item id
- */
- private static final int ARCHERY_TICKET = 1464;
-
- /**
- * Represents the shop containers.
- */
- private final Container[] containers = new Container[]{new Container(40, ContainerType.SHOP), new Container(40, ContainerType.SHOP)};
- /**
- * Represents the list of shop viewers.
- */
- private final List viewers = new ArrayList<>(20);
-
- /**
- * Represents the title of the shop.
- */
- private final String title;
-
- /**
- * Represents the items in the store.
- */
- private Item[] items;
-
- /**
- * Represents if it's a general store.
- */
- private final boolean general;
-
- /**
- * Represents the currency the shop allows.
- */
- private final int currency;
-
- /**
- * If the shop buys for high alch.
- */
- private final boolean highAlch;
-
- /**
- * Sell price for all shop items, if needed.
- */
- private int sellAllFor;
-
- /**
- * The last restock.
- */
- private int lastRestock;
-
- /**
- * If the shop should restock.
- */
- private boolean restock;
-
- /**
- * If it's a point shop.
- */
- private boolean pointShop;
-
- /**
- * The npcs of the shop.
- */
- private int[] npcs;
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param items the items.
- * @param general the general.
- * @param currency the currency.
- * @param highAlch if high alch.
- */
- public Shop(String title, Item[] items, boolean general, int currency, boolean highAlch) {
- this.title = title;
- this.items = items;
- this.general = general;
- this.currency = currency;
- this.highAlch = highAlch;
- this.getContainer(0).add(items);
- this.setRestock(true);
- lastRestock = GameWorld.getTicks() + 100;
- }
-
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param items the items.
- * @param general the general.
- * @param currency the currency.
- * @param highAlch if high alch.
- * @param restock if restock.
- */
- public Shop(String title, Item[] items, boolean general, int currency, boolean highAlch, boolean restock, int sellAllFor) {
- this(title, items, general, currency, highAlch);
- this.sellAllFor = sellAllFor;
- this.setRestock(restock);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}
- *
- * @param title the shop title
- * @param items items the shop can handle
- * @param general is this a general store
- * @param currency what currency is used
- */
- public Shop(String title, Item[] items, int[] npcs, boolean general, int currency) {
- this(title, items, general, currency, false);
- this.setNpcs(npcs);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param items the items.
- * @param general the general.
- */
- public Shop(String title, Item[] items, boolean general) {
- this(title, items, general, COINS, false);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param general the general.
- */
- public Shop(String title, boolean general) {
- this(title, GENERAL_STORE_ITEMS, general);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param general the general.
- * @param highAlch if highAlch.
- */
- public Shop(String title, boolean general, boolean highAlch) {
- this(title, GENERAL_STORE_ITEMS, general, COINS, highAlch);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param general the general.
- * @param highAlch if highAlch.
- */
- public Shop(String title, boolean general, int currency, boolean highAlch) {
- this(title, GENERAL_STORE_ITEMS, general, currency, highAlch);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param items the items.
- * @param npcs the npcs.
- * @param general the general.
- */
- public Shop(String title, Item[] items, int[] npcs, boolean general) {
- this(title, items, general, COINS, false);
- this.setNpcs(npcs);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param npcs the npcs.
- * @param general the general.
- */
- public Shop(String title, int[] npcs, boolean general) {
- this(title, GENERAL_STORE_ITEMS, npcs, general);
- this.setNpcs(npcs);
- }
-
- /**
- * Constructs a new {@code Shop} {@code Object}.
- *
- * @param title the title.
- * @param npcs the npcs.
- * @param general the general.
- * @param highAlch if highAlch.
- */
- public Shop(String title, int[] npcs, boolean general, boolean highAlch) {
- this(title, GENERAL_STORE_ITEMS, general, 995, highAlch);
- this.setNpcs(npcs);
- }
-
- /**
- * Method used to open the shop.
- *
- * @param player the shop.
- */
- public void open(final Player player) {
- ShopViewer.extend(player, this).open();
-
- // Browse the Lumbridge General Store
- if (getTitle().equalsIgnoreCase("Lumbridge General Store")) {
- player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 18);
- }
-
- // Browse through Oziach's Armour Shop
- if (getTitle().equalsIgnoreCase("Oziach's Armour")) {
- player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 20);
- }
- }
-
- public void give(Player player, final int slot, int amount, int tabIndex) {
- final Container container = getContainer(tabIndex);
- final Item item = container.get(slot);
- if (item == null) {
- return;
- }
- final Item add = new Item(item.getId(), amount);
- if (add.getAmount() < 1 || !player.getInventory().hasSpaceFor(add)) {
- player.getPacketDispatch().sendMessage("You have no inventory space at the moment and cannot get anything.");
- return;
- }
- add.setAmount(getAmount(player, add));
- if (add.getAmount() < 1 || !player.getInventory().hasSpaceFor(add)) {
- player.getPacketDispatch().sendMessage("You have no inventory space at the moment and cannot get anything.");
- return;
- }
- player.getInventory().add(add);
- update();
- }
-
- /**
- * Method used to buy an item from the shop.
- *
- * @param slot the slot.
- * @param amount the amount.
- */
- public void buy(Player player, final int slot, int amount, int tabIndex) {
- if (tabIndex == 1 && player.getIronmanManager().checkRestriction()) {
- return;
- }
- final Container container = getContainer(tabIndex);
- final Item item = container.get(slot);
- if (item == null) {
- return;
- }
- if (item.getAmount() == 0) {
- player.getPacketDispatch().sendMessage("There is no stock of that item at the moment.");
- return;
- }
- if (amount > item.getAmount() && !(item.getAmount() == -1)) {
- amount = item.getAmount();
- }
- final Item add = new Item(item.getId(), amount);
- if (player.getInventory().getMaximumAdd(add) < amount) {
- add.setAmount(player.getInventory().getMaximumAdd(add));
- }
- if (add.getAmount() < 1 || !player.getInventory().hasSpaceFor(add)) {
- player.getPacketDispatch().sendMessage("You have no inventory space at the moment and cannot buy anything.");
- return;
- }
- add.setAmount(getAmount(player, add));
- if (add.getAmount() < 1 || !player.getInventory().hasSpaceFor(add)) {
- player.getPacketDispatch().sendMessage("You have no inventory space at the moment and cannot buy anything.");
- return;
- }
- int price = add.getAmount() * getBuyPrice(item, player);
- final Item currency = new Item(getCurrency(), price);
- if (!canBuy(player, item, price, currency)) {
- return;
- }
- if (handleBuy(player, currency)) {
- if (pointShop) {
- decrementPoints(player, price);
- }
- if (tabIndex == 0) {
- if(!(container.getAmount(item) == -1))
- container.replace(new Item(item.getId(), container.getAmount(item) - add.getAmount()), slot, true);
- } else {
- container.remove(add);
- container.shift();
- }
-
- // Achievement Diary Handlers
- if (add.getId() == Items.BLACK_CHAINBODY_1107 && getTitle().equalsIgnoreCase("Wayne's Chains") && !player.getAttribute("diary:falador:black-chain-bought", false)) {
- player.setAttribute("/save:diary:falador:black-chain-bought", true);
- }
- if (add.getId() == 12622 && getTitle().equalsIgnoreCase("Sarah's Farming Shop")) {
- player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 0, 0);
- }
- if (add.getId() == Items.CANDLE_36 && getTitle().equalsIgnoreCase("Candle Shop")) {
- player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 0, 9);
- }
- if (getTitle().equalsIgnoreCase("Ranging Guild Ticket Exchange")) {
- player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 8);
- }
-
- player.getInventory().add(add);
- update();
- }
- }
-
- /**
- * Method used to sell an item to the shop.
- *
- * @param slot the slot.
- * @param amount the amount.
- */
- public void sell(Player player, final int slot, int amount, int tabIndex) {
- final Item item = player.getInventory().get(slot);
- if (item == null) {
- return;
- }
- final ItemDefinition def = ItemDefinition.forId(item.getId());
- if (!canSell(player, item, def)) {
- return;
- }
- final Container container = getContainer(item);
- if (amount > player.getInventory().getAmount(item)) {
- amount = player.getInventory().getAmount(item);
- }
- Item add = new Item(item.getId(), amount);
- if (add.getAmount() > container.getMaximumAdd(add)) {
- add.setAmount(container.getMaximumAdd(add));
- }
- player.debug("" + add.getAmount());
- if (!container.hasSpaceFor(add) || add.getAmount() < 1) {
- player.getPacketDispatch().sendMessage("The shop has ran out of space.");
- return;
- }
- final Item currency = new Item(getCurrency(), getSellingValue(add, player));
- if(item.getDefinition().isStackable()){
- if (!player.getInventory().hasSpaceFor(currency)) {
- player.getPacketDispatch().sendMessage("You don't have enough space for that many " + currency.getName().toLowerCase() + ".");
- return;
- }
- }
- player.debug("Selling item");
- if (player.getInventory().remove(add, slot, true)) {
- if (currency.getAmount() > player.getInventory().getMaximumAdd(currency)) {
- currency.setAmount(player.getInventory().getMaximumAdd(currency));
- }
- if (!add.getDefinition().isUnnoted()) {
- add = new Item(add.getNoteChange(), add.getAmount());
- }
- if (container.getAmount(add.getId()) == -1 || container.add(add)) {
- if (currency.getAmount() > 0) {
- player.debug("Adding coins to inventory");
- player.getInventory().add(currency);
- }
- final ShopViewer viewer = player.getExtension(ShopViewer.class);
- tabIndex = container == getContainers()[0] ? 0 : 1;
- sendStock(player, tabIndex);
- if (viewer != null) {
- viewer.setTabIndex(tabIndex);
- }
- update();
- }
- }
- }
-
- /**
- * Values an item.
- *
- * @param player the player.
- * @param viewer the viewer.
- * @param item the item.
- * @param sell the sell.
- */
- public void value(Player player, ShopViewer viewer, Item item, boolean sell) {
- if (sell) {
- if (pointShop || item.getId() == viewer.getShop().getCurrency() || !item.getDefinition().isTradeable() || !viewer.getShop().itemAllowed(item.getId())) {
- player.getPacketDispatch().sendMessage("You can't sell this item.");
- return;
- }
- final int value = viewer.getShop().getSellingValue(new Item(item.getId(), 1), player);
- String currency = pointShop ? getPointsName() : ItemDefinition.forId(viewer.getShop().getCurrency()).getName().toLowerCase();
- if (value == 1 && currency.charAt(currency.length() - 1) == 's') {
- currency = currency.substring(0, currency.length() - 1);
- }
- player.getPacketDispatch().sendMessage(item.getName() + ": shop will buy for " + value + " " + currency + ".");
- } else {
- int value = viewer.getShop().getBuyPrice(item, player);
- String name = pointShop ? getPointsName() + "s" : ItemDefinition.forId(viewer.getShop().getCurrency()).getName().toLowerCase();
- if (value == 1 && (name.charAt(name.length() - 1) == 's')) {
- name = name.substring(0, name.length() - 1);
- }
- player.getPacketDispatch().sendMessage("" + item.getName() + ": currently costs " + value + " " + name + ".");
- }
- }
-
- /**
- * Method used to send a stock
- *
- * @param player
- * @param tabIndex
- */
- public void sendStock(final Player player, int tabIndex) {
- final boolean main = tabIndex == 0;
- player.getPacketDispatch().sendInterfaceConfig(620, 23, !main);
- player.getPacketDispatch().sendInterfaceConfig(620, 24, main);
- player.getPacketDispatch().sendInterfaceConfig(620, 29, !main);
- player.getPacketDispatch().sendInterfaceConfig(620, 25, main);
- player.getPacketDispatch().sendInterfaceConfig(620, 27, main);
- player.getPacketDispatch().sendInterfaceConfig(620, 26, false);
- player.getPacketDispatch().sendAccessMask(1278, main ? 23 : 24, 620, 0, 40);
- }
-
- /**
- * Method used to update the viewers.
- */
- public void update() {
- for (ShopViewer viewer : viewers) {
- viewer.update();
- }
- }
-
- /**
- * Method used to restock the shop.
- */
- public void restock() {
- for (Container container : containers) {
- for (int i = 0; i < container.toArray().length; i++) {
- final boolean main = (container == containers[0]);
- final Item item = container.toArray()[i];
- if (item == null) {
- continue;
- }
- boolean reduce = !main;
- if (main) {
- if (item.getAmount() < items[i].getAmount()) {
- item.setAmount(item.getAmount() + 1);
- }
- reduce = item.getAmount() > items[i].getAmount();
- }
- if (reduce) {
- int amount = item.getAmount() - 1;
- if (amount < 1 && !main) {
- container.remove(item);
- } else {
- item.setAmount(amount);
- }
- if (!main) {
- container.shift();
- }
- }
- }
- }
- update();
- }
-
- /**
- * Checks if the player can sell an item to the shop.
- *
- * @param player the player.
- * @param item the item.
- * @param def the def.
- * @return {@code True} if so.
- */
- public boolean canSell(Player player, Item item, ItemDefinition def) {
- if (pointShop || item.getDefinition().hasDestroyAction() || !def.isTradeable() || !itemAllowed(item.getId())) {
- player.getPacketDispatch().sendMessage("You can't sell this item to this shop.");
- return false;
- }
- if (item.getId() == getCurrency()) {
- player.getPacketDispatch().sendMessage("You can't sell " + item.getName().toLowerCase() + " to a shop.");
- return false;
- }
- return true;
- }
-
- /**
- * Gets the amount to buy/sell.
- *
- * @param player the player.
- * @param add the added item.
- * @return the amount.
- */
- public int getAmount(Player player, Item add) {
- return add.getAmount();
- }
-
- /**
- * Checks if the player can buy the item.
- *
- * @param player the player.
- * @param currency the currency.
- * @return {@code True} if so.
- */
- public boolean handleBuy(Player player, Item currency) {
- return pointShop || player.getInventory().remove(currency);
- }
-
- /**
- * Checks if the player can buy from the shop.
- *
- * @param player the player.
- * @param item the item.
- * @param price the price.
- * @param currency the currency.
- * @return {@code True} if they can buy.
- */
- public boolean canBuy(Player player, Item item, int price, Item currency) {
- if (!pointShop && !player.getInventory().containsItem(currency)) {
- player.getPacketDispatch().sendMessage("You don't have enough " + ItemDefinition.forId(getCurrency()).getName().toLowerCase() + ".");
- return false;
- }
- if (pointShop && getPoints(player) < price) {
- player.sendMessage("You don't have enough " + getPointsName() + "s.");
- return false;
- }
- return true;
- }
-
- /**
- * Gets the points.
- *
- * @param player the player.
- * @return the points.
- */
- public int getPoints(Player player) {
- return 0;
- }
-
- /**
- * Decrements the points.
- *
- * @param player the player.
- * @param decrement the decrementation.
- */
- public void decrementPoints(Player player, int decrement) {
-
- }
-
- /**
- * Gets the points name.
- *
- * @return the name.
- */
- public String getPointsName() {
- return "";
- }
-
- /**
- * Gets the value gained for selling this item to a certain shop.
- *
- * @param item The item to sell.
- * @param player the player.
- * @return The value.
- */
- public int getSellingValue(Item item, Player player) {
- if (!item.getDefinition().isUnnoted()) {
- player.setAttribute("shop:originalId",item.getId());
- item = new Item(item.getNoteChange(), item.getAmount());
- }
- int amount = getContainer(1).getAmount(item);
- if (amount < 1) {
- amount = getContainer(0).getAmount(item);
- }
- int value = getSellValue(player, amount, item);
- return value;
- }
-
- /**
- * Gets the selling value formula based.
- *
- * @param amount the amount.
- * @param item the item.
- * @return the selling value.
- */
- private int getSellValue(Player player, int amount, Item item) {
- int id = player.getAttribute("shop:originalId",item.getId());
- if(item.getAmount() > ContentAPI.amountInInventory(player, id)){
- item.setAmount(ContentAPI.amountInInventory(player, id));
- player.removeAttribute("shop:originalId");
- }
- double diff = item.getDefinition().isStackable() ? 0.005 : 0.05;
- double maxMod = 1.0 - (amount * diff);
- if (maxMod < 0.25) {
- maxMod = 0.25;
- }
- double minMod = maxMod - ((item.getAmount() - 1) * diff);
- if (minMod < 0.25) {
- minMod = 0.25;
- }
- double mod = (maxMod + minMod) / 2;
- SystemLogger.logInfo("" + item.getDefinition().getAlchemyValue(highAlch) + " " + mod + " " + item.getAmount());
- int baseValue = item.getDefinition().getAlchemyValue(highAlch);
- int value = (int) (baseValue * mod * item.getAmount());
- if(getCurrency() == Items.TOKKUL_6529 && item.getId() == Items.CHAOS_RUNE_562) value = 13;
- if(getCurrency() == Items.TOKKUL_6529 && item.getId() == Items.DEATH_RUNE_560) value = 27;
- if(item.getId() == 12183){
- value = 25 * item.getAmount();
- }
- return value;
- }
-
- /**
- * Gets the buying price.
- *
- * @param item the item.
- * @return the price.
- */
- public int getBuyPrice(Item item, Player player) {
- item = new Item(item.getId(), 1);
- int price = item.getDefinition().getMaxValue();
- int sellVal = getSellingValue(item, player);
- if (price < sellVal) {
- price = getSellValue(player, 0, item) + sellVal - (sellVal - item.getDefinition().getMaxValue());
- }
- if (price < 0) {
- price = 1;
- }
- if (getCurrency() == TOKKUL) {
- int tokkul = item.getDefinition().getConfiguration("tokkul_price", -1);
- if (tokkul > 0) {
- price = tokkul;
- }
- if (player.getAchievementDiaryManager().getKaramjaGlove() != -1) {
- price *= 0.86666666667;
- }
- }
- if (getCurrency() == ARCHERY_TICKET) {
- int tickets = item.getDefinition().getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE,-1);
- if (tickets > 0) {
- price = tickets;
- }
- }
- return (getSellAllFor() > 0 ? getSellAllFor() : price);
- }
-
- /**
- * Checks if the item is allowed to be sold to the shop.
- *
- * @param itemId the item id.
- * @return {@code True} if so.
- */
- public boolean itemAllowed(int itemId) {
- if (general) {
- return true;
- }
- int noteId = ItemDefinition.forId(itemId).getNoteId();
- if (!ItemDefinition.forId(itemId).isUnnoted()) {
- noteId = ItemDefinition.forId(noteId).getNoteId();
- }
- for (Item id : items) {
- if (itemId == id.getId() || (noteId > -1 && noteId == ItemDefinition.forId(id.getId()).getNoteId())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the container the item should go to.
- *
- * @param item the item.
- * @return the container.
- */
- public Container getContainer(Item item) {
- int itemId = item.getId();
- int noteId = ItemDefinition.forId(itemId).getNoteId();
- if (!ItemDefinition.forId(itemId).isUnnoted()) {
- noteId = ItemDefinition.forId(noteId).getNoteId();
- }
- for (Item i : items) {
- if (i.getId() == item.getId() || (noteId > -1 && noteId == ItemDefinition.forId(i.getId()).getNoteId())) {
- return getContainer(0);
- }
- }
- return getContainer(1);
- }
-
- /**
- * Creates a copy of this shop.
- *
- * @return the shop.
- */
- public Shop copy() {
- return new Shop(title, items, general, currency, highAlch);
- }
-
- /**
- * Gets the container on the slot.
- *
- * @param tabIndex the tab index.
- * @return the container.
- */
- public Container getContainer(int tabIndex) {
- if (tabIndex > containers.length) {
- throw new IndexOutOfBoundsException("Error! Shop tab index out of bounds.");
- }
- return containers[tabIndex];
- }
-
- /**
- * Gets the viewers.
- *
- * @return The viewers.
- */
- public List getViewers() {
- return viewers;
- }
-
- /**
- * Gets the title.
- *
- * @return The title.
- */
- public String getTitle() {
- return title;
- }
-
- /**
- * Gets the items.
- *
- * @return The items.
- */
- public Item[] getItems() {
- return items;
- }
-
- /**
- * Sets the items.
- *
- * @return true if the items were changed.
- */
- public boolean setItems(Item... item) {
- return items == item;
- }
-
- /**
- * Gets the general.
- *
- * @return The general.
- */
- public boolean isGeneral() {
- return general;
- }
-
- /**
- * Gets the currency.
- *
- * @return The currency.
- */
- public int getCurrency() {
- return currency;
- }
-
- /**
- * Gets the containers.
- *
- * @return The containers.
- */
- public Container[] getContainers() {
- return containers;
- }
-
- /**
- * Gets the bhighAlch.
- *
- * @return the highAlch
- */
- public boolean isHighAlch() {
- return highAlch;
- }
-
- @Override
- public String toString() {
- return "Shop [containers=" + Arrays.toString(containers) + ", viewers=" + viewers + ", title=" + title + ", items=" + Arrays.toString(items) + ", general=" + general + ", currency=" + currency + ", highAlch=" + highAlch + "]";
- }
-
- /**
- * Gets the lastRestock.
- *
- * @return the lastRestock
- */
- public int getLastRestock() {
- return lastRestock;
- }
-
- /**
- * Sets the balastRestock.
- *
- * @param lastRestock the lastRestock to set.
- */
- public void setLastRestock(int lastRestock) {
- this.lastRestock = lastRestock;
- }
-
- /**
- * Gets the npcs.
- *
- * @return the npcs
- */
- public int[] getNpcs() {
- return npcs;
- }
-
- /**
- * Sets the banpcs.
- *
- * @param npcs the npcs to set.
- */
- public void setNpcs(int[] npcs) {
- this.npcs = npcs;
- }
-
- /**
- * Gets the pointShop.
- *
- * @return the pointShop
- */
- public boolean isPointShop() {
- return pointShop;
- }
-
- /**
- * Sets the pointShop.
- *
- * @param pointShop the pointShop to set.
- */
- public void setPointShop(boolean pointShop) {
- this.pointShop = pointShop;
- }
-
- /**
- * Check if shop should restock.
- *
- * @return the restock
- */
- public boolean isRestock() {
- return restock;
- }
-
- /**
- * Sets the restock.
- *
- * @param reStock
- */
- public void setRestock(boolean reStock) {
- restock = reStock;
- }
-
-
- /**
- * Gets the SellAllFor value.
- *
- * @return the sellAllFor
- */
- public int getSellAllFor() {
- return sellAllFor;
- }
-
- public void setItems(ArrayList- items){
- this.items = items.toArray(new Item[0]);
- }
-
-}
\ No newline at end of file
diff --git a/Server/src/main/java/core/game/content/global/shop/Shop.kt b/Server/src/main/java/core/game/content/global/shop/Shop.kt
new file mode 100644
index 000000000..1ae9e865e
--- /dev/null
+++ b/Server/src/main/java/core/game/content/global/shop/Shop.kt
@@ -0,0 +1,865 @@
+package core.game.content.global.shop
+
+import rs09.game.world.GameWorld.ticks
+import api.ContentAPI.amountInInventory
+import rs09.game.system.SystemLogger.logInfo
+import core.game.node.entity.player.link.diary.DiaryType
+import core.cache.def.impl.ItemDefinition
+import core.game.container.Container
+import core.game.container.ContainerType
+import core.game.node.entity.player.Player
+import core.game.node.item.Item
+import org.rs09.consts.Items.BLACK_CHAINBODY_1107
+import org.rs09.consts.Items.BOWL_1923
+import org.rs09.consts.Items.BUCKET_1925
+import org.rs09.consts.Items.CAKE_TIN_1887
+import org.rs09.consts.Items.CANDLE_36
+import org.rs09.consts.Items.CHAOS_RUNE_562
+import org.rs09.consts.Items.CHISEL_1755
+import org.rs09.consts.Items.DEATH_RUNE_560
+import org.rs09.consts.Items.EMPTY_POT_1931
+import org.rs09.consts.Items.HAMMER_2347
+import org.rs09.consts.Items.JUG_1935
+import org.rs09.consts.Items.NEWCOMER_MAP_550
+import org.rs09.consts.Items.SECURITY_BOOK_9003
+import org.rs09.consts.Items.SHEARS_1735
+import org.rs09.consts.Items.TINDERBOX_590
+import org.rs09.consts.Items.TOKKUL_6529
+import rs09.game.system.config.ItemConfigParser
+import java.lang.IndexOutOfBoundsException
+import java.util.Arrays
+import java.util.ArrayList
+
+/**
+ * A class representing a shop.
+ *
+ * @author 'Vexia
+ * @author Jamix77
+ */
+open class Shop @JvmOverloads constructor(
+ /**
+ * Represents the title of the shop.
+ */
+ val title: String,
+ /**
+ * Represents the items in the store.
+ */
+ var items: Array
- ,
+ /**
+ * Represents if it's a general store.
+ */
+ val isGeneral: Boolean,
+ /**
+ * Represents the currency the shop allows.
+ */
+ val currency: Int = COINS,
+ /**
+ * If the shop buys for high alch.
+ */
+ val isHighAlch: Boolean = false
+) {
+ /**
+ * Gets the containers.
+ *
+ * @return The containers.
+ */
+ /**
+ * Represents the shop containers.
+ */
+ val containers = arrayOf(Container(40, ContainerType.SHOP), Container(40, ContainerType.SHOP))
+ /**
+ * Gets the viewers.
+ *
+ * @return The viewers.
+ */
+ /**
+ * Represents the list of shop viewers.
+ */
+ val viewers: List = ArrayList(20)
+ /**
+ * Gets the title.
+ *
+ * @return The title.
+ */
+ /**
+ * Gets the items.
+ *
+ * @return The items.
+ */
+ /**
+ * Gets the general.
+ *
+ * @return The general.
+ */
+ /**
+ * Gets the currency.
+ *
+ * @return The currency.
+ */
+ /**
+ * Gets the bhighAlch.
+ *
+ * @return the highAlch
+ */
+ /**
+ * Gets the SellAllFor value.
+ *
+ * @return the sellAllFor
+ */
+ /**
+ * Sell price for all shop items, if needed.
+ */
+ var sellAllFor = 0
+ private set
+ /**
+ * Gets the lastRestock.
+ *
+ * @return the lastRestock
+ */
+ /**
+ * Sets the balastRestock.
+ *
+ * @param lastRestock the lastRestock to set.
+ */
+ /**
+ * The last restock.
+ */
+ var lastRestock = 0
+ /**
+ * Check if shop should restock.
+ *
+ * @return the restock
+ */
+ /**
+ * Sets the restock.
+ *
+ * @param reStock
+ */
+ /**
+ * If the shop should restock.
+ */
+ var isRestock = false
+ /**
+ * Gets the pointShop.
+ *
+ * @return the pointShop
+ */
+ /**
+ * Sets the pointShop.
+ *
+ * @param pointShop the pointShop to set.
+ */
+ /**
+ * If it's a point shop.
+ */
+ var isPointShop = false
+ /**
+ * Gets the npcs.
+ *
+ * @return the npcs
+ */
+ /**
+ * Sets the banpcs.
+ *
+ * @param npcs the npcs to set.
+ */
+ /**
+ * The npcs of the shop.
+ */
+ var npcs: IntArray = intArrayOf()
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param items the items.
+ * @param general the general.
+ * @param currency the currency.
+ * @param highAlch if high alch.
+ * @param restock if restock.
+ */
+ constructor(
+ title: String,
+ items: Array
- ,
+ general: Boolean,
+ currency: Int,
+ highAlch: Boolean,
+ restock: Boolean,
+ sellAllFor: Int
+ ) : this(title, items, general, currency, highAlch) {
+ this.sellAllFor = sellAllFor
+ isRestock = restock
+ }
+
+ /**
+ * Constructs a new `Shop` `Object`
+ *
+ * @param title the shop title
+ * @param items items the shop can handle
+ * @param general is this a general store
+ * @param currency what currency is used
+ */
+ constructor(title: String, items: Array
- , npcs: IntArray, general: Boolean, currency: Int) : this(
+ title,
+ items,
+ general,
+ currency,
+ false
+ ) {
+ this.npcs = npcs
+ }
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param general the general.
+ */
+ constructor(title: String, general: Boolean) : this(title, GENERAL_STORE_ITEMS, general) {}
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param general the general.
+ * @param highAlch if highAlch.
+ */
+ constructor(title: String, general: Boolean, highAlch: Boolean) : this(
+ title,
+ GENERAL_STORE_ITEMS,
+ general,
+ COINS,
+ highAlch
+ ) {
+ }
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param general the general.
+ * @param highAlch if highAlch.
+ */
+ constructor(title: String, general: Boolean, currency: Int, highAlch: Boolean) : this(
+ title,
+ GENERAL_STORE_ITEMS,
+ general,
+ currency,
+ highAlch
+ ) {
+ }
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param items the items.
+ * @param npcs the npcs.
+ * @param general the general.
+ */
+ constructor(title: String, items: Array
- , npcs: IntArray, general: Boolean) : this(
+ title,
+ items,
+ general,
+ COINS,
+ false
+ ) {
+ this.npcs = npcs
+ }
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param npcs the npcs.
+ * @param general the general.
+ */
+ constructor(title: String, npcs: IntArray, general: Boolean) : this(title, GENERAL_STORE_ITEMS, npcs, general) {
+ this.npcs = npcs
+ }
+
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param npcs the npcs.
+ * @param general the general.
+ * @param highAlch if highAlch.
+ */
+ constructor(title: String, npcs: IntArray, general: Boolean, highAlch: Boolean) : this(
+ title,
+ GENERAL_STORE_ITEMS,
+ general,
+ 995,
+ highAlch
+ ) {
+ this.npcs = npcs
+ }
+
+ /**
+ * Method used to open the shop.
+ *
+ * @param player the shop.
+ */
+ fun open(player: Player) {
+ ShopViewer.extend(player, this).open()
+
+ // Browse the Lumbridge General Store
+ if (title.equals("Lumbridge General Store", ignoreCase = true)) {
+ player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 18)
+ }
+
+ // Browse through Oziach's Armour Shop
+ if (title.equals("Oziach's Armour", ignoreCase = true)) {
+ player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 20)
+ }
+ }
+
+ fun give(player: Player, slot: Int, amount: Int, tabIndex: Int) {
+ val container = getContainer(tabIndex)
+ val item = container[slot] ?: return
+ val add = Item(item.id, amount)
+ if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) {
+ player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot get anything.")
+ return
+ }
+ add.amount = getAmount(player, add)
+ if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) {
+ player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot get anything.")
+ return
+ }
+ player.inventory.add(add)
+ update()
+ }
+
+ /**
+ * Method used to buy an item from the shop.
+ *
+ * @param slot the slot.
+ * @param amount the amount.
+ */
+ fun buy(player: Player, slot: Int, amount: Int, tabIndex: Int) {
+ var amount = amount
+ if (tabIndex == 1 && player.ironmanManager.checkRestriction()) {
+ return
+ }
+ val container = getContainer(tabIndex)
+ val item = container[slot] ?: return
+ if (item.amount == 0) {
+ player.packetDispatch.sendMessage("There is no stock of that item at the moment.")
+ return
+ }
+ if (amount > item.amount && item.amount != -1) {
+ amount = item.amount
+ }
+ val add = Item(item.id, amount)
+ if (player.inventory.getMaximumAdd(add) < amount) {
+ add.amount = player.inventory.getMaximumAdd(add)
+ }
+ if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) {
+ player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot buy anything.")
+ return
+ }
+ add.amount = getAmount(player, add)
+ if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) {
+ player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot buy anything.")
+ return
+ }
+ val price = add.amount * getBuyPrice(item, player)
+ val currency = Item(currency, price)
+ if (!canBuy(player, item, price, currency)) {
+ return
+ }
+ if (handleBuy(player, currency)) {
+ if (isPointShop) {
+ decrementPoints(player, price)
+ }
+ if (tabIndex == 0) {
+ if (container.getAmount(item) != -1) container.replace(
+ Item(
+ item.id,
+ container.getAmount(item) - add.amount
+ ), slot, true
+ )
+ } else {
+ container.remove(add)
+ container.shift()
+ }
+
+ // Achievement Diary Handlers
+ if (add.id == BLACK_CHAINBODY_1107 && title.equals("Wayne's Chains", ignoreCase = true) && !player.getAttribute("diary:falador:black-chain-bought", false)) {
+ player.setAttribute("/save:diary:falador:black-chain-bought", true)
+ }
+ if (add.id == 12622 && title.equals("Sarah's Farming Shop", ignoreCase = true)) {
+ player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 0, 0)
+ }
+ if (add.id == CANDLE_36 && title.equals("Candle Shop", ignoreCase = true)) {
+ player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 9)
+ }
+ if (title.equals("Ranging Guild Ticket Exchange", ignoreCase = true)) {
+ player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 1, 8)
+ }
+ player.inventory.add(add)
+ update()
+ }
+ }
+
+ /**
+ * Method used to sell an item to the shop.
+ *
+ * @param slot the slot.
+ * @param amount the amount.
+ */
+ fun sell(player: Player, slot: Int, amount: Int, tabIndex: Int) {
+ var amount = amount
+ var tabIndex = tabIndex
+ val item = player.inventory[slot] ?: return
+ val def = ItemDefinition.forId(item.id)
+ if (!canSell(player, item, def)) {
+ return
+ }
+ val container = getContainer(item)
+ if (amount > player.inventory.getAmount(item)) {
+ amount = player.inventory.getAmount(item)
+ }
+ var add = Item(item.id, amount)
+ if (add.amount > container.getMaximumAdd(add)) {
+ add.amount = container.getMaximumAdd(add)
+ }
+ player.debug("" + add.amount)
+ if (!container.hasSpaceFor(add) || add.amount < 1) {
+ player.packetDispatch.sendMessage("The shop has ran out of space.")
+ return
+ }
+ val currency = Item(currency, getSellingValue(add, player))
+ if (item.definition.isStackable) {
+ if (!player.inventory.hasSpaceFor(currency)) {
+ player.packetDispatch.sendMessage("You don't have enough space for that many " + currency.name.toLowerCase() + ".")
+ return
+ }
+ }
+ player.debug("Selling item")
+ if (player.inventory.remove(add, slot, true)) {
+ if (currency.amount > player.inventory.getMaximumAdd(currency)) {
+ currency.amount = player.inventory.getMaximumAdd(currency)
+ }
+ if (!add.definition.isUnnoted) {
+ add = Item(add.noteChange, add.amount)
+ }
+ if (container.getAmount(add.id) == -1 || container.add(add)) {
+ if (currency.amount > 0) {
+ player.debug("Adding coins to inventory")
+ player.inventory.add(currency)
+ }
+ val viewer = player.getExtension(ShopViewer::class.java)
+ tabIndex = if (container === containers[0]) 0 else 1
+ sendStock(player, tabIndex)
+ if (viewer != null) {
+ viewer.tabIndex = tabIndex
+ }
+ update()
+ }
+ }
+ }
+
+ /**
+ * Values an item.
+ *
+ * @param player the player.
+ * @param viewer the viewer.
+ * @param item the item.
+ * @param sell the sell.
+ */
+ fun value(player: Player, viewer: ShopViewer, item: Item, sell: Boolean) {
+ if (sell) {
+ if (isPointShop || item.id == viewer.shop.currency || !item.definition.isTradeable || !viewer.shop.itemAllowed(
+ item.id
+ )
+ ) {
+ player.packetDispatch.sendMessage("You can't sell this item.")
+ return
+ }
+ val value = viewer.shop.getSellingValue(Item(item.id, 1), player)
+ var currency =
+ if (isPointShop) pointsName else ItemDefinition.forId(viewer.shop.currency).name.toLowerCase()
+ if (value == 1 && currency[currency.length - 1] == 's') {
+ currency = currency.substring(0, currency.length - 1)
+ }
+ player.packetDispatch.sendMessage(item.name + ": shop will buy for " + value + " " + currency + ".")
+ } else {
+ val value = viewer.shop.getBuyPrice(item, player)
+ var name =
+ if (isPointShop) pointsName + "s" else ItemDefinition.forId(viewer.shop.currency).name.toLowerCase()
+ if (value == 1 && name[name.length - 1] == 's') {
+ name = name.substring(0, name.length - 1)
+ }
+ player.packetDispatch.sendMessage("" + item.name + ": currently costs " + value + " " + name + ".")
+ }
+ }
+
+ /**
+ * Method used to send a stock
+ *
+ * @param player
+ * @param tabIndex
+ */
+ fun sendStock(player: Player, tabIndex: Int) {
+ val main = tabIndex == 0
+ player.packetDispatch.sendInterfaceConfig(620, 23, !main)
+ player.packetDispatch.sendInterfaceConfig(620, 24, main)
+ player.packetDispatch.sendInterfaceConfig(620, 29, !main)
+ player.packetDispatch.sendInterfaceConfig(620, 25, main)
+ player.packetDispatch.sendInterfaceConfig(620, 27, main)
+ player.packetDispatch.sendInterfaceConfig(620, 26, false)
+ player.packetDispatch.sendAccessMask(1278, if (main) 23 else 24, 620, 0, 40)
+ }
+
+ /**
+ * Method used to update the viewers.
+ */
+ fun update() {
+ for (viewer in viewers) {
+ viewer.update()
+ }
+ }
+
+ /**
+ * Method used to restock the shop.
+ */
+ fun restock() {
+ for (container in containers) {
+ for (i in container.toArray().indices) {
+ val main = container === containers[0]
+ val item = container.toArray()[i] ?: continue
+ var reduce = !main
+ if (main) {
+ if (item.amount < items[i].amount) {
+ item.amount = item.amount + 1
+ }
+ reduce = item.amount > items[i].amount
+ }
+ if (reduce) {
+ val amount = item.amount - 1
+ if (amount < 1 && !main) {
+ container.remove(item)
+ } else {
+ item.amount = amount
+ }
+ if (!main) {
+ container.shift()
+ }
+ }
+ }
+ }
+ update()
+ }
+
+ /**
+ * Checks if the player can sell an item to the shop.
+ *
+ * @param player the player.
+ * @param item the item.
+ * @param def the def.
+ * @return `True` if so.
+ */
+ open fun canSell(player: Player, item: Item, def: ItemDefinition): Boolean {
+ if (isPointShop || item.definition.hasDestroyAction() || !def.isTradeable || !itemAllowed(item.id)) {
+ player.packetDispatch.sendMessage("You can't sell this item to this shop.")
+ return false
+ }
+ if (item.id == currency) {
+ player.packetDispatch.sendMessage("You can't sell " + item.name.toLowerCase() + " to a shop.")
+ return false
+ }
+ return true
+ }
+
+ /**
+ * Gets the amount to buy/sell.
+ *
+ * @param player the player.
+ * @param add the added item.
+ * @return the amount.
+ */
+ fun getAmount(player: Player?, add: Item): Int {
+ return add.amount
+ }
+
+ /**
+ * Checks if the player can buy the item.
+ *
+ * @param player the player.
+ * @param currency the currency.
+ * @return `True` if so.
+ */
+ fun handleBuy(player: Player, currency: Item?): Boolean {
+ return isPointShop || player.inventory.remove(currency)
+ }
+
+ /**
+ * Checks if the player can buy from the shop.
+ *
+ * @param player the player.
+ * @param item the item.
+ * @param price the price.
+ * @param currency the currency.
+ * @return `True` if they can buy.
+ */
+ fun canBuy(player: Player, item: Item, price: Int, currency: Item): Boolean {
+ if (!isPointShop && !player.inventory.containsItem(currency)) {
+ player.packetDispatch.sendMessage(
+ "You don't have enough " + ItemDefinition.forId(currency.id).name.toLowerCase() + "."
+ )
+ return false
+ }
+ if (isPointShop && getPoints(player) < price) {
+ player.sendMessage("You don't have enough " + pointsName + "s.")
+ return false
+ }
+ return true
+ }
+
+ /**
+ * Gets the points.
+ *
+ * @param player the player.
+ * @return the points.
+ */
+ fun getPoints(player: Player?): Int {
+ return 0
+ }
+
+ /**
+ * Decrements the points.
+ *
+ * @param player the player.
+ * @param decrement the decrementation.
+ */
+ fun decrementPoints(player: Player?, decrement: Int) {}
+
+ /**
+ * Gets the points name.
+ *
+ * @return the name.
+ */
+ val pointsName: String
+ get() = ""
+
+ /**
+ * Gets the value gained for selling this item to a certain shop.
+ *
+ * @param item The item to sell.
+ * @param player the player.
+ * @return The value.
+ */
+ fun getSellingValue(item: Item, player: Player): Int {
+ var item = item
+ if (!item.definition.isUnnoted) {
+ player.setAttribute("shop:originalId", item.id)
+ item = Item(item.noteChange, item.amount)
+ }
+ var amount = getContainer(1).getAmount(item)
+ if (amount < 1) {
+ amount = getContainer(0).getAmount(item)
+ }
+ return getSellingValue(player, amount, item)
+ }
+
+ /**
+ * Gets the selling value formula based.
+ *
+ * @param amount the amount.
+ * @param item the item.
+ * @return the selling value.
+ */
+ private fun getSellingValue(player: Player, amount: Int, item: Item): Int {
+ val id = player.getAttribute("shop:originalId", item.id)
+ if (item.amount > amountInInventory(player, id)) {
+ item.amount = amountInInventory(player, id)
+ player.removeAttribute("shop:originalId")
+ }
+ val diff = if (item.definition.isStackable) 0.005 else 0.05
+ var maxMod = 1.0 - amount * diff
+ if (maxMod < 0.25) {
+ maxMod = 0.25
+ }
+ var minMod = maxMod - (item.amount - 1) * diff
+ if (minMod < 0.25) {
+ minMod = 0.25
+ }
+ val mod = (maxMod + minMod) / 2
+ logInfo("" + item.definition.getAlchemyValue(isHighAlch) + " " + mod + " " + item.amount)
+ val baseValue = item.definition.getAlchemyValue(isHighAlch)
+ var value = (baseValue * mod * item.amount).toInt()
+ if (currency == TOKKUL_6529 && item.id == CHAOS_RUNE_562) value = 13 * item.amount
+ if (currency == TOKKUL_6529 && item.id == DEATH_RUNE_560) value = 27 * item.amount
+ if (item.id == 12183) {
+ value = 25 * item.amount
+ }
+ return value
+ }
+
+ /**
+ * Gets the buying price.
+ *
+ * @param item the item.
+ * @return the price.
+ */
+ open fun getBuyPrice(item: Item, player: Player): Int {
+ var item = item
+ item = Item(item.id, 1)
+ var price = item.definition.maxValue
+ val sellVal = getSellingValue(item, player)
+ if (price < sellVal) {
+ price = getSellingValue(player, 0, item) + sellVal - (sellVal - item.definition.maxValue)
+ }
+ if (price < 0) {
+ price = 1
+ }
+ if (currency == TOKKUL) {
+ val tokkul = item.definition.getConfiguration("tokkul_price", -1)
+ if (tokkul > 0) {
+ price = tokkul
+ }
+ if (player.achievementDiaryManager.karamjaGlove != -1) {
+ price = kotlin.math.floor(price * 0.87).toInt()
+ }
+ }
+ if (currency == ARCHERY_TICKET) {
+ val tickets = item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, -1)
+ if (tickets > 0) {
+ price = tickets
+ }
+ }
+ return if (sellAllFor > 0) sellAllFor else price
+ }
+
+ /**
+ * Checks if the item is allowed to be sold to the shop.
+ *
+ * @param itemId the item id.
+ * @return `True` if so.
+ */
+ fun itemAllowed(itemId: Int): Boolean {
+ if (isGeneral) {
+ return true
+ }
+ var noteId = ItemDefinition.forId(itemId).noteId
+ if (!ItemDefinition.forId(itemId).isUnnoted) {
+ noteId = ItemDefinition.forId(noteId).noteId
+ }
+ for (id in items) {
+ if (itemId == id.id || noteId > -1 && noteId == ItemDefinition.forId(id.id).noteId) {
+ return true
+ }
+ }
+ return false
+ }
+
+ /**
+ * Gets the container the item should go to.
+ *
+ * @param item the item.
+ * @return the container.
+ */
+ fun getContainer(item: Item): Container {
+ val itemId = item.id
+ var noteId = ItemDefinition.forId(itemId).noteId
+ if (!ItemDefinition.forId(itemId).isUnnoted) {
+ noteId = ItemDefinition.forId(noteId).noteId
+ }
+ for (i in items) {
+ if (i.id == item.id || noteId > -1 && noteId == ItemDefinition.forId(i.id).noteId) {
+ return getContainer(0)
+ }
+ }
+ return getContainer(1)
+ }
+
+ /**
+ * Creates a copy of this shop.
+ *
+ * @return the shop.
+ */
+ fun copy(): Shop {
+ return Shop(title, items, isGeneral, currency, isHighAlch)
+ }
+
+ /**
+ * Gets the container on the slot.
+ *
+ * @param tabIndex the tab index.
+ * @return the container.
+ */
+ fun getContainer(tabIndex: Int): Container {
+ if (tabIndex > containers.size) {
+ throw IndexOutOfBoundsException("Error! Shop tab index out of bounds.")
+ }
+ return containers[tabIndex]
+ }
+
+ override fun toString(): String {
+ return "Shop [containers=" + Arrays.toString(containers) + ", viewers=" + viewers + ", title=" + title + ", items=" + Arrays.toString(
+ items
+ ) + ", general=" + isGeneral + ", currency=" + currency + ", highAlch=" + isHighAlch + "]"
+ }
+
+ fun setItems(items: ArrayList
- ) {
+ this.items = items.toTypedArray()
+ }
+
+ companion object {
+ /**
+ * Represents the general store items.
+ */
+ val GENERAL_STORE_ITEMS = arrayOf(
+ Item(EMPTY_POT_1931, 5),
+ Item(JUG_1935, 5),
+ Item(SHEARS_1735, 2),
+ Item(BUCKET_1925, 3),
+ Item(BOWL_1923, 2),
+ Item(CAKE_TIN_1887, 2),
+ Item(TINDERBOX_590, 2),
+ Item(CHISEL_1755, 2),
+ Item(HAMMER_2347, 5),
+ Item(NEWCOMER_MAP_550, 5),
+ Item(SECURITY_BOOK_9003, 5)
+ )
+
+ /**
+ * Represents the coins item.
+ */
+ private const val COINS = 995
+
+ /**
+ * Represents the tokkul item id.
+ */
+ private const val TOKKUL = 6529
+
+ /**
+ * Represents the archery ticket item id
+ */
+ private const val ARCHERY_TICKET = 1464
+ }
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param items the items.
+ * @param isGeneral the general.
+ * @param currency the currency.
+ * @param isHighAlch if high alch.
+ */
+ /**
+ * Constructs a new `Shop` `Object`.
+ *
+ * @param title the title.
+ * @param items the items.
+ * @param general the general.
+ */
+ init {
+ this.getContainer(0).add(*items)
+ isRestock = true
+ lastRestock = ticks + 100
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/java/core/game/content/zone/ChaosTunnelZone.java b/Server/src/main/java/core/game/content/zone/ChaosTunnelZone.java
index a3d4a3cb5..409ced2bb 100644
--- a/Server/src/main/java/core/game/content/zone/ChaosTunnelZone.java
+++ b/Server/src/main/java/core/game/content/zone/ChaosTunnelZone.java
@@ -13,6 +13,8 @@ import core.game.node.entity.Entity;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.object.Scenery;
+import org.json.simple.JSONObject;
+import rs09.ServerStore;
import rs09.game.world.GameWorld;
import core.game.world.map.Location;
import core.game.world.map.zone.MapZone;
@@ -261,13 +263,13 @@ public final class ChaosTunnelZone extends MapZone implements Plugin