Merge remote-tracking branch 'upstream/master'

This commit is contained in:
skelsoft 2021-08-12 07:01:57 +10:00
commit d2b3e9251a
79 changed files with 1639 additions and 1999 deletions

View file

@ -20,7 +20,7 @@ public final class AudioHandler {
try { try {
if (-1 == var1 && !musicEffectPlaying) { if (-1 == var1 && !musicEffectPlaying) {
GameObject.method1870(); 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); method2099(var1, CacheIndex.musicIndex, musicVolume);
} }
currentTrack = var1; 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) { if (0 != musicVolume && currentTrack != -1) {
Class70.method1285(CacheIndex.musicIndex, currentTrack, musicVolume); Class70.method1285(CacheIndex.musicIndex, currentTrack, musicVolume);
} }
musicEffectPlaying = false; 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.putOpcode(137);
TextureOperation12.outgoingBuffer.writeInt(currentTrack); TextureOperation12.outgoingBuffer.writeInt(currentTrack);
currentTrack = -1; currentTrack = -1;

View file

@ -27,7 +27,6 @@ public final class CS2Script extends Linkable {
static int anInt3775 = 0; static int anInt3775 = 0;
static int anInt2440 = 0; static int anInt2440 = 0;
static ReferenceCache aReferenceCache_2442 = new ReferenceCache(50); static ReferenceCache aReferenceCache_2442 = new ReferenceCache(50);
static ReferenceCache aReferenceCache_2450 = new ReferenceCache(64);
static byte[][][] aByteArrayArrayArray2452; static byte[][][] aByteArrayArrayArray2452;
RSInterface aClass11_2438; RSInterface aClass11_2438;
RSString aClass94_2439; 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() { static void method379() {
try { try {
int var2 = Class146.anInt1904 * 128 - -64; int var2 = Class146.anInt1904 * 128 - -64;

View file

@ -1,14 +1,16 @@
package org.runite.client; package org.runite.client;
import org.rs09.SystemLogger;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
final class Class79 { final class CSConfigCachefile {
static int anInt1124 = -1; static int anInt1124 = -1;
static int anInt1127 = 0; static int anInt1127 = 0;
int anInt1123; int lowerBound;
int anInt1125; int upperBound;
int anInt1128; int parentVarpIndex;
static void method1385(int var0, int var1) { 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 { try {
while (true) { CSConfigCachefile cacheFile = (CSConfigCachefile) VarpHelpers.varbitLookup.get(varbitID);
int var3 = var1.readUnsignedByte(); if (cacheFile == null) {
if (var3 == 0) { byte[] fileData = Class101.csConfigFileRAM.getFile(varbitID >>> 10, varbitID & 1023);
return; 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) { } 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 { try {
if (1 == var3) { boolean end = fileData.readUnsignedByte() == 0;
this.anInt1128 = var1.readUnsignedShort(); while (!end) {
this.anInt1123 = var1.readUnsignedByte(); this.parseConfigFile(fileData);
this.anInt1125 = var1.readUnsignedByte(); 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) { } catch (RuntimeException var5) {
throw ClientErrorException.clientError(var5, "kk.B(" + (var1 != null ? "{...}" : "null") + ',' + 1 + ',' + var3 + ')'); throw ClientErrorException.clientError(var5, "kk.B(" + (fileData != null ? "{...}" : "null") + ',' + 1 + ')');
} }
} }

View file

@ -2,7 +2,7 @@ package org.runite.client;
final class Class101 { final class Class101 {
static CacheIndex aClass153_1420; static CacheIndex csConfigFileRAM;
static Class3_Sub24_Sub4 aClass3_Sub24_Sub4_1421; static Class3_Sub24_Sub4 aClass3_Sub24_Sub4_1421;
static Class30 aClass30_1422; static Class30 aClass30_1422;
static CacheIndex aClass153_1423; static CacheIndex aClass153_1423;
@ -65,7 +65,7 @@ final class Class101 {
method1607(46, 78, true, null, null); method1607(46, 78, true, null, null);
} }
aClass153_1420 = null; csConfigFileRAM = null;
} catch (RuntimeException var2) { } catch (RuntimeException var2) {
throw ClientErrorException.clientError(var2, "nj.A(" + var0 + ')'); throw ClientErrorException.clientError(var2, "nj.A(" + var0 + ')');
} }

View file

@ -34,7 +34,7 @@ final class Class107 {
static void method1648(CacheIndex var0) { static void method1648(CacheIndex var0) {
try { try {
Class101.aClass153_1420 = var0; Class101.csConfigFileRAM = var0;
} catch (RuntimeException var3) { } catch (RuntimeException var3) {
throw ClientErrorException.clientError(var3, "og.B(" + (var0 != null ? "{...}" : "null") + ',' + 255 + ')'); throw ClientErrorException.clientError(var3, "og.B(" + (var0 != null ? "{...}" : "null") + ',' + 255 + ')');

View file

@ -51,7 +51,7 @@ final class Class108 {
int var2 = Class140_Sub7.canvasHeight; int var2 = Class140_Sub7.canvasHeight;
int var3 = var2 * 956 / 503; int var3 = var2 * 956 / 503;
Objects.requireNonNull(Class40.aAbstractSprite_680).method639((Class23.canvasWidth + -var3) / 2, 0, var3, var2); 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); Objects.requireNonNull(SequenceDefinition.aClass109_1856).method1667(Class23.canvasWidth / 2 + -(SequenceDefinition.aClass109_1856.width / 2), 18);
Class140_Sub2.aBoolean2713 = true; Class140_Sub2.aBoolean2713 = true;
if (var1 > -50) { if (var1 > -50) {

View file

@ -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) { static boolean method2031(byte var0, boolean var1, int var2, int var3, Class3_Sub2[][][] var4, int var5) {
try { 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) { if(Class158.aByteArrayArrayArray2008[WorldListCountry.localPlane][var2][var3] == var6) {
return false; return false;
} else if((Unsorted.aByteArrayArrayArray113[WorldListCountry.localPlane][var2][var3] & 4) == 0) { } else if((Unsorted.aByteArrayArrayArray113[WorldListCountry.localPlane][var2][var3] & 4) == 0) {

View file

@ -1,5 +1,6 @@
package org.runite.client; package org.runite.client;
import org.rs09.SystemLogger;
import org.rs09.client.data.NodeCache; import org.rs09.client.data.NodeCache;
import java.util.Objects; import java.util.Objects;
@ -11,26 +12,4 @@ public class Class163 {
public static int localNPCCount = 0; 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 + ')');
}
}
} }

View file

@ -115,7 +115,7 @@ final class Class25 {
static void method959() { static void method959() {
try { try {
CS2Script.aReferenceCache_2450.clear(); VarpHelpers.varbitLookup.clear();
} catch (RuntimeException var2) { } catch (RuntimeException var2) {
throw ClientErrorException.clientError(var2, "ec.B(" + 0 + ')'); throw ClientErrorException.clientError(var2, "ec.B(" + 0 + ')');

View file

@ -289,8 +289,8 @@ final class Class3_Sub28_Sub20 extends Node {
static void method725() { static void method725() {
try { try {
if(Class137.method1817() == 2) { if(Class137.method1817() == 2) {
byte var2 = (byte)(255 & Class79.anInt1127 + -4); byte var2 = (byte)(255 & CSConfigCachefile.anInt1127 + -4);
int var3 = Class79.anInt1127 % 104; int var3 = CSConfigCachefile.anInt1127 % 104;
int var4; int var4;
int var5; int var5;

View file

@ -6,15 +6,15 @@ final class Class3_Sub6 extends Linkable {
static byte[][] softReferenceTestArray; static byte[][] softReferenceTestArray;
static int[] anIntArray2288 = new int[32]; static int[] expectedMinimumValues = new int[32];
static int anInt2291; static int anInt2291;
static { static {
int var0 = 2; int accumulator = 2;
for (int var1 = 0; var1 < 32; ++var1) { for (int i = 0; i < 32; ++i) {
anIntArray2288[var1] = -1 + var0; expectedMinimumValues[i] = -1 + accumulator;
var0 += var0; accumulator += accumulator;
} }
anInt2291 = 1; anInt2291 = 1;

View file

@ -46,7 +46,7 @@ final class Class75_Sub3 extends Class75 {
Class67.aReferenceCache_1013.sweep(5); Class67.aReferenceCache_1013.sweep(5);
Texture.aReferenceCache_1146.sweep(5); Texture.aReferenceCache_1146.sweep(5);
Class159.aReferenceCache_2016.sweep(5); Class159.aReferenceCache_2016.sweep(5);
CS2Script.aReferenceCache_2450.sweep(5); VarpHelpers.varbitLookup.sweep(5);
Class136.aReferenceCache_1772.sweep(5); Class136.aReferenceCache_1772.sweep(5);
RenderAnimationDefinition.aReferenceCache_1955.sweep(5); RenderAnimationDefinition.aReferenceCache_1955.sweep(5);
TextureOperation25.aReferenceCache_3412.sweep(5); TextureOperation25.aReferenceCache_3412.sweep(5);

View file

@ -67,7 +67,7 @@ public final class Class97 {
static void method1593(int var0, CacheIndex var1) { static void method1593(int var0, CacheIndex var1) {
try { try {
Class154.anInt1966 = var1.getArchiveForName(TextCore.aClass94_3574); Class154.anInt1966 = var1.getArchiveForName(TextCore.aClass94_3574);
Class79.anInt1124 = var1.getArchiveForName(TextCore.aClass94_1341); CSConfigCachefile.anInt1124 = var1.getArchiveForName(TextCore.aClass94_1341);
if (var0 <= 108) { if (var0 <= 108) {
method1593(14, null); method1593(14, null);
} }

View file

@ -1349,8 +1349,8 @@ public final class Client extends GameShell {
} else { } else {
try { try {
if (PacketParser.anInt80 == 0) { if (PacketParser.anInt80 == 0) {
System.out.println("Trying " + 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.Companion.getJS5_SERVER_PORT()); Class17.aClass64_413 = Class38.gameSignlink.method1441((byte) 8, Class38_Sub1.accRegistryIp, GameConfig.JS5_SERVER_PORT);
++PacketParser.anInt80; ++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 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) { 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); this.method46(1000);
return; return;
} }

View file

@ -1,7 +1,11 @@
package org.runite.client; package org.runite.client;
import org.rs09.SystemLogger;
import java.awt.*; import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.net.URI; import java.net.URI;
public class ClientCommands { public class ClientCommands {
@ -192,6 +196,29 @@ public class ClientCommands {
if (command.equalsStringIgnoreCase(TextCore.COMMAND_SHIFT_DROP_CLICK)) { if (command.equalsStringIgnoreCase(TextCore.COMMAND_SHIFT_DROP_CLICK)) {
shiftClickEnabled = !shiftClickEnabled; 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.putOpcode(44);
TextureOperation12.outgoingBuffer.writeByte(command.length() + -1); TextureOperation12.outgoingBuffer.writeByte(command.length() + -1);
TextureOperation12.outgoingBuffer.writeString(command.substring(2)); TextureOperation12.outgoingBuffer.writeString(command.substring(2));
@ -220,7 +247,7 @@ public class ClientCommands {
Class159.aReferenceCache_2016.clearSoftReferences();//Originally Class133.method1803(); Class159.aReferenceCache_2016.clearSoftReferences();//Originally Class133.method1803();
Class3_Sub31.aReferenceCache_2604.clearSoftReferences();//Class38.method1025(); Class3_Sub31.aReferenceCache_2604.clearSoftReferences();//Class38.method1025();
Class27.aReferenceCache_511.clearSoftReferences();//Class38.method1025(); Class27.aReferenceCache_511.clearSoftReferences();//Class38.method1025();
CS2Script.aReferenceCache_2450.clearSoftReferences();//Class40.method1044(); VarpHelpers.varbitLookup.clearSoftReferences();//Class40.method1044();
Class136.aReferenceCache_1772.clearSoftReferences(); Class136.aReferenceCache_1772.clearSoftReferences();
RenderAnimationDefinition.aReferenceCache_1955.clearSoftReferences();//Originally: Class158_Sub1.method2192(); RenderAnimationDefinition.aReferenceCache_1955.clearSoftReferences();//Originally: Class158_Sub1.method2192();
TextureOperation25.aReferenceCache_3412.clearSoftReferences();//Originally: Class159.method2196(); TextureOperation25.aReferenceCache_3412.clearSoftReferences();//Originally: Class159.method2196();

View file

@ -188,7 +188,7 @@ final class KeyboardListener implements KeyListener, FocusListener {
try { try {
if(TextureOperation33.aClass148_3049 != null) { if(TextureOperation33.aClass148_3049 != null) {
int var2 = Class79.method1386(var1); int var2 = CSConfigCachefile.method1386(var1);
if(var2 >= 0) { if(var2 >= 0) {
int var3 = 1 + Class25.anInt491 & 127; int var3 = 1 + Class25.anInt491 & 127;
if(var3 != Class3_Sub28_Sub9.anInt3620) { if(var3 != Class3_Sub28_Sub9.anInt3620) {

View file

@ -902,11 +902,11 @@ public final class NPCDefinition {
static int method1484(int var1) { static int method1484(int var1) {
try { try {
Class79 var2 = CS2Script.method378(var1, (byte)127); CSConfigCachefile var2 = CSConfigCachefile.getCSConfigFileFromVarbitID(var1);
int var3 = Objects.requireNonNull(var2).anInt1128; int var3 = Objects.requireNonNull(var2).parentVarpIndex;
int var5 = var2.anInt1125; int var5 = var2.upperBound;
int var4 = var2.anInt1123; int var4 = var2.lowerBound;
int var6 = Class3_Sub6.anIntArray2288[var5 + -var4]; int var6 = Class3_Sub6.expectedMinimumValues[var5 + -var4];
return ItemDefinition.ram[var3] >> var4 & var6; return ItemDefinition.ram[var3] >> var4 & var6;
} catch (RuntimeException var7) { } catch (RuntimeException var7) {
throw ClientErrorException.clientError(var7, "me.B(" + 64835055 + ',' + var1 + ')'); throw ClientErrorException.clientError(var7, "me.B(" + 64835055 + ',' + var1 + ')');

View file

@ -77,7 +77,7 @@ public final class PacketParser {
if (60 == Unsorted.incomingOpcode) { if (60 == Unsorted.incomingOpcode) {
nodeModelId = BufferedDataStream.incomingBuffer.readUnsignedShort128(); nodeModelId = BufferedDataStream.incomingBuffer.readUnsignedShort128();
byte var69 = BufferedDataStream.incomingBuffer.readSignedNegativeByte(); byte var69 = BufferedDataStream.incomingBuffer.readSignedNegativeByte();
TextureOperation39.method281(var69, nodeModelId); VarpHelpers.setVarp(var69, nodeModelId);
Unsorted.incomingOpcode = -1; Unsorted.incomingOpcode = -1;
return true; return true;
} else { } else {
@ -442,7 +442,7 @@ public final class PacketParser {
} else if (Unsorted.incomingOpcode == 226) { } else if (Unsorted.incomingOpcode == 226) {
nodeModelId = BufferedDataStream.incomingBuffer.readInt(); nodeModelId = BufferedDataStream.incomingBuffer.readInt();
var19 = BufferedDataStream.incomingBuffer.readUnsignedShort128(); var19 = BufferedDataStream.incomingBuffer.readUnsignedShort128();
TextureOperation39.method281(nodeModelId, var19); VarpHelpers.setVarp(nodeModelId, var19);
Unsorted.incomingOpcode = -1; Unsorted.incomingOpcode = -1;
return true; return true;
} else if (Unsorted.incomingOpcode == 21) { } else if (Unsorted.incomingOpcode == 21) {
@ -1027,7 +1027,7 @@ public final class PacketParser {
var19 = BufferedDataStream.incomingBuffer.readUnsignedShort128(); var19 = BufferedDataStream.incomingBuffer.readUnsignedShort128();
modelId = BufferedDataStream.incomingBuffer.readUnsignedShortLE128(); modelId = BufferedDataStream.incomingBuffer.readUnsignedShortLE128();
Class146.updateInterfacePacketCounter(var19); Class146.updateInterfacePacketCounter(var19);
Class79.method1385(modelId, nodeModelId); CSConfigCachefile.method1385(modelId, nodeModelId);
Unsorted.incomingOpcode = -1; Unsorted.incomingOpcode = -1;
return true; return true;
@ -1123,7 +1123,7 @@ public final class PacketParser {
} else if (37 == Unsorted.incomingOpcode) { } else if (37 == Unsorted.incomingOpcode) {
nodeModelId = BufferedDataStream.incomingBuffer.readUnsignedByte128(); nodeModelId = BufferedDataStream.incomingBuffer.readUnsignedByte128();
var19 = BufferedDataStream.incomingBuffer.readUnsignedShortLE(); var19 = BufferedDataStream.incomingBuffer.readUnsignedShortLE();
Class163.method2209((byte) -122, nodeModelId, var19); VarpHelpers.setVarbit((byte) -122, nodeModelId, var19);
Unsorted.incomingOpcode = -1; Unsorted.incomingOpcode = -1;
return true; return true;
} else if (Unsorted.incomingOpcode == 155) { } else if (Unsorted.incomingOpcode == 155) {
@ -1400,7 +1400,7 @@ public final class PacketParser {
} else if (Unsorted.incomingOpcode == 84) { } else if (Unsorted.incomingOpcode == 84) {
nodeModelId = BufferedDataStream.incomingBuffer.readIntLE(); nodeModelId = BufferedDataStream.incomingBuffer.readIntLE();
var19 = BufferedDataStream.incomingBuffer.readUnsignedShortLE128(); var19 = BufferedDataStream.incomingBuffer.readUnsignedShortLE128();
Class163.method2209((byte) -106, nodeModelId, var19); VarpHelpers.setVarbit((byte) -106, nodeModelId, var19);
Unsorted.incomingOpcode = -1; Unsorted.incomingOpcode = -1;
return true; return true;
} else { } else {

View file

@ -196,6 +196,7 @@ public class TextCore {
*/ */
static RSString COMMAND_HIGHRES_GRAPHICS_RESIZE = RSString.parse("::wm2"); static RSString COMMAND_HIGHRES_GRAPHICS_RESIZE = RSString.parse("::wm2");
static RSString COMMAND_SHIFT_DROP_CLICK = RSString.parse("::shiftclick"); 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_REPLACE_CANVAS = RSString.parse("::replacecanvas");
static RSString COMMAND_HIGHRES_GRAPHICS_WINDOW = RSString.parse("::wm1"); static RSString COMMAND_HIGHRES_GRAPHICS_WINDOW = RSString.parse("::wm1");
static RSString COMMAND_QA_OP_TEST = RSString.parse("::qa_op_test"); static RSString COMMAND_QA_OP_TEST = RSString.parse("::qa_op_test");

View file

@ -346,15 +346,15 @@ public final class Texture {
} }
if (6 == anIntArray3331[var7]) { if (6 == anIntArray3331[var7]) {
var32 = 10 <= Class79.anInt1127 % 20 ? 16776960 : 16711680; var32 = 10 <= CSConfigCachefile.anInt1127 % 20 ? 16776960 : 16711680;
} }
if (anIntArray3331[var7] == 7) { if (anIntArray3331[var7] == 7) {
var32 = Class79.anInt1127 % 20 < 10 ? 255 : 65535; var32 = CSConfigCachefile.anInt1127 % 20 < 10 ? 255 : 65535;
} }
if (8 == anIntArray3331[var7]) { if (8 == anIntArray3331[var7]) {
var32 = Class79.anInt1127 % 20 >= 10 ? 8454016 : '\ub000'; var32 = CSConfigCachefile.anInt1127 % 20 >= 10 ? 8454016 : '\ub000';
} }
if (9 == anIntArray3331[var7]) { if (9 == anIntArray3331[var7]) {
@ -405,15 +405,15 @@ public final class Texture {
} }
if (1 == anIntArray3336[var7]) { 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) { 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) { 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]) { if (4 == anIntArray3336[var7]) {

View file

@ -1,5 +1,6 @@
package org.runite.client; package org.runite.client;
import org.rs09.SystemLogger;
import org.rs09.client.util.ArrayUtils; import org.rs09.client.util.ArrayUtils;
import org.rs09.client.filestore.resources.configs.cursors.CursorDefinition; 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) { static void method306(int var0, int var2) {
try { try {
Class79 var3 = CS2Script.method378(var0, (byte)127); CSConfigCachefile var3 = CSConfigCachefile.getCSConfigFileFromVarbitID(var0);
int var6 = Objects.requireNonNull(var3).anInt1125; int var6 = Objects.requireNonNull(var3).upperBound;
int var5 = var3.anInt1123; int var5 = var3.lowerBound;
int var4 = var3.anInt1128; int var4 = var3.parentVarpIndex;
int var7 = Class3_Sub6.anIntArray2288[var6 - var5]; int var7 = Class3_Sub6.expectedMinimumValues[var6 - var5];
if(var2 < 0 || var7 < var2) { if(var2 < 0 || var7 < var2) {
SystemLogger.logInfo(var7 + " < " + var2);
var2 = 0; var2 = 0;
} }

View file

@ -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) { final void method161(byte var1) {
try { try {
super.method161(var1); super.method161(var1);

View file

@ -12,8 +12,6 @@ import org.rs09.client.util.ArrayUtils;
import org.runite.client.drawcalls.*; import org.runite.client.drawcalls.*;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Objects; import java.util.Objects;
@ -1964,7 +1962,7 @@ public class Unsorted {
Class136.method1816(512, -7); Class136.method1816(512, -7);
TextureOperation19.method257(); TextureOperation19.method257();
} else { } else {
Class3_Sub5.method112((byte) (-4 + Class79.anInt1127 & 0xFF)); Class3_Sub5.method112((byte) (-4 + CSConfigCachefile.anInt1127 & 0xFF));
Class136.method1816(2, -7); Class136.method1816(2, -7);
} }
@ -2646,7 +2644,7 @@ public class Unsorted {
++var2; ++var2;
} }
if (var1.retrieveSpriteFile(Class79.anInt1124)) { if (var1.retrieveSpriteFile(CSConfigCachefile.anInt1124)) {
++var2; ++var2;
} }
@ -4720,7 +4718,7 @@ public class Unsorted {
} }
} }
Class79.method1390(new DataBuffer(var4)); CSConfigCachefile.method1390(new DataBuffer(var4));
} }
} catch (Exception var8) { } catch (Exception var8) {
} }
@ -4913,7 +4911,7 @@ public class Unsorted {
static void method338(int var1, boolean var2, int var3, int var4, int var5) { static void method338(int var1, boolean var2, int var3, int var4, int var5) {
try { try {
++Class79.anInt1127; ++CSConfigCachefile.anInt1127;
Class124.method1745(); Class124.method1745();
if(!var2) { if(!var2) {
Class3_Sub5.method116(true); Class3_Sub5.method116(true);
@ -5022,7 +5020,7 @@ public class Unsorted {
} }
Class58.method1194(); Class58.method1194();
byte var19 = Class137.method1817() != 2 ?1:(byte)Class79.anInt1127; byte var19 = Class137.method1817() != 2 ?1:(byte) CSConfigCachefile.anInt1127;
if(HDToolKit.highDetail) { if(HDToolKit.highDetail) {
HDToolKit.method1846(); HDToolKit.method1846();
HDToolKit.method1831(true); HDToolKit.method1831(true);

View file

@ -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 + ')');
}
}
}

View file

@ -12,13 +12,13 @@ public final class ContextMenu {
int width = Class21.anInt3552; int width = Class21.anInt3552;
int height = Class21.anInt3537; int height = Class21.anInt3537;
int contextMenuColor = 6116423; //Context Menu RGB || 6116423 Classic || Old var5 || ColorCore.getHexColors() 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) { 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().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.RCM_BORDER_OPACITY); Toolkit.getActiveToolkit().drawRect(1 + x, 1 + y, width + -2, height, GameConfig.RCM_BORDER_COLOR, GameConfig.getRCM_BORDER_OPACITY());
} else { } else {
Toolkit.getActiveToolkit().fillRect(1 + x, 2 + y, width + -2, 16, GameConfig.RCM_TITLE_COLOR, GameConfig.RCM_TITLE_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.RCM_BORDER_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); FontType.bold.method681(RSString.parse(GameConfig.RCM_TITLE), x - -3, y + 14, contextMenuColor, -1);

View file

@ -11,384 +11,382 @@ import java.util.*
* Handles the client's config loading * Handles the client's config loading
* @author Ceikry * @author Ceikry
*/ */
class GameConfig { object GameConfig {
companion object { /**
* Debug Booleans
*/
@JvmField
var ITEM_DEBUG_ENABLED = false
/** @JvmField
* Debug Booleans var OBJECT_DEBUG_ENABLED = false
*/
@JvmField
var ITEM_DEBUG_ENABLED = false
@JvmField @JvmField
var OBJECT_DEBUG_ENABLED = false var NPC_DEBUG_ENABLED = false
@JvmField @JvmField
var NPC_DEBUG_ENABLED = false var HD_LOGIN_DEBUG = false
@JvmField @JvmField
var HD_LOGIN_DEBUG = false var HD_LOGIN_VERBOSE = false
@JvmField @JvmField
var HD_LOGIN_VERBOSE = false var CACHE_DEBUG = false
@JvmField @JvmField
var CACHE_DEBUG = false var WORLD_MAP_DEBUG = false
@JvmField /**
var WORLD_MAP_DEBUG = false * Context Menu Presets
*/
@JvmField
var RCM_STYLE_PRESET = "classic"
/** /**
* Context Menu Presets * Context Menu Customization
*/ */
@JvmField @JvmField
var RCM_STYLE_PRESET = "classic" var RCM_BG_COLOR = 6116423
/** @JvmStatic
* Context Menu Customization var RCM_BG_OPACITY = 255
*/
@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 = "<col=0>Choose Option</col>"
@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
set(value) { set(value) {
if(value > 255 || value < 0) field = 255 if(value > 255 || value < 0) field = 255
else field = value else field = value
} }
@JvmField @JvmField
var slayerTaskID = 0 var RCM_TITLE_COLOR = 0
@JvmField @JvmStatic
var slayerTaskAmount = 0 var RCM_TITLE_OPACITY = 255
set(value) {
@JvmField if(value > 255 || value < 0) field = 255
var VERBOSE_LOGGING = false else field = value
@JvmStatic
fun setSlayerAmount(amount : Int){
slayerTaskAmount = amount
if(slayerTaskAmount < 0) slayerTaskAmount = 0
SlayerTracker.lastUpdate = System.currentTimeMillis()
} }
@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 = "<col=0>Choose Option</col>"
@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 when (RCM_STYLE_PRESET) {
fun parse(path: String){ "classic" -> {
val reader = FileReader(path) RS3_CONTEXT_STYLE = false
val parser = JSONParser() RCM_BG_COLOR = 6116423
val data = parser.parse(reader) as JSONObject RCM_BG_OPACITY = 255
RCM_TITLE = "<col=5d5447>Choose Option</col>"
//Networking RCM_TITLE_COLOR = 0
if(data.containsKey("ip_address")) IP_ADDRESS = data["ip_address"].toString() else IP_ADDRESS = "play.2009scape.org" RCM_TITLE_OPACITY = 255
if(data.containsKey("ip_management")) IP_MANAGEMENT = data["ip_management"].toString() else IP_MANAGEMENT = IP_ADDRESS RCM_BORDER_COLOR = 0
if(data.containsKey("wl_port")) WL_PORT = data["wl_port"].toString().toInt() RCM_BORDER_OPACITY = 255
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
}
}
} }
"rs3" -> {
//Parse debug options RS3_CONTEXT_STYLE = true
if(data.containsKey("debug")){ RCM_BG_COLOR = 662822
val debug = data["debug"] as JSONObject RCM_BG_OPACITY = 255
if(debug.containsKey("item_debug")) ITEM_DEBUG_ENABLED = debug["item_debug"] as Boolean RCM_TITLE = "<col=C6B895>Choose Option</col>"
if(debug.containsKey("npc_debug")) NPC_DEBUG_ENABLED = debug["npc_debug"] as Boolean RCM_TITLE_COLOR = 1512718
if(debug.containsKey("object_debug")) OBJECT_DEBUG_ENABLED = debug["object_debug"] as Boolean RCM_TITLE_OPACITY = 165
if(debug.containsKey("hd_login_region_debug")) HD_LOGIN_DEBUG = debug["hd_login_region_debug"] as Boolean RCM_BORDER_COLOR = 16777215
if(debug.containsKey("hd_login_region_debug_verbose")) HD_LOGIN_VERBOSE = debug["hd_login_region_debug_verbose"] as Boolean RCM_BORDER_OPACITY = 255
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
} }
}
/** }
* 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 fun extendRenderDistance() {
* ie, classicbox, rs3, rounded, rounded2 if (RENDER_DISTANCE_INCREASE) {
* Then we introduce color schemes that a user could select /** **DO NOT CHANGE THESE NUMBERS UNLESS YOU KNOW WHAT YOU ARE DOING**
* ie, classic, rs3, alternate, alternate2, custom * Render Distance Overrides
* @author Woah *
* (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) { RENDER_DISTANCE_VALUE = if (RENDER_DISTANCE_INCREASE) 28672F else 3584.0f
"classic" -> { RENDER_DISTANCE_TILE_VALUE = if (RENDER_DISTANCE_INCREASE) 56 else 28
RS3_CONTEXT_STYLE = false RENDER_DISTANCE_FOG_FIX = if (RENDER_DISTANCE_INCREASE) 28672F else 3328.0f
RCM_BG_COLOR = 6116423
RCM_BG_OPACITY = 255
RCM_TITLE = "<col=5d5447>Choose Option</col>"
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 = "<col=C6B895>Choose Option</col>"
RCM_TITLE_COLOR = 1512718
RCM_TITLE_OPACITY = 165
RCM_BORDER_COLOR = 16777215
RCM_BORDER_OPACITY = 255
}
}
} }
}
fun extendRenderDistance() { /**
if (RENDER_DISTANCE_INCREASE) { * Client Info
/** **DO NOT CHANGE THESE NUMBERS UNLESS YOU KNOW WHAT YOU ARE DOING** * Not Editable
* Render Distance Overrides */
* @JvmField
* (Simple formula) Tile amount * 512 var CLIENT_BUILD = 530
* 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
}
}
/** @JvmField
* Client Info var CLIENT_VERSION = 1
* Not Editable
*/
@JvmField
var CLIENT_BUILD = 530
@JvmField @JvmField
var CLIENT_VERSION = 1 var PACKAGE_NAME = "org.runite.client"
@JvmField @JvmField
var PACKAGE_NAME = "org.runite.client" var RSA = true
@JvmField @JvmField
var RSA = true var ISAAC = false
@JvmField @JvmField
var ISAAC = false var EXPONENT = BigInteger("65537")
@JvmField @JvmField
var EXPONENT = BigInteger("65537") var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051")
@JvmField @JvmField
var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051") var SERVER_NAME = "2009scape"
@JvmField /**
var SERVER_NAME = "2009scape" * Path to config
*/
@JvmField
var configLocation = "config.json"
/** /**
* Path to config * Holiday Event Toggles
*/ */
@JvmField @JvmField
var configLocation = "config.json" var HOLIDAYS_ENABLED = true
/** @JvmField
* Holiday Event Toggles var EASTER_EVENT_ENABLED = false
*/ /**
@JvmField * Halloween event NPC Definitions are handled inside of NPCDefinition.java
var HOLIDAYS_ENABLED = true */
@JvmField
var HALLOWEEN_EVENT_ENABLED = false
@JvmField @JvmField
var EASTER_EVENT_ENABLED = false var THANKSGIVING_EVENT_ENABLED = false
/**
* Halloween event NPC Definitions are handled inside of NPCDefinition.java
*/
@JvmField
var HALLOWEEN_EVENT_ENABLED = false
@JvmField @JvmField
var THANKSGIVING_EVENT_ENABLED = false var CHRISTMAS_EVENT_ENABLED = false
@JvmField private val calendar: Calendar = Calendar.getInstance()
var CHRISTMAS_EVENT_ENABLED = false private val month = calendar.get(Calendar.MONTH)
private val day = calendar.get(Calendar.DAY_OF_MONTH)
private val calendar: Calendar = Calendar.getInstance() @JvmStatic
private val month = calendar.get(Calendar.MONTH) fun implementHoliday() {
private val day = calendar.get(Calendar.DAY_OF_MONTH) if (HOLIDAYS_ENABLED) {
when (month) {
@JvmStatic 3 -> {
fun implementHoliday() { if (day <= 8) {
if (HOLIDAYS_ENABLED) { EASTER_EVENT_ENABLED = true
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
} }
} }
} }

View file

@ -10,6 +10,6 @@
"WorldTechnicalInformation": { "WorldTechnicalInformation": {
"world_limit": "10", "world_limit": "10",
"worldhop_delay": "20000" "worldhop_delay": "20000"
} },
"secret_key": "2009scape_development"
} }

View file

@ -1,7 +1,8 @@
package ms; package ms;
import ms.classloader.ClassLoadServer;
import ms.net.NioReactor; import ms.net.NioReactor;
import ms.net.packet.IoBuffer;
import ms.net.packet.PacketHeader;
import ms.net.packet.WorldPacketRepository; import ms.net.packet.WorldPacketRepository;
import ms.system.ShutdownSequence; import ms.system.ShutdownSequence;
import ms.system.mysql.SQLManager; import ms.system.mysql.SQLManager;
@ -100,7 +101,6 @@ public final class Management {
new Command("-rlcache", "Reloads launcher/client resource cache") { new Command("-rlcache", "Reloads launcher/client resource cache") {
@Override @Override
public void run(String... args) { public void run(String... args) {
ClassLoadServer.resetResourceCache();
System.out.println("Reloaded resource cache!"); System.out.println("Reloaded resource cache!");
} }
}, },
@ -118,6 +118,27 @@ public final class Management {
player.setWorldId(0); player.setWorldId(0);
System.out.println("Kicked player " + name + "!"); 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(); SQLManager.init();
//NioReactor.configure(ServerConstants.PORT).start(); //NioReactor.configure(ServerConstants.PORT).start();
NioReactor.configure(5555).start(); NioReactor.configure(5555).start();
new ClassLoadServer().start();
Runtime.getRuntime().addShutdownHook(new ShutdownSequence()); Runtime.getRuntime().addShutdownHook(new ShutdownSequence());
System.out.println("Status: ready."); System.out.println("Status: ready.");
System.out.println("Use -commands for a list of commands!"); System.out.println("Use -commands for a list of commands!");

View file

@ -29,18 +29,6 @@ public final class ServerConstants {
*/ */
public static final OperatingSystem OS = System.getProperty("os.name").toUpperCase().contains("WIN") ? OperatingSystem.WINDOWS : OperatingSystem.UNIX; 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. * Stops from instantiating.
*/ */

View file

@ -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<String, byte[]> resourceCache = new HashMap<String, byte[]>();
/**
* 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!");
}
}

View file

@ -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<String, byte[]> 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();
}
}

View file

@ -67,6 +67,10 @@ public final class IoEventHandler {
ByteBuffer buffer = ByteBuffer.allocate(100_000); ByteBuffer buffer = ByteBuffer.allocate(100_000);
IoSession session = (IoSession) key.attachment(); IoSession session = (IoSession) key.attachment();
if (channel.read(buffer) == -1) { if (channel.read(buffer) == -1) {
if(session == null){
key.cancel();
return;
}
if(session.getGameServer() != null){ if(session.getGameServer() != null){
WorldDatabase.unRegister(session.getGameServer()); WorldDatabase.unRegister(session.getGameServer());
} }
@ -87,8 +91,10 @@ public final class IoEventHandler {
*/ */
public void write(SelectionKey key) { public void write(SelectionKey key) {
IoSession session = (IoSession) key.attachment(); IoSession session = (IoSession) key.attachment();
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); if(session != null) {
session.write(); key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
session.write();
}
} }
/** /**

View file

@ -168,9 +168,9 @@ public class IoSession {
} }
writingQueue.remove(0); writingQueue.remove(0);
} }
writingLock.unlock();
} catch (IOException e) { } catch (IOException e) {
disconnect(); disconnect();
} finally {
writingLock.unlock(); writingLock.unlock();
} }
} }

View file

@ -96,6 +96,7 @@ public final class NioReactor implements Runnable {
SelectionKey key = keys.next(); SelectionKey key = keys.next();
keys.remove(); keys.remove();
try { try {
if(key == null) continue;
if (!key.isValid() || !key.channel().isOpen()) { if (!key.isValid() || !key.channel().isOpen()) {
key.cancel(); key.cancel();
continue; continue;

View file

@ -4,6 +4,7 @@ import java.nio.ByteBuffer;
import ms.net.IoReadEvent; import ms.net.IoReadEvent;
import ms.net.IoSession; import ms.net.IoSession;
import ms.system.util.ManagementConstants;
import ms.world.WorldDatabase; import ms.world.WorldDatabase;
import ms.system.util.ByteBufferUtils; import ms.system.util.ByteBufferUtils;
@ -12,11 +13,6 @@ import ms.system.util.ByteBufferUtils;
* @author Emperor * @author Emperor
*/ */
public final class HSReadEvent extends IoReadEvent { public final class HSReadEvent extends IoReadEvent {
/**
* The password used to verify
*/
private static final String PASSWORD = "0x14ari0SSbh98989910";
/** /**
* Constructs a new {@code HSReadEvent}. * Constructs a new {@code HSReadEvent}.
@ -33,7 +29,7 @@ public final class HSReadEvent extends IoReadEvent {
switch (opcode) { switch (opcode) {
case 88: case 88:
String password = ByteBufferUtils.getString(buffer); String password = ByteBufferUtils.getString(buffer);
if (!password.equals(PASSWORD)) { if (!password.equals(ManagementConstants.getSECRET_KEY())) {
System.out.println("Password mismatch (attempt=" + password + ")!"); System.out.println("Password mismatch (attempt=" + password + ")!");
session.disconnect(); session.disconnect();
break; break;

View file

@ -547,7 +547,7 @@ public class IoBuffer {
long second = getIntB(); long second = getIntB();
if (second < 0) if (second < 0)
second = second & 0xffffffffL; second = second & 0xffffffffL;
return (first << -41780448) + second; return (first << 32) + second;
} }
/** /**
@ -567,7 +567,7 @@ public class IoBuffer {
if (peek <= Short.MAX_VALUE) { if (peek <= Short.MAX_VALUE) {
return buf.getShort() & 0xFFFF; return buf.getShort() & 0xFFFF;
} }
return (buf.getInt() & 0xFFFFFFFF) - 32768; return buf.getInt() - 32768;
} }
/** /**

View file

@ -5,7 +5,7 @@ import ms.system.PunishmentStorage
import ms.system.communication.ClanRank import ms.system.communication.ClanRank
import ms.system.communication.ClanRepository import ms.system.communication.ClanRepository
import ms.system.communication.CommunicationInfo 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.GameServer
import ms.world.PlayerSession import ms.world.PlayerSession
import ms.world.WorldDatabase import ms.world.WorldDatabase

View file

@ -49,7 +49,7 @@ public final class PunishmentStorage {
return; return;
} }
long end = Long.MAX_VALUE; long end = Long.MAX_VALUE;
if (duration != -1l && duration != 0L) { if (duration != -1L && duration != 0L) {
end = System.currentTimeMillis() + duration; end = System.currentTimeMillis() + duration;
} else if (duration == 0L) { } else if (duration == 0L) {
end = 0L; end = 0L;

View file

@ -12,10 +12,7 @@ import java.nio.ByteBuffer;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
/** /**
@ -184,9 +181,7 @@ public final class CommunicationInfo {
String bl = set.getString("blocked"); String bl = set.getString("blocked");
if (bl != null && !bl.isEmpty()) { if (bl != null && !bl.isEmpty()) {
tokens = bl.split(","); tokens = bl.split(",");
for (String name : tokens) { blocked.addAll(Arrays.asList(tokens));
blocked.add(name);
}
} }
clanName = set.getString("clanName"); clanName = set.getString("clanName");
currentClan = set.getString("currentClan"); currentClan = set.getString("currentClan");
@ -236,6 +231,9 @@ public final class CommunicationInfo {
case 2: case 2:
tradeSetting = Integer.parseInt(tokens[2]); tradeSetting = Integer.parseInt(tokens[2]);
break; break;
default:
System.out.println("Illegal arg count in chatsetting string: " + chatSettings);
break;
} }
} }
} }

View file

@ -1,11 +1,11 @@
package ms.system.mysql package ms.system.mysql
import ms.system.util.ManagementConstants import ms.system.util.ManagementConstants
import ms.system.util.ManagementConstants.Companion.DATABASE_HOST_ADDRESS import ms.system.util.ManagementConstants.DATABASE_HOST_ADDRESS
import ms.system.util.ManagementConstants.Companion.DATABASE_NAME import ms.system.util.ManagementConstants.DATABASE_NAME
import ms.system.util.ManagementConstants.Companion.DATABASE_PASSWORD import ms.system.util.ManagementConstants.DATABASE_PASSWORD
import ms.system.util.ManagementConstants.Companion.DATABASE_PORT import ms.system.util.ManagementConstants.DATABASE_PORT
import ms.system.util.ManagementConstants.Companion.DATABASE_USERNAME import ms.system.util.ManagementConstants.DATABASE_USERNAME
import java.sql.Connection import java.sql.Connection
import java.sql.DriverManager import java.sql.DriverManager
import java.sql.SQLException import java.sql.SQLException

View file

@ -30,19 +30,20 @@ class ManagementConfigParser(path: String) {
data = parser.parse(reader) as JSONObject data = parser.parse(reader) as JSONObject
parseDatabaseInformation() parseDatabaseInformation()
parseWorldTechnicalSettings() parseWorldTechnicalSettings()
ManagementConstants.SECRET_KEY = data!!["secret_key"].toString()
} }
} }
private fun parseDatabaseInformation(){ private fun parseDatabaseInformation(){
data ?: return data ?: return
val dbData = data!!["DatabaseInformation"] as JSONObject val dbData = data!!["DatabaseInformation"] as JSONObject
ManagementConstants().parseDBProp(dbData) ManagementConstants.parseDBProp(dbData)
} }
private fun parseWorldTechnicalSettings(){ private fun parseWorldTechnicalSettings(){
data ?: return data ?: return
val wtiData = data!!["WorldTechnicalInformation"] as JSONObject val wtiData = data!!["WorldTechnicalInformation"] as JSONObject
ManagementConstants().parseWTIProp(wtiData) ManagementConstants.parseWTIProp(wtiData)
} }
/** /**

View file

@ -2,32 +2,31 @@ package ms.system.util
import org.json.simple.JSONObject import org.json.simple.JSONObject
class ManagementConstants { object ManagementConstants {
companion object { //MySQL main database name
var DATABASE_NAME: String = "global"
//MySQL main database name //MySQL database username
var DATABASE_NAME: String = "global" var DATABASE_USERNAME: String = "root"
//MySQL database username //MySQL database password
var DATABASE_USERNAME: String = "root" var DATABASE_PASSWORD: String = ""
//MySQL database password //MySQL host
var DATABASE_PASSWORD: String = "" var DATABASE_HOST_ADDRESS: String = "127.0.0.1"
//MySQL host //MySQL port
var DATABASE_HOST_ADDRESS: String = "127.0.0.1" var DATABASE_PORT: Int = 3306
//MySQL port //Max amount of worlds supported on the world list
var DATABASE_PORT: Int = 3306 var MAX_WORLD_AMOUNT: Int = 10
//Max amount of worlds supported on the world list //User world hop delay in seconds
var MAX_WORLD_AMOUNT: Int = 10 var WORLD_HOP_DELAY: Long = 20_000L
//User world hop delay in seconds @JvmStatic
var WORLD_HOP_DELAY: Long = 20_000L var SECRET_KEY: String = ""
}
fun parseDBProp(data: JSONObject) { fun parseDBProp(data: JSONObject) {
DATABASE_NAME = data["database_name"].toString() DATABASE_NAME = data["database_name"].toString()

View file

@ -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) { } catch (RuntimeException runtimeexception) {
runtimeexception.printStackTrace();
} }
return 0; return 0;
} }

View file

@ -66,7 +66,7 @@ public final class PlayerSession {
/** /**
* The time stamp of last disconnection. * The time stamp of last disconnection.
*/ */
private long disconnectionTime = 0l; private long disconnectionTime = 0L;
/** /**
* How long the player is banned for. * How long the player is banned for.
@ -463,11 +463,8 @@ public final class PlayerSession {
this.disconnectionTime = time; this.disconnectionTime = time;
} }
@Override public boolean equalsSession(PlayerSession o){
public boolean equals(Object o) { return username.equals(o.username);
if(o instanceof PlayerSession) {
return username.equals(((PlayerSession) o).username);
} else return false;
} }
@Override @Override

View file

@ -9,12 +9,12 @@ import java.util.*
object MSLogger { object MSLogger {
val t = Terminal() val t = Terminal()
val formatter = SimpleDateFormat("HH:mm:ss")
var tradeLog: Writer? = null var tradeLog: Writer? = null
var tradeLogWriter: BufferedWriter? = null var tradeLogWriter: BufferedWriter? = null
fun getTime(): String{ fun getTime(): String{
val formatter = SimpleDateFormat("HH:mm:ss")
return "[" + formatter.format(Date(System.currentTimeMillis())) +"]" return "[" + formatter.format(Date(System.currentTimeMillis())) +"]"
} }

View file

@ -62771,7 +62771,7 @@
{ {
"default": [], "default": [],
"charm": [], "charm": [],
"ids": "428, 429", "ids": "428,429",
"description": "Shade (Stronghold of Security) (So Shade Robes can drop)", "description": "Shade (Stronghold of Security) (So Shade Robes can drop)",
"main": [ "main": [
{ {

Binary file not shown.

View file

@ -100,6 +100,7 @@ public abstract class CutscenePlugin extends ActivityPlugin {
unpause(); unpause();
} }
player.unlock(); player.unlock();
player.getInterfaceManager().openDefaultTabs();
player.getWalkingQueue().reset(); player.getWalkingQueue().reset();
player.getLocks().unlockMovement(); player.getLocks().unlockMovement();
} }

View file

@ -1,5 +1,6 @@
package core.game.content.activity.guild; package core.game.content.activity.guild;
import api.ContentAPI;
import core.cache.def.impl.NPCDefinition; import core.cache.def.impl.NPCDefinition;
import core.cache.def.impl.SceneryDefinition; import core.cache.def.impl.SceneryDefinition;
import core.game.content.dialogue.DialoguePlugin; import core.game.content.dialogue.DialoguePlugin;
@ -60,7 +61,7 @@ public final class WizardGuildPlugin extends OptionHandler {
switch (id) { switch (id) {
case 1600: case 1600:
case 1601: 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."); player.getDialogueInterpreter().sendDialogue("You need a Magic level of at least 66 to enter.");
return true; return true;
} }

View file

@ -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 };
}
}

View file

@ -137,7 +137,7 @@ public final class HansDialoguePlugin extends DialoguePlugin {
case 12: case 12:
switch(buttonId){ switch(buttonId){
case 1: case 1:
options("1.0x","2.5x","10x","20x"); options("1.0x","2.5x","Stay 5.0x");
stage++; stage++;
break; break;
case 2: case 2:
@ -166,13 +166,9 @@ public final class HansDialoguePlugin extends DialoguePlugin {
} }
break; break;
case 3: case 3:
player.getSkills().experienceMutiplier = 10.0; playerl(FacialExpression.FRIENDLY, "I'd rather stay 5x, thank you.");
stage = 14; stage = END_DIALOGUE;
break; return true;
case 4:
player.getSkills().experienceMutiplier = 20.0;
stage = 14;
break;
} }
npc("One moment, please..."); npc("One moment, please...");
break; break;

View file

@ -38,7 +38,6 @@ public final class SimonTempleton extends DialoguePlugin{
return true; return true;
} }
} }
player.getPacketDispatch().sendMessage("" + args.length);
npc("G'day, mate!. Got any new", "pyramid artefacts for me?"); npc("G'day, mate!. Got any new", "pyramid artefacts for me?");
return true; return true;
} }

View file

@ -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<ShopViewer> 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<ShopViewer> 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<Item> items){
this.items = items.toArray(new Item[0]);
}
}

View file

@ -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<Item>,
/**
* 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<ShopViewer> = 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<Item>,
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<Item>, 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<Item>, 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>(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<Item>) {
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
}
}

View file

@ -13,6 +13,8 @@ import core.game.node.entity.Entity;
import core.game.node.entity.npc.NPC; import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player; import core.game.node.entity.player.Player;
import core.game.node.object.Scenery; import core.game.node.object.Scenery;
import org.json.simple.JSONObject;
import rs09.ServerStore;
import rs09.game.world.GameWorld; import rs09.game.world.GameWorld;
import core.game.world.map.Location; import core.game.world.map.Location;
import core.game.world.map.zone.MapZone; import core.game.world.map.zone.MapZone;
@ -261,13 +263,13 @@ public final class ChaosTunnelZone extends MapZone implements Plugin<Object> {
* @param player The player. * @param player The player.
*/ */
private void commenceBorkBattle(Player player) { private void commenceBorkBattle(Player player) {
if ((System.currentTimeMillis() - player.getSavedData().getActivityData().getLastBorkBattle()) < 24 * 60 * 60_000 && GameWorld.getSettings().isHosted()) { if (ServerStore.getBoolean(getStoreFile(), player.getUsername().toLowerCase()) && GameWorld.getSettings().isHosted()) {
player.getPacketDispatch().sendMessage("The portal's magic is too weak to teleport you right now."); player.getPacketDispatch().sendMessage("The portal's magic is too weak to teleport you right now.");
return; return;
} }
player.lock(10); player.lock(10);
player.graphics(Graphics.create(110)); player.graphics(Graphics.create(110));
player.getSavedData().getActivityData().setLastBorkBattle(System.currentTimeMillis()); getStoreFile().put(player.getUsername().toLowerCase(), true);
ActivityManager.start(player, "Bork cutscene", false); ActivityManager.start(player, "Bork cutscene", false);
} }
@ -352,4 +354,12 @@ public final class ChaosTunnelZone extends MapZone implements Plugin<Object> {
PORTALS.put(location, loc); PORTALS.put(location, loc);
} }
/**
* Returns the Server Store file for Bork being killed for the day
* @return The JSONObject containing the boolean of whether Bork has been killed
*/
private JSONObject getStoreFile() {
return ServerStore.getArchive("daily-bork-killed");
}
} }

View file

@ -44,7 +44,7 @@ public class RoavarDialogue extends DialoguePlugin {
stage = 1; stage = 1;
break; break;
case 1: case 1:
interpreter.sendOptions("Select an Option", "Can I buy a beer?", "Can I hear some gossipp?", "Do you have a spare silver sickle?", "Nothing thanks."); interpreter.sendOptions("Select an Option", "Can I buy a beer?", "Can I hear some gossipp?", "Nothing thanks.");
stage = 2; stage = 2;
break; break;
case 2: case 2:
@ -58,10 +58,6 @@ public class RoavarDialogue extends DialoguePlugin {
stage = 20; stage = 20;
break; break;
case 3: case 3:
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Would you happen to have a spare silver sickle?");
stage = 30;
break;
case 4:
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nothing thanks."); interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nothing thanks.");
stage = 40; stage = 40;
break; break;

View file

@ -1,5 +1,6 @@
package core.game.node.entity.combat.spell; package core.game.node.entity.combat.spell;
import api.ContentAPI;
import core.game.node.entity.skill.Skills; import core.game.node.entity.skill.Skills;
import core.game.node.entity.skill.magic.Runes; import core.game.node.entity.skill.magic.Runes;
import core.game.node.entity.Entity; import core.game.node.entity.Entity;
@ -181,6 +182,11 @@ public final class CurseSpells extends CombatSpell {
} }
} }
@Override
public void addExperience(Entity entity, int hit) {
entity.getSkills().addExperience(Skills.MAGIC, getExperience());
}
@Override @Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable { public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(2, new CurseSpells(SpellType.CONFUSE, 3, 13.0, 99, CONFUSE_START, CONFUSE_PROJECTILE, CONFUSE_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3))); SpellBook.MODERN.register(2, new CurseSpells(SpellType.CONFUSE, 3, 13.0, 99, CONFUSE_START, CONFUSE_PROJECTILE, CONFUSE_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3)));

View file

@ -513,7 +513,7 @@ public class NPC extends Entity {
if (getZoneMonitor().handleDeath(killer)) { if (getZoneMonitor().handleDeath(killer)) {
return; return;
} }
if (task != null && killer instanceof Player && ((Player) killer).getSlayer().getTask() == task) { if (task != null && killer instanceof Player && ((Player) killer).getSlayer().getTask() == task && ((Player) killer).getSlayer().hasTask()) {
((Player) killer).getSlayer().finalizeDeath(killer.asPlayer(), this); ((Player) killer).getSlayer().finalizeDeath(killer.asPlayer(), this);
} }
if (killer instanceof Player && killer.getAttribute("jobs:id",null) != null) { if (killer instanceof Player && killer.getAttribute("jobs:id",null) != null) {

View file

@ -22,6 +22,9 @@ import org.rs09.consts.Items;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import static java.lang.Math.floor;
import static java.lang.Math.max;
/** /**
* Represents an entity's skills. * Represents an entity's skills.
* @author Emperor * @author Emperor
@ -453,8 +456,8 @@ public final class Skills {
int points = 0; int points = 0;
int output = 0; int output = 0;
for (byte lvl = 1; lvl < 100; lvl++) { for (byte lvl = 1; lvl < 100; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); points += floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
output = (int) Math.floor(points / 4); output = (int) floor(points / 4);
if ((output - 1) >= exp) { if ((output - 1) >= exp) {
return lvl; return lvl;
} }
@ -467,8 +470,8 @@ public final class Skills {
int points = 0; int points = 0;
int output = 0; int output = 0;
for (byte lvl = 1; lvl < 100; lvl++) { for (byte lvl = 1; lvl < 100; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); points += floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
output = (int) Math.floor(points / 4); output = (int) floor(points / 4);
if ((output - 1) >= exp) { if ((output - 1) >= exp) {
return lvl; return lvl;
} }
@ -485,11 +488,11 @@ public final class Skills {
int points = 0; int points = 0;
int output = 0; int output = 0;
for (int lvl = 1; lvl <= level; lvl++) { for (int lvl = 1; lvl <= level; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); points += floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
if (lvl >= level) { if (lvl >= level) {
return output; return output;
} }
output = (int) Math.floor(points / 4); output = (int) floor(points / 4);
} }
return 0; return 0;
} }
@ -523,19 +526,13 @@ public final class Skills {
if (entity instanceof NPC) { if (entity instanceof NPC) {
return ((NPC) entity).getDefinition().getCombatLevel(); return ((NPC) entity).getDefinition().getCombatLevel();
} }
int combatLevel = 0;
int melee = staticLevels[ATTACK] + staticLevels[STRENGTH]; double base = 0.25 * (staticLevels[DEFENCE] + staticLevels[HITPOINTS] + floor(0.5 * staticLevels[PRAYER]));
int range = (int) (1.5 * staticLevels[RANGE]); double meleeBase = 0.325 * (staticLevels[ATTACK] + staticLevels[STRENGTH]);
int mage = (int) (1.5 * staticLevels[MAGIC]); double rangeBase = 0.325 * (floor(staticLevels[RANGE] / 2.0) * 1.5);
if (melee > range && melee > mage) { double magicBase = 0.325 * (floor(staticLevels[MAGIC] / 2.0) * 1.5);
combatLevel = melee;
} else if (range > melee && range > mage) { return (int) (base + max(meleeBase, max(rangeBase, magicBase)));
combatLevel = range;
} else {
combatLevel = mage;
}
combatLevel = staticLevels[DEFENCE] + staticLevels[HITPOINTS] + (staticLevels[PRAYER] / 2) + (int) (1.3 * combatLevel);
return combatLevel / 4;
} }
/** /**

View file

@ -119,6 +119,11 @@ public final class PortalOptionPlugin extends OptionHandler {
player.getHouseManager().enter(player, buttonId == 2, true); player.getHouseManager().enter(player, buttonId == 2, true);
break; break;
case 3: case 3:
if(player.getIronmanManager().isIronman()){
end();
ContentAPI.sendMessage(player, "You can't do that as an ironman.");
return true;
}
ContentAPI.sendInputDialogue(player, false, "Enter friend's name:", (value) -> { ContentAPI.sendInputDialogue(player, false, "Enter friend's name:", (value) -> {
Player p = Repository.getPlayerByName((String) value); Player p = Repository.getPlayerByName((String) value);
if (p == null || !p.isActive()) { if (p == null || !p.isActive()) {

View file

@ -105,10 +105,12 @@ public final class SlayerManager {
* @param npc The NPC. You're currently * @param npc The NPC. You're currently
*/ */
public void finalizeDeath(Player player, NPC npc) { public void finalizeDeath(Player player, NPC npc) {
player.getSkills().addExperience(Skills.SLAYER,npc.getSkills().getMaximumLifepoints()); if(hasTask()) {
decrementAmount(1); player.getSkills().addExperience(Skills.SLAYER, npc.getSkills().getMaximumLifepoints());
if (!hasTask()) { decrementAmount(1);
clear(); }
if(!hasTask()){
flags.setTaskStreak(flags.getTaskStreak() + 1); flags.setTaskStreak(flags.getTaskStreak() + 1);
flags.setCompletedTasks(flags.getCompletedTasks() + 1); flags.setCompletedTasks(flags.getCompletedTasks() + 1);
if ((flags.getCompletedTasks() > 4 || flags.canEarnPoints() ) && flags.getMaster() != Master.TURAEL && flags.getPoints() < 64000) { if ((flags.getCompletedTasks() > 4 || flags.canEarnPoints() ) && flags.getMaster() != Master.TURAEL && flags.getPoints() < 64000) {
@ -251,7 +253,7 @@ public final class SlayerManager {
* @return {@code True} if so. * @return {@code True} if so.
*/ */
public boolean hasTask() { public boolean hasTask() {
return getAmount() != 0; return getAmount() > 0;
} }
/** /**

View file

@ -3,6 +3,8 @@ package core.net.event;
import core.cache.misc.buffer.ByteBufferUtils; import core.cache.misc.buffer.ByteBufferUtils;
import core.net.IoSession; import core.net.IoSession;
import core.net.IoWriteEvent; import core.net.IoWriteEvent;
import rs09.Server;
import rs09.ServerConstants;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -12,11 +14,6 @@ import java.nio.ByteBuffer;
*/ */
public final class MSHSWriteEvent extends IoWriteEvent { public final class MSHSWriteEvent extends IoWriteEvent {
/**
* The password used to verify
*/
private static final String PASSWORD = "0x14ari0SSbh98989910";
/** /**
* Constructs a new {@code MSHSWriteEvent} {@code Object} * Constructs a new {@code MSHSWriteEvent} {@code Object}
* @param session The session. * @param session The session.
@ -28,9 +25,9 @@ public final class MSHSWriteEvent extends IoWriteEvent {
@Override @Override
public void write(IoSession session, Object context) { public void write(IoSession session, Object context) {
ByteBuffer buffer = ByteBuffer.allocate(2 + PASSWORD.length()); ByteBuffer buffer = ByteBuffer.allocate(2 + ServerConstants.MS_SECRET_KEY.length());
buffer.put((byte) 88); buffer.put((byte) 88);
ByteBufferUtils.putString(PASSWORD, buffer); ByteBufferUtils.putString(ServerConstants.MS_SECRET_KEY, buffer);
session.queue((ByteBuffer) buffer.flip()); session.queue((ByteBuffer) buffer.flip());
} }

View file

@ -77,6 +77,7 @@ public final class PacketRepository {
OUTGOING_PACKETS.put(UpdateRandomFile.class, new UpdateRandomFile()); // OUTGOING_PACKETS.put(UpdateRandomFile.class, new UpdateRandomFile()); //
OUTGOING_PACKETS.put(InstancedLocationUpdate.class, new InstancedLocationUpdate()); // OUTGOING_PACKETS.put(InstancedLocationUpdate.class, new InstancedLocationUpdate()); //
OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); // OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); //
OUTGOING_PACKETS.put(Varbit.class, new Varbit());
INCOMING_PACKETS.put(22, new ClientFocusPacket()); INCOMING_PACKETS.put(22, new ClientFocusPacket());
INCOMING_PACKETS.put(93, new PingPacketHandler()); INCOMING_PACKETS.put(93, new PingPacketHandler());
INCOMING_PACKETS.put(44, new CommandPacket()); INCOMING_PACKETS.put(44, new CommandPacket());

View file

@ -0,0 +1,22 @@
package core.net.packet.context;
import core.game.node.entity.player.Player;
import core.net.packet.Context;
public class VarbitContext implements Context {
Player player;
public int varbitId;
public int value;
public VarbitContext(Player player, int varbitId, int value){
this.player = player;
this.varbitId = varbitId;
this.value = value;
}
@Override
public Player getPlayer() {
return player;
}
}

View file

@ -266,6 +266,7 @@ public final class InteractionPacket implements IncomingPacket {
player.debug("dir=" + object.getDirection()); player.debug("dir=" + object.getDirection());
VarbitDefinition def = VarbitDefinition.forObjectID(SceneryDefinition.forId(objectId).getVarbitID()); VarbitDefinition def = VarbitDefinition.forObjectID(SceneryDefinition.forId(objectId).getVarbitID());
player.debug("Varp ID=" + def.getConfigId() + " Offset=" + def.getBitShift() + " Size=" + def.getBitSize()); player.debug("Varp ID=" + def.getConfigId() + " Offset=" + def.getBitShift() + " Size=" + def.getBitSize());
player.debug("Varbit: " + def.getId());
if (option.getHandler() != null) { if (option.getHandler() != null) {
player.debug("Object handler: " + option.getHandler().getClass().getSimpleName()); player.debug("Object handler: " + option.getHandler().getClass().getSimpleName());
} }

View file

@ -0,0 +1,21 @@
package core.net.packet.out;
import core.net.packet.IoBuffer;
import core.net.packet.OutgoingPacket;
import core.net.packet.context.VarbitContext;
public class Varbit implements OutgoingPacket<VarbitContext> {
@Override
public void send(VarbitContext varbitContext) {
IoBuffer buffer;
if(varbitContext.value > 255){
buffer = new IoBuffer(84);
buffer.putLEInt((128 | varbitContext.value) & 255);
} else {
buffer = new IoBuffer(37);
buffer.put((byte) 128 | varbitContext.value);
}
buffer.putLEShort(varbitContext.varbitId);
varbitContext.getPlayer().getSession().write(buffer);
}
}

View file

@ -16,10 +16,14 @@ import rs09.game.system.config.ServerConfigParser
import rs09.game.world.GameWorld import rs09.game.world.GameWorld
import rs09.game.world.repository.Repository import rs09.game.world.repository.Repository
import java.io.File import java.io.File
import java.io.FileWriter
import java.lang.management.ManagementFactory
import java.lang.management.ThreadMXBean
import java.net.BindException import java.net.BindException
import java.util.* import java.util.*
import kotlin.system.exitProcess import kotlin.system.exitProcess
/** /**
* The main class, for those that are unable to read the class' name. * The main class, for those that are unable to read the class' name.
* @author Emperor * @author Emperor
@ -108,6 +112,13 @@ object Server {
while(running){ while(running){
if(System.currentTimeMillis() - lastHeartbeat > 1800 && running){ if(System.currentTimeMillis() - lastHeartbeat > 1800 && running){
SystemLogger.logErr("Triggering reboot due to heartbeat timeout") SystemLogger.logErr("Triggering reboot due to heartbeat timeout")
SystemLogger.logErr("Creating thread dump...")
val dump = threadDump(true, true)
FileWriter("latestdump.txt").use {
it.write(dump)
it.flush()
it.close()
}
exitProcess(0) exitProcess(0)
} }
delay(625) delay(625)
@ -140,6 +151,15 @@ object Server {
return startTime return startTime
} }
private fun threadDump(lockedMonitors: Boolean, lockedSynchronizers: Boolean): String? {
val threadDump = StringBuffer(System.lineSeparator())
val threadMXBean: ThreadMXBean = ManagementFactory.getThreadMXBean()
for (threadInfo in threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
threadDump.append(threadInfo.toString())
}
return threadDump.toString()
}
/** /**
* Sets the bastartTime.ZZ * Sets the bastartTime.ZZ
* @param startTime the startTime to set. * @param startTime the startTime to set.

View file

@ -106,6 +106,9 @@ class ServerConstants {
@JvmField @JvmField
var GE_AUTOSTOCK_ENABLED = false var GE_AUTOSTOCK_ENABLED = false
@JvmField
var MS_SECRET_KEY = ""
//location names for the ::to command. //location names for the ::to command.
val TELEPORT_DESTINATIONS = arrayOf( val TELEPORT_DESTINATIONS = arrayOf(
arrayOf(Location.create(2974, 4383, 2), "corp", "corporal", "corporeal"), arrayOf(Location.create(2974, 4383, 2), "corp", "corporal", "corporeal"),
@ -218,6 +221,9 @@ class ServerConstants {
if(data.containsKey("daily_restart")){ if(data.containsKey("daily_restart")){
DAILY_RESTART = data["daily_restart"] as Boolean DAILY_RESTART = data["daily_restart"] as Boolean
} }
if(data.containsKey("ms_secret_key")) MS_SECRET_KEY = data["ms_secret_key"].toString()
else MS_SECRET_KEY = "2009scape_development"
} }
} }
} }

View file

@ -100,14 +100,17 @@ object ServerStore {
} }
} }
@JvmStatic
fun JSONObject.getString(key: String): String { fun JSONObject.getString(key: String): String {
return this[key] as? String ?: "nothing" return this[key] as? String ?: "nothing"
} }
@JvmStatic
fun JSONObject.getLong(key: String): Long { fun JSONObject.getLong(key: String): Long {
return this[key] as? Long ?: 0L return this[key] as? Long ?: 0L
} }
@JvmStatic
fun JSONObject.getBoolean(key: String): Boolean { fun JSONObject.getBoolean(key: String): Boolean {
return this[key] as? Boolean ?: false return this[key] as? Boolean ?: false
} }

View file

@ -2,6 +2,8 @@ package rs09.game
import core.cache.def.impl.VarbitDefinition import core.cache.def.impl.VarbitDefinition
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.net.packet.PacketRepository
import core.net.packet.context.VarbitContext
import org.json.simple.JSONArray import org.json.simple.JSONArray
import org.json.simple.JSONObject import org.json.simple.JSONObject
import rs09.game.node.entity.skill.farming.FarmingPatch import rs09.game.node.entity.skill.farming.FarmingPatch
@ -32,6 +34,10 @@ class VarpManager(val player: Player) {
get(def.configId).setVarbit(def.bitShift,value).send(player) get(def.configId).setVarbit(def.bitShift,value).send(player)
} }
fun setVarbit(varbitIndex: Int, value: Int){
PacketRepository.send(core.net.packet.out.Varbit::class.java, VarbitContext(player, varbitIndex, value))
}
fun flagSave(index: Int){ fun flagSave(index: Int){
get(index).save = true get(index).save = true
} }

View file

@ -44,10 +44,10 @@ class CerterEventInterface : InterfaceListener() {
player.packetDispatch.sendString(items[correct],CERTER_INTERFACE,optionFromIndex(correctIndex)) player.packetDispatch.sendString(items[correct],CERTER_INTERFACE,optionFromIndex(correctIndex))
val tempOptions = falseOptions val tempOptions = falseOptions.toMutableList()
val false1 = tempOptions.random() val false1 = tempOptions.random()
tempOptions.remove(false1)
var false2 = tempOptions.random() var false2 = tempOptions.random()
while(false1 == false2) false2 = tempOptions.random()
player.packetDispatch.sendString(false1,CERTER_INTERFACE,optionFromIndex(indexes[0])) player.packetDispatch.sendString(false1,CERTER_INTERFACE,optionFromIndex(indexes[0]))
player.packetDispatch.sendString(false2,CERTER_INTERFACE,optionFromIndex(indexes[1])) player.packetDispatch.sendString(false2,CERTER_INTERFACE,optionFromIndex(indexes[1]))

View file

@ -75,10 +75,7 @@ class WorkForInteractionListener : InteractionListener() {
val type = typeMap[node.id] ?: return@on false val type = typeMap[node.id] ?: return@on false
jobId = if(type == 0) { jobId = if(type == 0) {
var job = gatheringMap[node.id]?.random() var job = gatheringMap[node.id]?.filter { checkRequirement(player, it) }?.random()
while(!checkRequirement(player,job)){
job = gatheringMap[node.id]?.random()
}
amount = job?.getAmount() ?: 0 amount = job?.getAmount() ?: 0
job?.ordinal ?: 0 job?.ordinal ?: 0
} else { } else {
@ -111,8 +108,7 @@ class WorkForInteractionListener : InteractionListener() {
fun checkRequirement(player: Player, jobs: GatheringJobs?): Boolean{ fun checkRequirement(player: Player, jobs: GatheringJobs?): Boolean{
jobs ?: return true jobs ?: return true
val requirement: Pair<Int,Int> = Pair(jobs.lvlReq,jobs.skill) if(player.skills.getLevel(jobs.skill) < jobs.lvlReq){
if(player.skills.getLevel(requirement.second) < requirement.first){
return false return false
} }
return true return true

View file

@ -18,9 +18,6 @@ class DSEquipListeners : InteractionListener() {
Items.SARADOMIN_PLATEBODY_2661, Items.SARADOMIN_PLATEBODY_2661,
Items.GUTHIX_PLATEBODY_2669, Items.GUTHIX_PLATEBODY_2669,
Items.GREEN_DHIDE_BODY_1135, Items.GREEN_DHIDE_BODY_1135,
Items.BLUE_DHIDE_BODY_2499,
Items.RED_DHIDE_BODY_2501,
Items.BLACK_DHIDE_BODY_2503,
Items.DHIDE_BODYG_7370, Items.DHIDE_BODYG_7370,
Items.DHIDE_BODY_G_7374, Items.DHIDE_BODY_G_7374,
Items.DHIDE_BODY_T_7372, Items.DHIDE_BODY_T_7372,

View file

@ -216,14 +216,12 @@ class BoneGrinderListener : InteractionListener() {
val bone = Bones.values()[player.getAttribute(LOADED_BONE_KEY,-1)] val bone = Bones.values()[player.getAttribute(LOADED_BONE_KEY,-1)]
player.lock()
Pulser.submit(object : Pulse(){ Pulser.submit(object : Pulse(){
var stage = 0 var stage = 0
override fun pulse(): Boolean { override fun pulse(): Boolean {
when(stage++){ when(stage++){
0 -> { 0 -> player.animator.animate(SCOOP_ANIM)
player.lock()
player.animator.animate(SCOOP_ANIM)
}
SCOOP_ANIM.duration -> { SCOOP_ANIM.duration -> {
player.unlock() player.unlock()
if(player.inventory.remove(Item(Items.EMPTY_POT_1931))){ if(player.inventory.remove(Item(Items.EMPTY_POT_1931))){

View file

@ -41,7 +41,7 @@ class EnchantedValleyListeners : InteractionListener() {
fun getSpirit(player: Player): NPC { fun getSpirit(player: Player): NPC {
val level = player.properties.currentCombatLevel val level = player.properties.currentCombatLevel
var index = Math.ceil(level / 20.0).toInt() var index = Math.ceil(level / 20.0).toInt()
if(index > TREE_SPIRIT_IDS.size) index = TREE_SPIRIT_IDS.size if(index >= TREE_SPIRIT_IDS.size) index = TREE_SPIRIT_IDS.size - 1
return NPC(TREE_SPIRIT_IDS[index]) return NPC(TREE_SPIRIT_IDS[index])
} }
} }

View file

@ -53,8 +53,9 @@ fun getNewTTL(): Int{
} }
fun getNewLoc(): Location { fun getNewLoc(): Location {
var loc = locations.random() val possibleLoc = locations.toTypedArray().toMutableList()
while(usedLocations.contains(loc)) loc = locations.random() possibleLoc.removeAll(usedLocations)
val loc = possibleLoc.random()
usedLocations.add(loc) usedLocations.add(loc)
return loc return loc
} }

View file

@ -18,6 +18,9 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics import core.game.world.update.flag.context.Graphics
import core.net.packet.PacketRepository
import core.net.packet.context.VarbitContext
import core.net.packet.out.Varbit
import core.plugin.Initializable import core.plugin.Initializable
import core.plugin.Plugin import core.plugin.Plugin
import rs09.game.system.command.CommandPlugin import rs09.game.system.command.CommandPlugin
@ -221,14 +224,14 @@ class VisualCommand : CommandPlugin() {
val cfg_index = (args.getOrNull(2)?.toString()?.toInt() ?: -1) val cfg_index = (args.getOrNull(2)?.toString()?.toInt() ?: -1)
if(cfg_index == -1){ if(cfg_index == -1){
ContentAPI.submitWorldPulse(object : Pulse(3, player){ ContentAPI.submitWorldPulse(object : Pulse(3, player){
var pos = 0 var pos = 32
var shift = 0 var shift = 0
override fun pulse(): Boolean { override fun pulse(): Boolean {
for(i in 0..1999){ for(i in 0..1999){
player?.configManager?.forceSet(i, pos shl shift, false) player?.configManager?.forceSet(i, pos shl shift, false)
} }
player?.sendMessage("$pos << $shift") player?.sendMessage("$pos shl $shift")
if(pos++ >= 32){ if(pos++ >= 63){
shift += 4 shift += 4
pos = 0 pos = 0
} }
@ -246,6 +249,27 @@ class VisualCommand : CommandPlugin() {
}) })
} }
} }
"setbit" -> {
if (args!!.size < 2) {
player!!.debug("syntax error: bit value")
return true
}
var bit = toInteger(args[0]!!)
var value = toInteger(args[1]!!)
var val2 = toInteger(args[2]!!)
player!!.debug("$value $val2")
PacketRepository.send(Varbit::class.java, VarbitContext(player, value, val2))
return true
}
"setbits" -> {
args ?: return false
val start = toInteger(args[1]!!)
val end = toInteger(args[2]!!)
val value = toInteger(args[3]!!)
for(i in start until end){
player?.varpManager?.setVarbit(i, value)
}
}
"loop_anim_on_i" -> { "loop_anim_on_i" -> {
var anim = toInteger(args!![1]!!) var anim = toInteger(args!![1]!!)
ContentAPI.submitWorldPulse(object : Pulse(3){ ContentAPI.submitWorldPulse(object : Pulse(3){

View file

@ -32,9 +32,10 @@ class MajorUpdateWorker {
var started = false var started = false
val sequence = UpdateSequence() val sequence = UpdateSequence()
val sdf = SimpleDateFormat("HHmmss") val sdf = SimpleDateFormat("HHmmss")
fun start() = GlobalScope.launch { val worker = Thread {
Thread.currentThread().name = "Major Update Worker"
started = true started = true
delay(600L) Thread.sleep(600L)
while(true){ while(true){
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
val rmlist = ArrayList<Pulse>() val rmlist = ArrayList<Pulse>()
@ -94,7 +95,12 @@ class MajorUpdateWorker {
} }
val end = System.currentTimeMillis() val end = System.currentTimeMillis()
delay(max(600 - (end - start), 0)) Thread.sleep(max(600 - (end - start), 0))
}
}
fun start() {
if(!started){
worker.start()
} }
} }
} }

View file

@ -43,7 +43,8 @@
"database_username": "root", "database_username": "root",
"database_password": "", "database_password": "",
"database_address": "127.0.0.1", "database_address": "127.0.0.1",
"database_port": "3306" "database_port": "3306",
"ms_secret_key": "2009scape_development"
}, },
"PluginToggles": { "PluginToggles": {