# Conflicts:
#	Server/src/main/java/net/simon987/server/GameServer.java
This commit is contained in:
sg495 2018-01-08 18:28:37 +01:00
commit d65660b5e9
39 changed files with 320 additions and 311 deletions

View File

@ -15,6 +15,9 @@
<orderEntry type="module" module-name="Server" /> <orderEntry type="module" module-name="Server" />
<orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" /> <orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" /> <orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" />
<orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:2.10.1" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" /> <orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" /> <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />

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,6 +37,8 @@ public class CubotLeg extends CpuHardware implements JSONSerialisable {
@Override @Override
public void handleInterrupt(Status status) { public void handleInterrupt(Status status) {
if (cubot.getCurrentAction() == Action.IDLE) {
int a = getCpu().getRegisterSet().getRegister("A").getValue(); int a = getCpu().getRegisterSet().getRegister("A").getValue();
int b = getCpu().getRegisterSet().getRegister("B").getValue(); int b = getCpu().getRegisterSet().getRegister("B").getValue();
@ -71,6 +73,7 @@ public class CubotLeg extends CpuHardware implements JSONSerialisable {
} }
} }
} }
}
@Override @Override
public JSONObject serialise() { public JSONObject serialise() {

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();
User user = (User) event.getSource();
Cubot cubot = new Cubot();
cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
Point point = null;
while (point == null || cubot.getWorld() == null) {
int spawnX = GameServer.INSTANCE.getConfig().getInt("new_user_worldX") + random.nextInt(5); int spawnX = GameServer.INSTANCE.getConfig().getInt("new_user_worldX") + random.nextInt(5);
int spawnY = GameServer.INSTANCE.getConfig().getInt("new_user_worldY") + 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.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true));
point = cubot.getWorld().getRandomPassableTile();
}
cubot.setX(point.x);
cubot.setY(point.y);
cubot.getWorld().getGameObjects().add(cubot); cubot.getWorld().getGameObjects().add(cubot);
cubot.getWorld().incUpdatable(); cubot.getWorld().incUpdatable();
cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
cubot.setHeldItem(GameServer.INSTANCE.getConfig().getInt("new_user_item")); 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

@ -14,6 +14,9 @@
<orderEntry type="module" module-name="Server" /> <orderEntry type="module" module-name="Server" />
<orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" /> <orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" /> <orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" />
<orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:2.10.1" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" /> <orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" /> <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />

View File

@ -17,5 +17,8 @@
<orderEntry type="module" module-name="Server" /> <orderEntry type="module" module-name="Server" />
<orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" /> <orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" /> <orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" />
<orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:2.10.1" level="project" />
</component> </component>
</module> </module>

View File

@ -54,11 +54,14 @@ public class Factory extends GameObject implements Updatable {
for (Object id : tmpNpcArray) { for (Object id : tmpNpcArray) {
NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((int) (long) id); NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((int) (long) id);
npc.setFactory(this);
if (npc != null) {
npc.setFactory(this);
npcs.add(npc); npcs.add(npc);
} }
}
} else { } else {
if (cooldown == 0) { if (cooldown == 0) {

View File

@ -17,5 +17,8 @@
<orderEntry type="module" module-name="Server" /> <orderEntry type="module" module-name="Server" />
<orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" /> <orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" /> <orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" />
<orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:2.10.1" level="project" />
</component> </component>
</module> </module>

View File

@ -18,5 +18,6 @@
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" />
<orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:2.10.1" level="project" />
</component> </component>
</module> </module>

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

@ -224,7 +224,7 @@ public class GameServer implements Runnable {
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.getWorlds().size() + " | U:" + gameUniverse.getUsers().size());
try{
DB db = mongo.getDB("mar"); DB db = mongo.getDB("mar");
int unloaded_worlds = 0; int unloaded_worlds = 0;
@ -273,6 +273,10 @@ public class GameServer implements Runnable {
LogManager.LOGGER.info(""+insertedWorlds+" worlds saved, "+unloaded_worlds+" unloaded"); LogManager.LOGGER.info(""+insertedWorlds+" worlds saved, "+unloaded_worlds+" unloaded");
LogManager.LOGGER.info("Done!"); LogManager.LOGGER.info("Done!");
} catch (Exception e) {
LogManager.LOGGER.severe("Problem happened during save function");
e.printStackTrace();
}
} }
public ServerConfiguration getConfig() { public ServerConfiguration getConfig() {

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,8 +175,19 @@ public class Assembler {
out.writeChar(0); out.writeChar(0);
} else { } else {
//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); 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;
@ -31,11 +31,11 @@ public class AssemblyResult {
/** /**
* 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

@ -204,7 +204,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 {

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

@ -21,6 +21,7 @@ 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"));
if (user.getUser().getUserCode() != null) {
AssemblyResult ar = new Assembler(user.getUser().getCpu().getInstructionSet(), AssemblyResult ar = new Assembler(user.getUser().getCpu().getInstructionSet(),
user.getUser().getCpu().getRegisterSet(), user.getUser().getCpu().getRegisterSet(),
GameServer.INSTANCE.getConfig()).parse(user.getUser().getUserCode()); GameServer.INSTANCE.getConfig()).parse(user.getUser().getUserCode());
@ -31,7 +32,7 @@ public class CodeUploadHandler implements MessageHandler {
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 &&
@ -46,6 +47,7 @@ public class CodeUploadHandler implements MessageHandler {
user.getWebSocket().send(response.toJSONString()); 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) {
try {
handler.handle(user, json); 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

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