Merge branch 'master' into vaults

# Conflicts:
#	Server/src/main/java/net/simon987/server/GameServer.java
#	Server/src/main/java/net/simon987/server/game/World.java
This commit is contained in:
simon 2018-01-17 20:29:37 -05:00
commit 3d10e4306b
46 changed files with 698 additions and 643 deletions

View File

@ -52,7 +52,6 @@ public class CubotLaser extends CpuHardware {
Point frontTile = cubot.getFrontTile(); Point frontTile = cubot.getFrontTile();
ArrayList<GameObject> objects = cubot.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y); ArrayList<GameObject> objects = cubot.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y);
if (cubot.getCurrentAction() == Action.IDLE && objects.size() > 0) { if (cubot.getCurrentAction() == Action.IDLE && objects.size() > 0) {
//FIXME: Problem here if more than 1 object //FIXME: Problem here if more than 1 object
if (objects.get(0) instanceof InventoryHolder) { if (objects.get(0) instanceof InventoryHolder) {

View File

@ -37,37 +37,40 @@ public class CubotLeg extends CpuHardware implements JSONSerialisable {
@Override @Override
public void handleInterrupt(Status status) { 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); Direction dir = Direction.getDirection(b);
if (dir != null) { if (dir != null) {
cubot.setDirection(Direction.getDirection(b)); if (cubot.spendEnergy(20)) {
status.setErrorFlag(false); cubot.setDirection(Direction.getDirection(b));
status.setErrorFlag(false);
}
} else { } else {
status.setErrorFlag(true); 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);
}
} }
} }
} }

View File

@ -20,35 +20,35 @@ public class UserCreationListener implements GameEventListener {
@Override @Override
public void handle(GameEvent event) { 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(); 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.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.setEnergy(GameServer.INSTANCE.getConfig().getInt("battery_max_energy"));
cubot.setMaxEnergy(GameServer.INSTANCE.getConfig().getInt("battery_max_energy")); cubot.setMaxEnergy(GameServer.INSTANCE.getConfig().getInt("battery_max_energy"));
cubot.setParent(user); cubot.setParent(user);
Point point = cubot.getWorld().getRandomPassableTile();
cubot.setX(point.x);
cubot.setY(point.y);
user.setControlledUnit(cubot); user.setControlledUnit(cubot);
LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)");
} }
} }

View File

@ -14,6 +14,6 @@ public class CubotTest {
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
assertEquals(1,2); assertEquals(1, 1);
} }
} }

View File

@ -74,7 +74,7 @@ public class Factory extends GameObject implements Updatable {
npc.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); npc.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
npc.setX(p.x); npc.setX(p.x);
npc.setY(p.y); npc.setY(p.y);
getWorld().getGameObjects().add(npc); getWorld().addObject(npc);
getWorld().incUpdatable(); getWorld().incUpdatable();
npc.setFactory(this); npc.setFactory(this);

View File

@ -33,14 +33,9 @@ public class HarvestTask extends NPCTask {
if (pause == 0) { if (pause == 0) {
//Get biomass //Get biomass
ArrayList<GameObject> biomass = new ArrayList<>(10); /* todo replace by some sort of .collect call with object
id (See https://github.com/simon987/Much-Assembly-Required/pull/66)*/
for (GameObject object : npc.getWorld().getGameObjects()) { ArrayList<GameObject> biomass = npc.getWorld().findObjects(0x4000);
//Plant MAP_INFO
if ((object.getMapInfo() & 0x4000) == 0x4000) {
biomass.add(object);
}
}
//Get closest one //Get closest one
int minDist = Integer.MAX_VALUE; int minDist = Integer.MAX_VALUE;

View File

@ -48,7 +48,9 @@ public class HarvesterNPC extends NonPlayerCharacter {
@Override @Override
public void onDeadCallback() { public void onDeadCallback() {
getFactory().getNpcs().remove(this); if (getFactory() != null && getFactory().getNpcs() != null) {
getFactory().getNpcs().remove(this);
}
GameServer.INSTANCE.getEventDispatcher().dispatch( GameServer.INSTANCE.getEventDispatcher().dispatch(
new ObjectDeathEvent(this, ID)); new ObjectDeathEvent(this, ID));

View File

@ -53,7 +53,7 @@ public class WorldCreationListener implements GameEventListener {
continue; continue;
} }
world.getGameObjects().add(factory); world.addObject(factory);
world.incUpdatable(); world.incUpdatable();
LogManager.LOGGER.info("Spawned Factory at (" + world.getX() + ", " + world.getY() + LogManager.LOGGER.info("Spawned Factory at (" + world.getX() + ", " + world.getY() +
@ -84,7 +84,7 @@ public class WorldCreationListener implements GameEventListener {
if (radioTower.getAdjacentTile() != null) { if (radioTower.getAdjacentTile() != null) {
//Radio Tower has adjacent tiles //Radio Tower has adjacent tiles
world.getGameObjects().add(radioTower); world.addObject(radioTower);
world.incUpdatable(); //In case the Factory couldn't be spawned. world.incUpdatable(); //In case the Factory couldn't be spawned.
NpcPlugin.getRadioTowers().add(radioTower); NpcPlugin.getRadioTowers().add(radioTower);

View File

@ -29,18 +29,23 @@ public class ObjectDeathListener implements GameEventListener {
@Override @Override
public void handle(GameEvent event) { public void handle(GameEvent event) {
// a HarvesterNPC ObjectDeathEvent is received
// TODO: setup enum with all GameObject type IDs // TODO: setup enum with all GameObject type IDs
if (((ObjectDeathEvent) event).getSourceObjectId() == 10) { if (((ObjectDeathEvent) event).getSourceObjectId() == 10) {
//An HarvesterNPC ObjectDeathEvent is received
GameObject dyingHarvesterNPC = (GameObject)event.getSource(); GameObject dyingHarvesterNPC = (GameObject)event.getSource();
// create a new biomass
BiomassBlob newBiomassBlob = createBiomassBlobAt( //Don't spawn biomass on World border
dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); if (dyingHarvesterNPC.getX() != 0 && dyingHarvesterNPC.getX() != World.WORLD_SIZE - 1 &&
// add it to the world game objects dyingHarvesterNPC.getY() != 0 && dyingHarvesterNPC.getY() != World.WORLD_SIZE - 1) {
dyingHarvesterNPC.getWorld().getGameObjects().add(newBiomassBlob); //Create a new biomass
LogManager.LOGGER.fine("Spawned biomass at (" + newBiomassBlob.getX() + BiomassBlob newBiomassBlob = createBiomassBlobAt(
", " + newBiomassBlob.getY() + ")"); 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() + ")");
}
} }
} }

View File

@ -25,7 +25,9 @@ public class WorldCreationListener implements GameEventListener {
ArrayList<BiomassBlob> biomassBlobs = WorldUtils.generateBlobs(((WorldGenerationEvent) event).getWorld(), ArrayList<BiomassBlob> biomassBlobs = WorldUtils.generateBlobs(((WorldGenerationEvent) event).getWorld(),
minCount, maxCount, yield); minCount, maxCount, yield);
((WorldGenerationEvent) event).getWorld().getGameObjects().addAll(biomassBlobs); for (BiomassBlob blob : biomassBlobs) {
((WorldGenerationEvent) event).getWorld().addObject(blob);
}
} }
} }

View File

@ -17,11 +17,11 @@ public class WorldUpdateListener implements GameEventListener {
private HashMap<World, Long> worldWaitMap = new HashMap<>(200); private HashMap<World, Long> worldWaitMap = new HashMap<>(200);
private int minBlobCount; private static int minBlobCount;
private int maxBlobCount; private static int maxBlobCount;
private int blobYield; private static int blobYield;
private int waitTime; private static int waitTime;
private int blobThreshold; private static int blobThreshold;
public WorldUpdateListener(ServerConfiguration config) { public WorldUpdateListener(ServerConfiguration config) {
@ -45,7 +45,7 @@ public class WorldUpdateListener implements GameEventListener {
World world = ((WorldUpdateEvent) event).getWorld(); World world = ((WorldUpdateEvent) event).getWorld();
//If there is less than the respawn threshold, //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 //Set a timer for respawn_time ticks
if (!worldWaitMap.containsKey(world) || worldWaitMap.get(world) == 0L) { 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 //If the timer was set less than respawn_time ticks ago, respawn the blobs
ArrayList<BiomassBlob> newBlobs = WorldUtils.generateBlobs(world, minBlobCount, ArrayList<BiomassBlob> newBlobs = WorldUtils.generateBlobs(world, minBlobCount,
maxBlobCount, blobYield); 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 //Set the 'waitUntil' time to 0 to indicate that we are not waiting
worldWaitMap.replace(world, 0L); worldWaitMap.replace(world, 0L);

View File

@ -75,6 +75,15 @@
</archive> </archive>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
<configuration>
<workingDirectory>./src/main/resources</workingDirectory>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@ -9,7 +9,6 @@ import net.simon987.server.event.TickEvent;
import net.simon987.server.game.DayNightCycle; import net.simon987.server.game.DayNightCycle;
import net.simon987.server.game.GameUniverse; import net.simon987.server.game.GameUniverse;
import net.simon987.server.game.World; import net.simon987.server.game.World;
import net.simon987.server.io.FileUtils;
import net.simon987.server.logging.LogManager; import net.simon987.server.logging.LogManager;
import net.simon987.server.plugin.PluginManager; import net.simon987.server.plugin.PluginManager;
import net.simon987.server.user.User; import net.simon987.server.user.User;
@ -18,8 +17,6 @@ import net.simon987.server.crypto.CryptoProvider;
import java.io.File; import java.io.File;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class GameServer implements Runnable { public class GameServer implements Runnable {
@ -39,11 +36,20 @@ public class GameServer implements Runnable {
private CryptoProvider cryptoProvider; private CryptoProvider cryptoProvider;
private MongoClient mongo = null;
public GameServer() { public GameServer() {
this.config = new ServerConfiguration("config.properties"); this.config = new ServerConfiguration("config.properties");
try{
mongo = new MongoClient("localhost", 27017);
} catch (UnknownHostException e) {
e.printStackTrace();
}
gameUniverse = new GameUniverse(config); gameUniverse = new GameUniverse(config);
gameUniverse.setMongo(mongo);
pluginManager = new PluginManager(); pluginManager = new PluginManager();
maxExecutionTime = config.getInt("user_timeout"); maxExecutionTime = config.getInt("user_timeout");
@ -130,8 +136,7 @@ public class GameServer implements Runnable {
//Process user code //Process user code
ArrayList<User> users_ = new ArrayList<>(gameUniverse.getUsers()); for (User user : gameUniverse.getUsers()) {
for (User user : users_) {
if (user.getCpu() != null) { if (user.getCpu() != null) {
try { try {
@ -151,10 +156,8 @@ public class GameServer implements Runnable {
} }
//Process each worlds //Process each worlds
//Avoid concurrent modification
ArrayList<World> worlds = new ArrayList<>(gameUniverse.getWorlds());
int updatedWorlds = 0; int updatedWorlds = 0;
for (World world : worlds) { for (World world : gameUniverse.getWorlds()) {
if (world.shouldUpdate()) { if (world.shouldUpdate()) {
world.update(); world.update();
updatedWorlds++; updatedWorlds++;
@ -166,115 +169,100 @@ public class GameServer implements Runnable {
save(); save();
} }
// Clean up history files
if (gameUniverse.getTime() % config.getInt("clean_interval") == 0) {
FileUtils.cleanHistory(config.getInt("history_size"));
}
socketServer.tick(); socketServer.tick();
LogManager.LOGGER.info("Processed " + gameUniverse.getWorlds().size() + " worlds (" + updatedWorlds + LogManager.LOGGER.info("Processed " + gameUniverse.getWorldCount() + " worlds (" + updatedWorlds +
") updated"); ") updated");
} }
void load() { void load() {
LogManager.LOGGER.info("Loading from MongoDB"); LogManager.LOGGER.info("Loading all data from MongoDB");
MongoClient mongo;
try {
mongo = new MongoClient("localhost", 27017);
DB db = mongo.getDB("mar"); DB db = mongo.getDB("mar");
DBCollection worlds = db.getCollection("world"); DBCollection worlds = db.getCollection("world");
DBCollection users = db.getCollection("user"); DBCollection users = db.getCollection("user");
DBCollection server = db.getCollection("server"); DBCollection server = db.getCollection("server");
//Load worlds BasicDBObject whereQuery = new BasicDBObject();
DBCursor cursor = worlds.find(); whereQuery.put("shouldUpdate", true);
while (cursor.hasNext()) { DBCursor cursor = worlds.find(whereQuery);
GameServer.INSTANCE.getGameUniverse().getWorlds().add(World.deserialize(cursor.next())); GameUniverse universe = GameServer.INSTANCE.getGameUniverse();
} while (cursor.hasNext()) {
World w = World.deserialize(cursor.next());
//Load users universe.addWorld(w);
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();
} }
//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() { 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; int unloaded_worlds = 0;
try {
mongo = new MongoClient("localhost", 27017);
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 int insertedWorlds = 0;
GameUniverse universe = GameServer.INSTANCE.getGameUniverse();
DBCollection worlds = db.getCollection("world"); for (World w : universe.getWorlds()) {
DBCollection users = db.getCollection("user"); // LogManager.LOGGER.fine("Saving world "+w.getId()+" to mongodb");
DBCollection server = db.getCollection("server");
List<DBObject> worldDocuments = new ArrayList<>();
int perBatch = 35;
int insertedWorlds = 0;
ArrayList<World> worlds_ = new ArrayList<>(GameServer.INSTANCE.getGameUniverse().getWorlds());
for (World w : worlds_) {
worldDocuments.add(w.mongoSerialise());
insertedWorlds++; insertedWorlds++;
worlds.save(w.mongoSerialise());
if (worldDocuments.size() >= perBatch || insertedWorlds >= GameServer.INSTANCE.getGameUniverse().getWorlds().size()) { // If the world should unload, it is removed from the Universe after having been saved.
worlds.insert(worldDocuments); if (w.shouldUnload()){
worldDocuments.clear(); unloaded_worlds++;
} // LogManager.LOGGER.fine("Unloading world "+w.getId()+" from universe");
} universe.removeWorld(w);
}
}
List<DBObject> userDocuments = new ArrayList<>(); for (User u : GameServer.INSTANCE.getGameUniverse().getUsers()) {
int insertedUsers = 0;
ArrayList<User> users_ = new ArrayList<>(GameServer.INSTANCE.getGameUniverse().getUsers());
for (User u : users_) {
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()) { BasicDBObject serverObj = new BasicDBObject();
users.insert(userDocuments); serverObj.put("_id","serverinfo"); // a constant id ensures only one entry is kept and updated, instead of a new entry created every save.
userDocuments.clear(); serverObj.put("time", gameUniverse.getTime());
} serverObj.put("nextObjectId", gameUniverse.getNextObjectId());
} server.save(serverObj);
BasicDBObject serverObj = new BasicDBObject(); LogManager.LOGGER.info(""+insertedWorlds+" worlds saved, "+unloaded_worlds+" unloaded");
serverObj.put("time", gameUniverse.getTime()); LogManager.LOGGER.info("Done!");
serverObj.put("nextObjectId", gameUniverse.getNextObjectId()); } catch (Exception e) {
server.insert(serverObj); LogManager.LOGGER.severe("Problem happened during save function");
LogManager.LOGGER.info("Done!");
} catch (UnknownHostException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -24,7 +24,7 @@ public class Assembler {
private RegisterSet registerSet; 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) { public Assembler(InstructionSet instructionSet, RegisterSet registerSet, ServerConfiguration config) {
this.instructionSet = instructionSet; this.instructionSet = instructionSet;
@ -54,7 +54,7 @@ public class Assembler {
*/ */
private static String removeLabel(String line) { 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); line = removeComment(line);
//Check for labels //Check for labels
Pattern pattern = Pattern.compile("\\b\\w*\\b:"); Pattern pattern = Pattern.compile("^\\s*\\b\\w*\\b:");
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
if (matcher.find()) { 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)); LogManager.LOGGER.fine("DEBUG: Label " + label + " @ " + (result.origin + currentOffset));
result.labels.put(label, (char) (result.origin + currentOffset)); result.labels.put(label, (char) (result.origin + currentOffset));
@ -175,7 +175,18 @@ public class Assembler {
out.writeChar(0); out.writeChar(0);
} else { } 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 * @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 { int currentLine, int currentOffset) throws AssemblyException {
String[] tokens = line.split("\\s+"); String[] tokens = line.split("\\s+");
if (tokens[0].toUpperCase().equals(".TEXT")) { if (tokens[0].toUpperCase().equals(".TEXT")) {
result.defineSegment(Segment.TEXT, currentLine, currentOffset); result.defineSecton(Section.TEXT, currentLine, currentOffset);
throw new PseudoInstructionException(currentLine); throw new PseudoInstructionException(currentLine);
} else if (tokens[0].toUpperCase().equals(".DATA")) { } else if (tokens[0].toUpperCase().equals(".DATA")) {
LogManager.LOGGER.fine("DEBUG: .data @" + currentLine); LogManager.LOGGER.fine("DEBUG: .data @" + currentLine);
result.defineSegment(Segment.DATA, currentLine, currentOffset); result.defineSecton(Section.DATA, currentLine, currentOffset);
throw new PseudoInstructionException(currentLine); throw new PseudoInstructionException(currentLine);
} }
} }
@ -296,7 +307,7 @@ public class Assembler {
String[] tokens = line.split("\\s+"); 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) { if (tokens[1].toUpperCase().equals("EQU") && tokens.length == 3) {
try { try {
//Save value as a label //Save value as a label
@ -385,7 +396,7 @@ public class Assembler {
} }
//Check for pseudo instructions //Check for pseudo instructions
checkForSegmentDeclaration(line, result, currentLine, currentOffset); checkForSectionDeclaration(line, result, currentLine, currentOffset);
checkForEQUInstruction(line, result.labels, currentLine); checkForEQUInstruction(line, result.labels, currentLine);
checkForORGInstruction(line, result, currentLine); checkForORGInstruction(line, result, currentLine);

View File

@ -2,7 +2,7 @@ package net.simon987.server.assembly;
import net.simon987.server.ServerConfiguration; import net.simon987.server.ServerConfiguration;
import net.simon987.server.assembly.exception.AssemblyException; 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 net.simon987.server.logging.LogManager;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -27,15 +27,15 @@ public class AssemblyResult {
* List of exceptions encountered during the assembly attempt, * List of exceptions encountered during the assembly attempt,
* they will be displayed in the editor * they will be displayed in the editor
*/ */
ArrayList<AssemblyException> exceptions = new ArrayList<>(50); public ArrayList<AssemblyException> exceptions = new ArrayList<>(50);
/** /**
* Offset of the code segment * Offset of the code segment
*/ */
private int codeSegmentOffset; private int codeSectionOffset;
/** /**
* Line of the code segment definition * Line of the code segment definition
*/ */
private int codeSegmentLine; private int codeSectionLine;
/** /**
* The encoded user code (will be incomplete or invalid if the * The encoded user code (will be incomplete or invalid if the
@ -45,60 +45,60 @@ public class AssemblyResult {
/** /**
* Offset of the data segment * Offset of the data segment
*/ */
private int dataSegmentOffset; private int dataSectionOffset;
/** /**
* Line of the data segment definition * Line of the data segment definition
*/ */
private int dataSegmentLine; private int dataSectionLine;
/** /**
* Whether or not the code segment is set * Whether or not the code segment is set
*/ */
private boolean codeSegmentSet = false; private boolean codeSectionSet = false;
/** /**
* Whether or not the data segment is set * Whether or not the data segment is set
*/ */
private boolean dataSegmentSet = false; private boolean dataSectionSet = false;
AssemblyResult(ServerConfiguration config) { AssemblyResult(ServerConfiguration config) {
origin = config.getInt("org_offset"); origin = config.getInt("org_offset");
} }
/** /**
* Define a segment. * Define a section.
* *
* @param segment Segment to define * @param section Section to define
* @param currentOffset Current offset, in bytes of the segment * @param currentOffset Current offset, in bytes of the section
* @param currentLine Line number of the segment declaration * @param currentLine Line number of the section declaration
* @throws DuplicateSegmentException when a segment is defined twice * @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) { if (section == Section.TEXT) {
//Code segment //Code section
if (!codeSegmentSet) { if (!codeSectionSet) {
codeSegmentOffset = origin + currentOffset; codeSectionOffset = origin + currentOffset;
codeSegmentLine = currentLine; codeSectionLine = currentLine;
LogManager.LOGGER.fine("DEBUG: .text offset @" + codeSegmentOffset); LogManager.LOGGER.fine("DEBUG: .text offset @" + codeSectionOffset);
codeSegmentSet = true; codeSectionSet = true;
} else { } else {
throw new DuplicateSegmentException(currentLine); throw new DuplicateSectionException(currentLine);
} }
} else { } else {
//Data segment //Data section
if (!dataSegmentSet) { if (!dataSectionSet) {
dataSegmentOffset = origin + currentOffset; dataSectionOffset = origin + currentOffset;
dataSegmentLine = currentLine; dataSectionLine = currentLine;
LogManager.LOGGER.fine("DEBUG: .data offset @" + dataSegmentOffset); LogManager.LOGGER.fine("DEBUG: .data offset @" + dataSectionOffset);
dataSegmentSet = true; dataSectionSet = true;
} else { } else {
throw new DuplicateSegmentException(currentLine); throw new DuplicateSectionException(currentLine);
} }
} }
@ -113,9 +113,9 @@ public class AssemblyResult {
return assembledCode; return assembledCode;
} }
public int getCodeSegmentOffset() { public int getCodeSectionOffset() {
if (codeSegmentSet) { if (codeSectionSet) {
return codeSegmentOffset; return codeSectionOffset;
} else { } else {
return origin; return origin;
} }

View File

@ -43,10 +43,10 @@ public class CPU implements MongoSerialisable {
private RegisterSet registerSet; 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 * 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 * Instruction pointer, always points to the next instruction
@ -73,7 +73,7 @@ public class CPU implements MongoSerialisable {
instructionSet = new DefaultInstructionSet(); instructionSet = new DefaultInstructionSet();
registerSet = new DefaultRegisterSet(); registerSet = new DefaultRegisterSet();
attachedHardware = new HashMap<>(); attachedHardware = new HashMap<>();
codeSegmentOffset = config.getInt("org_offset"); codeSectionOffset = config.getInt("org_offset");
instructionSet.add(new JmpInstruction(this)); instructionSet.add(new JmpInstruction(this));
instructionSet.add(new JnzInstruction(this)); instructionSet.add(new JnzInstruction(this));
@ -112,7 +112,7 @@ public class CPU implements MongoSerialisable {
public void reset() { public void reset() {
status.clear(); status.clear();
ip = codeSegmentOffset; ip = codeSectionOffset;
} }
public int execute(int timeout) { public int execute(int timeout) {
@ -352,7 +352,7 @@ public class CPU implements MongoSerialisable {
dbObject.put("memory", memory.mongoSerialise()); dbObject.put("memory", memory.mongoSerialise());
dbObject.put("registerSet", registerSet.mongoSerialise()); dbObject.put("registerSet", registerSet.mongoSerialise());
dbObject.put("codeSegmentOffset", codeSegmentOffset); dbObject.put("codeSegmentOffset", codeSectionOffset);
BasicDBList hardwareList = new BasicDBList(); BasicDBList hardwareList = new BasicDBList();
@ -375,7 +375,7 @@ public class CPU implements MongoSerialisable {
CPU cpu = new CPU(GameServer.INSTANCE.getConfig(), user); 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"); BasicDBList hardwareList = (BasicDBList) obj.get("hardware");
@ -416,8 +416,8 @@ public class CPU implements MongoSerialisable {
this.ip = ip; this.ip = ip;
} }
public void setCodeSegmentOffset(int codeSegmentOffset) { public void setCodeSectionOffset(int codeSectionOffset) {
this.codeSegmentOffset = codeSegmentOffset; this.codeSectionOffset = codeSectionOffset;
} }
public void attachHardware(CpuHardware hardware, int address) { public void attachHardware(CpuHardware hardware, int address) {

View File

@ -44,6 +44,8 @@ public class DefaultInstructionSet implements InstructionSet {
add(new RclInstruction()); add(new RclInstruction());
add(new RcrInstruction()); add(new RcrInstruction());
add(new SarInstruction()); add(new SarInstruction());
add(new IncInstruction());
add(new DecInstruction());
} }
/** /**

View File

@ -6,7 +6,6 @@ import com.mongodb.DBObject;
import net.simon987.server.GameServer; import net.simon987.server.GameServer;
import net.simon987.server.io.MongoSerialisable; import net.simon987.server.io.MongoSerialisable;
import net.simon987.server.logging.LogManager; import net.simon987.server.logging.LogManager;
import org.json.simple.JSONObject;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -157,36 +156,6 @@ public class Memory implements Target, MongoSerialisable {
return memory; 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) { public void setBytes(byte[] bytes) {
this.words = new char[bytes.length / 2]; this.words = new char[bytes.length / 2];
ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).asCharBuffer().get(this.words); ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).asCharBuffer().get(this.words);

View File

@ -224,11 +224,30 @@ public class Operand {
} }
//label is invalid //label is invalid
data = Integer.decode(expr); data = Integer.decode(expr);
value += registerSet.size() * 2; //refers to memory with disp value += registerSet.size() * 2; //refers to memory with disp
return true; return true;
} catch (NumberFormatException e) { } 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; return false;
} }
} }

View File

@ -3,10 +3,9 @@ package net.simon987.server.assembly;
/** /**
* Section of a user-created program. * Section of a user-created program.
* The execution will start at the beginning of the code * The execution will start at the beginning of the code
* segment and a warning message will be displayed when execution * segment.
* reached the data segment during debugging
*/ */
public enum Segment { public enum Section {
/** /**
* Code section of the program. Contains executable code * Code section of the program. Contains executable code

View File

@ -3,17 +3,17 @@ package net.simon987.server.assembly.exception;
/** /**
* Threw when a user attempts to define the same section twice * 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 * 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); super(message, line);
} }
} }

View File

@ -11,7 +11,7 @@ public class FatalAssemblyException extends AssemblyException {
private static final String message = "A fatal assembly error has occurred"; 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) { public FatalAssemblyException(String msg, int line) {
super(msg, line); super(msg, line);

View File

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

View File

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

View File

@ -7,12 +7,14 @@ public class ObjectDeathEvent extends GameEvent {
/** /**
* The GameObject type ID of object that init this event * The GameObject type ID of object that init this event
*/ */
private int sourceObjectId; private long sourceObjectId;
public ObjectDeathEvent(Object source, int sourceObjectId) { public ObjectDeathEvent(Object source, int sourceObjectId) {
setSource(source); setSource(source);
this.sourceObjectId = sourceObjectId; this.sourceObjectId = sourceObjectId;
} }
public int getSourceObjectId() { return sourceObjectId; } public long getSourceObjectId() {
return sourceObjectId;
}
} }

View File

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

View File

@ -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..)
* <br>
* 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;
}
}

View File

@ -84,9 +84,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable
} }
if (leftWorld != null) { if (leftWorld != null) {
world.getGameObjects().remove(this); world.removeObject(this);
world.decUpdatable(); world.decUpdatable();
leftWorld.getGameObjects().add(this); leftWorld.addObject(this);
leftWorld.incUpdatable(); leftWorld.incUpdatable();
setWorld(leftWorld); setWorld(leftWorld);
@ -103,9 +103,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable
} }
if (rightWorld != null) { if (rightWorld != null) {
world.getGameObjects().remove(this); world.removeObject(this);
world.decUpdatable(); world.decUpdatable();
rightWorld.getGameObjects().add(this); rightWorld.addObject(this);
rightWorld.incUpdatable(); rightWorld.incUpdatable();
setWorld(rightWorld); setWorld(rightWorld);
@ -123,9 +123,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable
} }
if (upWorld != null) { if (upWorld != null) {
world.getGameObjects().remove(this); world.removeObject(this);
world.decUpdatable(); world.decUpdatable();
upWorld.getGameObjects().add(this); upWorld.addObject(this);
upWorld.incUpdatable(); upWorld.incUpdatable();
setWorld(upWorld); setWorld(upWorld);
@ -143,9 +143,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable
if (downWorld != null) { if (downWorld != null) {
world.getGameObjects().remove(this); world.removeObject(this);
world.decUpdatable(); world.decUpdatable();
downWorld.getGameObjects().add(this); downWorld.addObject(this);
downWorld.incUpdatable(); downWorld.incUpdatable();
setWorld(downWorld); setWorld(downWorld);

View File

@ -1,5 +1,6 @@
package net.simon987.server.game; package net.simon987.server.game;
import com.mongodb.*;
import net.simon987.server.GameServer; import net.simon987.server.GameServer;
import net.simon987.server.ServerConfiguration; import net.simon987.server.ServerConfiguration;
import net.simon987.server.assembly.Assembler; 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.logging.LogManager;
import net.simon987.server.user.User; import net.simon987.server.user.User;
import java.util.ArrayList; import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
public class GameUniverse { public class GameUniverse {
private ArrayList<World> worlds; //private ArrayList<World> worlds;
private ArrayList<User> users; private ConcurrentHashMap<String, World> worlds;
//username:user
private ConcurrentHashMap<String, User> users;
private WorldGenerator worldGenerator; private WorldGenerator worldGenerator;
private MongoClient mongo = null;
private long time; private long time;
private long nextObjectId = 0; private long nextObjectId = 0;
@ -25,64 +32,144 @@ public class GameUniverse {
public GameUniverse(ServerConfiguration config) { public GameUniverse(ServerConfiguration config) {
worlds = new ArrayList<>(32); worlds = new ConcurrentHashMap<>(256);
users = new ArrayList<>(16); users = new ConcurrentHashMap<>(16);
worldGenerator = new WorldGenerator(config); worldGenerator = new WorldGenerator(config);
}
public void setMongo(MongoClient mongo){
this.mongo = mongo;
} }
public long getTime() { public long getTime() {
return time; 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) { BasicDBObject whereQuery = new BasicDBObject();
if (world.getX() == x && world.getY() == y) { whereQuery.put("_id", World.idFromCoordinates(x,y));
return world; DBCursor cursor = worlds.find(whereQuery);
} if (cursor.hasNext()) {
World w = World.deserialize(cursor.next());
return w;
} }
else{
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 {
return null; 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; World world = null;
try { try {
world = worldGenerator.generateWorld(x, y); world = worldGenerator.generateWorld(x, y);
} catch (CancelledException e) { } catch (CancelledException e) {
e.printStackTrace(); e.printStackTrace();
} }
return world; return world;
} }
public User getUser(String username) { public User getUser(String username) {
return users.get(username);
for (User user : users) {
if (user.getUsername().equals(username)) {
return user;
}
}
return null;
} }
public User getOrCreateUser(String username, boolean makeControlledUnit) { public User getOrCreateUser(String username, boolean makeControlledUnit) {
@ -110,7 +197,7 @@ public class GameUniverse {
char[] assembledCode = ar.getWords(); char[] assembledCode = ar.getWords();
user.getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length); user.getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length);
user.getCpu().setCodeSegmentOffset(ar.getCodeSegmentOffset()); user.getCpu().setCodeSectionOffset(ar.getCodeSectionOffset());
} else { } else {
@ -119,7 +206,7 @@ public class GameUniverse {
user.setUsername(username); user.setUsername(username);
users.add(user); addUser(user);
return user; return user;
@ -141,12 +228,11 @@ public class GameUniverse {
*/ */
public GameObject getObject(long id) { public GameObject getObject(long id) {
// for (World world : getWorlds()) {
for (World world : worlds) { GameObject obj = world.findObject(id);
for (GameObject object : world.getGameObjects()) {
if (object.getObjectId() == id) { if (obj != null) {
return object; return obj;
}
} }
} }
@ -159,12 +245,20 @@ public class GameUniverse {
time++; time++;
} }
public ArrayList<World> getWorlds() { public Collection<World> getWorlds() {
return worlds; return worlds.values();
} }
public ArrayList<User> getUsers() { public int getWorldCount() {
return users; return worlds.size();
}
public Collection<User> getUsers() {
return users.values();
}
public int getUserCount() {
return users.size();
} }
public long getNextObjectId() { 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) { public void removeUser(User user) {
users.remove(user); users.remove(user.getUsername());
} }
public int getMaxWidth() { public int getMaxWidth() {

View File

@ -11,7 +11,9 @@ import net.simon987.server.io.MongoSerialisable;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class World implements MongoSerialisable { public class World implements MongoSerialisable {
@ -29,7 +31,7 @@ public class World implements MongoSerialisable {
private TileMap tileMap; private TileMap tileMap;
private ArrayList<GameObject> gameObjects = new ArrayList<>(16); private ConcurrentHashMap<Long, GameObject> gameObjects = new ConcurrentHashMap<>(8);
/** /**
* If this number is greater than 0, the World will be updated. * 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) { public boolean isTileBlocked(int x, int y) {
return getGameObjectsBlockingAt(x, y).size() > 0 || tileMap.getTileAt(x, y) == TileMap.WALL_TILE; 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() { public int getX() {
@ -69,26 +92,48 @@ public class World implements MongoSerialisable {
return y; return y;
} }
/** public ArrayList<GameObject> findObjects(Class clazz) {
* Get all the game objects that are instances of the specified class
*/
public ArrayList getGameObjects(Class<? extends GameObject> clazz) {
ArrayList<GameObject> objects = new ArrayList<>(gameObjects.size()); ArrayList<GameObject> matchingObjects = new ArrayList<>(2);
for (GameObject object : gameObjects) { for (GameObject obj : gameObjects.values()) {
if (object.getClass().equals(clazz)) {
objects.add(object); if (obj.getClass().equals(clazz)) {
matchingObjects.add(obj);
} }
} }
return objects; return matchingObjects;
} }
public ArrayList<GameObject> getGameObjects() {
return gameObjects; public ArrayList<GameObject> findObjects(int mapInfo) {
ArrayList<GameObject> 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 * Update this World and its GameObjects
* <br> * <br>
@ -100,13 +145,11 @@ public class World implements MongoSerialisable {
GameEvent event = new WorldUpdateEvent(this); GameEvent event = new WorldUpdateEvent(this);
GameServer.INSTANCE.getEventDispatcher().dispatch(event); //Ignore cancellation GameServer.INSTANCE.getEventDispatcher().dispatch(event); //Ignore cancellation
ArrayList<GameObject> gameObjects_ = new ArrayList<>(gameObjects); for (GameObject object : gameObjects.values()) {
for (GameObject object : gameObjects_) {
//Clean up dead objects //Clean up dead objects
if (object.isDead()) { if (object.isDead()) {
object.onDeadCallback(); object.onDeadCallback();
gameObjects.remove(object); removeObject(object);
//LogManager.LOGGER.fine("Removed object " + object + " id: " + object.getObjectId()); //LogManager.LOGGER.fine("Removed object " + object + " id: " + object.getObjectId());
} else if (object instanceof Updatable) { } else if (object instanceof Updatable) {
((Updatable) object).update(); ((Updatable) object).update();
@ -120,11 +163,13 @@ public class World implements MongoSerialisable {
BasicDBObject dbObject = new BasicDBObject(); BasicDBObject dbObject = new BasicDBObject();
BasicDBList objects = new BasicDBList(); BasicDBList objects = new BasicDBList();
ArrayList<GameObject> gameObjects_ = new ArrayList<>(gameObjects); for (GameObject obj : gameObjects.values()) {
for (GameObject obj : gameObjects_) {
objects.add(obj.mongoSerialise()); objects.add(obj.mongoSerialise());
} }
dbObject.put("_id", getId());
dbObject.put("objects", objects); dbObject.put("objects", objects);
dbObject.put("terrain", tileMap.mongoSerialise()); dbObject.put("terrain", tileMap.mongoSerialise());
@ -133,7 +178,7 @@ public class World implements MongoSerialisable {
dbObject.put("size", worldSize); dbObject.put("size", worldSize);
dbObject.put("updatable", updatable); dbObject.put("updatable", updatable);
dbObject.put("shouldUpdate",shouldUpdate());
return dbObject; return dbObject;
} }
@ -171,7 +216,7 @@ public class World implements MongoSerialisable {
GameObject object = GameObject.deserialize((DBObject) obj); GameObject object = GameObject.deserialize((DBObject) obj);
object.setWorld(world); object.setWorld(world);
world.gameObjects.add(object); world.addObject(object);
} }
return world; return world;
@ -209,7 +254,7 @@ public class World implements MongoSerialisable {
} }
//Objects //Objects
for (GameObject obj : this.gameObjects) { for (GameObject obj : gameObjects.values()) {
mapInfo[obj.getX()][obj.getY()] |= obj.getMapInfo(); mapInfo[obj.getX()][obj.getY()] |= obj.getMapInfo();
} }
@ -263,17 +308,16 @@ public class World implements MongoSerialisable {
*/ */
public ArrayList<GameObject> getGameObjectsBlockingAt(int x, int y) { public ArrayList<GameObject> getGameObjectsBlockingAt(int x, int y) {
ArrayList<GameObject> gameObjects = new ArrayList<>(2); ArrayList<GameObject> objectsLooking = new ArrayList<>(2);
for (GameObject obj : gameObjects.values()) {
for (GameObject obj : this.gameObjects) {
if (obj.isAt(x, y)) { 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 * @return the list of game objects at a location
*/ */
public ArrayList<GameObject> getGameObjectsAt(int x, int y) { public ArrayList<GameObject> getGameObjectsAt(int x, int y) {
ArrayList<GameObject> gameObjects = new ArrayList<>(2); ArrayList<GameObject> objectsAt = new ArrayList<>(2);
for (GameObject obj : gameObjects.values()) {
for (GameObject obj : this.gameObjects) { if (obj.isAt(x, y)) {
objectsAt.add(obj);
if (obj.getX() == x && obj.getY() == y) {
gameObjects.add(obj);
} }
} }
return objectsAt;
return gameObjects;
} }
public void incUpdatable() { public void incUpdatable() {
@ -315,4 +357,76 @@ public class World implements MongoSerialisable {
public int getWorldSize() { public int getWorldSize() {
return worldSize; return worldSize;
} }
private GameUniverse universe = null;
public void setUniverse(GameUniverse universe){
this.universe = universe;
}
public ArrayList<World> getNeighbouringLoadedWorlds(){
ArrayList<World> 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<World> getNeighbouringExistingWorlds(){
ArrayList<World> 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<GameObject> getGameObjects() {
return gameObjects.values();
}
} }

View File

@ -8,7 +8,7 @@ import java.util.Collections;
/** /**
* Class to compute paths in the game universe. It supports * Class to compute paths in the game universe. It supports
* paths between within the same World. * paths within the same World.
*/ */
public class Pathfinder { public class Pathfinder {

View File

@ -1,35 +1,12 @@
package net.simon987.server.io; 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.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FileUtils { 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 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 * Creates a new stamp containing the current date and time
@ -42,143 +19,4 @@ public class FileUtils {
return f.format(millisToDate); 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);
}
} }

View File

@ -19,9 +19,30 @@ public class LogManager {
public static void initialize() { public static void initialize() {
LOGGER.setUseParentHandlers(false); 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.setLevel(Level.ALL);
handler.setFormatter(new GenericFormatter());
try { try {
Handler fileHandler = new FileHandler("mar.log"); Handler fileHandler = new FileHandler("mar.log");
@ -29,6 +50,7 @@ public class LogManager {
fileHandler.setFormatter(new GenericFormatter()); fileHandler.setFormatter(new GenericFormatter());
LOGGER.addHandler(handler); LOGGER.addHandler(handler);
LOGGER.addHandler(errHandler);
LOGGER.addHandler(fileHandler); LOGGER.addHandler(fileHandler);
LOGGER.setLevel(Level.ALL); LOGGER.setLevel(Level.ALL);
@ -36,6 +58,5 @@ public class LogManager {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -44,6 +44,7 @@ public class User implements MongoSerialisable {
BasicDBObject dbObject = new BasicDBObject(); 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("username", username);
dbObject.put("code", userCode); dbObject.put("code", userCode);
dbObject.put("controlledUnit", controlledUnit.getObjectId()); dbObject.put("controlledUnit", controlledUnit.getObjectId());

View File

@ -21,30 +21,35 @@ public class CodeUploadHandler implements MessageHandler {
//TODO Should we wait at the end of the tick to modify the CPU ? //TODO Should we wait at the end of the tick to modify the CPU ?
user.getUser().setUserCode((String) json.get("code")); user.getUser().setUserCode((String) json.get("code"));
AssemblyResult ar = new Assembler(user.getUser().getCpu().getInstructionSet(), if (user.getUser().getUserCode() != null) {
user.getUser().getCpu().getRegisterSet(), AssemblyResult ar = new Assembler(user.getUser().getCpu().getInstructionSet(),
GameServer.INSTANCE.getConfig()).parse(user.getUser().getUserCode()); 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 //Write assembled code to mem
char[] assembledCode = ar.getWords(); char[] assembledCode = ar.getWords();
user.getUser().getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length); user.getUser().getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length);
user.getUser().getCpu().setCodeSegmentOffset(ar.getCodeSegmentOffset()); user.getUser().getCpu().setCodeSectionOffset(ar.getCodeSectionOffset());
//Clear keyboard buffer //Clear keyboard buffer
if (user.getUser().getControlledUnit() != null && if (user.getUser().getControlledUnit() != null &&
user.getUser().getControlledUnit().getKeyboardBuffer() != null) { user.getUser().getControlledUnit().getKeyboardBuffer() != null) {
user.getUser().getControlledUnit().getKeyboardBuffer().clear(); 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());
} }

View File

@ -2,6 +2,7 @@ package net.simon987.server.webserver;
import net.simon987.server.logging.LogManager; import net.simon987.server.logging.LogManager;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@ -28,9 +29,16 @@ public class MessageEventDispatcher {
try { try {
JSONObject json = (JSONObject) parser.parse(message); JSONObject json = (JSONObject) parser.parse(message);
if (json.containsKey("t")) { if (json.containsKey("t") && user.getWebSocket().isOpen()) {
for (MessageHandler handler : handlers) { 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 { } else {
LogManager.LOGGER.severe("Malformed JSON sent by " + user.getUser().getUsername()); LogManager.LOGGER.severe("Malformed JSON sent by " + user.getUser().getUsername());

View File

@ -1,9 +1,10 @@
package net.simon987.server.webserver; package net.simon987.server.webserver;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
public interface MessageHandler { public interface MessageHandler {
void handle(OnlineUser user, JSONObject json); void handle(OnlineUser user, JSONObject json) throws WebsocketNotConnectedException;
} }

View File

@ -7,8 +7,6 @@ import net.simon987.server.logging.LogManager;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import java.util.ArrayList;
public class ObjectsRequestHandler implements MessageHandler { public class ObjectsRequestHandler implements MessageHandler {
@ -29,13 +27,12 @@ public class ObjectsRequestHandler implements MessageHandler {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(x, y, false); World world = GameServer.INSTANCE.getGameUniverse().getWorld(x, y, false);
if (world != null) { if (world != null) {
ArrayList<GameObject> gameObjects = world.getGameObjects();
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
JSONArray objects = new JSONArray(); JSONArray objects = new JSONArray();
for (GameObject object : gameObjects) { for (GameObject object : world.getGameObjects()) {
objects.add(object.serialise()); objects.add(object.serialise());
} }

View File

@ -5,7 +5,6 @@ import net.simon987.server.assembly.exception.CancelledException;
import net.simon987.server.user.User; import net.simon987.server.user.User;
import org.junit.Test; import org.junit.Test;
import java.io.File;
import java.util.Random; import java.util.Random;
public class CPUTest { public class CPUTest {
@ -13,7 +12,7 @@ public class CPUTest {
@Test @Test
public void executeInstruction() throws CancelledException { public void executeInstruction() throws CancelledException {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
User user = new User(); User user = new User();
CPU cpu = new CPU(config, user); CPU cpu = new CPU(config, user);

View File

@ -3,15 +3,13 @@ package net.simon987.server.assembly;
import net.simon987.server.ServerConfiguration; import net.simon987.server.ServerConfiguration;
import org.junit.Test; import org.junit.Test;
import java.io.File;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class MemoryTest { public class MemoryTest {
@Test @Test
public void getSet() { public void getSet() {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
int memorySize = config.getInt("memory_size"); int memorySize = config.getInt("memory_size");
Memory memory = new Memory(memorySize); Memory memory = new Memory(memorySize);
@ -31,7 +29,7 @@ public class MemoryTest {
@Test @Test
public void write() { public void write() {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
int memorySize = config.getInt("memory_size"); int memorySize = config.getInt("memory_size");
Memory memory = new Memory(memorySize); Memory memory = new Memory(memorySize);

View File

@ -7,8 +7,6 @@ import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import org.junit.Test; import org.junit.Test;
import java.io.File;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -20,7 +18,7 @@ public class AddInstructionTest {
*/ */
@Test @Test
public void addTargetTarget() { public void addTargetTarget() {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
int memorySize = config.getInt("memory_size"); int memorySize = config.getInt("memory_size");
//Memory //Memory
@ -131,7 +129,7 @@ public class AddInstructionTest {
*/ */
@Test @Test
public void addTargetImm() { public void addTargetImm() {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
int memorySize = config.getInt("memory_size"); int memorySize = config.getInt("memory_size");
//Memory //Memory

View File

@ -5,8 +5,6 @@ import net.simon987.server.assembly.Memory;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import org.junit.Test; import org.junit.Test;
import java.io.File;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -14,7 +12,7 @@ public class AndInstructionTest {
@Test @Test
public void executeTargetTarget() { public void executeTargetTarget() {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
int memorySize = config.getInt("memory_size"); int memorySize = config.getInt("memory_size");
//Memory //Memory
@ -56,7 +54,7 @@ public class AndInstructionTest {
@Test @Test
public void executeTargetImm() { public void executeTargetImm() {
ServerConfiguration config = new ServerConfiguration(new File("config.properties")); ServerConfiguration config = new ServerConfiguration("config.properties");
int memorySize = config.getInt("memory_size"); int memorySize = config.getInt("memory_size");
//Memory //Memory

View File

@ -5,15 +5,13 @@ import net.simon987.server.assembly.*;
import net.simon987.server.user.User; import net.simon987.server.user.User;
import org.junit.Test; import org.junit.Test;
import java.io.File;
public class CallInstructionTest { public class CallInstructionTest {
@Test @Test
public void execute() throws Exception { 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"); int memorySize = config.getInt("memory_size");
//Memory //Memory