Change server config language from JSON to TOML

This commit is contained in:
Ceikry 2021-12-19 03:53:30 +00:00
parent 70a709fb14
commit cd7470ff66
47 changed files with 141 additions and 3346 deletions

View file

@ -76,3 +76,4 @@
< --- ABOVE Released December 15, 2021 https://gitlab.com/2009scape/2009scape/-/tags/Dec-15-2021 ---- >
- Implemented server performance monitor, many performance improvements
- Fishing and fishing trawler now use closer-to-empirical formulae.
- Server configuration language has been changed from JSON to TOML.

View file

@ -23,6 +23,7 @@ repositories {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.5.20'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
implementation group: 'com.moandjiezana.toml', name: 'toml4j', version: '0.7.2'
implementation files(
"libs/PrimitiveExtensions-1.0.jar",
"libs/ConstLib-1.3.jar",

View file

@ -1,193 +0,0 @@
package core.cache;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.HashMap;
import java.util.Map;
import core.cache.misc.buffer.ByteBufferUtils;
/**
* The server data storage.
* @author Emperor
*/
public final class AriosStore {
/**
* The storage.
*/
private static Map<String, StoreFile> storage = new HashMap<>();
/**
* If the store has initialized.
*/
private static boolean initialized;
/**
* Initializes the store.
* @param path The file path.
*/
public static void init(String path) {
storage = new HashMap<>();
File file = new File(path + "/dynamic_cache.keldagrim");
if (file.exists()) {
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
FileChannel channel = raf.getChannel();
ByteBuffer buffer = channel.map(MapMode.READ_WRITE, 0, channel.size());
int size = buffer.getShort() & 0xFFFF;
for (int i = 0; i < size; i++) {
StoreFile store = new StoreFile();
store.setDynamic(true);
String archive = ByteBufferUtils.getString(buffer);
byte[] data = new byte[buffer.getInt()];
buffer.get(data);
store.setData(data);
storage.put(archive, store);
}
if (buffer.hasRemaining()) {
throw new IllegalStateException("Unable to read all dynamic data (size=" + size + ")!");
}
channel.close();
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
initialized = true;
}
/**
* Used for writing the static store.
* @param path The path.
*/
public static void createStaticStore(String path) {
write(path + "/static_cache.keldagrim", false);
}
/**
* Writes all the dynamic storage files (on server termination).
* @param path The path.
*/
public static void dump(String path) {
write(path + "/dynamic_cache.keldagrim", true);
}
/**
* Writes the store file to the given file path.
* @param filePath The file path.
* @param dynamic If the dynamic store is being written.
*/
public static void write(String filePath, boolean dynamic) {
if (!initialized) {
throw new IllegalStateException("Server store has not been initialized!");
}
File f = new File(filePath);
if (f.exists()) {
f.delete();
}
ByteBuffer buffer = ByteBuffer.allocate(1 << 28);
buffer.putShort((short) 0);
int size = 0;
for (String archive : storage.keySet()) {
StoreFile file = storage.get(archive);
if (file.isDynamic() != dynamic) {
continue;
}
size++;
ByteBuffer buf = file.data();
ByteBufferUtils.putString(archive, buffer);
buffer.putInt(buf.remaining());
buffer.put(buf);
}
buffer.putShort(0, (short) size);
buffer.flip();
try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
FileChannel channel = raf.getChannel();
channel.write(buffer);
channel.close();
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Sets the archive data.
* @param archive The archive id.
* @param buffer The readable buffer.
*/
public static void setArchive(String archive, ByteBuffer buffer) {
setArchive(archive, buffer, true);
}
/**
* Sets the archive data.
* @param archive The archive id.
* @param buffer The readable buffer.
* @param dynamic If the data changes during server runtime.
*/
public static void setArchive(String archive, ByteBuffer buffer, boolean dynamic) {
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
setArchive(archive, data, dynamic, true);
}
/**
* Sets the archive data.
* @param archive The archive index.
* @param data The archive data.
* @param dynamic If the data changes during server runtime.
*/
public static void setArchive(String archive, byte[] data, boolean dynamic) {
setArchive(archive, data, dynamic, true);
}
/**
* Sets the archive data.
* @param archive The archive index.
* @param data The archive data.
* @param dynamic If the data changes during server runtime.
* @param overwrite If the archive should be overwritten.
*/
public static void setArchive(String archive, byte[] data, boolean dynamic, boolean overwrite) {
StoreFile file = storage.get(archive);
if (file == null) {
storage.put(archive, file = new StoreFile());
} else if (!overwrite) {
throw new IllegalStateException("Already contained archive " + archive + "!");
}
file.setDynamic(dynamic);
file.setData(data);
}
/**
* Gets the archive data for the given archive id.
* @param archive The archive index.
* @return The archive data.
*/
public static ByteBuffer getArchive(String archive) {
return get(archive).data();
}
/**
* Sets the archive file.
* @param archive The archive.
* @param file The file.
*/
public static void set(String archive, StoreFile file) {
storage.put(archive, file);
}
/**
* Gets the store file for the given archive.
* @param archive The archive id.
* @return The store file.
*/
public static StoreFile get(String archive) {
return storage.get(archive);
}
}

View file

@ -2,8 +2,6 @@ package core.game.content.activity.bountyhunter;
import java.nio.ByteBuffer;
import core.cache.AriosStore;
import core.cache.StoreFile;
import core.cache.misc.buffer.ByteBufferUtils;
import core.game.component.Component;
import core.game.node.entity.player.Player;
@ -53,8 +51,7 @@ public final class BHScoreBoard {
* Initializes the score boards data.
*/
public static void init() {
StoreFile file = AriosStore.get("bh_scores");
if (file == null) { // Indicates no cache exists yet.
/* if (true) { // Indicates no cache exists yet.
return;
}
ByteBuffer buffer = file.data();
@ -65,7 +62,7 @@ public final class BHScoreBoard {
for (int i = 0; i < SIZE; i++) {
ROGUES.scores[i] = buffer.getInt();
ROGUES.names[i] = ByteBufferUtils.getString(buffer);
}
}*/
}
/**
@ -82,7 +79,7 @@ public final class BHScoreBoard {
ByteBufferUtils.putString(ROGUES.names[i], buffer);
}
buffer.flip();
AriosStore.setArchive("bh_scores", buffer);
//AriosStore.setArchive("bh_scores", buffer);
}
/**

View file

@ -8,9 +8,6 @@ import core.game.node.entity.Entity;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.system.script.ScriptContext;
import core.game.system.script.ScriptManager;
import core.game.system.script.context.*;
import core.net.packet.PacketRepository;
import core.net.packet.context.ContainerContext;
import core.net.packet.out.ContainerPacket;
@ -41,11 +38,6 @@ public final class DialogueInterpreter {
*/
private static final Map<Integer, DialoguePlugin> PLUGINS = new HashMap<>();
/**
* The dialogue scripts.
*/
private static final Map<Integer, ScriptContext> SCRIPTS = new HashMap<>();
/**
* a List of dialogue actions.
*/
@ -56,11 +48,6 @@ public final class DialogueInterpreter {
*/
private DialoguePlugin dialogue;
/**
* Scripted dialogue current stage.
*/
private ScriptContext dialogueStage;
/**
* The current dialogue key.
*/
@ -116,16 +103,6 @@ public final class DialogueInterpreter {
} else if (args.length < 1) {
args = new Object[] { dialogueKey };
}
ScriptContext script = SCRIPTS.get(dialogueKey);
if (script != null) {
Object[] arguments = new Object[args.length + 1];
for (int i = 0; i < args.length; i++) {
arguments[i + 1] = args[i];
}
arguments[0] = player;
startScript(script, arguments);
return true;
}
DialoguePlugin plugin = PLUGINS.get(dialogueKey);
if (plugin == null) {
return false;
@ -146,42 +123,12 @@ public final class DialogueInterpreter {
this.dialogue.open(args);
}
/**
* Starts a dialogue script.
* @param script The script.
* @param args The arguments.
*/
public void startScript(ScriptContext script, Object... args) {
startScript(key, script, args);
}
/**
* Starts a dialogue script.
* @param dialogueKey The dialogue key.
* @param script The script.
* @param args The arguments.
*/
public void startScript(int dialogueKey, ScriptContext script, Object... args) {
key = dialogueKey;
(dialogueStage = script).execute(args);
if (script.isInstant()) {
dialogueStage = script = ScriptManager.run(script, args);
}
}
/**
* Handles an dialogue input.
* @param componentId The id of the chatbox component.
* @param buttonId The button id.
*/
public void handle(int componentId, int buttonId) {
if (dialogueStage != null) {
dialogueStage = ScriptManager.run(dialogueStage, player, key, buttonId);
if (!(dialogueStage instanceof PDialInstruction || dialogueStage instanceof NPCDialInstruction || dialogueStage instanceof OptionDialInstruction || dialogueStage instanceof PlainMessageInstruction || dialogueStage instanceof ItemMessageInstruction)) {
player.getInterfaceManager().closeChatbox();
}
return;
}
player.setAttribute("chatbox-buttonid",buttonId);
if((player.getDialogueInterpreter().getDialogue().file != null && player.getDialogueInterpreter().getDialogue().file.getCurrentStage() == END_DIALOGUE) || player.getDialogueInterpreter().getDialogue().stage == END_DIALOGUE){
player.getInterfaceManager().closeChatbox();
@ -202,23 +149,19 @@ public final class DialogueInterpreter {
* @return {@code True} if successful.
*/
public boolean close() {
if (dialogue != null || dialogueStage != null) {
if (dialogue != null) {
actions.clear();
if (player.getInterfaceManager().getChatbox() != null && player.getInterfaceManager().getChatbox().getCloseEvent() != null) {
return true;
}
if (dialogueStage != null) {
dialogueStage = null;
player.getInterfaceManager().closeChatbox();
}
if (dialogue != null) {
DialoguePlugin d = dialogue;
dialogue = null;
d.close();
}
}
return dialogue == null && dialogueStage == null;
return dialogue == null;
}
/**
@ -234,30 +177,6 @@ public final class DialogueInterpreter {
PLUGINS.put(id, plugin);
}
/**
* Adds a dialogue script for the given key.
* @param dialogueKey The dialogue key.
* @param context The dialogue script.
*/
public static void add(int dialogueKey, ScriptContext context) {
if (SCRIPTS.containsKey(dialogueKey)) {
// throw new IllegalArgumentException("Dialogue " + dialogueKey +
// " is already in use - [old=" +
// SCRIPTS.get(dialogueKey).getClass().getSimpleName() + ", new=" +
// context.getClass().getSimpleName() + "]!");
}
SCRIPTS.put(dialogueKey, context);
}
/**
* Gets the script context for the given dialogue key.
* @param key The dialogue key.
* @return The script context.
*/
public static ScriptContext getScript(int key) {
return SCRIPTS.get(key);
}
/**
* Send plain messages based on the amount of specified messages.
* @param messages The messages.
@ -603,22 +522,6 @@ public final class DialogueInterpreter {
return 1 << 16 | name.hashCode();
}
/**
* Gets the dialogueStage.
* @return The dialogueStage.
*/
public ScriptContext getDialogueStage() {
return dialogueStage;
}
/**
* Sets the dialogueStage.
* @param dialogueStage The dialogueStage to set.
*/
public void setDialogueStage(ScriptContext dialogueStage) {
this.dialogueStage = dialogueStage;
}
/**
* Adds a dialogue reward.
* @param action the reward.

View file

@ -1,9 +1,7 @@
package core.game.content.holiday;
import core.cache.AriosStore;
import core.cache.def.impl.ItemDefinition;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@ -32,7 +30,7 @@ public final class ItemLimitation {
* @return {@code True} if parsed.
*/
public boolean parse() {
if (AriosStore.get("hir_limits") == null) {
/* if (AriosStore.get("hir_limits") == null) {
return true;
}
ByteBuffer buffer = AriosStore.getArchive("hir_limits");
@ -41,7 +39,7 @@ public final class ItemLimitation {
int itemId = buffer.getShort() & 0xFFFF;
int amount = buffer.getShort() & 0xFFFF;
ITEMS.put(itemId, amount);
}
}*/
return true;
}
@ -49,14 +47,14 @@ public final class ItemLimitation {
* Dumps the item limitation data.
*/
public static void dump() {
ByteBuffer buffer = ByteBuffer.allocate(ITEMS.size() * 4 + 1);
/* ByteBuffer buffer = ByteBuffer.allocate(ITEMS.size() * 4 + 1);
buffer.put((byte) ITEMS.size());
for (int itemId : ITEMS.keySet()) {
buffer.putShort((short) itemId);
buffer.putShort((short) (int) ITEMS.get(itemId));
}
buffer.flip();
AriosStore.setArchive("hir_limits", buffer);
AriosStore.setArchive("hir_limits", buffer);*/
}
/**

View file

@ -1,171 +0,0 @@
package core.game.node.entity.player.link.spawn;
import core.cache.AriosStore;
import core.cache.StoreFile;
import core.cache.misc.buffer.ByteBufferUtils;
import core.game.component.Component;
import core.game.node.entity.player.Player;
import core.tools.StringUtils;
import java.nio.ByteBuffer;
/**
* The score board.
* @author Emperor
* @author Vexia
*
*/
public final class PKScoreBoard {
/**
* If it's been initialized.
*/
private static boolean initialized;
/**
* The score board size.
*/
private static final int SIZE = 49;
/**
* The names.
*/
private static String[] names = new String[SIZE];
/**
* The scores.
*/
private static int[] scores = new int[SIZE];
/**
* static block
*/
static {
for (int i = 0; i < SIZE; i++) {
names[i] = "Nobody yet";
}
init();
initialized = true;
}
/**
* Initializes the score boards data.
*/
public static void init() {
StoreFile file = AriosStore.get("pk_scores");
if (file == null) { //Indicates no cache exists yet.
return;
}
ByteBuffer buffer = file.data();
for (int i = 0; i < SIZE; i++) {
scores[i] = buffer.getInt();
names[i] = ByteBufferUtils.getString(buffer);
}
}
/**
* Updates the store file for the scores.
*/
public static void update() {
ByteBuffer buffer = ByteBuffer.allocate(5000);
for (int i = 0; i < SIZE; i++) {
buffer.putInt(scores[i]);
ByteBufferUtils.putString(names[i], buffer);
}
buffer.flip();
AriosStore.setArchive("pk_scores", buffer);
}
/**
* Opens the score board.
* @param player The player.
*/
public static void open(Player player) {
if (!initialized) {
initialized = true;
init();
}
int component = 632;
player.getPacketDispatch().sendString("PK Scoreboard", 632, 14);
player.getPacketDispatch().sendString("Top 50 (name - kills):", 632, 13);
player.getInterfaceManager().open(new Component(component));
String msg = "";
for (int i = 0; i < SIZE; i++) {
msg = names[i];
if (!msg.equals("Nobody yet")) {
msg = StringUtils.formatDisplayName(msg) + " - " + scores[i];
}
player.getPacketDispatch().sendString(msg, component, 16 + i);
}
}
/**
* Checks if the ratings of the player is good enough for the score board.
* @param player The player.
*/
public static void check(Player player) {
if(player.isAdmin()) {
return;
}
if (!initialized) {
initialized = true;
init();
}
int score = player.getSavedData().getSpawnData().getKills();
int myScore = 0;
for (int i = 0; i < names.length; i++) {
if (names[i].equals(player.getName())) {
myScore = scores[i];
break;
}
}
if (score == myScore) {
return;
}
for (int i = 0; i < SIZE; i++) {
if (score > scores[i]) {
insert(player, score, i);
update();
break;
}
}
}
/**
* Resets the board.
*/
public static void reset() {
scores = new int[SIZE];
names = new String[SIZE];
for (int i = 0; i < names.length; i++) {
names[i] = "Nobody yet";
}
}
/**
* Inserts the player in the score board.
* @param player The player.
* @param score The score.
* @param index The board index.
*/
private static void insert(Player player, int score, int index) {
if (scores[index] == score) {
return;
}
if (names[index].equals(player.getName())) {
scores[index] = score;
return;
}
for (int i = SIZE - 2; i >= index; i--) {
String name = names[i];
if (name.equals(player.getName())) {
name = names[--i];
}
scores[i + 1] = scores[i];
names[i + 1] = name;
}
names[index] = player.getName();
scores[index] = score;
}
}

View file

@ -442,7 +442,6 @@ public class SpawnData {
if (killStreak > 4) {
Repository.sendNews("<img=10><col=CC6600>News: " + getStreakMessage(killer, killed));
}
PKScoreBoard.check(killer);
}
/**

View file

@ -1,73 +0,0 @@
package core.game.system.script;
/**
* Represents the instruction types.
* @author Emperor
*/
public enum InstructionType {
/**
* The condition type.
*/
CONDITION('$'),
/**
* The instruction type.
*/
INSTRUCTION('*'),
/**
* The method type.
*/
METHOD('#'),
/**
* The local method type.
*/
LOCAL_METHOD('@'),
/**
* The go to type.
*/
GOTO('>'),
/**
* The end bracket type.
*/
END_BRACKET('}');
/**
* Gets the instruction type.
* @param c The character.
* @return The instruction type.
*/
public static InstructionType forIndicator(char c) {
for (InstructionType type : values()) {
if (type.indication == c) {
return type;
}
}
return null;
}
/**
* The character indication.
*/
private final char indication;
/**
* Constructs a new {@code InstructionType} {@code Object}.
* @param indication The indicator.
*/
private InstructionType(char indication) {
this.indication = indication;
}
/**
* Gets the indication.
* @return The indication character.
*/
public char getIndication() {
return indication;
}
}

View file

@ -1,77 +0,0 @@
package core.game.system.script;
/**
* Represents a method call.
* @author Emperor
*/
public final class MethodCall {
/**
* The method name.
*/
private final String methodName;
/**
* The arguments.
*/
private final String arguments;
/**
* The method script.
*/
private ScriptContext script;
/**
* Constructs a new {@code MethodCall} {@code Object}.
* @param methodName The method name.
* @param arguments The arguments.
*/
public MethodCall(String methodName, String arguments) {
this(methodName, arguments, null);
}
/**
* Constructs a new {@code MethodCall} {@code Object}.
* @param methodName The method name.
* @param arguments The arguments.
* @param script The script context.
*/
public MethodCall(String methodName, String arguments, ScriptContext script) {
this.methodName = methodName;
this.arguments = arguments;
this.script = script;
}
/**
* Gets the methodName.
* @return The methodName.
*/
public String getMethodName() {
return methodName;
}
/**
* Gets the arguments.
* @return The arguments.
*/
public String getArguments() {
return arguments;
}
/**
* Gets the script.
* @return The script.
*/
public ScriptContext getScript() {
return script;
}
/**
* Sets the script.
* @param script The script to set.
*/
public void setScript(ScriptContext script) {
this.script = script;
}
}

View file

@ -1,29 +0,0 @@
package core.game.system.script;
/**
* Represents a parameter call.
* @author Emperor
*/
public final class ParamCall {
/**
* The parameter name.
*/
private final String parameter;
/**
* Constructs a new {@code MethodParam} {@code Object}.
* @param parameter The parameter name.
*/
public ParamCall(String parameter) {
this.parameter = parameter;
}
/**
* Gets the parameter.
* @return The parameter.
*/
public String getParameter() {
return parameter;
}
}

View file

@ -1,58 +0,0 @@
package core.game.system.script;
import core.game.system.script.exc.ScriptException;
/**
* Used for building scripts.
* @author Emperor
*/
public abstract class ScriptBuilder {
/**
* The builder arguments.
*/
protected Object[] arguments;
/**
* Constructs a new {@code ScriptBuilder} {@code Object}.
*/
public ScriptBuilder(Object[] arguments) {
this.arguments = arguments;
}
/**
* Parses the builder arguments.
* @param args The arguments to parse.
* @return The builder arguments.
*/
public abstract Object[] parseArguments(String args);
/**
* Initializes the script.
* @param context The script context.
*/
public abstract void configureScript(ScriptContext context);
/**
* Creates a new script builder.
* @param args The arguments.
* @return The builder.
*/
public abstract ScriptBuilder create(Object... args);
/**
* Handles a local method.
* @param name The method name.
* @param context The method script.
* @param current The current script.
*/
public abstract void handleLocalMethod(String name, ScriptContext context, ScriptContext current) throws ScriptException;
/**
* Gets the builder arguments.
* @return The arguments.
*/
public Object[] getArguments() {
return arguments;
}
}

View file

@ -1,599 +0,0 @@
package core.game.system.script;
import rs09.ServerConstants;
import rs09.game.system.SystemLogger;
import rs09.game.ai.AIPBuilder;
import rs09.game.ai.AIPlayer;
import core.game.system.script.exc.InvalidGOTOException;
import core.game.system.script.exc.InvalidInstructionException;
import core.game.system.script.exc.InvalidInterpreterException;
import core.game.system.script.exc.ScriptException;
import rs09.game.world.GameWorld;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.util.*;
/**
* Used for compiling scripts.
* @author Emperor
*/
public final class ScriptCompiler {
/**
* The current line index.
*/
private static int lineId;
/**
* The mapping of methods.
*/
private static Map<String, MethodCall> methodScripts;
/**
* The mapping of method calls.
*/
private static Map<ScriptContext, MethodCall> methodCalls;
/**
* The mapping of fields.
*/
private static Map<String, Object> fields;
/**
* The mapping of field calls.
*/
@SuppressWarnings("unused")
private static Map<ScriptContext, String> fieldCalls;
/**
* The current builder.
*/
private static ScriptBuilder builder;
/**
* The instructions.
*/
private static Map<String, ScriptContext> instructions;
/**
* The main method.
* @param args The arguments cast on runtime.
*/
public static void main(String... args) {
try {
GameWorld.prompt(false);
ScriptContext context = parseRaw(new File(ServerConstants.DIALOGUE_SCRIPTS_PATH + "test.asc"));
AIPlayer player = AIPBuilder.create(null);
context.execute(player);
ScriptManager.run(context, player);
} catch (Throwable e) {
e.printStackTrace();
}
System.exit(0);
}
/**
* Loads the instructions.
* @throws Throwable When an exception occurs.
*/
public static void loadInstructions() throws Throwable {
if (instructions != null) {
return;
}
instructions = new HashMap<>();
for (File file : new File("core/game/system/script/context/").listFiles()) {
String name = file.getName();
if (name.contains("$")) {
continue;
}
Class<?> context = Class.forName("org.crandor.game.system.script.context." + name.replace(".class", ""));
Object object = context.newInstance();
if (object instanceof ScriptContext) {
ScriptContext script = (ScriptContext) object;
instructions.put(script.getName(), script);
}
}
}
/**
* Parses a raw script
* @param file The script file.
* @throws Throwable When an exception occurs.
*/
public static ScriptContext parseRaw(File file) throws Throwable {
loadInstructions();
BufferedReader br = Files.newBufferedReader(file.toPath());
lineId = -1;
String line;
builder = null;
methodScripts = new HashMap<>();
methodCalls = new HashMap<>();
fields = new HashMap<>();
try {
Queue<String> rawScript = new LinkedList<>();
boolean first = true;
while ((line = br.readLine()) != null) {
lineId++;
StringBuilder sb = formatArgument(new StringBuilder(line));
int commentIndex = sb.toString().indexOf("//");
if (commentIndex > -1) {
sb.setLength(commentIndex);
}
if (first && sb.length() > 0) {
first = false;
if (line.charAt(0) == '@') {
builder = createBuilder(sb);
continue;
}
}
rawScript.add(sb.toString());
}
lineId = 0;
if (builder != null) {
lineId++;
}
line = rawScript.poll();
if (line == null) {
br.close();
throw new ScriptException("ScriptAPI " + file.getName() + " is empty!", -1);
}
br.close();
ScriptContext context = parseScript(line, rawScript, new ScriptEntry(null, null, null, false), null);
if (context != null) {
for (ScriptContext caller : methodCalls.keySet()) {
MethodCall call = methodCalls.get(caller);
MethodCall method = methodScripts.get(call.getMethodName());
if (method == null) {
throw new InvalidGOTOException(call.getMethodName() + "", -1);
}
ScriptContext script = method.getScript();
if (call.getArguments() != null && call.getArguments().length() > 0) {
String[] parameterNames = getArguments(method.getArguments());
Object[] values = getParameters(call.getArguments(), 0);
if (values.length != parameterNames.length) {
throw new IllegalArgumentException("Not enough parameters name=" + call.getMethodName() + "!");
}
for (int i = 0; i < parameterNames.length; i++) {
fields.put(parameterNames[i], values[i]);
}
script = checkScriptParameters(script, caller, null);
}
script.setName(call.getMethodName());
caller.setInstruction(script);
}
}
return context;
} catch (ScriptException e) {
e.printStackTrace();
} catch (Throwable t) {
br.close();
throw new ScriptException("Error parsing line " + lineId + "!", t);
}
br.close();
return null;
}
/**
* Checks for parameters.
* @param script The script to check.
* @param original The original script, to prevent infinite looping.
*/
private static ScriptContext checkScriptParameters(ScriptContext script, ScriptContext last, ScriptContext original) {
Object[] copy = null;
for (int i = 0; i < script.parameters.length; i++) {
Object object = script.parameters[i];
if (object instanceof ParamCall) {
if (copy == null) {
copy = Arrays.copyOf(script.parameters, script.parameters.length);
}
ParamCall call = (ParamCall) object;
copy[i] = fields.get(call.getParameter());
if (copy[i] == null) {
System.out.println("Could not find field " + call.getParameter());
}
}
}
if (copy == null) {
copy = script.parameters;
}
ScriptContext context = script.parse(copy);
if (script == last.getCondition()) {
last.setCondition(context);
} else {
last.setInstruction(context);
}
context.setCondition(script.getCondition());
context.setInstruction(script.getInstruction());
if (original == null) {
original = context;
}
script = context;
if (script.getCondition() != null && script.getCondition() != original) {
checkScriptParameters(script.getCondition(), script, original);
}
if (script.getInstruction() != null && script.getInstruction() != original) {
checkScriptParameters(script.getInstruction(), script, original);
}
return script;
}
/**
* Parses the script.
* @param line The first line the parse.
* @param rawScript The script data queue.
* @param script The main script context.
* @throws IOException When an I/O exception occurs.
*/
private static ScriptContext parseScript(String line, Queue<String> rawScript, ScriptEntry script, ScriptContext previous) throws Throwable {
ScriptContext condition = null;
ScriptContext current = null;
InstructionType type = null;
boolean main = script.getName() == null;
stop: while (line != null) {
if (main) {
lineId++;
}
if (line.length() < 1) {
line = rawScript.poll();
continue;
}
char c = line.charAt(0);
Object[] ctx = parse(InstructionType.forIndicator(c), line);
type = (InstructionType) ctx[0];
String name = (String) ctx[1];
String arguments = (String) ctx[2];
boolean bracket = (Boolean) ctx[3];
switch (type) {
case LOCAL_METHOD:
case METHOD:
Queue<String> queue = new LinkedList<>();
queue.add(Boolean.toString(bracket));
String data;
int bracketCount = bracket ? 1 : 0;
while ((data = rawScript.poll()) != null) {
if (main) {
lineId++;
}
c = data.length() > 0 ? data.charAt(0) : 'f';
queue.add(data);
if (data.indexOf('{') > -1) {
bracketCount++;
}
if (parse(InstructionType.forIndicator(c), data)[0] == InstructionType.END_BRACKET) {
bracketCount--;
}
if (bracketCount < 1) {
break;
}
}
queue.poll();
ScriptContext context = parseScript(queue.poll(), queue, new ScriptEntry(null, null, name, bracket), current);
if (type == InstructionType.METHOD) {
methodScripts.put(name, new MethodCall(name, arguments, context));
} else {
handleLocalMethod(name, context, current);
}
break;
case CONDITION:
context = getInstruction(name, arguments);
if (context == null) {
throw new InvalidInstructionException(name, lineId);
}
if (current != null) {
current.setCondition(context);
} else {
condition = context;
}
script = new ScriptEntry(context, script, null, bracket);
current = context;
break;
case INSTRUCTION:
case GOTO:
if (type == InstructionType.GOTO) {
if (name == null) {
name = arguments;
arguments = null;
}
methodCalls.put(current, new MethodCall(name, arguments));
if (!script.isBracket() && script.getPreviousEntry() != null) {
script = script.getPreviousEntry();
current = script.getCurrent();
while (current.getInstruction() != null) {
current = current.getInstruction();
}
}
break;
} else {
context = getInstruction(name, arguments);
if (context == null) {
throw new InvalidInstructionException(name + " - " + arguments, lineId);
}
}
if (script.getCurrent() == null) {
current = context;
script.setCurrent(context);
context.setCondition(condition);
condition = null;
break;
}
current.setInstruction(context);
current = context;
if (!script.isBracket() && script.getPreviousEntry() != null) {
script = script.getPreviousEntry();
current = script.getCurrent();
while (current.getInstruction() != null) {
current = current.getInstruction();
}
}
break;
case END_BRACKET:
if (script.isBracket() && script.getPreviousEntry() != null) {
script = script.getPreviousEntry();
current = script.getCurrent();
while (current.getInstruction() != null) {
current = current.getInstruction();
}
break;
}
break stop;
}
line = rawScript.poll();
}
if (script.getPreviousEntry() != null) {
SystemLogger.logErr("Error parsing " + type + " at line " + lineId + ": " + script.getName() + "!");
}
return script.getCurrent();
}
/**
* Handles a local method.
* @param name The name.
* @param context The method script.
* @param current The current script.
* @throws ScriptException When an exception occurs.
*/
private static void handleLocalMethod(String name, ScriptContext context, ScriptContext current) throws ScriptException {
if (builder != null) {
builder.handleLocalMethod(name, context, current);
}
}
/**
* Gets the instruction for the given name.
* @param name The name.
* @param arguments The arguments.
* @return The script context.
*/
public static ScriptContext getInstruction(String name, String arguments) {
ScriptContext context = instructions.get(name);
if (context != null) {
context = context.parse(getParameters(arguments, 0));
}
// ScriptContext context = builder != null ?
// builder.newInstruction(name, arguments) : null;
// if (context == null) {
// String[] args = getArguments(arguments);
// switch (name) {
// case "startactivity":
// name = args[0];
// context = new StartActivityInstruction(name, getParameters(arguments,
// 1));
// break;
// case "message":
// for (int i = 0; i < args.length; i++) {
// args[i] = getString(args[i]);
// }
// context = new PMessageInstruction(args);
// break;
// case "hasitem":
// Item[] items = new Item[args.length / 2];
// for (int i = 0; i < items.length; i++) {
// items[i] = new Item(Integer.parseInt(args[i]),
// Integer.parseInt(args[i + 1]));
// }
// context = new InvItemCondition(items);
// break;
// }
// }
return context;
}
/**
* Gets the parameters.
* @param arguments The argument line.
* @param offset The offset.
* @return The parameters.
*/
public static Object[] getParameters(String arguments, int offset) {
String[] args = getArguments(arguments);
Object[] params = new Object[args.length - offset];
for (int i = offset; i < params.length; i++) {
Object object = null;
char c = args[i].charAt(0);
if (c == '"') {
object = getString(args[i]);
} else if (Character.isDigit(c)) {
object = Integer.parseInt(args[i]);
} else if (args[i].equals("true")) {
object = true;
} else if (args[i].equals("false")) {
object = false;
} else {
object = new ParamCall(args[i]);
}
params[i - offset] = object;
}
return params;
}
/**
* Gets the string without the surrounding "".
* @param string The string.
* @return The string without surrounding ""s.
*/
public static String getString(String string) {
return string.substring(1, string.length() - 1);
}
/**
* Parses the script context.
* @param type The instruction type.
* @param line The line.
* @return The script context.
*/
private static Object[] parse(InstructionType type, String line) {
int index = 1;
if (type == null) {
index = 0;
type = InstructionType.INSTRUCTION;
}
String instructionName = null;
String arguments = null;
boolean bracketUsed = false;
StringBuilder sb = new StringBuilder();
boolean openingParenthese = false;
boolean string = false;
for (; index < line.length(); index++) {
char ch = line.charAt(index);
if (!string) {
if (ch == ':' && !openingParenthese && type == InstructionType.INSTRUCTION) {
type = InstructionType.METHOD;
instructionName = formatArgument(sb).toString();
sb = new StringBuilder();
continue;
}
if (ch == '(') {
openingParenthese = true;
if (type != InstructionType.METHOD) {
instructionName = formatArgument(sb).toString();
}
sb = new StringBuilder();
continue;
}
if (ch == ')') {
arguments = formatArgument(sb).toString();
sb = new StringBuilder();
continue;
}
if (ch == '{') {
if (type == InstructionType.LOCAL_METHOD) {
instructionName = formatArgument(sb).toString();
sb = new StringBuilder();
}
bracketUsed = true;
break;
}
}
if (ch == '"') {
string = !string;
}
sb.append(ch);
}
if (arguments == null) {
arguments = formatArgument(sb).toString();
}
return new Object[] { type, instructionName, arguments, bracketUsed };
}
/**
* Creates a builder from the arguments.
* @param sb The arguments string builder.
* @return The script builder.
* @throws InvalidInterpreterException When the interpreter could not be
* found.
*/
private static ScriptBuilder createBuilder(StringBuilder sb) throws InvalidInterpreterException {
String[] args = sb.substring(1).toString().replaceFirst(" ", ";").split(";");
ScriptType i = ScriptType.forTag(args[0]);
if (i == null) {
throw new InvalidInterpreterException();
}
StringBuilder s = new StringBuilder();
for (int j = 1; j < args.length; j++) {
if (j != 1) {
s.append(";");
}
s.append(args[j]);
}
Object[] builderArguments = i.getBuilder().parseArguments(formatArgument(s).toString());
return i.getBuilder().create(builderArguments);
}
/**
* Gets the arguments.
* @param argumentLine The argument line.
* @return The arguments.
*/
public static String[] getArguments(String argumentLine) {
String[] args = new String[20];
int size = 0;
StringBuilder sb = new StringBuilder();
boolean string = false;
for (int i = 0; i < argumentLine.length(); i++) {
char c = argumentLine.charAt(i);
if (c == '"') {
string = !string;
}
if (!string) {
if (c == ',') {
args[size++] = sb.toString();
sb = new StringBuilder();
if (size == args.length) {
args = Arrays.copyOf(args, args.length * 2);
}
continue;
}
if (c == ' ') {
continue;
}
}
sb.append(c);
}
if (sb.length() > 0) {
args[size++] = sb.toString();
}
if (size == 0) {
return null;
}
return Arrays.copyOf(args, size);
}
/**
* Formats an argument.
* @return The formatted argument.
*/
public static StringBuilder formatArgument(String string) {
return formatArgument(new StringBuilder(string));
}
/**
* Formats an argument.
* @param sb The argument string builder.
* @return The formatted argument.
*/
public static StringBuilder formatArgument(StringBuilder sb) {
while (sb.length() > 0 && (sb.charAt(0) == ' ' || sb.charAt(0) == ' ')) {
sb.deleteCharAt(0);
}
char c;
while (sb.length() > 0 && ((c = sb.charAt(sb.length() - 1)) == ' ' || c == ' ')) {
sb.deleteCharAt(sb.length() - 1);
}
return sb;
}
/**
* Gets the script builder used.
* @return The script builder.
*/
public static ScriptBuilder getBuilder() {
return builder;
}
}

View file

@ -1,165 +0,0 @@
package core.game.system.script;
/**
* ScriptAPI context, this can be a condition or an instruction.
* @author Emperor
*/
public abstract class ScriptContext {
/**
* The default arguments.
*/
private boolean instant = true;
/**
* The name of this script.
*/
private String name;
/**
* The argument line.
*/
protected Object[] parameters;
/**
* The condition.
*/
private ScriptContext condition;
/**
* The instruction.
*/
private ScriptContext instruction;
/**
* Constructs a new {@code ScriptContext} {@code Object}.
* @param name The script context name.
*/
public ScriptContext(String name) {
this.name = name;
}
/**
* Parses the parameters and creates a new script context object.
* @param params The parameters.
* @return The script context.
*/
public abstract ScriptContext parse(Object... params);
/**
* Executes the script.
* @param args The arguments.
* @return {@code True} if successfully executed.
*/
public abstract boolean execute(Object... args);
/**
* Creates a new instance of this script with the given argument line.
* @param args The argument line.
* @return The script context.
*/
public ScriptContext create(String args) {
ScriptContext context = ScriptCompiler.getInstruction(name, args);
if (context == null) {
return null;
}
context.condition = condition;
context.instruction = instruction;
return context;
}
/**
* Runs the script.
* @param args The script arguments.
* @return {@code True} if successfully executed.
*/
public ScriptContext run(Object... args) {
if (condition != null && condition.execute(args)) {
return condition;
}
if (instruction != null && instruction.execute(args)) {
return instruction;
}
return null;
}
/**
* Gets the name.
* @return The name.
*/
public String getName() {
return name;
}
/**
* Sets the name.
* @param name The name.
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the condition.
* @return The condition.
*/
public ScriptContext getCondition() {
return condition;
}
/**
* Sets the condition.
* @param condition The condition to set.
*/
public void setCondition(ScriptContext condition) {
this.condition = condition;
}
/**
* Gets the instruction.
* @return The instruction.
*/
public ScriptContext getInstruction() {
return instruction;
}
/**
* Sets the instruction.
* @param instruction The instruction to set.
*/
public void setInstruction(ScriptContext instruction) {
this.instruction = instruction;
}
/**
* Gets the instant.
* @return The instant.
*/
public boolean isInstant() {
return instant;
}
/**
* Sets the instant.
* @param instant The instant to set.
*/
public void setInstant(boolean instant) {
this.instant = instant;
}
/**
* Gets the parameters.
* @return The parameters.
*/
public Object[] getParameters() {
return parameters;
}
/**
* Sets the parameters.
* @param parameters The parameters to set.
*/
public void setParameters(Object[] parameters) {
this.parameters = parameters;
}
}

View file

@ -1,104 +0,0 @@
package core.game.system.script;
/**
* A script compiling entry.
* @author Emperor
*/
public class ScriptEntry {
/**
* The current script context.
*/
private ScriptContext current;
/**
* The previous script context.
*/
private ScriptEntry previousEntry;
/**
* The instruction name.
*/
private String name;
/**
* If a bracket was used.
*/
private boolean bracket;
/**
* Constructs a new {@code ScriptEntry} {@code Object}.
* @param current The current script context.
* @param previous The previous script entry.
*/
public ScriptEntry(ScriptContext current, ScriptEntry previous, String name, boolean bracket) {
this.current = current;
this.previousEntry = previous;
this.name = name;
this.bracket = bracket;
}
/**
* Gets the current.
* @return The current.
*/
public ScriptContext getCurrent() {
return current;
}
/**
* Sets the current.
* @param current The current to set.
*/
public void setCurrent(ScriptContext current) {
this.current = current;
}
/**
* Gets the previous.
* @return The previous.
*/
public ScriptEntry getPreviousEntry() {
return previousEntry;
}
/**
* Sets the previous.
* @param previous The previous to set.
*/
public void setPrevious(ScriptEntry previous) {
this.previousEntry = previous;
}
/**
* Gets the bracket.
* @return The bracket.
*/
public boolean isBracket() {
return bracket;
}
/**
* Sets the bracket.
* @param bracket The bracket to set.
*/
public void setBracket(boolean bracket) {
this.bracket = bracket;
}
/**
* Gets the name.
* @return The name.
*/
public String getName() {
return name;
}
/**
* Sets the name.
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
}

View file

@ -1,116 +0,0 @@
package core.game.system.script;
import rs09.ServerConstants;
import rs09.game.system.SystemLogger;
import rs09.game.world.GameWorld;
import java.io.File;
/**
* A class used to manage the loading of scripts.
* @author 'Vexia
*/
public final class ScriptManager {
/**
* The amount of scripts loaded.
*/
private static int amount;
/**
* Method used to load the script manager.
* @param args the arguments.
*/
public static void main(String... args) {
load();
}
/**
* Runs the script and returns the current script context after executing.
* @param context The script to run.
* @param args The arguments.
* @return The last script context executed.
*/
public static ScriptContext run(ScriptContext context, Object... args) {
ScriptContext ctx = context;
do {
ctx = ctx.run(args);
} while (ctx != null && ctx.isInstant());
return ctx;
}
/**
* Runs the script and returns the current script context after executing.
* @param context The script to run.
* @param name The method name.
* @return The method script context.
*/
public static ScriptContext getMethod(ScriptContext context, String name) {
ScriptContext ctx = context;
while (ctx != null) {
if (ctx.getCondition() != null) {
context = getMethod(ctx.getCondition(), name);
if (context != null) {
return context;
}
}
if (ctx.getName().equals(name)) {
// System.out.println(ctx + ", " +
// Arrays.toString(ctx.getParameters()));
return ctx;
}
ctx = ctx.getInstruction();
}
return null;
}
/**
* Initiates the chain reaction of script loading.
*/
public static void load() {
amount = 0;
if(ServerConstants.SCRIPTS_PATH != null)
load(new File(ServerConstants.SCRIPTS_PATH));
SystemLogger.logInfo("Parsed " + amount + " " + GameWorld.getSettings().getName() + " script" + (amount == 1 ? "" : "s") + "...");
}
/**
* Method used to load a script by its path.
* @param path the path.
*/
public static void load(final String path) {
load(new File(path));
}
/**
* Loads scripts from a directory.
* @param directory the directory.
* @throws Throwable the throwable.
*/
public static void load(final File directory) {
try {
for (File file : directory.listFiles()) {
if (file.getName().equals(".DS_Store")) {
continue;
}
//Files to EXCLUDE from loading
if (file.getName().equals("simon_templeton.asc") || file.getName().equals("ardougne_baker.asc") || file.getName().equals("anna_isaakson.asc")){
continue;
}
if (file.isDirectory()) {
load(file);
continue;
}
// ScriptContext context = ScriptCompiler.parseRaw(file);
// if (ScriptCompiler.getBuilder() != null) {
// ScriptCompiler.getBuilder().configureScript(context);
// }
amount++;
}
} catch (Throwable e) {
e.printStackTrace();
SystemLogger.logErr("Error loading at directory - " + directory + "!");
}
}
}

View file

@ -1,78 +0,0 @@
package core.game.system.script;
import core.game.system.script.build.DialogueScriptBuilder;
import java.util.HashMap;
import java.util.Map;
/**
* Represents the information for a script type.
* @author 'Vexia
*/
public enum ScriptType {
DIALOGUE("dialogue", new DialogueScriptBuilder(null));
/**
* The mapping of the script informations.
*/
private static final Map<String, ScriptType> INFOS = new HashMap<>();
/**
* The tag of the script info.
*/
private final String tag;
/**
* The script builder.
*/
private final ScriptBuilder builder;
/**
* Constructs a new {@code ScriptInfo} {@code Object}.
* @param tag the tag.
*/
private ScriptType(String tag, ScriptBuilder builder) {
this.tag = tag;
this.builder = builder;
}
/**
* Gets the script info by the tag.
* @param tag the tag.
* @return the tag.
*/
public static ScriptType forTag(final String tag) {
ScriptType info = INFOS.get(tag);
if (info == null) {
throw new NullPointerException("Error! Unknown script type for tag - " + tag + ".");
}
return info;
}
/**
* Gets the tag.
* @return The tag.
*/
public String getTag() {
return tag;
}
/**
* Gets the builder.
* @return The builder.
*/
public ScriptBuilder getBuilder() {
return builder;
}
/**
* static-block for populating map.
*/
static {
for (ScriptType info : values()) {
INFOS.put(info.getTag(), info);
}
}
}

View file

@ -1,99 +0,0 @@
package core.game.system.script.build;
import core.game.content.dialogue.DialogueInterpreter;
import core.game.system.script.ScriptBuilder;
import core.game.system.script.ScriptCompiler;
import core.game.system.script.ScriptContext;
import core.game.system.script.context.OptionDialInstruction;
import core.game.system.script.exc.InvalidInstructionException;
import core.game.system.script.exc.ScriptException;
import java.util.Arrays;
/**
* Handles dialogue script building.
* @author Emperor
*/
public final class DialogueScriptBuilder extends ScriptBuilder {
/**
* Constructs a new {@code DialogueScriptBuilder} {@code Object}.
* @param args The builder arguments.
*/
public DialogueScriptBuilder(Object[] args) {
super(args);
}
@Override
public void configureScript(ScriptContext context) {
if (arguments[0] instanceof String) {
for (int i = 0; i < arguments.length; i++) {
DialogueInterpreter.add(DialogueInterpreter.getDialogueKey((String) arguments[i]), context);
}
return;
}
for (int i = 0; i < arguments.length; i++) {
DialogueInterpreter.add((Integer) arguments[i], context);
}
}
@Override
public ScriptBuilder create(Object... args) {
return new DialogueScriptBuilder(args);
}
@Override
public Object[] parseArguments(String args) {
Object[] objects = null;
if (args.startsWith("npc:")) {
args = args.replace("npc:", "").replaceAll(" ", "");
String[] str = args.split(",");
objects = new Object[str.length];
for (int i = 0; i < str.length; i++) {
objects[i] = Integer.parseInt(str[i]);
}
} else if (args.startsWith("type:")) {
args = args.replace("npc:", "");
objects = new Object[20];
int length = 0;
StringBuilder sb = new StringBuilder();
boolean creating = false;
for (int i = 0; i < args.length(); i++) {
char c = args.charAt(i);
if (c == '"') {
if (creating && sb.length() > 0) {
objects[length++] = sb.toString();
sb = new StringBuilder();
}
creating = !creating;
continue;
}
if (creating) {
sb.append(c);
}
}
objects = Arrays.copyOf(objects, length);
}
return objects;
}
@Override
public void handleLocalMethod(String name, ScriptContext context, ScriptContext current) throws ScriptException {
if (name.startsWith("option")) {
if (!(current instanceof OptionDialInstruction)) {
throw new InvalidInstructionException("Can't set local method option for instruction " + current + "!", -1);
}
OptionDialInstruction ins = (OptionDialInstruction) current;
StringBuilder sb = new StringBuilder(name.substring("option".length()));
int index = Integer.parseInt(ScriptCompiler.formatArgument(sb).toString());
index -= 1;
if (index < 0 || index >= ins.getOptionHandlers().length) {
throw new IllegalArgumentException("Index out of bounds - " + index + "!");
}
// System.out.println("Setting index " + index + " (" + name + "), "
// + context);
ins.getOptionHandlers()[index] = context;
}
}
}

View file

@ -1,63 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.system.script.ScriptContext;
/**
* Used for adding an item to the inventory.
* @author 'Vexia
*/
public final class AddItemInstruction extends ScriptContext {
/**
* The id of the item.
*/
private final int id;
/**
* The amount to add.
*/
private final int amount;
/**
* Constructs a new {@code PauseInstruction} {@code Object}.
*/
public AddItemInstruction() {
this(-1, -1);
}
/**
* Constructs a new {@code AddItemInstruction} {@code Object}.
* @param id the id.
* @param amount the amount.
*/
public AddItemInstruction(int id, int amount) {
super("additem");
this.id = id;
this.amount = amount;
}
@Override
public ScriptContext parse(Object... params) {
int id = 0;
int amount = 0;
if (params[0] instanceof Integer) {
id = (Integer) params[0];
}
if (params[1] instanceof Integer) {
amount = (Integer) params[1];
}
AddItemInstruction context = new AddItemInstruction(id, amount);
context.parameters = params;
return context;
}
@Override
public boolean execute(final Object... args) {
final Player player = (Player) args[0];
player.getInventory().add(new Item(id, amount), player);
return true;
}
}

View file

@ -1,50 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.Entity;
import core.game.system.script.ScriptContext;
/**
* Used to check current random value (set by setrandom(value) instruction).
* @author Emperor
*/
public final class CheckRandomCondition extends ScriptContext {
/**
* Sets the value.
*/
private final int value;
/**
* Constructs a new {@code CheckRandomCondition} {@code Object}.
*/
public CheckRandomCondition() {
this(0);
}
/**
* Constructs a new {@code CheckRandomCondition} {@code Object}.
* @param value The value.
*/
public CheckRandomCondition(int value) {
super("israndom");
this.value = value;
}
@Override
public ScriptContext parse(Object... params) {
int value = 0;
if (params[0] instanceof Integer) {
value = (Integer) params[0];
}
CheckRandomCondition context = new CheckRandomCondition(value);
context.parameters = params;
return context;
}
@Override
public boolean execute(Object... args) {
System.out.println("CheckRandomCondition:" + (String) ((Entity) args[0]).getAttribute("asc_random") );
return ((Entity) args[0]).getAttribute("asc_random", 0) == value;
}
}

View file

@ -1,58 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* ScriptAPI condition for checking if a player has an item in the inventory.
* @author Emperor
*/
public final class InvItemCondition extends ScriptContext {
/**
* The items required.
*/
private final Item[] items;
/**
* Constructs a new {@code InvItemCondition} {@code Object}.
*/
public InvItemCondition() {
this(null);
}
/**
* Constructs a new {@code InvItemCondition} {@code Object}.
* @param items the items required.
*/
public InvItemCondition(Item[] items) {
super("hasitem");
this.items = items;
}
@Override
public boolean execute(Object... args) {
return ((Player) args[0]).getInventory().containsItems(items);
}
@Override
public ScriptContext parse(Object... params) {
Item[] items = new Item[params.length / 2];
int index = 0;
for (int i = 0; i < params.length; i++) {
if (params[i] instanceof Integer) {
items[index++] = new Item((Integer) params[i], (Integer) params[i + 1]);
i++;
}
}
if (index != items.length) {
items = Arrays.copyOf(items, index);
}
ScriptContext context = new InvItemCondition(items);
context.setParameters(params);
return context;
}
}

View file

@ -1,55 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
/**
* Handles a send item message to a player.
* @author 'Vexia
*/
public class ItemMessageInstruction extends ScriptContext {
/**
* The item id.
*/
private final int id;
/**
* The message to send.
*/
private final String message;
/**
* Constructs a new {@code PlainMessageInstruction} {@code Object}.
*/
public ItemMessageInstruction() {
this(-1, null);
}
/**
* Constructs a new {@code PlainMessageInstruction} {@code Object}.
*/
public ItemMessageInstruction(int id, final String message) {
super("itemmessage");
super.setInstant(false);
this.id = id;
this.message = message;
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
player.getDialogueInterpreter().sendItemMessage(id, message);
player.getDialogueInterpreter().setDialogueStage(this);
return true;
}
@Override
public ScriptContext parse(Object... params) {
int id = (Integer) params[0];
String message = (String) params[1];
ItemMessageInstruction context = new ItemMessageInstruction(id, message);
context.parameters = params;
return context;
}
}

View file

@ -1,124 +0,0 @@
package core.game.system.script.context;
import core.game.content.dialogue.FacialExpression;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.system.script.ParamCall;
import core.game.system.script.ScriptCompiler;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* The NPC dialogue instruction.
* @author Emperor
*/
public final class NPCDialInstruction extends ScriptContext {
/**
* The messages.
*/
private final String[] messages;
/**
* The facial expression.
*/
private final int expression;
/**
* If the continue option should be hidden.
*/
private boolean hideContinue;
/**
* The NPC id to show for this dialogue.
*/
private int forceNPCId;
/**
* Constructs a new {@code PDialInstruction} {@code Object}.
*/
public NPCDialInstruction() {
this(null, -1);
}
/**
* Constructs a new {@code PDialInstruction} {@code Object}.
* @param messages The messages.
* @param expression The facial expression animation id.
*/
public NPCDialInstruction(String[] messages, int expression) {
super("npc");
super.setInstant(false);
this.messages = messages;
this.expression = expression;
}
@Override
// Arguments should be [player, npc]!
public boolean execute(Object... args) {
Player player = (Player) args[0]; // 1 = NPC
int npcId = -1;
if (args[1] instanceof NPC) {
npcId = ((NPC) args[1]).getId();
} else {
npcId = (Integer) args[1];
}
String[] messages = new String[this.messages.length];
for (int i = 0; i < messages.length; i++) {
String message = this.messages[i];
if (message.contains(">playername<")) {
message = message.replace(">playername<", player.getUsername());
}
messages[i] = message;
}
player.getDialogueInterpreter().sendDialogues(forceNPCId == -1 ? npcId : forceNPCId, expression, hideContinue, messages);
player.getDialogueInterpreter().setDialogueStage(this);
return true;
}
@Override
public ScriptContext parse(Object... params) {
String[] messages = new String[6];
int messageIndex = 0;
int expression = FacialExpression.HALF_GUILTY.getAnimationId();
int npcId = -1;
boolean hide = false;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof ParamCall) {
String param = ((ParamCall) o).getParameter();
if (param.startsWith("anim:")) {
String expr = ScriptCompiler.formatArgument(param.substring("anim:".length())).toString();
FacialExpression exp = null;
for (FacialExpression e : FacialExpression.values()) {
if (e.name().equals(expr)) {
exp = e;
break;
}
}
if (exp != null) {
expression = exp.getAnimationId();
} else {
expression = Integer.parseInt(expr);
}
} else if (param.startsWith("hidecont:")) {
hide = Boolean.parseBoolean(ScriptCompiler.formatArgument(param.substring("hidecont:".length())).toString());
} else if (param.startsWith("npc:")) {
npcId = Integer.parseInt(ScriptCompiler.formatArgument(param.substring("npc:".length())).toString());
}
} else if (o instanceof String) {
messages[messageIndex++] = (String) o;
}
}
if (messageIndex != messages.length) {
messages = Arrays.copyOf(messages, messageIndex);
}
NPCDialInstruction context = new NPCDialInstruction(messages, expression);
context.forceNPCId = npcId;
context.hideContinue = hide;
context.parameters = params;
return context;
}
}

View file

@ -1,136 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import rs09.game.system.SystemLogger;
import core.game.system.script.ParamCall;
import core.game.system.script.ScriptCompiler;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* Sends an option dialogue.
* @author Emperor
*/
public final class OptionDialInstruction extends ScriptContext {
/**
* The title.
*/
private final String title;
/**
* The options.
*/
private final String[] options;
/**
* The option handlers.
*/
private final ScriptContext[] optionHandlers;
/**
* Constructs a new {@code OptionDialInstruction} {@code Object}.
*/
public OptionDialInstruction() {
this(null);
}
/**
* Constructs a new {@code OptionDialInstruction} {@code Object}.
* @param title The title.
* @param options The options.
*/
public OptionDialInstruction(String title, String... options) {
super("option");
super.setInstant(false);
this.title = title;
this.options = options;
this.optionHandlers = new ScriptContext[options.length];
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
player.getDialogueInterpreter().sendOptions(title, options);
player.getDialogueInterpreter().setDialogueStage(this);
return true;
}
@Override
public ScriptContext parse(Object... params) {
String[] messages = new String[params.length];
int messageIndex = 0;
String title = null;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof String) {
messages[messageIndex++] = (String) o;
} else if (o instanceof ParamCall) {
String param = ((ParamCall) o).getParameter();
if (param.startsWith("title:")) {
title = ScriptCompiler.formatArgument(param.substring("title:".length())).toString();
} else {
messages[messageIndex++] = param;
}
}
}
if (messageIndex != messages.length) {
messages = Arrays.copyOf(messages, messageIndex);
}
OptionDialInstruction context = new OptionDialInstruction(title, messages);
for (int i = 0; i < context.optionHandlers.length; i++) {
if (i < optionHandlers.length) {
context.optionHandlers[i] = optionHandlers[i];
}
}
context.parameters = params;
return context;
}
@Override
public ScriptContext create(String args) {
System.out.println("OptionDialInstruction: " + args);
ScriptContext context = super.create(args);
if (context != null) {
OptionDialInstruction other = (OptionDialInstruction) context;
for (int i = 0; i < other.optionHandlers.length; i++) {
if (i >= optionHandlers.length) {
break;
}
other.optionHandlers[i] = optionHandlers[i];
}
}
return context;
}
@Override
public ScriptContext run(Object... args) {
if (args.length < 3) {
return null;
}
int option = (Integer) args[2] - 1;
if (option > optionHandlers.length -1) {
SystemLogger.logErr("Error! Option out of bounds for option handlers.");
return null;
}
ScriptContext context = optionHandlers[option];
if (context == null) {
SystemLogger.logErr("No option handler found!");
((Player) args[0]).getDialogueInterpreter().close();
return null;
}
context.execute(args);
return context;
}
/**
* Gets the optionHandlers.
* @return The optionHandlers.
*/
public ScriptContext[] getOptionHandlers() {
return optionHandlers;
}
}

View file

@ -1,110 +0,0 @@
package core.game.system.script.context;
import core.game.content.dialogue.FacialExpression;
import core.game.node.entity.player.Player;
import core.game.system.script.ParamCall;
import core.game.system.script.ScriptCompiler;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* Player dialogue instruction.
* @author Emperor
*/
public class PDialInstruction extends ScriptContext {
/**
* The messages.
*/
private final String[] messages;
/**
* The facial expression.
*/
private final int expression;
/**
* If the continue option should be hidden.
*/
private boolean hideContinue;
/**
* Constructs a new {@code PDialInstruction} {@code Object}.
*/
public PDialInstruction() {
this(null, -1);
}
/**
* Constructs a new {@code PDialInstruction} {@code Object}.
* @param messages The messages.
* @param expression The facial expression animation id.
*/
public PDialInstruction(String[] messages, int expression) {
super("player");
super.setInstant(false);
this.messages = messages;
this.expression = expression;
}
@Override
// Arguments should be [player, npc]!
public boolean execute(Object... args) {
Player player = (Player) args[0]; // 1 = NPC
String[] messages = new String[this.messages.length];
for (int i = 0; i < messages.length; i++) {
String message = this.messages[i];
if (message.contains(">playername<")) {
message = message.replace(">playername<", player.getUsername());
}
messages[i] = message;
}
player.getDialogueInterpreter().sendDialogues(player, expression, hideContinue, messages);
player.getDialogueInterpreter().setDialogueStage(this);
return true;
}
@Override
public ScriptContext parse(Object... params) {
String[] messages = new String[6];
int messageIndex = 0;
int expression = FacialExpression.HALF_GUILTY.getAnimationId();
boolean hide = false;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof ParamCall) {
String param = ((ParamCall) o).getParameter();
if (param.startsWith("anim:")) {
String expr = ScriptCompiler.formatArgument(param.substring("anim:".length())).toString();
FacialExpression exp = null;
for (FacialExpression e : FacialExpression.values()) {
if (e.name().equals(expr)) {
exp = e;
break;
}
}
if (exp != null) {
expression = exp.getAnimationId();
} else {
expression = Integer.parseInt(expr);
}
} else if (param.startsWith("hidecont:")) {
hide = Boolean.parseBoolean(ScriptCompiler.formatArgument(param.substring("hidecont:".length())).toString());
} else {
messages[messageIndex++] = param;
}
} else if (o instanceof String) {
messages[messageIndex++] = (String) o;
}
}
if (messageIndex != messages.length) {
messages = Arrays.copyOf(messages, messageIndex);
}
PDialInstruction context = new PDialInstruction(messages, expression);
context.hideContinue = hide;
context.parameters = params;
return context;
}
}

View file

@ -1,66 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* Handles a send message to player instruction.
* @author Emperor
*/
public class PMessageInstruction extends ScriptContext {
/**
* The messages to send.
*/
private final String[] messages;
/**
* Constructs a new {@code PMessageInstruction} {@code Object}.
*/
public PMessageInstruction() {
this(null);
}
/**
* Constructs a new {@code PMessageInstruction} {@code Object}.
* @param messages The messages.
*/
public PMessageInstruction(String[] messages) {
super("message");
this.messages = messages;
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
for (String s : messages) {
player.getPacketDispatch().sendMessage(s);
}
return true;
}
@Override
public String toString() {
return Arrays.toString(messages);
}
@Override
public ScriptContext parse(Object... params) {
String[] messages = new String[params.length];
int messageIndex = 0;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof String) {
messages[messageIndex++] = (String) o;
}
}
if (messageIndex != messages.length) {
messages = Arrays.copyOf(messages, messageIndex);
}
PMessageInstruction context = new PMessageInstruction(messages);
context.parameters = params;
return context;
}
}

View file

@ -1,59 +0,0 @@
package core.game.system.script.context;
import core.game.system.script.ScriptContext;
import core.game.system.script.ScriptManager;
import core.game.system.task.Pulse;
import rs09.game.world.GameWorld;
/**
* Used for pausing the script.
* @author Emperor
*/
public final class PauseInstruction extends ScriptContext {
/**
* The amount of ticks to pause for.
*/
private final int ticks;
/**
* Constructs a new {@code PauseInstruction} {@code Object}.
*/
public PauseInstruction() {
this(-1);
}
/**
* Constructs a new {@code PauseInstruction} {@code Object}.
* @param ticks The amount of ticks to pause for.
*/
public PauseInstruction(int ticks) {
super("pause");
super.setInstant(false);
this.ticks = ticks;
}
@Override
public ScriptContext parse(Object... params) {
int ticks = -1;
if (params[0] instanceof Integer) {
ticks = (Integer) params[0];
}
PauseInstruction context = new PauseInstruction(ticks);
context.parameters = params;
return context;
}
@Override
public boolean execute(final Object... args) {
GameWorld.getPulser().submit(new Pulse(ticks) {
@Override
public boolean pulse() {
ScriptManager.run(PauseInstruction.this, args);
return true;
}
});
return true;
}
}

View file

@ -1,66 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* Handles a send dialogue plain message to a player.
* @author Emperor
*/
public class PlainMessageInstruction extends ScriptContext {
/**
* The messages to send.
*/
private final String[] messages;
/**
* Constructs a new {@code PlainMessageInstruction} {@code Object}.
*/
public PlainMessageInstruction() {
this(null);
}
/**
* Constructs a new {@code PlainMessageInstruction} {@code Object}.
* @param messages the messages.
*/
public PlainMessageInstruction(String[] messages) {
super("plainmessage");
super.setInstant(false);
this.messages = messages;
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
player.getDialogueInterpreter().sendDialogue(messages);
player.getDialogueInterpreter().setDialogueStage(this);
return true;
}
@Override
public String toString() {
return Arrays.toString(messages);
}
@Override
public ScriptContext parse(Object... params) {
String[] messages = new String[params.length];
int messageIndex = 0;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof String) {
messages[messageIndex++] = (String) o;
}
}
if (messageIndex != messages.length) {
messages = Arrays.copyOf(messages, messageIndex);
}
PlainMessageInstruction context = new PlainMessageInstruction(messages);
context.parameters = params;
return context;
}
}

View file

@ -1,66 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.system.script.ScriptContext;
/**
* Used for removing an item to the inventory.
* @author 'Vexia
*/
public final class RemoveItemInstruction extends ScriptContext {
/**
* The id of the item.
*/
private final int id;
/**
* The amount to add.
*/
private final int amount;
/**
* Constructs a new {@code RemoveItemInstruction} {@code Object}.
*/
public RemoveItemInstruction() {
this(-1, -1);
}
/**
* Constructs a new {@code AddItemInstruction} {@code Object}.
* @param id the id.
* @param amount the amount.
*/
public RemoveItemInstruction(int id, int amount) {
super("removeitem");
this.id = id;
this.amount = amount;
}
@Override
public ScriptContext parse(Object... params) {
int id = 0;
int amount = 0;
if (params[0] instanceof Integer) {
id = (Integer) params[0];
}
if (params[1] instanceof Integer) {
amount = (Integer) params[1];
}
RemoveItemInstruction context = new RemoveItemInstruction(id, amount);
context.parameters = params;
return context;
}
@Override
public boolean execute(final Object... args) {
final Player player = (Player) args[0];
final Item item = new Item(id, amount);
if (!player.getInventory().containsItem(item)) {
return false;
}
return player.getInventory().remove(item);
}
}

View file

@ -1,63 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
/**
* Sets an attribute.
* @author Emperor
*/
public final class SetAttributeInstruction extends ScriptContext {
/**
* The attribute key
*/
private final String key;
/**
* The object.
*/
private final Object value;
/**
* Constructs a new {@code PMessageInstruction} {@code Object}.
*/
public SetAttributeInstruction() {
this(null, null);
}
/**
* Constructs a new {@code SetAttributeInstruction} {@code Object}.
* @param key The attribute key.
* @param value The value.
*/
public SetAttributeInstruction(String key, Object value) {
super("setattribute");
this.key = key;
this.value = value;
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
player.setAttribute(key, value);
return true;
}
@Override
public ScriptContext parse(Object... params) {
String key = null;
Object value = null;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof String && key == null) {
key = (String) o;
} else {
value = o;
}
}
SetAttributeInstruction context = new SetAttributeInstruction(key, value);
context.parameters = params;
return context;
}
}

View file

@ -1,51 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.Entity;
import core.game.system.script.ScriptContext;
import core.tools.RandomFunction;
/**
* Sets a random value.
* @author Emperor
*/
public final class SetRandomInstruction extends ScriptContext {
/**
* Sets the value.
*/
private final int value;
/**
* Constructs a new {@code SetRandomInstruction} {@code Object}.
*/
public SetRandomInstruction() {
this(1);
}
/**
* Constructs a new {@code SetRandomInstruction} {@code Object}.
* @param value The value.
*/
public SetRandomInstruction(int value) {
super("setrandom");
this.value = value;
}
@Override
public ScriptContext parse(Object... params) {
int value = 0;
if (params[0] instanceof Integer) {
value = (Integer) params[0];
}
SetRandomInstruction context = new SetRandomInstruction(value);
context.parameters = params;
return context;
}
@Override
public boolean execute(Object... args) {
((Entity) args[0]).setAttribute("asc_random", RandomFunction.randomize(value));
return true;
}
}

View file

@ -1,55 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
import core.game.world.map.RegionManager;
/**
* Handles the opening of a shop instruction.
* @author 'Vexia
*/
public class ShopInstruction extends ScriptContext {
/**
* The id to open.
*/
private int id;
/**
* Constructs a new {@code ShopInstruction} {@code Object}.
*/
public ShopInstruction() {
this(-1);
}
/**
* Constructs a new {@code ShopInstruction} {@code Object}.
* @param id the id.
*/
public ShopInstruction(int id) {
super("openshop");
this.setInstant(false);
this.id = id;
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
NPC n = RegionManager.getNpc(player, id);
n.openShop(player);
return true;
}
@Override
public ScriptContext parse(Object... params) {
int id = -1;
if (params[0] instanceof Integer) {
id = (Integer) params[0];
}
ShopInstruction context = new ShopInstruction(id);
context.parameters = params;
return context;
}
}

View file

@ -1,78 +0,0 @@
package core.game.system.script.context;
import core.game.content.activity.ActivityManager;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
import java.util.Arrays;
/**
* The start activity instruction.
* @author Emperor
*/
public final class StartActivityInstruction extends ScriptContext {
/**
* The activity to start.
*/
private final String activity;
/**
* The arguments.
*/
private final Object[] arguments;
/**
* Constructs a new {@code StartActivityInstruction} {@code Object}.
*/
public StartActivityInstruction() {
this(null);
}
/**
* Constructs a new {@code StartActivityInstruction} {@code Object}.
* @param activity The name of the activity to start.
* @param arguments The arguments.
*/
public StartActivityInstruction(String activity, Object... arguments) {
super("startactivity");
this.activity = activity;
this.arguments = arguments;
}
@Override
public boolean execute(Object... args) {
Player player = (Player) args[0];
args = new Object[arguments.length + 1];
args[0] = player;
for (int i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
// System.out.println("Starting activity " + activity + " - " +
// Arrays.toString(args));
ActivityManager.start(player, activity, false, args);
return true;
}
@Override
public ScriptContext parse(Object... params) {
String activityName = null;
Object[] args = new Object[params.length - 1];
int paramIndex = 0;
for (int i = 0; i < params.length; i++) {
Object o = params[i];
if (o instanceof String && activityName == null) {
activityName = (String) o;
continue;
}
args[paramIndex++] = params[i];
}
if (paramIndex != args.length) {
args = Arrays.copyOf(args, paramIndex);
}
StartActivityInstruction context = new StartActivityInstruction(activityName, args);
context.parameters = params;
return context;
}
}

View file

@ -1,30 +0,0 @@
package core.game.system.script.context;
import core.game.node.entity.player.Player;
import core.game.system.script.ScriptContext;
/**
* ScriptAPI condition for checking if a player has warrior guild tokens.
* @author 'Vexia
*/
public final class WGuildTokenCondition extends ScriptContext {
/**
* Constructs a new {@code WGuildTokenCondition} {@code Object}.
*/
public WGuildTokenCondition() {
super("hasWarriorTokens");
}
@Override
public boolean execute(Object... args) {
return ((Player) args[0]).getSavedData().getActivityData().getWarriorGuildTokens() > 0;
}
@Override
public ScriptContext parse(Object... params) {
ScriptContext context = new WGuildTokenCondition();
context.setParameters(params);
return context;
}
}

View file

@ -1,29 +0,0 @@
package core.game.system.script.exc;
/**
* Thrown when a GOTO method name could not be found.
* @author Emperor
*/
public final class InvalidGOTOException extends ScriptException {
/**
* The serial UID.
*/
private static final long serialVersionUID = 8909510580401378793L;
/**
* Constructs a new {@code InvalidGOTOException} {@code Object}.
* @param lineId The parsing line id.
*/
public InvalidGOTOException(int lineId) {
super(lineId);
}
/**
* Constructs a new {@code InvalidGOTOException} {@code Object}.
* @param lineId The parsing line id.
*/
public InvalidGOTOException(String cause, int lineId) {
super(cause, lineId);
}
}

View file

@ -1,29 +0,0 @@
package core.game.system.script.exc;
/**
* Thrown when an instruction could not be found.
* @author Emperor
*/
public class InvalidInstructionException extends ScriptException {
/**
* The serial UID.
*/
private static final long serialVersionUID = -7969980063835245652L;
/**
* Constructs a new {@code InvalidInstructionException} {@code Object}.
* @param lineId The parsing line id.
*/
public InvalidInstructionException(int lineId) {
super(lineId);
}
/**
* Constructs a new {@code InvalidInstructionException} {@code Object}.
* @param lineId The parsing line id.
*/
public InvalidInstructionException(String cause, int lineId) {
super(cause, lineId);
}
}

View file

@ -1,38 +0,0 @@
package core.game.system.script.exc;
/**
* An exception thrown when the interpreter could not be found.
* @author Emperor
*/
public final class InvalidInterpreterException extends ScriptException {
/**
* The serial UID.
*/
private static final long serialVersionUID = 6096860966849544737L;
/**
* Constructs a new {@code InvalidInterpreterException} {@code Object}.
*/
public InvalidInterpreterException() {
super();
}
/**
* Constructs a new {@code InvalidInterpreterException} {@code Object}.
* @param lineId The line id.
*/
public InvalidInterpreterException(int lineId) {
super(lineId);
}
/**
* Constructs a new {@code InvalidInterpreterException} {@code Object}.
* @param cause The cause.
* @param lineId The parsing line id.
*/
public InvalidInterpreterException(String cause, int lineId) {
super(cause, lineId);
}
}

View file

@ -1,55 +0,0 @@
package core.game.system.script.exc;
/**
* An exception thrown when compiling an asc script.
* @author 'Vexia
*/
public class ScriptException extends Exception {
/**
* The serial version UID.
*/
private static final long serialVersionUID = -1328749105522163758L;
/**
* The line index.
*/
protected final int lineId;
/**
* Constructs a new {@code ScriptException} {@code Object}.
*/
public ScriptException() {
this(-1);
}
/**
* Constructs a new {@code ScriptException} {@code Object}.
* @param lineId The parsing line id.
*/
public ScriptException(int lineId) {
super();
this.lineId = lineId;
}
/**
* Constructs a new {@code ScriptException} {@code Object}.
* @param message the message.
* @param lineId The parsing line id.
*/
public ScriptException(final String message, int lineId) {
super("Error parsing line " + lineId + ": " + message);
this.lineId = lineId;
}
/**
* Constructs a new {@code ScriptException} {@code Object}.
* @param message The error message.
* @param cause The cause.
*/
public ScriptException(String message, Throwable cause) {
super(message, cause);
lineId = -1;
}
}

View file

@ -1,23 +0,0 @@
package core.game.system.script.exc;
/**
* An exception thrown when the script type is unknown.
* @author Emperor
*/
public class UnknownScriptException extends ScriptException {
/**
* The serial UID.
*/
private static final long serialVersionUID = -4897522544605020858L;
/**
* Constructs a new {@code UnknownScriptException} {@code Object}.
* @param message The cause.
* @param lineId The parsing line index.
*/
public UnknownScriptException(String message, int lineId) {
super(message, lineId);
}
}

View file

@ -328,7 +328,7 @@ public class IoSession {
* @return The player.
*/
public Player getPlayer() {
return (Player) object;
return object instanceof Player ? ((Player) object) : null;
}
/**

View file

@ -167,7 +167,7 @@ public class ActionButtonPacket implements IncomingPacket {
slot = buffer.getLEShort();
componentId = data >> 16;
buttonId = data & 0xffff;
if (player.getDialogueInterpreter().getDialogue() == null && player.getDialogueInterpreter().getDialogueStage() == null) {
if (player.getDialogueInterpreter().getDialogue() == null) {
player.getInterfaceManager().closeChatbox();
List<DialogueAction> actions = player.getDialogueInterpreter().getActions();
if (actions.size() > 0) {
@ -207,7 +207,7 @@ public class ActionButtonPacket implements IncomingPacket {
slot = buffer.getShort();
}
if (componentId == 49) {
if (player.getDialogueInterpreter().getDialogue() == null && player.getDialogueInterpreter().getDialogueStage() == null) {
if (player.getDialogueInterpreter().getDialogue() == null) {
player.setAttribute("chatbox-buttonid",buttonId);
player.getInterfaceManager().closeChatbox();
return null;

View file

@ -60,17 +60,10 @@ object Server {
fun main(args: Array<String>) {
if (args.isNotEmpty()) {
SystemLogger.logInfo("Using config file: ${args[0]}")
ServerConfigParser(args[0])
ServerConfigParser.parse(args[0])
} else {
SystemLogger.logInfo("Using config file: ${"worldprops" + File.separator + "default.json"}")
ServerConfigParser("worldprops" + File.separator + "default.json")
}
if (GameWorld.settings?.isGui == true) {
try {
ConsoleFrame.getInstance().init()
} catch (e: Exception) {
SystemLogger.logWarn("X11 server missing - launching server with no GUI!")
}
SystemLogger.logInfo("Using config file: ${"worldprops" + File.separator + "default.conf"}")
ServerConfigParser.parse("worldprops" + File.separator + "default.conf")
}
startTime = System.currentTimeMillis()
val t = TimeStamp()

View file

@ -27,7 +27,7 @@ class ServerConstants {
@JvmField
var CACHE_PATH: String? = null
//path for the server store (obsolete, but kept for the sake of system sanity.)
//path for the server store
@JvmField
var STORE_PATH: String? = null
@ -64,11 +64,11 @@ class ServerConstants {
//the max number of players.
@JvmField
var MAX_PLAYERS = 0
var MAX_PLAYERS = 2000
//the max number of NPCs
@JvmField
var MAX_NPCS = 0
var MAX_NPCS = 32000
//the location where new players are placed on login.
@JvmField
@ -181,55 +181,5 @@ class ServerConstants {
@JvmField
var DAILY_RESTART = false
/**
* Parses a JSONObject and retrieves the values for all settings in this file.
* @author Ceikry
* @param data : The JSONObject to parse.
*/
fun parse(data: JSONObject) {
MAX_PLAYERS = data["max_players"].toString().toInt()
MAX_NPCS = data["max_npcs"].toString().toInt()
START_LOCATION = rs09.JSONUtils.parseLocation(data["new_player_location"].toString())
HOME_LOCATION = rs09.JSONUtils.parseLocation(data["home_location"].toString())
DATA_PATH = rs09.JSONUtils.parsePath(data["data_path"].toString())
CACHE_PATH = rs09.JSONUtils.parsePath(data["cache_path"].toString())
STORE_PATH = rs09.JSONUtils.parsePath(data["store_path"].toString())
PLAYER_SAVE_PATH = rs09.JSONUtils.parsePath(data["save_path"].toString())
CONFIG_PATH = rs09.JSONUtils.parsePath(data["configs_path"].toString())
PLAYER_ATTRIBUTE_PATH = PLAYER_SAVE_PATH + "attributes" + File.separator
GRAND_EXCHANGE_DATA_PATH = rs09.JSONUtils.parsePath(data["grand_exchange_data_path"].toString())
BOT_DATA_PATH = rs09.JSONUtils.parsePath(data["bot_data_path"].toString())
RDT_DATA_PATH = rs09.JSONUtils.parsePath(data["rare_drop_table_path"].toString())
OBJECT_PARSER_PATH = rs09.JSONUtils.parsePath(data["object_parser_path"].toString())
SCRIPTS_PATH = rs09.JSONUtils.parsePath(data["scripts_path"].toString())
DIALOGUE_SCRIPTS_PATH = rs09.JSONUtils.parsePath(data["dialogue_scripts_path"].toString())
if(data.containsKey("logs_path")){
LOGS_PATH = data["logs_path"].toString()
}
if(data.containsKey("writeLogs")){
WRITE_LOGS = data["writeLogs"] as Boolean
}
if(data.containsKey("enable_gui")){
ALLOW_GUI = data["enable_gui"] as Boolean
}
DATABASE_NAME = data["database_name"].toString()
DATABASE_USER = data["database_username"].toString()
DATABASE_PASS = data["database_password"].toString()
DATABASE_ADDRESS = data["database_address"].toString()
DATABASE_PORT = data["database_port"].toString()
DATABASE = Database(DATABASE_ADDRESS, DATABASE_NAME, DATABASE_USER, DATABASE_PASS)
if(data.containsKey("daily_restart")){
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

@ -14,7 +14,7 @@ object ServerStore {
var counter = 0
fun init(){
val dir = File(ServerConstants.DATA_PATH + File.separator + "serverstore")
val dir = File(ServerConstants.STORE_PATH!!)
if(!dir.exists()){
dir.mkdirs()
return

View file

@ -1,63 +1,146 @@
package rs09.game.system.config
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import com.moandjiezana.toml.Toml
import core.game.world.map.Location
import core.tools.StringUtils
import core.tools.mysql.Database
import rs09.JSONUtils.Companion.parsePath
import rs09.ServerConstants
import rs09.game.system.SystemLogger
import rs09.game.world.GameSettings
import rs09.game.world.GameWorld
import rs09.plugin.PluginManager
import java.io.File
import java.io.FileReader
import kotlin.system.exitProcess
/**
* Class for parsing the server config, I.E default.json
* @param path the path to the JSON file to parse.
* Class for parsing the server config, I.E default.toml
* @param path the path to the TOML file to parse.
* @author Ceikry
*/
class ServerConfigParser(path: String) {
val pathTo = rs09.JSONUtils.parsePath(path)
val confFile = File(pathTo)
val parser = JSONParser()
var reader: FileReader? = null
var data: JSONObject? = null
object ServerConfigParser {
var confFile: File? = null
var tomlData: Toml? = null
init {
if(!confFile.canonicalFile.exists()){
println("Could not find ${confFile.canonicalFile} - Double check your working directory!")
fun parse(path: String){
confFile = File(parsePath(path))
if(!confFile!!.canonicalFile.exists()){
SystemLogger.logErr("${confFile!!.canonicalFile} does not exist in the current working directory.")
exitProcess(0)
} else if(!pathTo.contains(".json")) {
println("Config file MUST be a JSON file!!")
println("(Got $pathTo)")
} else {
reader = FileReader(pathTo)
data = parser.parse(reader) as JSONObject
ServerConstants.SERVER_NAME = data!!["name"] as String
parseGameSettings()
parseServerSettings()
parsePluginToggles()
try {
tomlData = Toml().read(confFile)
parseGameSettings()
parseServerSettings()
} catch (e: java.lang.IllegalStateException) {
SystemLogger.logErr("Passed config file is not a TOML file. Path: ${confFile!!.canonicalPath}")
SystemLogger.logErr("Exception received: $e")
SystemLogger.logAlert("Shutting down...")
exitProcess(0)
}
}
}
private fun parseGameSettings(){
data ?: return
val gsData = data!!["GameSettings"] as JSONObject
GameWorld.settings = GameSettings.parse(gsData)
tomlData ?: return
val data = tomlData!!
GameWorld.settings = GameSettings(
name = ServerConstants.SERVER_NAME,
isBeta = data.getBoolean("world.debug"),
isDevMode = data.getBoolean("world.dev"),
isGui = data.getBoolean("world.start_gui"),
worldId = data.getString("world.world_id").toInt(),
countryIndex = data.getString("world.country_id").toInt(),
activity = data.getString("world.activity"),
isMembers = data.getBoolean("world.members"),
isPvp = data.getBoolean("world.pvp"),
isQuickChat = false,
isLootshare = false,
msAddress = data.getString("server.msip"),
default_xp_rate = data.getDouble("world.default_xp_rate"),
allow_slayer_reroll = data.getBoolean("world.allow_slayer_reroll"),
enable_default_clan = data.getBoolean("world.enable_default_clan"),
enable_bots = data.getBoolean("world.enable_bots"),
autostock_ge = data.getBoolean("world.autostock_ge"),
allow_token_purchase = data.getBoolean("world.allow_token_purchase"),
skillcape_perks = data.getBoolean("world.skillcape_perks"),
increased_door_time = data.getBoolean("world.increased_door_time"),
enabled_botting = data.getBoolean("world.enable_botting"),
max_adv_bots = data.getLong("world.max_adv_bots").toInt(),
wild_pvp_enabled = data.getBoolean("world.wild_pvp_enabled"),
message_model = data.getString("world.motw_identifier").toInt(),
message_string = data.getString("world.motw_text").replace("@name",ServerConstants.SERVER_NAME)
)
}
private fun parseServerSettings(){
data ?: return
val ssData = data!!["ServerSettings"] as JSONObject
ServerConstants.parse(ssData)
tomlData ?: return
val data = tomlData!!
ServerConstants.DATA_PATH = data.getString("paths.data_path")
ServerConstants.WRITE_LOGS = data.getBoolean("server.write_logs")
ServerConstants.DATABASE_NAME = data.getString("database.database_name")
ServerConstants.DATABASE_USER = data.getString("database.database_username")
ServerConstants.DATABASE_PASS = data.getString("database.database_password")
ServerConstants.DATABASE_ADDRESS = data.getString("database.database_address")
ServerConstants.DATABASE_PORT = data.getString("database.database_port")
ServerConstants.DATABASE = Database(ServerConstants.DATABASE_ADDRESS + ":" + ServerConstants.DATABASE_PORT, ServerConstants.DATABASE_NAME, ServerConstants.DATABASE_USER, ServerConstants.DATABASE_PASS)
ServerConstants.CACHE_PATH = data.getPath("paths.cache_path")
ServerConstants.CONFIG_PATH = data.getPath("paths.configs_path")
ServerConstants.PLAYER_SAVE_PATH = data.getPath("paths.save_path")
ServerConstants.STORE_PATH = data.getPath("paths.store_path")
ServerConstants.RDT_DATA_PATH = data.getPath("paths.rare_drop_table_path")
ServerConstants.OBJECT_PARSER_PATH = data.getPath("paths.object_parser_path")
ServerConstants.LOGS_PATH = data.getPath("paths.logs_path")
ServerConstants.SERVER_NAME = data.getPath("world.name")
ServerConstants.BOT_DATA_PATH = data.getPath("paths.bot_data")
ServerConstants.MS_SECRET_KEY = data.getString("server.secret_key")
ServerConstants.HOME_LOCATION = parseLocation(data.getString("world.home_location"))
ServerConstants.START_LOCATION = parseLocation(data.getString("world.new_player_location"))
ServerConstants.DAILY_RESTART = data.getBoolean("world.daily_restart")
}
private fun parsePluginToggles(){
data ?: return
val dpData = data!!["PluginToggles"] as JSONObject
dpData.map {
if(!(it.value as Boolean)){
PluginManager.disabledPlugins.put(it.key.toString(),it.value as Boolean)
}
private fun Toml.getPath(key: String): String{
try {
return parsePath(getString(key).replace("@data", ServerConstants.DATA_PATH!!))
} catch (e: Exception){
SystemLogger.logErr("Error parsing key: $key")
exitProcess(0)
}
}
/**
* Parses a location from the format "x,y,z"
* @author Ceikry
* @param locString The string to parse
* @return Location
*/
fun parseLocation(locString: String): Location {
val locTokens = locString.split(",").map { it.toInt() }
return Location(locTokens[0], locTokens[1], locTokens[2])
}
/**
* Parses a path string
* @author Ceikry
* @param pathString The string to parse
* @return a String with the proper file separators for the current OS.
*/
fun parsePath(pathString: String): String {
var pathTokens: List<String>? = null
if(pathString.contains("/"))
pathTokens = pathString.split("/")
else if(pathString.contains("\\"))
pathTokens = pathString.split("\\")
pathTokens ?: return pathString //return the initial pathString if path does not contain file separators.
var pathProduct = ""
for(token in pathTokens){
if(token != "")
pathProduct += "$token${File.separator}"
}
return pathProduct
}
}

View file

@ -1,7 +1,6 @@
package rs09.game.world
import core.cache.Cache
import core.cache.AriosStore
import core.cache.def.impl.SceneryDefinition
import core.game.ge.GrandExchangeDatabase
import core.game.node.entity.npc.drop.RareDropTable
@ -130,7 +129,6 @@ object GameWorld {
fun prompt(run: Boolean, directory: String?){
SystemLogger.logInfo("Prompting ${settings?.name} Game World...")
Cache.init(ServerConstants.CACHE_PATH)
AriosStore.init(ServerConstants.STORE_PATH)
databaseManager = DatabaseManager(ServerConstants.DATABASE)
databaseManager!!.connect()
GrandExchangeDatabase.init()

View file

@ -1,62 +0,0 @@
{
"name": "2009scape",
"GameSettings": {
"debug": true,
"dev": true,
"startGui": false,
"worldID":"1",
"countryID": "0",
"activity": "2009scape classic.",
"pvpWorld": false,
"msip": "127.0.0.1",
"default_xp_rate": "5",
"allow_slayer_reroll": false,
"enable_default_clan": true,
"enable_bots": true,
"autostock_ge": true,
"allow_token_purchase": true,
"max_adv_bots": "100",
"message_of_the_week_identifier": "0",
"skillcape_perks": false,
"message_of_the_week_text": "Welcome to 2009Scape! <br><col=11ff00>N</col><col=ecff00>o</col><col=ff8300>w</col <col=ff0000>i</col><col=ff00d4>n</col> <col=6100ff>T</col><col=000fff>e</col><col=00f0ff>c</col><col=00ff59>h</col><col=93ff00>n</col><col=ff9e00>i</col><col=ff0000>c</col><col=ff00d1>o</col><col=2700ff>l</col><col=00f7ff>o</col><col=00ff0c>r</col><col=ff0000>!</col>"
},
"ServerSettings": {
"writeLogs": true,
"max_players": "2000",
"max_npcs": "32000",
"new_player_location": "2524,5002,0",
"home_location": "3222,3218,0",
"data_path": "data",
"cache_path": "./data/cache",
"store_path": "./data/store",
"save_path": "./data/players",
"configs_path": "./data/configs",
"grand_exchange_data_path": "./data/eco/",
"rare_drop_table_path": "./data/RDT.xml",
"object_parser_path": "./data/ObjectParser.xml",
"scripts_path": "scripts/",
"dialogue_scripts_path": "scripts/dialogue/",
"logs_path": "data/logs/",
"bot_data_path": "data/botdata/",
"database_name": "global",
"database_username": "root",
"database_password": "",
"database_address": "127.0.0.1",
"database_port": "3306",
"ms_secret_key": "2009scape_development",
"enable_gui": false
},
"PluginToggles": {
"Trivia": false,
"RPS": false,
"Boredom": false,
"ShootingStars": true,
"MysteryBox": true,
"PKZone": false,
"ObjectParser": true,
"BlackJack": false
}
}