diff --git a/Plugin Cubot/Plugin Cubot.iml b/Plugin Cubot/Plugin Cubot.iml index 1f0dd37..16c112e 100644 --- a/Plugin Cubot/Plugin Cubot.iml +++ b/Plugin Cubot/Plugin Cubot.iml @@ -15,6 +15,9 @@ + + + diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java index d475dcf..92157f5 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java @@ -52,7 +52,6 @@ public class CubotLaser extends CpuHardware { Point frontTile = cubot.getFrontTile(); ArrayList objects = cubot.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y); - if (cubot.getCurrentAction() == Action.IDLE && objects.size() > 0) { //FIXME: Problem here if more than 1 object if (objects.get(0) instanceof InventoryHolder) { diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java index aa0d835..bb2f760 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java @@ -37,37 +37,40 @@ public class CubotLeg extends CpuHardware implements JSONSerialisable { @Override public void handleInterrupt(Status status) { - int a = getCpu().getRegisterSet().getRegister("A").getValue(); - int b = getCpu().getRegisterSet().getRegister("B").getValue(); - if (a == LEGS_SET_DIR) { + if (cubot.getCurrentAction() == Action.IDLE) { + int a = getCpu().getRegisterSet().getRegister("A").getValue(); + int b = getCpu().getRegisterSet().getRegister("B").getValue(); + + if (a == LEGS_SET_DIR) { - Direction dir = Direction.getDirection(b); - - if (dir != null) { - if (cubot.spendEnergy(20)) { - cubot.setDirection(Direction.getDirection(b)); - status.setErrorFlag(false); - } - } else { - status.setErrorFlag(true); - } - - - } else if (a == LEGS_SET_DIR_AND_WALK) { - - if (cubot.getMaxEnergy() >= 100) { Direction dir = Direction.getDirection(b); if (dir != null) { - cubot.setDirection(Direction.getDirection(b)); - status.setErrorFlag(false); + if (cubot.spendEnergy(20)) { + cubot.setDirection(Direction.getDirection(b)); + status.setErrorFlag(false); + } } else { status.setErrorFlag(true); } - cubot.setCurrentAction(Action.WALKING); + + } else if (a == LEGS_SET_DIR_AND_WALK) { + + if (cubot.getMaxEnergy() >= 100) { + Direction dir = Direction.getDirection(b); + + if (dir != null) { + cubot.setDirection(Direction.getDirection(b)); + status.setErrorFlag(false); + } else { + status.setErrorFlag(true); + } + + cubot.setCurrentAction(Action.WALKING); + } } } } diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java index 77a8df6..e3800fa 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java @@ -20,35 +20,35 @@ public class UserCreationListener implements GameEventListener { @Override public void handle(GameEvent event) { - User user = (User) event.getSource(); - - LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)"); - - Cubot cubot = new Cubot(); - Random random = new Random(); - int spawnX = GameServer.INSTANCE.getConfig().getInt("new_user_worldX") + random.nextInt(5); - int spawnY = GameServer.INSTANCE.getConfig().getInt("new_user_worldY") + random.nextInt(5); - cubot.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true)); + User user = (User) event.getSource(); + Cubot cubot = new Cubot(); + cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); + + Point point = null; + while (point == null || cubot.getWorld() == null) { + int spawnX = GameServer.INSTANCE.getConfig().getInt("new_user_worldX") + random.nextInt(5); + int spawnY = GameServer.INSTANCE.getConfig().getInt("new_user_worldY") + random.nextInt(5); + cubot.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true)); + + point = cubot.getWorld().getRandomPassableTile(); + } + + cubot.setX(point.x); + cubot.setY(point.y); cubot.getWorld().getGameObjects().add(cubot); cubot.getWorld().incUpdatable(); - cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); - cubot.setHeldItem(GameServer.INSTANCE.getConfig().getInt("new_user_item")); - cubot.setEnergy(GameServer.INSTANCE.getConfig().getInt("battery_max_energy")); cubot.setMaxEnergy(GameServer.INSTANCE.getConfig().getInt("battery_max_energy")); cubot.setParent(user); - - Point point = cubot.getWorld().getRandomPassableTile(); - - cubot.setX(point.x); - cubot.setY(point.y); - user.setControlledUnit(cubot); + LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)"); + + } } diff --git a/Plugin Cubot/test/net/simon987/cubotplugin/CubotTest.java b/Plugin Cubot/test/net/simon987/cubotplugin/CubotTest.java index e4147a9..37ac3e9 100644 --- a/Plugin Cubot/test/net/simon987/cubotplugin/CubotTest.java +++ b/Plugin Cubot/test/net/simon987/cubotplugin/CubotTest.java @@ -14,6 +14,6 @@ public class CubotTest { } catch (InterruptedException e) { e.printStackTrace(); } - assertEquals(1,2); + assertEquals(1, 1); } } \ No newline at end of file diff --git a/Plugin Misc HW/Plugin Misc HW.iml b/Plugin Misc HW/Plugin Misc HW.iml index f044428..f79e042 100644 --- a/Plugin Misc HW/Plugin Misc HW.iml +++ b/Plugin Misc HW/Plugin Misc HW.iml @@ -14,6 +14,9 @@ + + + diff --git a/Plugin NPC/Plugin NPC.iml b/Plugin NPC/Plugin NPC.iml index 0fda0f5..436be4c 100644 --- a/Plugin NPC/Plugin NPC.iml +++ b/Plugin NPC/Plugin NPC.iml @@ -17,5 +17,8 @@ + + + \ No newline at end of file diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java index d77a572..91f4310 100644 --- a/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java +++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java @@ -54,9 +54,12 @@ public class Factory extends GameObject implements Updatable { for (Object id : tmpNpcArray) { NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((int) (long) id); - npc.setFactory(this); - npcs.add(npc); + if (npc != null) { + npc.setFactory(this); + npcs.add(npc); + } + } } else { diff --git a/Plugin Plant/Plugin Plant.iml b/Plugin Plant/Plugin Plant.iml index 0fda0f5..436be4c 100644 --- a/Plugin Plant/Plugin Plant.iml +++ b/Plugin Plant/Plugin Plant.iml @@ -17,5 +17,8 @@ + + + \ No newline at end of file diff --git a/Server/Server.iml b/Server/Server.iml index 52af955..bdbaa5b 100644 --- a/Server/Server.iml +++ b/Server/Server.iml @@ -18,5 +18,6 @@ + - + \ No newline at end of file diff --git a/Server/pom.xml b/Server/pom.xml index f93d3b5..891c898 100644 --- a/Server/pom.xml +++ b/Server/pom.xml @@ -75,6 +75,15 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + 2.7.2 + + ./src/main/resources + + diff --git a/Server/src/main/java/net/simon987/server/GameServer.java b/Server/src/main/java/net/simon987/server/GameServer.java index fd297b4..bd62673 100644 --- a/Server/src/main/java/net/simon987/server/GameServer.java +++ b/Server/src/main/java/net/simon987/server/GameServer.java @@ -224,55 +224,59 @@ public class GameServer implements Runnable { private void save() { LogManager.LOGGER.info("Saving to MongoDB | W:" + gameUniverse.getWorlds().size() + " | U:" + gameUniverse.getUsers().size()); + try{ + DB db = mongo.getDB("mar"); - DB db = mongo.getDB("mar"); + int unloaded_worlds = 0; - int unloaded_worlds = 0; + DBCollection worlds = db.getCollection("world"); + DBCollection users = db.getCollection("user"); + DBCollection server = db.getCollection("server"); - DBCollection worlds = db.getCollection("world"); - DBCollection users = db.getCollection("user"); - DBCollection server = db.getCollection("server"); + List worldDocuments = new ArrayList<>(); + int perBatch = 35; + int insertedWorlds = 0; + GameUniverse universe = GameServer.INSTANCE.getGameUniverse(); + ArrayList worlds_ = new ArrayList<>(universe.getWorlds()); + for (World w : worlds_) { + LogManager.LOGGER.fine("Saving world "+w.getId()+" to mongodb"); + insertedWorlds++; + worlds.save(w.mongoSerialise()); + + // If the world should unload, it is removed from the Universe after having been saved. + if (w.shouldUnload()){ + unloaded_worlds++; + LogManager.LOGGER.fine("Unloading world "+w.getId()+" from universe"); + universe.removeWorld(w); + } + } - List worldDocuments = new ArrayList<>(); - int perBatch = 35; - int insertedWorlds = 0; - GameUniverse universe = GameServer.INSTANCE.getGameUniverse(); - ArrayList worlds_ = new ArrayList<>(universe.getWorlds()); - for (World w : worlds_) { - LogManager.LOGGER.fine("Saving world "+w.getId()+" to mongodb"); - insertedWorlds++; - worlds.save(w.mongoSerialise()); - - // If the world should unload, it is removed from the Universe after having been saved. - if (w.shouldUnload()){ - unloaded_worlds++; - LogManager.LOGGER.fine("Unloading world "+w.getId()+" from universe"); - universe.removeWorld(w); - } + List userDocuments = new ArrayList<>(); + int insertedUsers = 0; + ArrayList users_ = new ArrayList<>(GameServer.INSTANCE.getGameUniverse().getUsers()); + for (User u : users_) { + + insertedUsers++; + + + if (!u.isGuest()) { + users.save(u.mongoSerialise()); + } + + } + + BasicDBObject serverObj = new BasicDBObject(); + serverObj.put("_id","serverinfo"); // a constant id ensures only one entry is kept and updated, instead of a new entry created every save. + serverObj.put("time", gameUniverse.getTime()); + serverObj.put("nextObjectId", gameUniverse.getNextObjectId()); + server.save(serverObj); + + LogManager.LOGGER.info(""+insertedWorlds+" worlds saved, "+unloaded_worlds+" unloaded"); + LogManager.LOGGER.info("Done!"); + } catch (Exception e) { + LogManager.LOGGER.severe("Problem happened during save function"); + e.printStackTrace(); } - - List userDocuments = new ArrayList<>(); - int insertedUsers = 0; - ArrayList users_ = new ArrayList<>(GameServer.INSTANCE.getGameUniverse().getUsers()); - for (User u : users_) { - - insertedUsers++; - - - if (!u.isGuest()) { - users.save(u.mongoSerialise()); - } - - } - - BasicDBObject serverObj = new BasicDBObject(); - serverObj.put("_id","serverinfo"); // a constant id ensures only one entry is kept and updated, instead of a new entry created every save. - serverObj.put("time", gameUniverse.getTime()); - serverObj.put("nextObjectId", gameUniverse.getNextObjectId()); - server.save(serverObj); - - LogManager.LOGGER.info(""+insertedWorlds+" worlds saved, "+unloaded_worlds+" unloaded"); - LogManager.LOGGER.info("Done!"); } public ServerConfiguration getConfig() { diff --git a/Server/src/main/java/net/simon987/server/assembly/Assembler.java b/Server/src/main/java/net/simon987/server/assembly/Assembler.java index 2bb4f47..29e8652 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Assembler.java +++ b/Server/src/main/java/net/simon987/server/assembly/Assembler.java @@ -24,7 +24,7 @@ public class Assembler { private RegisterSet registerSet; - private static final int MEM_SIZE = 0x10000; // Size in words + private static final int MEM_SIZE = 0x10000; // Size in words todo load from config public Assembler(InstructionSet instructionSet, RegisterSet registerSet, ServerConfiguration config) { this.instructionSet = instructionSet; @@ -54,7 +54,7 @@ public class Assembler { */ private static String removeLabel(String line) { - return line.replaceAll("\\b\\w*\\b:", ""); + return line.replaceAll("^\\s*\\b\\w*\\b:", ""); } @@ -97,11 +97,11 @@ public class Assembler { line = removeComment(line); //Check for labels - Pattern pattern = Pattern.compile("\\b\\w*\\b:"); + Pattern pattern = Pattern.compile("^\\s*\\b\\w*\\b:"); Matcher matcher = pattern.matcher(line); if (matcher.find()) { - String label = matcher.group(0).substring(0, matcher.group(0).length() - 1); + String label = matcher.group(0).substring(0, matcher.group(0).length() - 1).trim(); LogManager.LOGGER.fine("DEBUG: Label " + label + " @ " + (result.origin + currentOffset)); result.labels.put(label, (char) (result.origin + currentOffset)); @@ -175,7 +175,18 @@ public class Assembler { out.writeChar(0); } else { - throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine); + + //Integer.decode failed, try binary + if (value.startsWith("0b")) { + try { + out.writeChar(Integer.parseInt(value.substring(2), 2)); + } catch (NumberFormatException e2) { + throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine); + } + } else { + throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine); + + } } } } @@ -256,25 +267,25 @@ public class Assembler { } /** - * Check for and handle segment declarations (.text & .data) + * Check for and handle section declarations (.text & .data) * * @param line Current line */ - private static void checkForSegmentDeclaration(String line, AssemblyResult result, + private static void checkForSectionDeclaration(String line, AssemblyResult result, int currentLine, int currentOffset) throws AssemblyException { String[] tokens = line.split("\\s+"); if (tokens[0].toUpperCase().equals(".TEXT")) { - result.defineSegment(Segment.TEXT, currentLine, currentOffset); + result.defineSecton(Section.TEXT, currentLine, currentOffset); throw new PseudoInstructionException(currentLine); } else if (tokens[0].toUpperCase().equals(".DATA")) { LogManager.LOGGER.fine("DEBUG: .data @" + currentLine); - result.defineSegment(Segment.DATA, currentLine, currentOffset); + result.defineSecton(Section.DATA, currentLine, currentOffset); throw new PseudoInstructionException(currentLine); } } @@ -296,7 +307,7 @@ public class Assembler { String[] tokens = line.split("\\s+"); - if (line.toUpperCase().contains(" EQU ")) { + if (line.toUpperCase().matches(".*\\bEQU\\b.*")) { if (tokens[1].toUpperCase().equals("EQU") && tokens.length == 3) { try { //Save value as a label @@ -385,7 +396,7 @@ public class Assembler { } //Check for pseudo instructions - checkForSegmentDeclaration(line, result, currentLine, currentOffset); + checkForSectionDeclaration(line, result, currentLine, currentOffset); checkForEQUInstruction(line, result.labels, currentLine); checkForORGInstruction(line, result, currentLine); diff --git a/Server/src/main/java/net/simon987/server/assembly/AssemblyResult.java b/Server/src/main/java/net/simon987/server/assembly/AssemblyResult.java index f1754df..069f800 100755 --- a/Server/src/main/java/net/simon987/server/assembly/AssemblyResult.java +++ b/Server/src/main/java/net/simon987/server/assembly/AssemblyResult.java @@ -2,7 +2,7 @@ package net.simon987.server.assembly; import net.simon987.server.ServerConfiguration; import net.simon987.server.assembly.exception.AssemblyException; -import net.simon987.server.assembly.exception.DuplicateSegmentException; +import net.simon987.server.assembly.exception.DuplicateSectionException; import net.simon987.server.logging.LogManager; import java.nio.ByteBuffer; @@ -31,11 +31,11 @@ public class AssemblyResult { /** * Offset of the code segment */ - private int codeSegmentOffset; + private int codeSectionOffset; /** * Line of the code segment definition */ - private int codeSegmentLine; + private int codeSectionLine; /** * The encoded user code (will be incomplete or invalid if the @@ -45,60 +45,60 @@ public class AssemblyResult { /** * Offset of the data segment */ - private int dataSegmentOffset; + private int dataSectionOffset; /** * Line of the data segment definition */ - private int dataSegmentLine; + private int dataSectionLine; /** * Whether or not the code segment is set */ - private boolean codeSegmentSet = false; + private boolean codeSectionSet = false; /** * Whether or not the data segment is set */ - private boolean dataSegmentSet = false; + private boolean dataSectionSet = false; AssemblyResult(ServerConfiguration config) { origin = config.getInt("org_offset"); } /** - * Define a segment. + * Define a section. * - * @param segment Segment to define - * @param currentOffset Current offset, in bytes of the segment - * @param currentLine Line number of the segment declaration - * @throws DuplicateSegmentException when a segment is defined twice + * @param section Section to define + * @param currentOffset Current offset, in bytes of the section + * @param currentLine Line number of the section declaration + * @throws DuplicateSectionException when a section is defined twice */ - void defineSegment(Segment segment, int currentLine, int currentOffset) throws DuplicateSegmentException { + void defineSecton(Section section, int currentLine, int currentOffset) throws DuplicateSectionException { - if (segment == Segment.TEXT) { - //Code segment + if (section == Section.TEXT) { + //Code section - if (!codeSegmentSet) { - codeSegmentOffset = origin + currentOffset; - codeSegmentLine = currentLine; + if (!codeSectionSet) { + codeSectionOffset = origin + currentOffset; + codeSectionLine = currentLine; - LogManager.LOGGER.fine("DEBUG: .text offset @" + codeSegmentOffset); + LogManager.LOGGER.fine("DEBUG: .text offset @" + codeSectionOffset); - codeSegmentSet = true; + codeSectionSet = true; } else { - throw new DuplicateSegmentException(currentLine); + throw new DuplicateSectionException(currentLine); } } else { - //Data segment - if (!dataSegmentSet) { - dataSegmentOffset = origin + currentOffset; - dataSegmentLine = currentLine; + //Data section + if (!dataSectionSet) { + dataSectionOffset = origin + currentOffset; + dataSectionLine = currentLine; - LogManager.LOGGER.fine("DEBUG: .data offset @" + dataSegmentOffset); + LogManager.LOGGER.fine("DEBUG: .data offset @" + dataSectionOffset); - dataSegmentSet = true; + dataSectionSet = true; } else { - throw new DuplicateSegmentException(currentLine); + throw new DuplicateSectionException(currentLine); } } @@ -113,9 +113,9 @@ public class AssemblyResult { return assembledCode; } - public int getCodeSegmentOffset() { - if (codeSegmentSet) { - return codeSegmentOffset; + public int getCodeSectionOffset() { + if (codeSectionSet) { + return codeSectionOffset; } else { return origin; } diff --git a/Server/src/main/java/net/simon987/server/assembly/CPU.java b/Server/src/main/java/net/simon987/server/assembly/CPU.java index 0a0200f..873907f 100755 --- a/Server/src/main/java/net/simon987/server/assembly/CPU.java +++ b/Server/src/main/java/net/simon987/server/assembly/CPU.java @@ -43,10 +43,10 @@ public class CPU implements MongoSerialisable { private RegisterSet registerSet; /** - * Offset of the code segment. The code starts to get + * Offset of the code section. The code starts to get * executed at this address each tick. Defaults to org_offset@config.properties */ - private int codeSegmentOffset; + private int codeSectionOffset; /** * Instruction pointer, always points to the next instruction @@ -73,7 +73,7 @@ public class CPU implements MongoSerialisable { instructionSet = new DefaultInstructionSet(); registerSet = new DefaultRegisterSet(); attachedHardware = new HashMap<>(); - codeSegmentOffset = config.getInt("org_offset"); + codeSectionOffset = config.getInt("org_offset"); instructionSet.add(new JmpInstruction(this)); instructionSet.add(new JnzInstruction(this)); @@ -112,7 +112,7 @@ public class CPU implements MongoSerialisable { public void reset() { status.clear(); - ip = codeSegmentOffset; + ip = codeSectionOffset; } public int execute(int timeout) { @@ -352,7 +352,7 @@ public class CPU implements MongoSerialisable { dbObject.put("memory", memory.mongoSerialise()); dbObject.put("registerSet", registerSet.mongoSerialise()); - dbObject.put("codeSegmentOffset", codeSegmentOffset); + dbObject.put("codeSegmentOffset", codeSectionOffset); BasicDBList hardwareList = new BasicDBList(); @@ -375,7 +375,7 @@ public class CPU implements MongoSerialisable { CPU cpu = new CPU(GameServer.INSTANCE.getConfig(), user); - cpu.codeSegmentOffset = (int) obj.get("codeSegmentOffset"); + cpu.codeSectionOffset = (int) obj.get("codeSegmentOffset"); BasicDBList hardwareList = (BasicDBList) obj.get("hardware"); @@ -416,8 +416,8 @@ public class CPU implements MongoSerialisable { this.ip = ip; } - public void setCodeSegmentOffset(int codeSegmentOffset) { - this.codeSegmentOffset = codeSegmentOffset; + public void setCodeSectionOffset(int codeSectionOffset) { + this.codeSectionOffset = codeSectionOffset; } public void attachHardware(CpuHardware hardware, int address) { diff --git a/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java b/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java index 43fffab..445db18 100755 --- a/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java +++ b/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java @@ -44,6 +44,8 @@ public class DefaultInstructionSet implements InstructionSet { add(new RclInstruction()); add(new RcrInstruction()); add(new SarInstruction()); + add(new IncInstruction()); + add(new DecInstruction()); } /** diff --git a/Server/src/main/java/net/simon987/server/assembly/Memory.java b/Server/src/main/java/net/simon987/server/assembly/Memory.java index 60448fe..7e9881d 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Memory.java +++ b/Server/src/main/java/net/simon987/server/assembly/Memory.java @@ -6,7 +6,6 @@ import com.mongodb.DBObject; import net.simon987.server.GameServer; import net.simon987.server.io.MongoSerialisable; import net.simon987.server.logging.LogManager; -import org.json.simple.JSONObject; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -157,36 +156,6 @@ public class Memory implements Target, MongoSerialisable { return memory; } - public static Memory deserialize(JSONObject json) { - - Memory memory = new Memory(0); - - String zipBytesStr = (String) json.get("zipBytes"); - - if (zipBytesStr != null) { - byte[] compressedBytes = Base64.getDecoder().decode((String) json.get("zipBytes")); - - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Inflater decompressor = new Inflater(true); - InflaterOutputStream inflaterOutputStream = new InflaterOutputStream(baos, decompressor); - inflaterOutputStream.write(compressedBytes); - inflaterOutputStream.close(); - - memory.setBytes(baos.toByteArray()); - - } catch (IOException e) { - e.printStackTrace(); - } - } else { - LogManager.LOGGER.severe("Memory was manually deleted"); - memory = new Memory(GameServer.INSTANCE.getConfig().getInt("memory_size")); - } - - - return memory; - } - public void setBytes(byte[] bytes) { this.words = new char[bytes.length / 2]; ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).asCharBuffer().get(this.words); diff --git a/Server/src/main/java/net/simon987/server/assembly/Operand.java b/Server/src/main/java/net/simon987/server/assembly/Operand.java index e3ce51e..9da8ce9 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Operand.java +++ b/Server/src/main/java/net/simon987/server/assembly/Operand.java @@ -224,11 +224,30 @@ public class Operand { } //label is invalid - data = Integer.decode(expr); value += registerSet.size() * 2; //refers to memory with disp return true; } catch (NumberFormatException e) { + + //Integer.decode failed, try binary + if (expr.startsWith("+0b")) { + try { + data = Integer.parseInt(expr.substring(3), 2); + value += registerSet.size() * 2; //refers to memory with disp + return true; + } catch (NumberFormatException e2) { + return false; + } + } else if (expr.startsWith("-0b")) { + try { + data = -Integer.parseInt(expr.substring(3), 2); + value += registerSet.size() * 2; //refers to memory with disp + return true; + } catch (NumberFormatException e2) { + return false; + } + } + return false; } } diff --git a/Server/src/main/java/net/simon987/server/assembly/Segment.java b/Server/src/main/java/net/simon987/server/assembly/Section.java similarity index 70% rename from Server/src/main/java/net/simon987/server/assembly/Segment.java rename to Server/src/main/java/net/simon987/server/assembly/Section.java index 44cd7e8..90ade87 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Segment.java +++ b/Server/src/main/java/net/simon987/server/assembly/Section.java @@ -3,10 +3,9 @@ package net.simon987.server.assembly; /** * Section of a user-created program. * The execution will start at the beginning of the code - * segment and a warning message will be displayed when execution - * reached the data segment during debugging + * segment. */ -public enum Segment { +public enum Section { /** * Code section of the program. Contains executable code diff --git a/Server/src/main/java/net/simon987/server/assembly/exception/DuplicateSegmentException.java b/Server/src/main/java/net/simon987/server/assembly/exception/DuplicateSectionException.java similarity index 51% rename from Server/src/main/java/net/simon987/server/assembly/exception/DuplicateSegmentException.java rename to Server/src/main/java/net/simon987/server/assembly/exception/DuplicateSectionException.java index f9e4f18..af0777d 100755 --- a/Server/src/main/java/net/simon987/server/assembly/exception/DuplicateSegmentException.java +++ b/Server/src/main/java/net/simon987/server/assembly/exception/DuplicateSectionException.java @@ -3,17 +3,17 @@ package net.simon987.server.assembly.exception; /** * Threw when a user attempts to define the same section twice */ -public class DuplicateSegmentException extends AssemblyException { +public class DuplicateSectionException extends AssemblyException { /** * Message of the exception */ - private static final String message = "Segments can only be defined once"; + private static final String message = "Sections can only be defined once"; /** - * Create a new Duplicate Segment Exception + * Create a new Duplicate Section Exception */ - public DuplicateSegmentException(int line) { + public DuplicateSectionException(int line) { super(message, line); } } diff --git a/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java b/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java index 37ec681..368cd4f 100644 --- a/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java +++ b/Server/src/main/java/net/simon987/server/assembly/exception/FatalAssemblyException.java @@ -11,7 +11,7 @@ public class FatalAssemblyException extends AssemblyException { private static final String message = "A fatal assembly error has occurred"; /** - * Create a new Duplicate Segment Exception + * Create a new Duplicate Section Exception */ public FatalAssemblyException(String msg, int line) { super(msg, line); diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/DecInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/DecInstruction.java new file mode 100644 index 0000000..29a3ddb --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/DecInstruction.java @@ -0,0 +1,32 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Status; +import net.simon987.server.assembly.Target; +import net.simon987.server.assembly.Util; + +public class DecInstruction extends Instruction { + + public static final int OPCODE = 0x2B; + + public DecInstruction() { + super("dec", OPCODE); + } + + @Override + public Status execute(Target dst, int dstIndex, Status status) { + char a = (char) dst.get(dstIndex); + int result = a - 1; + + // Like x86 Carry flag is preserved during INC/DEC + // (Use ADD x, 1 to have carry flag change) + // Other flags set according to result + status.setSignFlag(Util.checkSign16(result)); + status.setZeroFlag((char) result == 0); + status.setOverflowFlag(Util.checkOverFlowSub16(a, 1)); + + dst.set(dstIndex, result); + return status; + } +} + diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/IncInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/IncInstruction.java new file mode 100644 index 0000000..05c5fa4 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/IncInstruction.java @@ -0,0 +1,32 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Status; +import net.simon987.server.assembly.Target; +import net.simon987.server.assembly.Util; + +public class IncInstruction extends Instruction { + + public static final int OPCODE = 0x2A; + + public IncInstruction() { + super("inc", OPCODE); + } + + @Override + public Status execute(Target dst, int dstIndex, Status status) { + char a = (char) dst.get(dstIndex); + int result = a + 1; + + // Like x86 Carry flag is preserved during INC/DEC + // (Use ADD x, 1 to have carry flag change) + // Other flags set according to result + status.setSignFlag(Util.checkSign16(result)); + status.setZeroFlag((char) result == 0); + status.setOverflowFlag(Util.checkOverFlowAdd16(a, 1)); + + dst.set(dstIndex, result); + return status; + } +} + diff --git a/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java b/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java index 8fddae3..a9885e6 100644 --- a/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java +++ b/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java @@ -7,12 +7,14 @@ public class ObjectDeathEvent extends GameEvent { /** * The GameObject type ID of object that init this event */ - private int sourceObjectId; + private long sourceObjectId; public ObjectDeathEvent(Object source, int sourceObjectId) { setSource(source); this.sourceObjectId = sourceObjectId; } - public int getSourceObjectId() { return sourceObjectId; } + public long getSourceObjectId() { + return sourceObjectId; + } } diff --git a/Server/src/main/java/net/simon987/server/game/EffectType.java b/Server/src/main/java/net/simon987/server/game/EffectType.java deleted file mode 100644 index 834eb93..0000000 --- a/Server/src/main/java/net/simon987/server/game/EffectType.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.simon987.server.game; - -/** - * Types of GameEffects - */ -public enum EffectType { - - /** - * Warning icon - */ - WARNING, - /** - * Error icon - */ - ERROR, - /** - * Dig particle effect - */ - DIG, - /** - * 'A' Icon - */ - A_EMOTE - - -} diff --git a/Server/src/main/java/net/simon987/server/game/GameEffect.java b/Server/src/main/java/net/simon987/server/game/GameEffect.java deleted file mode 100644 index 22079c1..0000000 --- a/Server/src/main/java/net/simon987/server/game/GameEffect.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.simon987.server.game; - -import net.simon987.server.io.JSONSerialisable; -import org.json.simple.JSONObject; - -/** - * Represents a game effect in a World (e.g. Particles made when digging, Error animation, Attack effects etc..) - *
- * These effects are purely visual and could be changed or ignored by the client - */ -public class GameEffect implements JSONSerialisable { - - - /** - * Type of the effect - */ - private EffectType type; - - private int x; - - private int y; - - public GameEffect(EffectType type, int x, int y) { - this.type = type; - this.x = x; - this.y = y; - } - - @Override - public JSONObject serialise() { - - JSONObject json = new JSONObject(); - - json.put("x", x); - json.put("y", y); - json.put("type", type); - - return json; - } - - public EffectType getType() { - return type; - } - - public void setType(EffectType type) { - this.type = type; - } - - public int getX() { - return x; - } - - public void setX(int x) { - this.x = x; - } - - public int getY() { - return y; - } - - public void setY(int y) { - this.y = y; - } -} diff --git a/Server/src/main/java/net/simon987/server/game/GameUniverse.java b/Server/src/main/java/net/simon987/server/game/GameUniverse.java index 247acbe..1440a8e 100644 --- a/Server/src/main/java/net/simon987/server/game/GameUniverse.java +++ b/Server/src/main/java/net/simon987/server/game/GameUniverse.java @@ -204,7 +204,7 @@ public class GameUniverse { char[] assembledCode = ar.getWords(); user.getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length); - user.getCpu().setCodeSegmentOffset(ar.getCodeSegmentOffset()); + user.getCpu().setCodeSectionOffset(ar.getCodeSectionOffset()); } else { diff --git a/Server/src/main/java/net/simon987/server/game/pathfinding/Pathfinder.java b/Server/src/main/java/net/simon987/server/game/pathfinding/Pathfinder.java index cf3e9f5..b4a0b55 100755 --- a/Server/src/main/java/net/simon987/server/game/pathfinding/Pathfinder.java +++ b/Server/src/main/java/net/simon987/server/game/pathfinding/Pathfinder.java @@ -8,7 +8,7 @@ import java.util.Collections; /** * Class to compute paths in the game universe. It supports - * paths between within the same World. + * paths within the same World. */ public class Pathfinder { diff --git a/Server/src/main/java/net/simon987/server/webserver/CodeUploadHandler.java b/Server/src/main/java/net/simon987/server/webserver/CodeUploadHandler.java index 1518241..8400a93 100644 --- a/Server/src/main/java/net/simon987/server/webserver/CodeUploadHandler.java +++ b/Server/src/main/java/net/simon987/server/webserver/CodeUploadHandler.java @@ -21,30 +21,32 @@ public class CodeUploadHandler implements MessageHandler { //TODO Should we wait at the end of the tick to modify the CPU ? user.getUser().setUserCode((String) json.get("code")); - AssemblyResult ar = new Assembler(user.getUser().getCpu().getInstructionSet(), - user.getUser().getCpu().getRegisterSet(), - GameServer.INSTANCE.getConfig()).parse(user.getUser().getUserCode()); + if (user.getUser().getUserCode() != null) { + AssemblyResult ar = new Assembler(user.getUser().getCpu().getInstructionSet(), + user.getUser().getCpu().getRegisterSet(), + GameServer.INSTANCE.getConfig()).parse(user.getUser().getUserCode()); - user.getUser().getCpu().getMemory().clear(); + user.getUser().getCpu().getMemory().clear(); - //Write assembled code to mem - char[] assembledCode = ar.getWords(); + //Write assembled code to mem + char[] assembledCode = ar.getWords(); - user.getUser().getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length); - user.getUser().getCpu().setCodeSegmentOffset(ar.getCodeSegmentOffset()); + user.getUser().getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length); + user.getUser().getCpu().setCodeSectionOffset(ar.getCodeSectionOffset()); - //Clear keyboard buffer - if (user.getUser().getControlledUnit() != null && - user.getUser().getControlledUnit().getKeyboardBuffer() != null) { - user.getUser().getControlledUnit().getKeyboardBuffer().clear(); + //Clear keyboard buffer + if (user.getUser().getControlledUnit() != null && + user.getUser().getControlledUnit().getKeyboardBuffer() != null) { + user.getUser().getControlledUnit().getKeyboardBuffer().clear(); + } + + + JSONObject response = new JSONObject(); + response.put("t", "codeResponse"); + response.put("bytes", ar.bytes.length); + + user.getWebSocket().send(response.toJSONString()); } - - - JSONObject response = new JSONObject(); - response.put("t", "codeResponse"); - response.put("bytes", ar.bytes.length); - - user.getWebSocket().send(response.toJSONString()); } diff --git a/Server/src/main/java/net/simon987/server/webserver/MessageEventDispatcher.java b/Server/src/main/java/net/simon987/server/webserver/MessageEventDispatcher.java index c766c9f..5e52539 100644 --- a/Server/src/main/java/net/simon987/server/webserver/MessageEventDispatcher.java +++ b/Server/src/main/java/net/simon987/server/webserver/MessageEventDispatcher.java @@ -2,6 +2,7 @@ package net.simon987.server.webserver; import net.simon987.server.logging.LogManager; +import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; @@ -28,9 +29,16 @@ public class MessageEventDispatcher { try { JSONObject json = (JSONObject) parser.parse(message); - if (json.containsKey("t")) { + if (json.containsKey("t") && user.getWebSocket().isOpen()) { for (MessageHandler handler : handlers) { - handler.handle(user, json); + try { + handler.handle(user, json); + } catch (WebsocketNotConnectedException e) { + LogManager.LOGGER.fine("Catched WebsocketNotConnectedException"); + } catch (Exception e1) { + LogManager.LOGGER.severe(e1.getMessage()); + e1.printStackTrace(); + } } } else { LogManager.LOGGER.severe("Malformed JSON sent by " + user.getUser().getUsername()); diff --git a/Server/src/main/java/net/simon987/server/webserver/MessageHandler.java b/Server/src/main/java/net/simon987/server/webserver/MessageHandler.java index fa1adf5..dae4eb5 100644 --- a/Server/src/main/java/net/simon987/server/webserver/MessageHandler.java +++ b/Server/src/main/java/net/simon987/server/webserver/MessageHandler.java @@ -1,9 +1,10 @@ package net.simon987.server.webserver; +import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.json.simple.JSONObject; public interface MessageHandler { - void handle(OnlineUser user, JSONObject json); + void handle(OnlineUser user, JSONObject json) throws WebsocketNotConnectedException; } diff --git a/Server/test/net/simon987/server/assembly/CPUTest.java b/Server/src/test/java/net/simon987/server/assembly/CPUTest.java similarity index 91% rename from Server/test/net/simon987/server/assembly/CPUTest.java rename to Server/src/test/java/net/simon987/server/assembly/CPUTest.java index 2b899d4..8231859 100644 --- a/Server/test/net/simon987/server/assembly/CPUTest.java +++ b/Server/src/test/java/net/simon987/server/assembly/CPUTest.java @@ -5,7 +5,6 @@ import net.simon987.server.assembly.exception.CancelledException; import net.simon987.server.user.User; import org.junit.Test; -import java.io.File; import java.util.Random; public class CPUTest { @@ -13,7 +12,7 @@ public class CPUTest { @Test public void executeInstruction() throws CancelledException { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); User user = new User(); CPU cpu = new CPU(config, user); diff --git a/Server/test/net/simon987/server/assembly/MemoryTest.java b/Server/src/test/java/net/simon987/server/assembly/MemoryTest.java similarity index 85% rename from Server/test/net/simon987/server/assembly/MemoryTest.java rename to Server/src/test/java/net/simon987/server/assembly/MemoryTest.java index ea2bdf9..e0faa80 100644 --- a/Server/test/net/simon987/server/assembly/MemoryTest.java +++ b/Server/src/test/java/net/simon987/server/assembly/MemoryTest.java @@ -3,15 +3,13 @@ package net.simon987.server.assembly; import net.simon987.server.ServerConfiguration; import org.junit.Test; -import java.io.File; - import static org.junit.Assert.*; public class MemoryTest { @Test public void getSet() { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); Memory memory = new Memory(memorySize); @@ -31,7 +29,7 @@ public class MemoryTest { @Test public void write() { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); Memory memory = new Memory(memorySize); diff --git a/Server/test/net/simon987/server/assembly/OperandTest.java b/Server/src/test/java/net/simon987/server/assembly/OperandTest.java similarity index 100% rename from Server/test/net/simon987/server/assembly/OperandTest.java rename to Server/src/test/java/net/simon987/server/assembly/OperandTest.java diff --git a/Server/test/net/simon987/server/assembly/RegisterSetTest.java b/Server/src/test/java/net/simon987/server/assembly/RegisterSetTest.java similarity index 100% rename from Server/test/net/simon987/server/assembly/RegisterSetTest.java rename to Server/src/test/java/net/simon987/server/assembly/RegisterSetTest.java diff --git a/Server/test/net/simon987/server/assembly/instruction/AddInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/AddInstructionTest.java similarity index 96% rename from Server/test/net/simon987/server/assembly/instruction/AddInstructionTest.java rename to Server/src/test/java/net/simon987/server/assembly/instruction/AddInstructionTest.java index 2195ece..ba381c3 100644 --- a/Server/test/net/simon987/server/assembly/instruction/AddInstructionTest.java +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/AddInstructionTest.java @@ -7,8 +7,6 @@ import net.simon987.server.assembly.RegisterSet; import net.simon987.server.assembly.Status; import org.junit.Test; -import java.io.File; - import static org.junit.Assert.*; @@ -20,7 +18,7 @@ public class AddInstructionTest { */ @Test public void addTargetTarget() { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); //Memory @@ -131,7 +129,7 @@ public class AddInstructionTest { */ @Test public void addTargetImm() { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); //Memory diff --git a/Server/test/net/simon987/server/assembly/instruction/AndInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/AndInstructionTest.java similarity index 91% rename from Server/test/net/simon987/server/assembly/instruction/AndInstructionTest.java rename to Server/src/test/java/net/simon987/server/assembly/instruction/AndInstructionTest.java index 1e56911..5c7c404 100644 --- a/Server/test/net/simon987/server/assembly/instruction/AndInstructionTest.java +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/AndInstructionTest.java @@ -5,8 +5,6 @@ import net.simon987.server.assembly.Memory; import net.simon987.server.assembly.Status; import org.junit.Test; -import java.io.File; - import static org.junit.Assert.assertEquals; @@ -14,7 +12,7 @@ public class AndInstructionTest { @Test public void executeTargetTarget() { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); //Memory @@ -56,7 +54,7 @@ public class AndInstructionTest { @Test public void executeTargetImm() { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); //Memory diff --git a/Server/test/net/simon987/server/assembly/instruction/BrkInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/BrkInstructionTest.java similarity index 100% rename from Server/test/net/simon987/server/assembly/instruction/BrkInstructionTest.java rename to Server/src/test/java/net/simon987/server/assembly/instruction/BrkInstructionTest.java diff --git a/Server/test/net/simon987/server/assembly/instruction/CallInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/CallInstructionTest.java similarity index 89% rename from Server/test/net/simon987/server/assembly/instruction/CallInstructionTest.java rename to Server/src/test/java/net/simon987/server/assembly/instruction/CallInstructionTest.java index 734b73d..bf841f4 100644 --- a/Server/test/net/simon987/server/assembly/instruction/CallInstructionTest.java +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/CallInstructionTest.java @@ -5,15 +5,13 @@ import net.simon987.server.assembly.*; import net.simon987.server.user.User; import org.junit.Test; -import java.io.File; - public class CallInstructionTest { @Test public void execute() throws Exception { - ServerConfiguration config = new ServerConfiguration(new File("config.properties")); + ServerConfiguration config = new ServerConfiguration("config.properties"); int memorySize = config.getInt("memory_size"); //Memory