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..7934d36 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)); - cubot.getWorld().getGameObjects().add(cubot); - cubot.getWorld().incUpdatable(); + User user = (User) event.getSource(); + Cubot cubot = new Cubot(); cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); - cubot.setHeldItem(GameServer.INSTANCE.getConfig().getInt("new_user_item")); + 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().addObject(cubot); + cubot.getWorld().incUpdatable(); + + 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 NPC/src/main/java/net/simon987/npcplugin/Factory.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java index 91f4310..ded3ded 100644 --- a/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java +++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java @@ -74,7 +74,7 @@ public class Factory extends GameObject implements Updatable { npc.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); npc.setX(p.x); npc.setY(p.y); - getWorld().getGameObjects().add(npc); + getWorld().addObject(npc); getWorld().incUpdatable(); npc.setFactory(this); diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvestTask.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvestTask.java index 5c12479..520a4a1 100644 --- a/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvestTask.java +++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvestTask.java @@ -33,14 +33,9 @@ public class HarvestTask extends NPCTask { if (pause == 0) { //Get biomass - ArrayList biomass = new ArrayList<>(10); - - for (GameObject object : npc.getWorld().getGameObjects()) { - //Plant MAP_INFO - if ((object.getMapInfo() & 0x4000) == 0x4000) { - biomass.add(object); - } - } + /* todo replace by some sort of .collect call with object + id (See https://github.com/simon987/Much-Assembly-Required/pull/66)*/ + ArrayList biomass = npc.getWorld().findObjects(0x4000); //Get closest one int minDist = Integer.MAX_VALUE; diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java index 396a8e1..e40d0b6 100644 --- a/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java +++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java @@ -48,7 +48,9 @@ public class HarvesterNPC extends NonPlayerCharacter { @Override public void onDeadCallback() { - getFactory().getNpcs().remove(this); + if (getFactory() != null && getFactory().getNpcs() != null) { + getFactory().getNpcs().remove(this); + } GameServer.INSTANCE.getEventDispatcher().dispatch( new ObjectDeathEvent(this, ID)); diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/event/WorldCreationListener.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/event/WorldCreationListener.java index 0e0dcbf..b623680 100644 --- a/Plugin NPC/src/main/java/net/simon987/npcplugin/event/WorldCreationListener.java +++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/event/WorldCreationListener.java @@ -53,7 +53,7 @@ public class WorldCreationListener implements GameEventListener { continue; } - world.getGameObjects().add(factory); + world.addObject(factory); world.incUpdatable(); LogManager.LOGGER.info("Spawned Factory at (" + world.getX() + ", " + world.getY() + @@ -84,7 +84,7 @@ public class WorldCreationListener implements GameEventListener { if (radioTower.getAdjacentTile() != null) { //Radio Tower has adjacent tiles - world.getGameObjects().add(radioTower); + world.addObject(radioTower); world.incUpdatable(); //In case the Factory couldn't be spawned. NpcPlugin.getRadioTowers().add(radioTower); diff --git a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java index 036352e..6ace72f 100644 --- a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java +++ b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java @@ -29,18 +29,23 @@ public class ObjectDeathListener implements GameEventListener { @Override public void handle(GameEvent event) { - // a HarvesterNPC ObjectDeathEvent is received // TODO: setup enum with all GameObject type IDs if (((ObjectDeathEvent) event).getSourceObjectId() == 10) { + //An HarvesterNPC ObjectDeathEvent is received GameObject dyingHarvesterNPC = (GameObject)event.getSource(); - // create a new biomass - BiomassBlob newBiomassBlob = createBiomassBlobAt( - dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); - // add it to the world game objects - dyingHarvesterNPC.getWorld().getGameObjects().add(newBiomassBlob); - LogManager.LOGGER.fine("Spawned biomass at (" + newBiomassBlob.getX() + - ", " + newBiomassBlob.getY() + ")"); + + //Don't spawn biomass on World border + if (dyingHarvesterNPC.getX() != 0 && dyingHarvesterNPC.getX() != World.WORLD_SIZE - 1 && + dyingHarvesterNPC.getY() != 0 && dyingHarvesterNPC.getY() != World.WORLD_SIZE - 1) { + //Create a new biomass + BiomassBlob newBiomassBlob = createBiomassBlobAt( + dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); + //Add it to the world game objects + dyingHarvesterNPC.getWorld().addObject(newBiomassBlob); + LogManager.LOGGER.fine("Spawned biomass at (" + newBiomassBlob.getX() + + ", " + newBiomassBlob.getY() + ")"); + } } } diff --git a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldCreationListener.java b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldCreationListener.java index 0668afe..e48b43f 100644 --- a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldCreationListener.java +++ b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldCreationListener.java @@ -25,7 +25,9 @@ public class WorldCreationListener implements GameEventListener { ArrayList biomassBlobs = WorldUtils.generateBlobs(((WorldGenerationEvent) event).getWorld(), minCount, maxCount, yield); - ((WorldGenerationEvent) event).getWorld().getGameObjects().addAll(biomassBlobs); + for (BiomassBlob blob : biomassBlobs) { + ((WorldGenerationEvent) event).getWorld().addObject(blob); + } } } diff --git a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldUpdateListener.java b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldUpdateListener.java index 20e4461..afd9d9b 100644 --- a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldUpdateListener.java +++ b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/WorldUpdateListener.java @@ -17,11 +17,11 @@ public class WorldUpdateListener implements GameEventListener { private HashMap worldWaitMap = new HashMap<>(200); - private int minBlobCount; - private int maxBlobCount; - private int blobYield; - private int waitTime; - private int blobThreshold; + private static int minBlobCount; + private static int maxBlobCount; + private static int blobYield; + private static int waitTime; + private static int blobThreshold; public WorldUpdateListener(ServerConfiguration config) { @@ -45,7 +45,7 @@ public class WorldUpdateListener implements GameEventListener { World world = ((WorldUpdateEvent) event).getWorld(); //If there is less than the respawn threshold, - if (world.getGameObjects(BiomassBlob.class).size() < blobThreshold) { + if (world.findObjects(BiomassBlob.class).size() < blobThreshold) { //Set a timer for respawn_time ticks if (!worldWaitMap.containsKey(world) || worldWaitMap.get(world) == 0L) { @@ -59,7 +59,9 @@ public class WorldUpdateListener implements GameEventListener { //If the timer was set less than respawn_time ticks ago, respawn the blobs ArrayList newBlobs = WorldUtils.generateBlobs(world, minBlobCount, maxBlobCount, blobYield); - world.getGameObjects().addAll(newBlobs); + for (BiomassBlob blob : newBlobs) { + world.addObject(blob); + } //Set the 'waitUntil' time to 0 to indicate that we are not waiting worldWaitMap.replace(world, 0L); 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 e2e09e9..0f7acd8 100644 --- a/Server/src/main/java/net/simon987/server/GameServer.java +++ b/Server/src/main/java/net/simon987/server/GameServer.java @@ -9,7 +9,6 @@ import net.simon987.server.event.TickEvent; import net.simon987.server.game.DayNightCycle; import net.simon987.server.game.GameUniverse; import net.simon987.server.game.World; -import net.simon987.server.io.FileUtils; import net.simon987.server.logging.LogManager; import net.simon987.server.plugin.PluginManager; import net.simon987.server.user.User; @@ -18,8 +17,6 @@ import net.simon987.server.crypto.CryptoProvider; import java.io.File; import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; public class GameServer implements Runnable { @@ -39,11 +36,20 @@ public class GameServer implements Runnable { private CryptoProvider cryptoProvider; + private MongoClient mongo = null; + public GameServer() { this.config = new ServerConfiguration("config.properties"); + try{ + mongo = new MongoClient("localhost", 27017); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + gameUniverse = new GameUniverse(config); + gameUniverse.setMongo(mongo); pluginManager = new PluginManager(); maxExecutionTime = config.getInt("user_timeout"); @@ -130,8 +136,7 @@ public class GameServer implements Runnable { //Process user code - ArrayList users_ = new ArrayList<>(gameUniverse.getUsers()); - for (User user : users_) { + for (User user : gameUniverse.getUsers()) { if (user.getCpu() != null) { try { @@ -151,10 +156,8 @@ public class GameServer implements Runnable { } //Process each worlds - //Avoid concurrent modification - ArrayList worlds = new ArrayList<>(gameUniverse.getWorlds()); int updatedWorlds = 0; - for (World world : worlds) { + for (World world : gameUniverse.getWorlds()) { if (world.shouldUpdate()) { world.update(); updatedWorlds++; @@ -166,115 +169,100 @@ public class GameServer implements Runnable { save(); } - // Clean up history files - if (gameUniverse.getTime() % config.getInt("clean_interval") == 0) { - FileUtils.cleanHistory(config.getInt("history_size")); - } - socketServer.tick(); - LogManager.LOGGER.info("Processed " + gameUniverse.getWorlds().size() + " worlds (" + updatedWorlds + + LogManager.LOGGER.info("Processed " + gameUniverse.getWorldCount() + " worlds (" + updatedWorlds + ") updated"); } + + void load() { - LogManager.LOGGER.info("Loading from MongoDB"); - MongoClient mongo; - try { - mongo = new MongoClient("localhost", 27017); + LogManager.LOGGER.info("Loading all data from MongoDB"); - DB db = mongo.getDB("mar"); + DB db = mongo.getDB("mar"); - 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"); - //Load worlds - DBCursor cursor = worlds.find(); - while (cursor.hasNext()) { - GameServer.INSTANCE.getGameUniverse().getWorlds().add(World.deserialize(cursor.next())); - } - - //Load users - cursor = users.find(); - while (cursor.hasNext()) { - try { - GameServer.INSTANCE.getGameUniverse().getUsers().add(User.deserialize(cursor.next())); - } catch (CancelledException e) { - e.printStackTrace(); - } - } - - //Load misc server info - cursor = server.find(); - if (cursor.hasNext()) { - DBObject serverObj = cursor.next(); - gameUniverse.setTime((long) serverObj.get("time")); - gameUniverse.setNextObjectId((long) serverObj.get("nextObjectId")); - } - - LogManager.LOGGER.info("Done loading! W:" + GameServer.INSTANCE.getGameUniverse().getWorlds().size() + - " | U:" + GameServer.INSTANCE.getGameUniverse().getUsers().size()); - } catch (UnknownHostException e) { - e.printStackTrace(); + BasicDBObject whereQuery = new BasicDBObject(); + whereQuery.put("shouldUpdate", true); + DBCursor cursor = worlds.find(whereQuery); + GameUniverse universe = GameServer.INSTANCE.getGameUniverse(); + while (cursor.hasNext()) { + World w = World.deserialize(cursor.next()); + universe.addWorld(w); } + + //Load users + cursor = users.find(); + while (cursor.hasNext()) { + try { + universe.addUser(User.deserialize(cursor.next())); + } catch (CancelledException e) { + e.printStackTrace(); + } + } + + //Load misc server info + cursor = server.find(); + if (cursor.hasNext()) { + DBObject serverObj = cursor.next(); + gameUniverse.setTime((long) serverObj.get("time")); + gameUniverse.setNextObjectId((long) serverObj.get("nextObjectId")); + } + + LogManager.LOGGER.info("Done loading! W:" + GameServer.INSTANCE.getGameUniverse().getWorldCount() + + " | U:" + GameServer.INSTANCE.getGameUniverse().getUserCount()); } private void save() { - LogManager.LOGGER.info("Saving to MongoDB | W:" + gameUniverse.getWorlds().size() + " | U:" + gameUniverse.getUsers().size()); + LogManager.LOGGER.info("Saving to MongoDB | W:" + gameUniverse.getWorldCount() + " | U:" + gameUniverse.getUserCount()); + try{ + DB db = mongo.getDB("mar"); - MongoClient mongo; - try { - mongo = new MongoClient("localhost", 27017); + int unloaded_worlds = 0; - DB db = mongo.getDB("mar"); + DBCollection worlds = db.getCollection("world"); + DBCollection users = db.getCollection("user"); + DBCollection server = db.getCollection("server"); - db.dropDatabase(); //Todo: Update database / keep history instead of overwriting - - 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; - ArrayList worlds_ = new ArrayList<>(GameServer.INSTANCE.getGameUniverse().getWorlds()); - for (World w : worlds_) { - worldDocuments.add(w.mongoSerialise()); + int insertedWorlds = 0; + GameUniverse universe = GameServer.INSTANCE.getGameUniverse(); + for (World w : universe.getWorlds()) { +// LogManager.LOGGER.fine("Saving world "+w.getId()+" to mongodb"); insertedWorlds++; + worlds.save(w.mongoSerialise()); - if (worldDocuments.size() >= perBatch || insertedWorlds >= GameServer.INSTANCE.getGameUniverse().getWorlds().size()) { - worlds.insert(worldDocuments); - worldDocuments.clear(); - } - } + // 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_) { + for (User u : GameServer.INSTANCE.getGameUniverse().getUsers()) { - insertedUsers++; + if (!u.isGuest()) { + users.save(u.mongoSerialise()); + } - if (!u.isGuest()) { - userDocuments.add(u.mongoSerialise()); - } + } - if (userDocuments.size() >= perBatch || insertedUsers >= GameServer.INSTANCE.getGameUniverse().getUsers().size()) { - users.insert(userDocuments); - userDocuments.clear(); - } - } + 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); - BasicDBObject serverObj = new BasicDBObject(); - serverObj.put("time", gameUniverse.getTime()); - serverObj.put("nextObjectId", gameUniverse.getNextObjectId()); - server.insert(serverObj); - - LogManager.LOGGER.info("Done!"); - } catch (UnknownHostException e) { + 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(); } } 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..3e1bff7 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; @@ -27,15 +27,15 @@ public class AssemblyResult { * List of exceptions encountered during the assembly attempt, * they will be displayed in the editor */ - ArrayList exceptions = new ArrayList<>(50); + public ArrayList exceptions = new ArrayList<>(50); /** * 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/GameObject.java b/Server/src/main/java/net/simon987/server/game/GameObject.java index ddaef49..e70e97e 100755 --- a/Server/src/main/java/net/simon987/server/game/GameObject.java +++ b/Server/src/main/java/net/simon987/server/game/GameObject.java @@ -84,9 +84,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable } if (leftWorld != null) { - world.getGameObjects().remove(this); + world.removeObject(this); world.decUpdatable(); - leftWorld.getGameObjects().add(this); + leftWorld.addObject(this); leftWorld.incUpdatable(); setWorld(leftWorld); @@ -103,9 +103,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable } if (rightWorld != null) { - world.getGameObjects().remove(this); + world.removeObject(this); world.decUpdatable(); - rightWorld.getGameObjects().add(this); + rightWorld.addObject(this); rightWorld.incUpdatable(); setWorld(rightWorld); @@ -123,9 +123,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable } if (upWorld != null) { - world.getGameObjects().remove(this); + world.removeObject(this); world.decUpdatable(); - upWorld.getGameObjects().add(this); + upWorld.addObject(this); upWorld.incUpdatable(); setWorld(upWorld); @@ -143,9 +143,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable if (downWorld != null) { - world.getGameObjects().remove(this); + world.removeObject(this); world.decUpdatable(); - downWorld.getGameObjects().add(this); + downWorld.addObject(this); downWorld.incUpdatable(); setWorld(downWorld); 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 6ead02c..b9556c5 100644 --- a/Server/src/main/java/net/simon987/server/game/GameUniverse.java +++ b/Server/src/main/java/net/simon987/server/game/GameUniverse.java @@ -1,5 +1,6 @@ package net.simon987.server.game; +import com.mongodb.*; import net.simon987.server.GameServer; import net.simon987.server.ServerConfiguration; import net.simon987.server.assembly.Assembler; @@ -9,14 +10,20 @@ import net.simon987.server.assembly.exception.CancelledException; import net.simon987.server.logging.LogManager; import net.simon987.server.user.User; -import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; public class GameUniverse { - private ArrayList worlds; - private ArrayList users; + //private ArrayList worlds; + private ConcurrentHashMap worlds; + //username:user + private ConcurrentHashMap users; private WorldGenerator worldGenerator; + private MongoClient mongo = null; + + private long time; private long nextObjectId = 0; @@ -25,64 +32,144 @@ public class GameUniverse { public GameUniverse(ServerConfiguration config) { - worlds = new ArrayList<>(32); - users = new ArrayList<>(16); + worlds = new ConcurrentHashMap<>(256); + users = new ConcurrentHashMap<>(16); worldGenerator = new WorldGenerator(config); + } + public void setMongo(MongoClient mongo){ + this.mongo = mongo; } public long getTime() { return time; } - public World getWorld(int x, int y, boolean createNew) { + /** + * Attempts loading a world from mongoDB by coordinates + * + * @param x the x coordinate of the world + * @param y the y coordinate of the world + * + * @return World, null if not found + */ + private World loadWorld(int x, int y){ + + DB db = mongo.getDB("mar"); + DBCollection worlds = db.getCollection("world"); - for (World world : worlds) { - if (world.getX() == x && world.getY() == y) { - return world; - } + BasicDBObject whereQuery = new BasicDBObject(); + whereQuery.put("_id", World.idFromCoordinates(x,y)); + DBCursor cursor = worlds.find(whereQuery); + if (cursor.hasNext()) { + World w = World.deserialize(cursor.next()); + return w; } - - if (x >= 0 && x <= maxWidth && y >= 0 && y <= maxWidth) { - if (createNew) { - //World does not exist - World world = createWorld(x, y); - worlds.add(world); - - return world; - } else { - return null; - } - - } else { + else{ return null; } } - public World createWorld(int x, int y) { + /** + * Get a world by coordinates, attempts to load from mongoDB if not found. + * + * @param x the x coordinate of the world + * @param y the y coordinate of the world + * @param createNew if true, a new world is created when a world with given coordinates is not found + * + * @return World, null if not found and not created. + */ + public World getWorld(int x, int y, boolean createNew) { + // Wrapping coordinates around cyclically + x %= maxWidth+1; + y %= maxWidth+1; + + // Looks for a previously loaded world + World world = getLoadedWorld(x,y); + if (world != null){ + return world; + } + + // Tries loading the world from the database + world = loadWorld(x,y); + if (world != null){ + addWorld(world); + LogManager.LOGGER.fine("Loaded world "+(World.idFromCoordinates(x,y))+" from mongodb."); + return world; + } + + // World does not exist + if (createNew) { + // Creates a new world + world = createWorld(x, y); + addWorld(world); + LogManager.LOGGER.fine("Created new world "+(World.idFromCoordinates(x,y))+"."); + return world; + } else { + return null; + } + } + + public World getLoadedWorld(int x, int y) { + // Wrapping coordinates around cyclically + x %= maxWidth+1; + y %= maxWidth+1; + + return worlds.get(World.idFromCoordinates(x,y)); + } + + /** + * Adds a new or freshly loaded world to the universe (if not already present). + * + * @param world the world to be added + */ + public void addWorld(World world){ + World w = worlds.get(world.getId()); + if (w == null){ + world.setUniverse(this); + worlds.put(world.getId(),world); + } + } + + /** + * Removes the world with given coordinates from the universe. + * + * @param x the x coordinate of the world to be removed + * @param y the y coordinate of the world to be removed + */ + public void removeWorld(int x, int y){ + World w = worlds.remove(World.idFromCoordinates(x,y)); + if (w != null){ + w.setUniverse(null); + } + } + + /** + * Removes the given world from the universe. + * + * @param world the world to be removed. + */ + public void removeWorld(World world){ + World w = worlds.remove(world.getId()); + if (w != null){ + w.setUniverse(null); + } + } + + private World createWorld(int x, int y) { World world = null; try { world = worldGenerator.generateWorld(x, y); - - } catch (CancelledException e) { e.printStackTrace(); } - return world; } public User getUser(String username) { - - for (User user : users) { - if (user.getUsername().equals(username)) { - return user; - } - } - - return null; + return users.get(username); } public User getOrCreateUser(String username, boolean makeControlledUnit) { @@ -110,7 +197,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 { @@ -119,7 +206,7 @@ public class GameUniverse { user.setUsername(username); - users.add(user); + addUser(user); return user; @@ -141,12 +228,11 @@ public class GameUniverse { */ public GameObject getObject(long id) { - // - for (World world : worlds) { - for (GameObject object : world.getGameObjects()) { - if (object.getObjectId() == id) { - return object; - } + for (World world : getWorlds()) { + GameObject obj = world.findObject(id); + + if (obj != null) { + return obj; } } @@ -159,12 +245,20 @@ public class GameUniverse { time++; } - public ArrayList getWorlds() { - return worlds; + public Collection getWorlds() { + return worlds.values(); } - public ArrayList getUsers() { - return users; + public int getWorldCount() { + return worlds.size(); + } + + public Collection getUsers() { + return users.values(); + } + + public int getUserCount() { + return users.size(); } public long getNextObjectId() { @@ -187,8 +281,12 @@ public class GameUniverse { } + public void addUser(User user) { + users.put(user.getUsername(), user); + } + public void removeUser(User user) { - users.remove(user); + users.remove(user.getUsername()); } public int getMaxWidth() { diff --git a/Server/src/main/java/net/simon987/server/game/World.java b/Server/src/main/java/net/simon987/server/game/World.java index f88a2b2..0e54341 100644 --- a/Server/src/main/java/net/simon987/server/game/World.java +++ b/Server/src/main/java/net/simon987/server/game/World.java @@ -11,7 +11,9 @@ import net.simon987.server.io.MongoSerialisable; import java.awt.*; import java.util.ArrayList; +import java.util.Collection; import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; public class World implements MongoSerialisable { @@ -29,7 +31,7 @@ public class World implements MongoSerialisable { private TileMap tileMap; - private ArrayList gameObjects = new ArrayList<>(16); + private ConcurrentHashMap gameObjects = new ConcurrentHashMap<>(8); /** * If this number is greater than 0, the World will be updated. @@ -58,7 +60,28 @@ public class World implements MongoSerialisable { public boolean isTileBlocked(int x, int y) { return getGameObjectsBlockingAt(x, y).size() > 0 || tileMap.getTileAt(x, y) == TileMap.WALL_TILE; + } + /** + * Computes the world's unique id from its coordinates. + * + * @param x the x coordinate of the world + * @param y the y coordinate of the world + * + * @return long + */ + public static String idFromCoordinates(int x, int y){ + return "w-"+"0x"+Integer.toHexString(x)+"-"+"0x"+Integer.toHexString(y); + //return ((long)x)*(((long)maxWidth)+1)+((long)y); + } + + /** + * Returns the world's unique id, computed with idFromCoordinates. + * + * @return long + */ + public String getId(){ + return World.idFromCoordinates(x,y); } public int getX() { @@ -69,26 +92,48 @@ public class World implements MongoSerialisable { return y; } - /** - * Get all the game objects that are instances of the specified class - */ - public ArrayList getGameObjects(Class clazz) { + public ArrayList findObjects(Class clazz) { - ArrayList objects = new ArrayList<>(gameObjects.size()); + ArrayList matchingObjects = new ArrayList<>(2); - for (GameObject object : gameObjects) { - if (object.getClass().equals(clazz)) { - objects.add(object); + for (GameObject obj : gameObjects.values()) { + + if (obj.getClass().equals(clazz)) { + matchingObjects.add(obj); } } - return objects; + return matchingObjects; } - public ArrayList getGameObjects() { - return gameObjects; + + public ArrayList findObjects(int mapInfo) { + + ArrayList matchingObjects = new ArrayList<>(2); + + for (GameObject obj : gameObjects.values()) { + if ((obj.getMapInfo() & mapInfo) == mapInfo) { + matchingObjects.add(obj); + } + } + + return matchingObjects; } + public void addObject(GameObject object) { + gameObjects.put(object.getObjectId(), object); + } + + public void removeObject(GameObject object) { + gameObjects.remove(object.getObjectId()); + } + + public GameObject findObject(long objectId) { + return gameObjects.get(objectId); + } + + + /** * Update this World and its GameObjects *
@@ -100,13 +145,11 @@ public class World implements MongoSerialisable { GameEvent event = new WorldUpdateEvent(this); GameServer.INSTANCE.getEventDispatcher().dispatch(event); //Ignore cancellation - ArrayList gameObjects_ = new ArrayList<>(gameObjects); - - for (GameObject object : gameObjects_) { + for (GameObject object : gameObjects.values()) { //Clean up dead objects if (object.isDead()) { object.onDeadCallback(); - gameObjects.remove(object); + removeObject(object); //LogManager.LOGGER.fine("Removed object " + object + " id: " + object.getObjectId()); } else if (object instanceof Updatable) { ((Updatable) object).update(); @@ -120,11 +163,13 @@ public class World implements MongoSerialisable { BasicDBObject dbObject = new BasicDBObject(); BasicDBList objects = new BasicDBList(); - ArrayList gameObjects_ = new ArrayList<>(gameObjects); - for (GameObject obj : gameObjects_) { + for (GameObject obj : gameObjects.values()) { objects.add(obj.mongoSerialise()); } + + dbObject.put("_id", getId()); + dbObject.put("objects", objects); dbObject.put("terrain", tileMap.mongoSerialise()); @@ -133,7 +178,7 @@ public class World implements MongoSerialisable { dbObject.put("size", worldSize); dbObject.put("updatable", updatable); - + dbObject.put("shouldUpdate",shouldUpdate()); return dbObject; } @@ -171,7 +216,7 @@ public class World implements MongoSerialisable { GameObject object = GameObject.deserialize((DBObject) obj); object.setWorld(world); - world.gameObjects.add(object); + world.addObject(object); } return world; @@ -209,7 +254,7 @@ public class World implements MongoSerialisable { } //Objects - for (GameObject obj : this.gameObjects) { + for (GameObject obj : gameObjects.values()) { mapInfo[obj.getX()][obj.getY()] |= obj.getMapInfo(); } @@ -263,17 +308,16 @@ public class World implements MongoSerialisable { */ public ArrayList getGameObjectsBlockingAt(int x, int y) { - ArrayList gameObjects = new ArrayList<>(2); - - for (GameObject obj : this.gameObjects) { + ArrayList objectsLooking = new ArrayList<>(2); + for (GameObject obj : gameObjects.values()) { if (obj.isAt(x, y)) { - gameObjects.add(obj); + objectsLooking.add(obj); } } - return gameObjects; + return objectsLooking; } /** @@ -287,17 +331,15 @@ public class World implements MongoSerialisable { * @return the list of game objects at a location */ public ArrayList getGameObjectsAt(int x, int y) { - ArrayList gameObjects = new ArrayList<>(2); + ArrayList objectsAt = new ArrayList<>(2); + for (GameObject obj : gameObjects.values()) { - for (GameObject obj : this.gameObjects) { - - if (obj.getX() == x && obj.getY() == y) { - gameObjects.add(obj); + if (obj.isAt(x, y)) { + objectsAt.add(obj); } } - - return gameObjects; + return objectsAt; } public void incUpdatable() { @@ -315,4 +357,76 @@ public class World implements MongoSerialisable { public int getWorldSize() { return worldSize; } + + + private GameUniverse universe = null; + + public void setUniverse(GameUniverse universe){ + this.universe = universe; + } + + public ArrayList getNeighbouringLoadedWorlds(){ + ArrayList neighbouringWorlds = new ArrayList<>(); + + if (universe == null){ + return neighbouringWorlds; + } + + for (int dx=-1; dx<=+1; dx+=2){ + World nw = universe.getLoadedWorld(x+dx,y); + if (nw != null){ + neighbouringWorlds.add(nw); + } + } + for (int dy=-1; dy<=+1; dy+=2){ + World nw = universe.getLoadedWorld(x,y+dy); + if (nw != null){ + neighbouringWorlds.add(nw); + } + } + + return neighbouringWorlds; + } + + public ArrayList getNeighbouringExistingWorlds(){ + ArrayList neighbouringWorlds = new ArrayList<>(); + + if (universe == null){ + return neighbouringWorlds; + } + + for (int dx=-1; dx<=+1; dx+=2){ + World nw = universe.getWorld(x+dx,y,false); + if (nw != null){ + neighbouringWorlds.add(nw); + } + } + for (int dy=-1; dy<=+1; dy+=2){ + World nw = universe.getWorld(x,y+dy,false); + if (nw != null){ + neighbouringWorlds.add(nw); + } + } + + return neighbouringWorlds; + } + + + public boolean canUnload(){ + return updatable==0; + } + + public boolean shouldUnload(){ + boolean res = canUnload(); + + for (World nw : getNeighbouringLoadedWorlds() ){ + res &= nw.canUnload(); + } + + return res; + } + + public Collection getGameObjects() { + return gameObjects.values(); + } } 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 21a4518..785b163 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/io/FileUtils.java b/Server/src/main/java/net/simon987/server/io/FileUtils.java index 28c5a59..820dba1 100644 --- a/Server/src/main/java/net/simon987/server/io/FileUtils.java +++ b/Server/src/main/java/net/simon987/server/io/FileUtils.java @@ -1,35 +1,12 @@ package net.simon987.server.io; -import net.simon987.server.logging.LogManager; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; public class FileUtils { - private static final int BUFFER_SIZE = 1024; - private static final String STR_ENCODING = "UTF-8"; private static final String DATE_FORMAT = "yyyyMMddHHmmss"; - private static final String FILE_TYPE = ".zip"; - private static final Path ROOT_DIR; - private static final String DIR_NAME = "history"; - public static final Path DIR_PATH; - static { - ROOT_DIR = Paths.get(".").normalize(); - DIR_PATH = ROOT_DIR.resolve(DIR_NAME); - } - - //Private constructor - private FileUtils() { - - } /** * Creates a new stamp containing the current date and time @@ -42,143 +19,4 @@ public class FileUtils { return f.format(millisToDate); } - /** - * Created a directory if none exists with the specified name - * - * @param directory folder to create - * @return true is the file exists or create operation is successful - */ - public static boolean prepDirectory(Path directory) { - File file = directory.toFile(); - - //If the directory exists or the directory created successfully return true - if (file.exists() || file.mkdir()) { - return true; - - } else { - System.out.println("Error creating directory: " + file.toString()); - return false; - } - } - - /** - * Converts a file into an array of bytes - * - * @param path the file to be converted into bytes - * @return the byte array of the given file - */ - public static byte[] bytifyFile(Path path) { - byte[] bytes = null; - - try { - bytes = Files.readAllBytes(path); - - } catch (IOException e) { - System.out.println("Failed to extract bytes from: " + path); - e.printStackTrace(); - } - - return bytes; - } - - /** - * Takes in a file that had been converted to a byte[] to be written to a new - * zip file - * - * @param data - * contains data in byte array form to be written, typically a file - * that has been converted with bytifyFile() - * @throws IOException - * if an error occurs during the write process - */ - public static void writeSaveToZip(String name, byte[] data) throws IOException { - - String newFile = DIR_PATH.resolve(getDateTimeStamp() + FILE_TYPE).toString(); - FileOutputStream output = new FileOutputStream(newFile); - ZipOutputStream stream = new ZipOutputStream(output); - byte[] buffer = new byte[BUFFER_SIZE]; - ByteArrayInputStream bais = new ByteArrayInputStream(buffer); - - while ((bais.read(buffer)) > -1) { - // File name - ZipEntry entry = new ZipEntry(name); - // Set to start of next entry in the stream. - stream.putNextEntry(entry); - // Data to write. - stream.write(data); - // Close the current entry. - stream.closeEntry(); - } - - stream.close(); - output.close(); - } - - public static void cleanHistory(int size) { - - - File[] files = new File(DIR_PATH.toString()).listFiles(); - File[] sorted = new File[size]; - - File currentFile; - boolean changed; - - if (files != null) { - for (int i = 0; i < files.length / 2; i++) { - currentFile = files[i]; - files[i] = files[files.length - i - 1]; - files[files.length - i - 1] = currentFile; - } - - for (int f = 0; f < files.length; f++) { - changed = false; - - try { - long dirFile = Long.parseLong(files[f].getName().substring(0, (files[f].getName().length() - 4))); - - if (f < size && sorted[f] == null) { - sorted[f] = files[f]; - - } else { - - for (int s = 0; s < sorted.length; s++) { - - long sortedFile = Long.parseLong(sorted[s].getName().substring(0, (sorted[s].getName().length() - 4))); - - if (dirFile > sortedFile) { - - if (s == sorted.length - 1) { - sorted[s] = files[f]; - - } else { - sorted[s] = files[f]; - } - - changed = true; - } - } - - if (!changed) { - files[f].delete(); - } - - } - } catch (NumberFormatException e) { - LogManager.LOGGER.info("Non-save file in history directory: " + files[f].getName()); - } - } - } - - - } - - /** - * Converts a byte array into human readable format using the provided encoding - * - * @param bytes data to be encoded to String - * @return a String containing the encoded bytes - */ - public static String byteArrAsString(byte[] bytes) throws UnsupportedEncodingException { - return new String(bytes, STR_ENCODING); - } } diff --git a/Server/src/main/java/net/simon987/server/logging/LogManager.java b/Server/src/main/java/net/simon987/server/logging/LogManager.java index 1a2262a..47b11e3 100755 --- a/Server/src/main/java/net/simon987/server/logging/LogManager.java +++ b/Server/src/main/java/net/simon987/server/logging/LogManager.java @@ -19,9 +19,30 @@ public class LogManager { public static void initialize() { LOGGER.setUseParentHandlers(false); - Handler handler = new ConsoleHandler(); + /* + * Having warning/error directed to stderr + */ + Handler errHandler = new ConsoleHandler(); + errHandler.setFormatter(new GenericFormatter()); + errHandler.setLevel(Level.WARNING); + + /* + * Only have info and below directed to stdout + */ + Handler handler = new StreamHandler(System.out, new GenericFormatter()) { + @Override + public synchronized void publish(LogRecord record) { + super.publish(record); + flush(); + } + }; + handler.setFilter(new Filter() { + @Override + public boolean isLoggable(LogRecord record) { + return record.getLevel().intValue() <= Level.INFO.intValue(); + } + }); handler.setLevel(Level.ALL); - handler.setFormatter(new GenericFormatter()); try { Handler fileHandler = new FileHandler("mar.log"); @@ -29,6 +50,7 @@ public class LogManager { fileHandler.setFormatter(new GenericFormatter()); LOGGER.addHandler(handler); + LOGGER.addHandler(errHandler); LOGGER.addHandler(fileHandler); LOGGER.setLevel(Level.ALL); @@ -36,6 +58,5 @@ public class LogManager { e.printStackTrace(); } - } } diff --git a/Server/src/main/java/net/simon987/server/user/User.java b/Server/src/main/java/net/simon987/server/user/User.java index 55875ce..0da9acc 100755 --- a/Server/src/main/java/net/simon987/server/user/User.java +++ b/Server/src/main/java/net/simon987/server/user/User.java @@ -44,6 +44,7 @@ public class User implements MongoSerialisable { BasicDBObject dbObject = new BasicDBObject(); + dbObject.put("_id", username); // a constant id ensures only one entry per user is kept and updated, instead of a new entry created every save for every user. dbObject.put("username", username); dbObject.put("code", userCode); dbObject.put("controlledUnit", controlledUnit.getObjectId()); 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..f552ca0 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,35 @@ 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(); + } + + //Clear registers + user.getUser().getCpu().getRegisterSet().clear(); + + JSONObject response = new JSONObject(); + response.put("t", "codeResponse"); + response.put("bytes", ar.bytes.length); + response.put("exceptions", ar.exceptions.size()); + + 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/src/main/java/net/simon987/server/webserver/ObjectsRequestHandler.java b/Server/src/main/java/net/simon987/server/webserver/ObjectsRequestHandler.java index 6f8a634..f8edbb1 100644 --- a/Server/src/main/java/net/simon987/server/webserver/ObjectsRequestHandler.java +++ b/Server/src/main/java/net/simon987/server/webserver/ObjectsRequestHandler.java @@ -7,8 +7,6 @@ import net.simon987.server.logging.LogManager; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import java.util.ArrayList; - public class ObjectsRequestHandler implements MessageHandler { @@ -29,13 +27,12 @@ public class ObjectsRequestHandler implements MessageHandler { World world = GameServer.INSTANCE.getGameUniverse().getWorld(x, y, false); if (world != null) { - ArrayList gameObjects = world.getGameObjects(); JSONObject response = new JSONObject(); JSONArray objects = new JSONArray(); - for (GameObject object : gameObjects) { + for (GameObject object : world.getGameObjects()) { objects.add(object.serialise()); } 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