mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-10 14:26:45 +00:00
Merge pull request #153 from simon987/spark
Moved frontend to main server application
This commit is contained in:
commit
c5cb5df335
@ -1,7 +1,6 @@
|
||||
FROM alpine:3.7
|
||||
RUN apk add --no-cache maven openjdk8
|
||||
FROM maven:3.5-jdk-8
|
||||
COPY /. /app/
|
||||
WORKDIR /app
|
||||
RUN mvn package \
|
||||
&& cp Server/src/main/resources/config.properties /app/
|
||||
CMD ["java", "-jar", "/app/target/server-1.2a.jar"]
|
||||
RUN mvn package
|
||||
WORKDIR /app/target
|
||||
CMD ["java", "-jar", "/app/target/server-1.4a.jar"]
|
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Spring" name="Spring">
|
||||
<configuration />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -13,11 +18,38 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<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: 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: org.mongodb:mongo-java-driver:3.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.21" 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: org.hamcrest:hamcrest-core:1.1" level="project" />
|
||||
|
@ -1,13 +1,12 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.assembly.Memory;
|
||||
import net.simon987.server.game.*;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.User;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.awt.*;
|
||||
@ -19,42 +18,160 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
private static final char MAP_INFO = 0x0080;
|
||||
public static final int ID = 1;
|
||||
|
||||
/**
|
||||
* Hologram value that is displayed
|
||||
* <br>TODO: Move to CubotHologram class
|
||||
*/
|
||||
private int hologram = 0;
|
||||
/**
|
||||
* Hologram string that is displayed
|
||||
* <br>TODO: Move to CubotHologram class
|
||||
*/
|
||||
private String hologramString = "";
|
||||
/**
|
||||
* Hologram mode that was set during this tick
|
||||
* <br>TODO: Move to CubotHologram class
|
||||
*/
|
||||
private HologramMode hologramMode = HologramMode.CLEARED;
|
||||
/**
|
||||
* Hologram mode at the end of the last tick
|
||||
* <br>TODO: Move to CubotHologram class
|
||||
*/
|
||||
private HologramMode lastHologramMode = HologramMode.CLEARED;
|
||||
/**
|
||||
* Hologram color code. Format is handled by the client
|
||||
* <br>TODO: Move to CubotHologram class
|
||||
*/
|
||||
private int hologramColor = 0;
|
||||
|
||||
/**
|
||||
* Hit points
|
||||
*/
|
||||
private int hp;
|
||||
/**
|
||||
* Maximum hit points
|
||||
*/
|
||||
private int maxHp;
|
||||
|
||||
/**
|
||||
* Shield points
|
||||
*/
|
||||
private int shield;
|
||||
|
||||
/**
|
||||
* Maximum shield points
|
||||
*/
|
||||
private int maxShield;
|
||||
|
||||
/**
|
||||
* Item ID of the current 'active' item
|
||||
*/
|
||||
private int heldItem;
|
||||
|
||||
/**
|
||||
* Action that was set during the current tick. It is set to IDLE by default
|
||||
*/
|
||||
private Action currentAction = Action.IDLE;
|
||||
|
||||
/**
|
||||
* Action at the end of the last tick
|
||||
*/
|
||||
private Action lastAction = Action.IDLE;
|
||||
|
||||
/**
|
||||
* Status bit field that was set during the current tick. It is set to 0 by default
|
||||
* <br>See CubotStatus and addStatus() method
|
||||
*/
|
||||
private char currentStatus;
|
||||
|
||||
/**
|
||||
* Status bit field at the end of the last tick
|
||||
*/
|
||||
private char lastStatus;
|
||||
|
||||
/**
|
||||
* Buffer of keypress codes. It is not changed between ticks and it is reset when
|
||||
* the player uploads their code
|
||||
*/
|
||||
private ArrayList<Integer> keyboardBuffer = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Buffer of console messages (also called 'internal buffer') that was set during the current tick
|
||||
*/
|
||||
private ArrayList<char[]> consoleMessagesBuffer = new ArrayList<>(CONSOLE_BUFFER_MAX_SIZE);
|
||||
/**
|
||||
* Buffer of console messages (also called 'internal buffer') at the end of the last tick
|
||||
*/
|
||||
private ArrayList<char[]> lastConsoleMessagesBuffer = new ArrayList<>(CONSOLE_BUFFER_MAX_SIZE);
|
||||
/**
|
||||
* Console mode that was set during the current tick. It is set to NORMAL by default
|
||||
*/
|
||||
private ConsoleMode consoleMode = ConsoleMode.NORMAL;
|
||||
/**
|
||||
* Console mode at the end of the last tick
|
||||
*/
|
||||
private ConsoleMode lastConsoleMode = ConsoleMode.NORMAL;
|
||||
|
||||
/**
|
||||
* User that controls this Cubot
|
||||
*/
|
||||
private User parent;
|
||||
|
||||
/**
|
||||
* Energy units in kJ
|
||||
*/
|
||||
private int energy;
|
||||
|
||||
/**
|
||||
* Maximum energy units in kJ
|
||||
*/
|
||||
private int maxEnergy;
|
||||
|
||||
/**
|
||||
* Solar panel multiplier
|
||||
* <br>TODO: Set this constant in dimension
|
||||
*/
|
||||
private static final float SOLAR_PANEL_MULTIPLIER = 1;
|
||||
/**
|
||||
* Maximum size of the console buffer (also called 'internal buffer')
|
||||
*/
|
||||
private static final int CONSOLE_BUFFER_MAX_SIZE = 40;
|
||||
|
||||
/**
|
||||
* Display mode of the hologram hardware
|
||||
* <br>TODO: move this inside CubotHologram class
|
||||
*/
|
||||
public enum HologramMode {
|
||||
/**
|
||||
* Display nothing
|
||||
*/
|
||||
CLEARED,
|
||||
/**
|
||||
* Display value as hexadecimal in format 0x0000
|
||||
*/
|
||||
HEX,
|
||||
/**
|
||||
* Display string
|
||||
*/
|
||||
STRING,
|
||||
/**
|
||||
* Display value as decimal
|
||||
*/
|
||||
DEC
|
||||
}
|
||||
|
||||
public enum ConsoleMode {
|
||||
/**
|
||||
* Used by the ComPort hardware - clears the console screen (client-side)
|
||||
*/
|
||||
CLEAR,
|
||||
/**
|
||||
* No specific client-side action
|
||||
*/
|
||||
NORMAL
|
||||
}
|
||||
|
||||
|
||||
public Cubot() {
|
||||
|
||||
}
|
||||
@ -64,6 +181,9 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
return MAP_INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
@ -130,8 +250,8 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("t", ID);
|
||||
@ -155,7 +275,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static Cubot deserialize(DBObject obj) {
|
||||
public static Cubot deserialize(Document obj) {
|
||||
|
||||
Cubot cubot = new Cubot();
|
||||
cubot.setObjectId((long) obj.get("i"));
|
||||
@ -173,7 +293,52 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
cubot.maxShield = config.getInt("cubot_max_shield");
|
||||
|
||||
return cubot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset to 'factory settings', as it were when it was first created
|
||||
*/
|
||||
private void reset() {
|
||||
setDead(false);
|
||||
setHp(maxHp);
|
||||
setShield(0);
|
||||
setHeldItem(0);
|
||||
setEnergy(maxEnergy);
|
||||
clearKeyboardBuffer();
|
||||
consoleMessagesBuffer.clear();
|
||||
lastConsoleMessagesBuffer.clear();
|
||||
hologramColor = 0;
|
||||
currentStatus = 0;
|
||||
lastStatus = 0;
|
||||
addStatus(CubotStatus.FACTORY_NEW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDeadCallback() {
|
||||
LogManager.LOGGER.info(getParent().getUsername() + "'s Cubot died");
|
||||
|
||||
reset();
|
||||
|
||||
//Teleport to spawn point
|
||||
this.getWorld().removeObject(this);
|
||||
this.getWorld().decUpdatable();
|
||||
|
||||
ServerConfiguration config = GameServer.INSTANCE.getConfig();
|
||||
Random random = new Random();
|
||||
|
||||
int spawnX = config.getInt("new_user_worldX") + random.nextInt(5);
|
||||
int spawnY = config.getInt("new_user_worldY") + random.nextInt(5);
|
||||
String dimension = config.getString("new_user_dimension");
|
||||
this.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true, dimension));
|
||||
|
||||
Point point = this.getWorld().getRandomPassableTile();
|
||||
this.setX(point.x);
|
||||
this.setY(point.y);
|
||||
|
||||
this.getWorld().addObject(this);
|
||||
this.getWorld().incUpdatable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setHeldItem(int heldItem) {
|
||||
@ -314,18 +479,6 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
this.hologramMode = hologramMode;
|
||||
}
|
||||
|
||||
public enum HologramMode {
|
||||
CLEARED,
|
||||
HEX,
|
||||
STRING,
|
||||
DEC
|
||||
}
|
||||
|
||||
public enum ConsoleMode {
|
||||
CLEAR,
|
||||
NORMAL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAction(Action action) {
|
||||
currentAction = action;
|
||||
@ -373,6 +526,9 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
return lastStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently has no effect
|
||||
*/
|
||||
@Override
|
||||
public void setHealRate(int hp) {
|
||||
//no op
|
||||
@ -398,6 +554,13 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
this.maxHp = hp;
|
||||
}
|
||||
|
||||
public int getMaxShield() {
|
||||
return maxShield;
|
||||
}
|
||||
|
||||
public void setMaxShield(int maxShield) {
|
||||
this.maxShield = maxShield;
|
||||
}
|
||||
@Override
|
||||
public void heal(int amount) {
|
||||
hp += amount;
|
||||
@ -420,55 +583,4 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
|
||||
setDead(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
setDead(false);
|
||||
setHp(maxHp);
|
||||
setShield(0);
|
||||
setHeldItem(0);
|
||||
setEnergy(maxEnergy);
|
||||
clearKeyboardBuffer();
|
||||
consoleMessagesBuffer.clear();
|
||||
lastConsoleMessagesBuffer.clear();
|
||||
hologramColor = 0;
|
||||
currentStatus = 0;
|
||||
lastStatus = 0;
|
||||
addStatus(CubotStatus.FACTORY_NEW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDeadCallback() {
|
||||
LogManager.LOGGER.info(getParent().getUsername() + "'s Cubot died");
|
||||
|
||||
reset();
|
||||
|
||||
//Teleport to spawn point
|
||||
this.getWorld().removeObject(this);
|
||||
this.getWorld().decUpdatable();
|
||||
|
||||
ServerConfiguration config = GameServer.INSTANCE.getConfig();
|
||||
Random random = new Random();
|
||||
|
||||
int spawnX = config.getInt("new_user_worldX") + random.nextInt(5);
|
||||
int spawnY = config.getInt("new_user_worldY") + random.nextInt(5);
|
||||
String dimension = config.getString("new_user_dimension");
|
||||
this.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true, dimension));
|
||||
|
||||
Point point = this.getWorld().getRandomPassableTile();
|
||||
this.setX(point.x);
|
||||
this.setY(point.y);
|
||||
|
||||
this.getWorld().addObject(this);
|
||||
this.getWorld().incUpdatable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getMaxShield() {
|
||||
return maxShield;
|
||||
}
|
||||
|
||||
public void setMaxShield(int maxShield) {
|
||||
this.maxShield = maxShield;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotBattery extends CpuHardware {
|
||||
|
||||
@ -45,9 +44,9 @@ public class CubotBattery extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -56,7 +55,7 @@ public class CubotBattery extends CpuHardware {
|
||||
}
|
||||
|
||||
|
||||
public static CubotBattery deserialize(DBObject obj) {
|
||||
public static CubotBattery deserialize(Document obj) {
|
||||
return new CubotBattery((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.Programmable;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
@ -128,9 +127,9 @@ public class CubotComPort extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -138,7 +137,7 @@ public class CubotComPort extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotComPort deserialize(DBObject obj) {
|
||||
public static CubotComPort deserialize(Document obj) {
|
||||
return new CubotComPort((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotCore extends CpuHardware {
|
||||
|
||||
@ -42,9 +41,9 @@ public class CubotCore extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -53,7 +52,7 @@ public class CubotCore extends CpuHardware {
|
||||
}
|
||||
|
||||
|
||||
public static CubotCore deserialize(DBObject obj) {
|
||||
public static CubotCore deserialize(Document obj) {
|
||||
return new CubotCore((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.game.Action;
|
||||
import net.simon987.server.game.TileMap;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotDrill extends CpuHardware {
|
||||
|
||||
@ -62,9 +61,9 @@ public class CubotDrill extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -72,7 +71,7 @@ public class CubotDrill extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotDrill deserialize(DBObject obj) {
|
||||
public static CubotDrill deserialize(Document obj) {
|
||||
return new CubotDrill((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotFloppyDrive extends CpuHardware {
|
||||
|
||||
@ -79,9 +78,9 @@ public class CubotFloppyDrive extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -93,12 +92,12 @@ public class CubotFloppyDrive extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotFloppyDrive deserialize(DBObject obj) {
|
||||
public static CubotFloppyDrive deserialize(Document obj) {
|
||||
|
||||
CubotFloppyDrive drive = new CubotFloppyDrive((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
|
||||
if (obj.containsField("floppy")) {
|
||||
drive.floppyDisk = FloppyDisk.deserialise((DBObject) obj.get("floppy"));
|
||||
if (obj.containsKey("floppy")) {
|
||||
drive.floppyDisk = FloppyDisk.deserialise((Document) obj.get("floppy"));
|
||||
}
|
||||
|
||||
return drive;
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotHologram extends CpuHardware {
|
||||
|
||||
@ -83,14 +82,14 @@ public class CubotHologram extends CpuHardware {
|
||||
return HWID;
|
||||
}
|
||||
|
||||
public static CubotHologram deserialize(DBObject obj) {
|
||||
public static CubotHologram deserialize(Document obj) {
|
||||
return new CubotHologram((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotInventory extends CpuHardware {
|
||||
|
||||
@ -52,9 +51,9 @@ public class CubotInventory extends CpuHardware {
|
||||
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -62,7 +61,7 @@ public class CubotInventory extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotInventory deserialize(DBObject obj) {
|
||||
public static CubotInventory deserialize(Document obj) {
|
||||
return new CubotInventory((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotKeyboard extends CpuHardware {
|
||||
|
||||
@ -53,9 +52,9 @@ public class CubotKeyboard extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -63,7 +62,7 @@ public class CubotKeyboard extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotKeyboard deserialize(DBObject obj) {
|
||||
public static CubotKeyboard deserialize(Document obj) {
|
||||
return new CubotKeyboard((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
@ -9,6 +7,7 @@ import net.simon987.server.game.Action;
|
||||
import net.simon987.server.game.Attackable;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.InventoryHolder;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
@ -93,9 +92,9 @@ public class CubotLaser extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -103,7 +102,7 @@ public class CubotLaser extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotLaser deserialize(DBObject obj) {
|
||||
public static CubotLaser deserialize(Document obj) {
|
||||
return new CubotLaser((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.game.Action;
|
||||
import net.simon987.server.game.Direction;
|
||||
import net.simon987.server.io.JSONSerialisable;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class CubotLeg extends CpuHardware implements JSONSerialisable {
|
||||
@ -86,9 +85,9 @@ public class CubotLeg extends CpuHardware implements JSONSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -96,7 +95,7 @@ public class CubotLeg extends CpuHardware implements JSONSerialisable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotLeg deserialize(DBObject obj) {
|
||||
public static CubotLeg deserialize(Document obj) {
|
||||
return new CubotLeg((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Memory;
|
||||
@ -10,6 +8,7 @@ import net.simon987.server.game.pathfinding.Node;
|
||||
import net.simon987.server.game.pathfinding.Pathfinder;
|
||||
import net.simon987.server.io.JSONSerialisable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -150,9 +149,9 @@ public class CubotLidar extends CpuHardware implements JSONSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -160,7 +159,7 @@ public class CubotLidar extends CpuHardware implements JSONSerialisable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static CubotLidar deserialize(DBObject obj) {
|
||||
public static CubotLidar deserialize(Document obj) {
|
||||
return new CubotLidar((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.cubotplugin.event.ChargeShieldCommandListener;
|
||||
import net.simon987.cubotplugin.event.CpuInitialisationListener;
|
||||
import net.simon987.cubotplugin.event.UserCreationListener;
|
||||
@ -11,6 +10,7 @@ import net.simon987.server.io.CpuHardwareDeserializer;
|
||||
import net.simon987.server.io.GameObjectDeserializer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotPlugin extends ServerPlugin implements GameObjectDeserializer, CpuHardwareDeserializer {
|
||||
|
||||
@ -25,7 +25,7 @@ public class CubotPlugin extends ServerPlugin implements GameObjectDeserializer,
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameObject deserializeObject(DBObject object) {
|
||||
public GameObject deserializeObject(Document object) {
|
||||
|
||||
int objType = (int) object.get("t");
|
||||
|
||||
@ -38,7 +38,7 @@ public class CubotPlugin extends ServerPlugin implements GameObjectDeserializer,
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpuHardware deserializeHardware(DBObject obj) {
|
||||
public CpuHardware deserializeHardware(Document obj) {
|
||||
int hwid = (int) obj.get("hwid");
|
||||
|
||||
switch (hwid) {
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
public class CubotShield extends CpuHardware {
|
||||
|
||||
@ -28,8 +27,8 @@ public class CubotShield extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -49,8 +48,8 @@ public class CubotShield extends CpuHardware {
|
||||
getCpu().getRegisterSet().getRegister("B").setValue(shield);
|
||||
}
|
||||
}
|
||||
|
||||
public static CubotShield deserialize(DBObject obj) {
|
||||
|
||||
public static CubotShield deserialize(Document obj) {
|
||||
return new CubotShield((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
@ -1,17 +1,16 @@
|
||||
package net.simon987.cubotplugin;
|
||||
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.assembly.Memory;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Represents a floppy disk that is inside a floppy drive.
|
||||
* Floppies contains 80 tracks with 18 sectors per track.
|
||||
* That's 1440 sectors of 512 words. (total 1,474,560 bytes / 737,280 words / 1.44Mb)
|
||||
*/
|
||||
public class FloppyDisk implements MongoSerialisable {
|
||||
public class FloppyDisk implements MongoSerializable {
|
||||
|
||||
/**
|
||||
* Contents of the disk
|
||||
@ -84,8 +83,8 @@ public class FloppyDisk implements MongoSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("rwHeadTrack", rwHeadTrack);
|
||||
dbObject.put("memory", memory.mongoSerialise());
|
||||
@ -93,12 +92,12 @@ public class FloppyDisk implements MongoSerialisable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static FloppyDisk deserialise(DBObject obj) {
|
||||
public static FloppyDisk deserialise(Document obj) {
|
||||
|
||||
FloppyDisk floppyDisk = new FloppyDisk();
|
||||
|
||||
floppyDisk.rwHeadTrack = (int) obj.get("rwHeadTrack");
|
||||
floppyDisk.memory = Memory.deserialize((DBObject) obj.get("memory"));
|
||||
floppyDisk.memory = Memory.deserialize((Document) obj.get("memory"));
|
||||
|
||||
return floppyDisk;
|
||||
}
|
||||
|
@ -7,6 +7,9 @@ import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.GameEventListener;
|
||||
import net.simon987.server.game.GameObject;
|
||||
|
||||
/**
|
||||
* Debug command to add shield points to a Cubot
|
||||
*/
|
||||
public class ChargeShieldCommandListener implements GameEventListener {
|
||||
@Override
|
||||
public Class getListenedEventType() {
|
||||
|
@ -15,7 +15,6 @@ public class CpuInitialisationListener implements GameEventListener {
|
||||
|
||||
@Override
|
||||
public void handle(GameEvent event) {
|
||||
//LogManager.LOGGER.fine("(Plugin) Handled CPU Initialisation event (Cubot Plugin)");
|
||||
|
||||
CPU cpu = (CPU) event.getSource();
|
||||
User user = ((CpuInitialisationEvent) event).getUser();
|
||||
|
@ -57,7 +57,5 @@ public class UserCreationListener implements GameEventListener {
|
||||
user.setControlledUnit(cubot);
|
||||
|
||||
LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Spring" name="Spring">
|
||||
<configuration />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -12,11 +17,38 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<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: 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: org.mongodb:mongo-java-driver:3.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.21" 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: org.hamcrest:hamcrest-core:1.1" level="project" />
|
||||
|
@ -1,11 +1,14 @@
|
||||
package net.simon987.mischwplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Util;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Hardware to get game time
|
||||
*/
|
||||
public class Clock extends CpuHardware {
|
||||
|
||||
public static final char HWID = 0x0008;
|
||||
@ -34,9 +37,9 @@ public class Clock extends CpuHardware {
|
||||
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
package net.simon987.mischwplugin;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.mischwplugin.event.CpuInitialisationListener;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.io.CpuHardwareDeserializer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Plugin that adds miscellaneous hardware to the game
|
||||
*/
|
||||
public class MiscHWPlugin extends ServerPlugin implements CpuHardwareDeserializer {
|
||||
|
||||
|
||||
@ -19,7 +22,7 @@ public class MiscHWPlugin extends ServerPlugin implements CpuHardwareDeserialize
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpuHardware deserializeHardware(DBObject hwJson) {
|
||||
public CpuHardware deserializeHardware(Document hwJson) {
|
||||
int hwid = (int) hwJson.get("hwid");
|
||||
|
||||
switch (hwid) {
|
||||
|
@ -1,11 +1,14 @@
|
||||
package net.simon987.mischwplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Hardware to generate random numbers
|
||||
*/
|
||||
public class RandomNumberGenerator extends CpuHardware {
|
||||
|
||||
public static final char HWID = 0x0007;
|
||||
@ -31,9 +34,9 @@ public class RandomNumberGenerator extends CpuHardware {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Spring" name="Spring">
|
||||
<configuration />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -15,10 +20,37 @@
|
||||
<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="module" module-name="Server" />
|
||||
<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: 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: org.mongodb:mongo-java-driver:3.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.21" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -1,7 +1,5 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.Util;
|
||||
import net.simon987.server.game.Attackable;
|
||||
@ -9,28 +7,48 @@ import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.Rechargeable;
|
||||
import net.simon987.server.game.Updatable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Game object that deals damage to nearby objects and gives them energy
|
||||
*/
|
||||
public class ElectricBox extends GameObject implements Updatable, Attackable {
|
||||
|
||||
public static final int ID = 7;
|
||||
|
||||
/**
|
||||
* Hit points
|
||||
*/
|
||||
private int hp;
|
||||
/**
|
||||
* Maximum hit points
|
||||
*/
|
||||
private static final int maxHp = GameServer.INSTANCE.getConfig().getInt("electric_box_hp");
|
||||
/**
|
||||
* Number of hit points dealt to nearby objects each tick
|
||||
*/
|
||||
private static final int damageDealt = GameServer.INSTANCE.getConfig().getInt("electric_box_damage");
|
||||
/**
|
||||
* Number of energy points given to nearby objects each tick
|
||||
*/
|
||||
private static final int energyGiven = GameServer.INSTANCE.getConfig().getInt("electric_box_energy_given");
|
||||
|
||||
private int hp;
|
||||
|
||||
/**
|
||||
* List of nearby objects. Is updated every tick
|
||||
*/
|
||||
private ArrayList<Attackable> nearObjects = new ArrayList<>();
|
||||
|
||||
public ElectricBox() {
|
||||
|
||||
this.hp = maxHp;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently has no effect
|
||||
*/
|
||||
@Override
|
||||
public void setHealRate(int hp) {
|
||||
//no op
|
||||
@ -51,11 +69,17 @@ public class ElectricBox extends GameObject implements Updatable, Attackable {
|
||||
return hp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently has no effect
|
||||
*/
|
||||
@Override
|
||||
public void setMaxHp(int hp) {
|
||||
//No op
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently has no effect
|
||||
*/
|
||||
@Override
|
||||
public void heal(int amount) {
|
||||
//No op
|
||||
@ -77,6 +101,10 @@ public class ElectricBox extends GameObject implements Updatable, Attackable {
|
||||
return Obstacle.MAP_INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current list nearby objects
|
||||
* <br>An object is considered 'nearby' if its Manhattan distance is {@literal <= @} 1 and is Attackable
|
||||
*/
|
||||
private void updateNearObjects() {
|
||||
|
||||
nearObjects.clear();
|
||||
@ -89,6 +117,9 @@ public class ElectricBox extends GameObject implements Updatable, Attackable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
@ -118,8 +149,8 @@ public class ElectricBox extends GameObject implements Updatable, Attackable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
@ -130,7 +161,7 @@ public class ElectricBox extends GameObject implements Updatable, Attackable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static ElectricBox deserialize(DBObject obj) {
|
||||
public static ElectricBox deserialize(Document obj) {
|
||||
|
||||
ElectricBox electricBox = new ElectricBox();
|
||||
electricBox.setHp((int) obj.get("hp"));
|
||||
|
@ -1,25 +1,36 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.Updatable;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Game objects that regularly creates NonPlayerCharacters
|
||||
*/
|
||||
public class Factory extends GameObject implements Updatable {
|
||||
|
||||
private static final int MAP_INFO = 0x0200;
|
||||
static final int ID = 3;
|
||||
|
||||
/**
|
||||
* Maximum number of NonPlayerCharacters assigned to this Factory
|
||||
*/
|
||||
private static final int MAX_NPC_COUNT = GameServer.INSTANCE.getConfig().getInt("factory_max_npc_count");
|
||||
|
||||
/**
|
||||
* Number of ticks to wait after creating a NonPlayerCharacter
|
||||
*/
|
||||
private static final int NPC_CREATION_COOLDOWN = NonPlayerCharacter.LIFETIME / MAX_NPC_COUNT;
|
||||
|
||||
/**
|
||||
* List of associated NonPlayerCharacters
|
||||
*/
|
||||
private ArrayList<NonPlayerCharacter> npcs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@ -43,6 +54,10 @@ public class Factory extends GameObject implements Updatable {
|
||||
return MAP_INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick
|
||||
* <br>The fist time this is called, NPCs retrieved from the database are linked to the Factory
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
@ -61,6 +76,8 @@ public class Factory extends GameObject implements Updatable {
|
||||
|
||||
}
|
||||
|
||||
tmpNpcArray = null;
|
||||
|
||||
} else {
|
||||
|
||||
if (cooldown == 0) {
|
||||
@ -115,15 +132,15 @@ public class Factory extends GameObject implements Updatable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
dbObject.put("y", getY());
|
||||
dbObject.put("t", ID);
|
||||
|
||||
BasicDBList tmpNpcArray = new BasicDBList();
|
||||
List<Long> tmpNpcArray = new ArrayList<>(npcs.size());
|
||||
|
||||
for (NonPlayerCharacter npc : npcs) {
|
||||
tmpNpcArray.add(npc.getObjectId());
|
||||
@ -134,14 +151,14 @@ public class Factory extends GameObject implements Updatable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static Factory deserialise(DBObject obj) {
|
||||
public static Factory deserialise(Document obj) {
|
||||
|
||||
Factory factory = new Factory();
|
||||
factory.setObjectId((long) obj.get("i"));
|
||||
factory.setX((int) obj.get("x"));
|
||||
factory.setY((int) obj.get("y"));
|
||||
|
||||
factory.tmpNpcArray = ((BasicDBList) obj.get("n")).toArray();
|
||||
factory.tmpNpcArray = ((ArrayList) obj.get("tmpNpcArray")).toArray();
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
@ -10,19 +10,31 @@ import net.simon987.server.logging.LogManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Find Biomass, move towards it, collect it, repeat
|
||||
*/
|
||||
public class HarvestTask extends NPCTask {
|
||||
|
||||
private Random random;
|
||||
|
||||
/**
|
||||
* Number of ticks to wait before continuing
|
||||
*/
|
||||
private int pause;
|
||||
|
||||
/**
|
||||
* Direction of the next world to visit (randomly chosen)
|
||||
*/
|
||||
private Direction nextWorldDirection = null;
|
||||
|
||||
public HarvestTask() {
|
||||
random = new Random();
|
||||
pause = 0;
|
||||
}
|
||||
|
||||
private Direction nextWorldDirection = null;
|
||||
|
||||
/**
|
||||
* This task never finishes
|
||||
*/
|
||||
@Override
|
||||
public boolean checkCompleted() {
|
||||
return false;
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.event.ObjectDeathEvent;
|
||||
import net.simon987.server.game.Direction;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
|
||||
@ -12,6 +11,9 @@ public class HarvesterNPC extends NonPlayerCharacter {
|
||||
|
||||
public static final int ID = 10;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final int MAX_HEALTH = GameServer.INSTANCE.getConfig().getInt("harvester_hp_max");
|
||||
public static final int HEAL_RATE = GameServer.INSTANCE.getConfig().getInt("harvester_regen");
|
||||
|
||||
@ -77,22 +79,21 @@ public class HarvesterNPC extends NonPlayerCharacter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
dbObject.put("y", getY());
|
||||
dbObject.put("direction", getDirection().ordinal());
|
||||
dbObject.put("hp", getHp());
|
||||
// dbObject.put("energy", energy);
|
||||
dbObject.put("action", getAction().ordinal());
|
||||
dbObject.put("t", ID);
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static HarvesterNPC deserialize(DBObject obj) {
|
||||
public static HarvesterNPC deserialize(Document obj) {
|
||||
|
||||
HarvesterNPC npc = new HarvesterNPC();
|
||||
npc.setObjectId((long) obj.get("i"));
|
||||
@ -100,8 +101,6 @@ public class HarvesterNPC extends NonPlayerCharacter {
|
||||
npc.setY((int) obj.get("y"));
|
||||
npc.setHp((int) obj.get("hp"));
|
||||
npc.setDirection(Direction.getDirection((int) obj.get("direction")));
|
||||
// npc.energy = (int) obj.get("energy");
|
||||
// npc.maxEnergy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy");
|
||||
|
||||
return npc;
|
||||
|
||||
|
@ -9,27 +9,40 @@ import net.simon987.server.logging.LogManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Game object that actively interacts with the game world by doing tasks
|
||||
*/
|
||||
public abstract class NonPlayerCharacter extends GameObject implements Updatable, Attackable {
|
||||
|
||||
private static final int MAP_INFO = 0x0040;
|
||||
|
||||
/**
|
||||
* Maximum distance to travel from its factory, in Worlds
|
||||
*/
|
||||
private static final int MAX_FACTORY_DISTANCE = GameServer.INSTANCE.getConfig().getInt("npc_max_factory_distance");
|
||||
|
||||
/**
|
||||
* Number of ticks to live
|
||||
*/
|
||||
public static final int LIFETIME = GameServer.INSTANCE.getConfig().getInt("npc_lifetime");
|
||||
|
||||
// Set these just in case they aren't overridden in the subclass
|
||||
public static final int HP_MAX_DEFAULT = 100;
|
||||
public static final int HP_REGEN_RATE_DEFAULT = 0;
|
||||
|
||||
//Unused
|
||||
/**
|
||||
* Currently unused
|
||||
*/
|
||||
int energy;
|
||||
int maxEnergy;
|
||||
|
||||
/**
|
||||
* Current task
|
||||
*/
|
||||
private NPCTask task;
|
||||
|
||||
/**
|
||||
* Action at the end of the last tick
|
||||
*/
|
||||
private Action lastAction = Action.IDLE;
|
||||
|
||||
/**
|
||||
|
@ -1,10 +1,8 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.npcplugin.event.CpuInitialisationListener;
|
||||
import net.simon987.npcplugin.event.VaultWorldUpdateListener;
|
||||
import net.simon987.npcplugin.event.WorldCreationListener;
|
||||
import net.simon987.npcplugin.io.StatsDatabaseManager;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.game.GameObject;
|
||||
@ -12,6 +10,7 @@ import net.simon987.server.io.CpuHardwareDeserializer;
|
||||
import net.simon987.server.io.GameObjectDeserializer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -22,8 +21,6 @@ public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer, C
|
||||
*/
|
||||
private static ArrayList<RadioTower> radioTowers;
|
||||
|
||||
private static StatsDatabaseManager statsDbManager;
|
||||
|
||||
@Override
|
||||
public void init(ServerConfiguration configuration) {
|
||||
|
||||
@ -33,13 +30,11 @@ public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer, C
|
||||
|
||||
radioTowers = new ArrayList<>(32);
|
||||
|
||||
statsDbManager = new StatsDatabaseManager(configuration);
|
||||
|
||||
LogManager.LOGGER.info("Initialised NPC plugin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameObject deserializeObject(DBObject obj) {
|
||||
public GameObject deserializeObject(Document obj) {
|
||||
|
||||
int objType = (int) obj.get("t");
|
||||
|
||||
@ -65,7 +60,7 @@ public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer, C
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpuHardware deserializeHardware(DBObject obj) {
|
||||
public CpuHardware deserializeHardware(Document obj) {
|
||||
int hwid = (int) obj.get("hwid");
|
||||
|
||||
switch (hwid) {
|
||||
@ -80,7 +75,4 @@ public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer, C
|
||||
return radioTowers;
|
||||
}
|
||||
|
||||
public static StatsDatabaseManager getStatsDbManager() {
|
||||
return statsDbManager;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,12 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.game.Attackable;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
/**
|
||||
* Generic game object that blocks the path.
|
||||
* Some types of obstacles might have some more interesting features (see ElectricBox)
|
||||
*/
|
||||
public class Obstacle extends GameObject implements Attackable {
|
||||
|
||||
@ -90,8 +88,8 @@ public class Obstacle extends GameObject implements Attackable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
@ -117,7 +115,7 @@ public class Obstacle extends GameObject implements Attackable {
|
||||
return json;
|
||||
}
|
||||
|
||||
public static Obstacle deserialize(DBObject obj) {
|
||||
public static Obstacle deserialize(Document obj) {
|
||||
|
||||
Obstacle obstacle = new Obstacle((int) obj.get("hp"));
|
||||
obstacle.setObjectId((long) obj.get("i"));
|
||||
|
@ -1,23 +1,31 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.game.*;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class Portal extends GameObject implements Enterable {
|
||||
|
||||
private Location dst;
|
||||
/**
|
||||
* Destination location
|
||||
*/
|
||||
private Location destination;
|
||||
|
||||
public static final int MAP_INFO = 0x0020;
|
||||
|
||||
public static final int ID = 8;
|
||||
|
||||
/**
|
||||
* Called when an object attempts to walk directly into a Enterable object
|
||||
*
|
||||
* @param object The game object that attempted to enter
|
||||
* @return true if successful, false to block the object
|
||||
*/
|
||||
@Override
|
||||
public boolean enter(GameObject object) {
|
||||
|
||||
World world = GameServer.INSTANCE.getGameUniverse().getWorld(dst.worldX, dst.worldY, false, dst.dimension);
|
||||
World world = GameServer.INSTANCE.getGameUniverse().getWorld(destination.worldX, destination.worldY, false, destination.dimension);
|
||||
|
||||
if (object instanceof Updatable) {
|
||||
object.getWorld().decUpdatable();
|
||||
@ -27,8 +35,8 @@ public class Portal extends GameObject implements Enterable {
|
||||
object.setWorld(world);
|
||||
world.addObject(object);
|
||||
|
||||
object.setX(dst.x);
|
||||
object.setY(dst.y);
|
||||
object.setX(destination.x);
|
||||
object.setY(destination.y);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -39,27 +47,27 @@ public class Portal extends GameObject implements Enterable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
dbObject.put("y", getY());
|
||||
dbObject.put("t", ID);
|
||||
dbObject.put("dstWorldX", dst.worldX);
|
||||
dbObject.put("dstWorldY", dst.worldY);
|
||||
dbObject.put("dstX", dst.x);
|
||||
dbObject.put("dstY", dst.y);
|
||||
dbObject.put("dstDimension", dst.dimension);
|
||||
dbObject.put("dstWorldX", destination.worldX);
|
||||
dbObject.put("dstWorldY", destination.worldY);
|
||||
dbObject.put("dstX", destination.x);
|
||||
dbObject.put("dstY", destination.y);
|
||||
dbObject.put("dstDimension", destination.dimension);
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static Portal deserialize(DBObject obj) {
|
||||
public static Portal deserialize(Document obj) {
|
||||
|
||||
Portal portal = new Portal();
|
||||
|
||||
portal.dst = new Location(
|
||||
portal.destination = new Location(
|
||||
(int) obj.get("dstWorldX"),
|
||||
(int) obj.get("dstWorldY"),
|
||||
(String) obj.get("dstDimension"),
|
||||
@ -83,11 +91,11 @@ public class Portal extends GameObject implements Enterable {
|
||||
return json;
|
||||
}
|
||||
|
||||
public Location getDst() {
|
||||
return dst;
|
||||
public Location getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
public void setDst(Location dst) {
|
||||
this.dst = dst;
|
||||
public void setDestination(Location destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Util;
|
||||
import net.simon987.server.game.Action;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -67,9 +66,9 @@ public class RadioReceiverHardware extends CpuHardware {
|
||||
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("hwid", (int) HWID);
|
||||
dbObject.put("cubot", cubot.getObjectId());
|
||||
@ -77,7 +76,7 @@ public class RadioReceiverHardware extends CpuHardware {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static RadioReceiverHardware deserialize(DBObject obj) {
|
||||
public static RadioReceiverHardware deserialize(Document obj) {
|
||||
return new RadioReceiverHardware((ControllableUnit) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("cubot")));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.Programmable;
|
||||
import net.simon987.server.game.Updatable;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -24,7 +23,6 @@ public class RadioTower extends GameObject implements Programmable, Updatable {
|
||||
return MAP_INFO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Messages from the current tick
|
||||
*/
|
||||
@ -67,8 +65,8 @@ public class RadioTower extends GameObject implements Programmable, Updatable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
@ -78,7 +76,7 @@ public class RadioTower extends GameObject implements Programmable, Updatable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static RadioTower deserialize(DBObject obj) {
|
||||
public static RadioTower deserialize(Document obj) {
|
||||
|
||||
RadioTower tower = new RadioTower();
|
||||
tower.setObjectId((long) obj.get("i"));
|
||||
|
@ -141,7 +141,7 @@ public class VaultDimension {
|
||||
if (exitPortalPt != null) {
|
||||
|
||||
VaultExitPortal exitPortal = new VaultExitPortal();
|
||||
exitPortal.setDst(exitLocation);
|
||||
exitPortal.setDestination(exitLocation);
|
||||
exitPortal.setX(exitPortalPt.x);
|
||||
exitPortal.setY(exitPortalPt.y);
|
||||
exitPortal.setWorld(objectiveWorld);
|
||||
@ -158,7 +158,7 @@ public class VaultDimension {
|
||||
if (homePortalPt != null) {
|
||||
|
||||
Portal homePortal = new Portal();
|
||||
homePortal.setDst(exitLocation);
|
||||
homePortal.setDestination(exitLocation);
|
||||
homePortal.setX(homePortalPt.x);
|
||||
homePortal.setY(homePortalPt.y);
|
||||
homePortal.setWorld(homeWorld);
|
||||
|
@ -1,11 +1,10 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.crypto.RandomStringGenerator;
|
||||
import net.simon987.server.game.*;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -124,8 +123,8 @@ public class VaultDoor extends GameObject implements Programmable, Enterable, Up
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
@ -152,7 +151,7 @@ public class VaultDoor extends GameObject implements Programmable, Enterable, Up
|
||||
return json;
|
||||
}
|
||||
|
||||
public static VaultDoor deserialize(DBObject obj) {
|
||||
public static VaultDoor deserialize(Document obj) {
|
||||
|
||||
VaultDoor vaultDoor = new VaultDoor(0); //cypherId ?
|
||||
vaultDoor.setX((int) obj.get("x"));
|
||||
@ -160,7 +159,7 @@ public class VaultDoor extends GameObject implements Programmable, Enterable, Up
|
||||
vaultDoor.setObjectId((long) obj.get("i"));
|
||||
|
||||
|
||||
if (obj.containsField("homeX") && obj.containsField("homeY")) {
|
||||
if (obj.containsKey("homeX") && obj.containsKey("homeY")) {
|
||||
vaultDoor.setHomeX((int) obj.get("homeX"));
|
||||
vaultDoor.setHomeY((int) obj.get("homeY"));
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.Location;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Final exit portal located in the 'last' World of a Vault dimension
|
||||
@ -15,18 +14,18 @@ public class VaultExitPortal extends Portal {
|
||||
public static final int ID = 9;
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("i", getObjectId());
|
||||
dbObject.put("x", getX());
|
||||
dbObject.put("y", getY());
|
||||
dbObject.put("t", ID);
|
||||
dbObject.put("dstWorldX", getDst().worldX);
|
||||
dbObject.put("dstWorldY", getDst().worldY);
|
||||
dbObject.put("dstX", getDst().x);
|
||||
dbObject.put("dstY", getDst().y);
|
||||
dbObject.put("dstDimension", getDst().dimension);
|
||||
dbObject.put("dstWorldX", getDestination().worldX);
|
||||
dbObject.put("dstWorldY", getDestination().worldY);
|
||||
dbObject.put("dstX", getDestination().x);
|
||||
dbObject.put("dstY", getDestination().y);
|
||||
dbObject.put("dstDimension", getDestination().dimension);
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
@ -34,20 +33,21 @@ public class VaultExitPortal extends Portal {
|
||||
@Override
|
||||
public boolean enter(GameObject object) {
|
||||
|
||||
LogManager.LOGGER.info(((ControllableUnit) object).getParent().getUsername() + " Completed vault " +
|
||||
object.getWorld().getDimension());
|
||||
|
||||
NpcPlugin.getStatsDbManager().saveVaultCompletion((ControllableUnit) object, object.getWorld().getDimension());
|
||||
if (object instanceof ControllableUnit) {
|
||||
LogManager.LOGGER.info(((ControllableUnit) object).getParent().getUsername() + " Completed vault " +
|
||||
object.getWorld().getDimension());
|
||||
|
||||
((ControllableUnit) object).getParent().getStats().addToStringSet("completedVaults", getWorld().getDimension());
|
||||
}
|
||||
|
||||
return super.enter(object);
|
||||
}
|
||||
|
||||
public static Portal deserialize(DBObject obj) {
|
||||
public static Portal deserialize(Document obj) {
|
||||
|
||||
VaultExitPortal portal = new VaultExitPortal();
|
||||
|
||||
portal.setDst(new Location(
|
||||
portal.setDestination(new Location(
|
||||
(int) obj.get("dstWorldX"),
|
||||
(int) obj.get("dstWorldY"),
|
||||
(String) obj.get("dstDimension"),
|
||||
|
@ -14,11 +14,26 @@ import java.util.HashMap;
|
||||
|
||||
public class VaultWorldUpdateListener implements GameEventListener {
|
||||
|
||||
/**
|
||||
* Map of worlds and their time to wait until next respawn event
|
||||
*/
|
||||
private HashMap<World, Long> worldWaitMap = new HashMap<>(200);
|
||||
|
||||
/**
|
||||
* Lower bound of ElectricBox to be created on a respawn event
|
||||
*/
|
||||
private static int minElectricBoxCount;
|
||||
/**
|
||||
* Upper bound of ElectricBox to be created on a respawn event
|
||||
*/
|
||||
private static int maxElectricBoxCount;
|
||||
/**
|
||||
* Number of game ticks to wait after the threshold has been met
|
||||
*/
|
||||
private static int waitTime;
|
||||
/**
|
||||
* Threshold before starting the
|
||||
*/
|
||||
private static int electricBoxThreshold;
|
||||
|
||||
public VaultWorldUpdateListener(ServerConfiguration config) {
|
||||
@ -37,6 +52,7 @@ public class VaultWorldUpdateListener implements GameEventListener {
|
||||
@Override
|
||||
public void handle(GameEvent event) {
|
||||
|
||||
//TODO: Move this and the Biomass UpdateListener to a 'RespawnManager' kind of deal
|
||||
World world = ((WorldUpdateEvent) event).getWorld();
|
||||
|
||||
if (world.getDimension().startsWith("v")) {
|
||||
@ -66,6 +82,5 @@ public class VaultWorldUpdateListener implements GameEventListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ public class WorldCreationListener implements GameEventListener {
|
||||
|
||||
/**
|
||||
* Spawn rate. Higher = rarer: A factory will be spawn about every FACTORY_SPAWN_RATE generated Worlds
|
||||
* <br>TODO: Get from config.properties
|
||||
*/
|
||||
private static final int FACTORY_SPAWN_RATE = 35;
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
package net.simon987.npcplugin.io;
|
||||
|
||||
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import net.simon987.server.io.DatabaseManager;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class StatsDatabaseManager extends DatabaseManager {
|
||||
|
||||
public StatsDatabaseManager(ServerConfiguration config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
public void saveVaultCompletion(ControllableUnit unit, String dimension) {
|
||||
|
||||
Connection connection = getConnection();
|
||||
|
||||
try {
|
||||
|
||||
PreparedStatement p = connection.prepareStatement("INSERT INTO mar_vault_clear " +
|
||||
"(username, clear_time, vault_id) VALUES (?,?,?)");
|
||||
p.setString(1, unit.getParent().getUsername());
|
||||
p.setInt(2, 0);
|
||||
p.setString(3, dimension);
|
||||
|
||||
int result = p.executeUpdate();
|
||||
|
||||
LogManager.LOGGER.fine("Saved vault clear (" + result + " rows changed)");
|
||||
|
||||
} catch (MySQLIntegrityConstraintViolationException e) {
|
||||
LogManager.LOGGER.fine("This vault was already cleared by " + unit.getParent().getUsername());
|
||||
} catch (SQLException e) {
|
||||
LogManager.LOGGER.severe(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Spring" name="Spring">
|
||||
<configuration />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -15,10 +20,37 @@
|
||||
<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="module" module-name="Server" />
|
||||
<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: 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: org.mongodb:mongo-java-driver:3.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.21" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -1,9 +1,8 @@
|
||||
package net.simon987.biomassplugin;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.InventoryHolder;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class BiomassBlob extends GameObject implements InventoryHolder {
|
||||
@ -43,9 +42,9 @@ public class BiomassBlob extends GameObject implements InventoryHolder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("t", ID);
|
||||
dbObject.put("i", getObjectId());
|
||||
@ -65,15 +64,8 @@ public class BiomassBlob extends GameObject implements InventoryHolder {
|
||||
this.biomassCount = biomassCount;
|
||||
}
|
||||
|
||||
// public int getStyle() {
|
||||
// return style;
|
||||
// }
|
||||
//
|
||||
// public void setStyle(int style) {
|
||||
// this.style = style;
|
||||
// }
|
||||
|
||||
public static BiomassBlob deserialize(DBObject obj) {
|
||||
public static BiomassBlob deserialize(Document obj) {
|
||||
|
||||
BiomassBlob biomassBlob = new BiomassBlob();
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.simon987.biomassplugin;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.biomassplugin.event.ObjectDeathListener;
|
||||
import net.simon987.biomassplugin.event.WorldCreationListener;
|
||||
import net.simon987.biomassplugin.event.WorldUpdateListener;
|
||||
@ -9,6 +8,8 @@ import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.io.GameObjectDeserializer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
|
||||
|
||||
public class BiomassPlugin extends ServerPlugin implements GameObjectDeserializer {
|
||||
|
||||
@ -23,7 +24,7 @@ public class BiomassPlugin extends ServerPlugin implements GameObjectDeserialize
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameObject deserializeObject(DBObject object) {
|
||||
public GameObject deserializeObject(Document object) {
|
||||
|
||||
int objType = (int) object.get("t");
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.simon987.pluginradioactivecloud;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.io.GameObjectDeserializer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
|
||||
public class RadioactiveCloudPlugin extends ServerPlugin implements GameObjectDeserializer {
|
||||
|
||||
@ -16,7 +16,7 @@ public class RadioactiveCloudPlugin extends ServerPlugin implements GameObjectDe
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameObject deserializeObject(DBObject object) {
|
||||
public GameObject deserializeObject(Document object) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
31
README.md
31
README.md
@ -1,25 +1,18 @@
|
||||
# [Live demo](https://muchassemblyrequired.com)
|
||||
### [Official website](https://muchassemblyrequired.com)
|
||||
Program the 8086-like microprocessor of a robot in a grid-based multiplayer world. The game is web based so no installation is required.
|
||||
In its current state, players can walk around the game universe and collect Biomass blobs & Iron/copper ore using the online code editor.
|
||||
|
||||

|
||||
|
||||
Wiki: [GitHub](https://github.com/simon987/Much-Assembly-Required/wiki)
|
||||
Wiki: [GitHub](https://github.com/simon987/Much-Assembly-Required/wiki)
|
||||
Chat: [Slack](https://join.slack.com/t/muchassemblyrequired/shared_invite/enQtMjY3Mjc1OTUwNjEwLTkyOTIwOTA5OGY4MDVlMGI4NzM5YzlhMWJiMGY1OWE2NjUxODQ1NWQ1YTcxMTA1NGZkYzNjYzMyM2E1ODdmNzg)
|
||||
|
||||
## VS Code Extensions
|
||||
- [Much Assembly Required (Upload on Save)](https://marketplace.visualstudio.com/items?itemName=tomhodder.much-assembly-required-upload-on-save) by tomhodder
|
||||
- [Much Assembly Required Language Support](https://marketplace.visualstudio.com/items?itemName=PJB3005.much-assembly-required-language-support) by PJB3005
|
||||
|
||||
# Deploying the server
|
||||
|
||||
Note: You can find the frontend [here](https://github.com/simon987/Much-Assembly-Required-Frontend)
|
||||
|
||||
|
||||
## Linux (Ubuntu 16.04)
|
||||
```bash
|
||||
# Install tools
|
||||
sudo apt install git maven openjdk-8-jdk
|
||||
sudo apt install git maven openjdk-8-jdk mongodb
|
||||
|
||||
# Obtain source files
|
||||
git clone https://github.com/simon987/Much-Assembly-Required.git
|
||||
@ -30,7 +23,7 @@ mvn package
|
||||
|
||||
# Run
|
||||
cd target
|
||||
java -jar server-1.2a.jar
|
||||
java -jar server-1.4a.jar
|
||||
```
|
||||
|
||||
## Windows (tested on Windows 10)
|
||||
@ -61,10 +54,8 @@ mongod
|
||||
```batch
|
||||
:: Runs the MAR server
|
||||
cd Much-Assembly-Required\target
|
||||
java -jar server-1.2a.jar
|
||||
java -jar server-1.4a.jar
|
||||
```
|
||||
3. Run the frontend, following the instructions that you can find [here](https://github.com/simon987/Much-Assembly-Required-Frontend).
|
||||
|
||||
|
||||
## Docker
|
||||
### Requirements
|
||||
@ -79,8 +70,12 @@ application's directory:
|
||||
|
||||
`docker-compose up`
|
||||
|
||||
This will start MySQL and then build and run this application. It will
|
||||
be available via http://localhost.
|
||||
Make sure to change `mongo_address` in `config.properties` to `mongodb`.
|
||||
|
||||
Note that there is currently no frontend web application serving the
|
||||
WebSocket feed served by the `Server` application!
|
||||
# Running
|
||||
|
||||
Once the server is running, you should be able to connect to `http://localhost:4567` with your browser
|
||||
|
||||
## VS Code Extensions
|
||||
- [Much Assembly Required (Upload on Save)](https://marketplace.visualstudio.com/items?itemName=tomhodder.much-assembly-required-upload-on-save) by tomhodder
|
||||
- [Much Assembly Required Language Support](https://marketplace.visualstudio.com/items?itemName=PJB3005.much-assembly-required-language-support) by PJB3005
|
||||
|
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Spring" name="Spring">
|
||||
<configuration />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
@ -11,13 +16,40 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: org.java-websocket:Java-WebSocket:1.3.6" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.42" 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-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: org.mongodb:mongo-java-driver:3.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.0.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.8.v20171121" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.21" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -24,10 +24,6 @@
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../Server/src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>config.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
@ -92,22 +88,12 @@
|
||||
<version>1.4a</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.java-websocket</groupId>
|
||||
<artifactId>Java-WebSocket</artifactId>
|
||||
<version>1.3.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.42</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
@ -121,7 +107,27 @@
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>2.10.1</version>
|
||||
<version>3.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>5.0.5.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sparkjava</groupId>
|
||||
<artifactId>spark-core</artifactId>
|
||||
<version>2.7.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sparkjava</groupId>
|
||||
<artifactId>spark-template-velocity</artifactId>
|
||||
<version>2.7.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.21</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
@ -1,8 +1,11 @@
|
||||
package net.simon987.server;
|
||||
|
||||
|
||||
import com.mongodb.*;
|
||||
import net.simon987.server.assembly.exception.CancelledException;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import net.simon987.server.crypto.CryptoProvider;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.GameEventDispatcher;
|
||||
@ -14,10 +17,13 @@ import net.simon987.server.game.debug.*;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.PluginManager;
|
||||
import net.simon987.server.user.User;
|
||||
import net.simon987.server.webserver.SocketServer;
|
||||
import net.simon987.server.user.UserManager;
|
||||
import net.simon987.server.user.UserStatsHelper;
|
||||
import net.simon987.server.websocket.SocketServer;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GameServer implements Runnable {
|
||||
|
||||
@ -39,15 +45,21 @@ public class GameServer implements Runnable {
|
||||
|
||||
private MongoClient mongo = null;
|
||||
|
||||
private UserManager userManager;
|
||||
|
||||
private UserStatsHelper userStatsHelper;
|
||||
|
||||
public GameServer() {
|
||||
|
||||
this.config = new ServerConfiguration("config.properties");
|
||||
|
||||
try{
|
||||
mongo = new MongoClient("localhost", 27017);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mongo = new MongoClient(config.getString("mongo_address"), config.getInt("mongo_port"));
|
||||
MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname"));
|
||||
|
||||
MongoCollection<Document> userCollection = db.getCollection("user");
|
||||
|
||||
userManager = new UserManager(userCollection);
|
||||
userStatsHelper = new UserStatsHelper(userCollection);
|
||||
|
||||
gameUniverse = new GameUniverse(config);
|
||||
gameUniverse.setMongo(mongo);
|
||||
@ -69,7 +81,6 @@ public class GameServer implements Runnable {
|
||||
if (pluginFile.getName().endsWith(".jar")) {
|
||||
pluginManager.load(pluginFile, config);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (!pluginDir.mkdir()) {
|
||||
@ -93,7 +104,7 @@ public class GameServer implements Runnable {
|
||||
eventDispatcher.getListeners().add(new HealObjCommandListener());
|
||||
eventDispatcher.getListeners().add(new DamageObjCommandListener());
|
||||
eventDispatcher.getListeners().add(new SetEnergyCommandListener());
|
||||
|
||||
eventDispatcher.getListeners().add(new SaveGameCommandListener());
|
||||
}
|
||||
|
||||
public GameUniverse getGameUniverse() {
|
||||
@ -127,7 +138,7 @@ public class GameServer implements Runnable {
|
||||
uTime = System.currentTimeMillis() - startTime;
|
||||
waitTime = config.getInt("tick_length") - uTime;
|
||||
|
||||
LogManager.LOGGER.info("Wait time : " + waitTime + "ms | Update time: " + uTime + "ms | " + (int) (((double) uTime / waitTime) * 100) + "% load");
|
||||
// LogManager.LOGGER.info("Wait time : " + waitTime + "ms | Update time: " + uTime + "ms | " + (int) (((double) uTime / waitTime) * 100) + "% load");
|
||||
|
||||
try {
|
||||
if (waitTime >= 0) {
|
||||
@ -136,10 +147,7 @@ public class GameServer implements Runnable {
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
@ -149,7 +157,6 @@ public class GameServer implements Runnable {
|
||||
GameEvent event = new TickEvent(gameUniverse.getTime());
|
||||
eventDispatcher.dispatch(event); //Ignore cancellation
|
||||
|
||||
|
||||
//Process user code
|
||||
for (User user : gameUniverse.getUsers()) {
|
||||
|
||||
@ -186,25 +193,22 @@ public class GameServer implements Runnable {
|
||||
|
||||
socketServer.tick();
|
||||
|
||||
LogManager.LOGGER.info("Processed " + gameUniverse.getWorldCount() + " worlds (" + updatedWorlds +
|
||||
" updated)");
|
||||
// LogManager.LOGGER.info("Processed " + gameUniverse.getWorldCount() + " worlds (" + updatedWorlds +
|
||||
// " updated)");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void load() {
|
||||
|
||||
LogManager.LOGGER.info("Loading all data from MongoDB");
|
||||
|
||||
DB db = mongo.getDB("mar");
|
||||
MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname"));
|
||||
|
||||
DBCollection worlds = db.getCollection("world");
|
||||
DBCollection users = db.getCollection("user");
|
||||
DBCollection server = db.getCollection("server");
|
||||
MongoCollection<Document> worlds = db.getCollection("world");
|
||||
MongoCollection<Document> server = db.getCollection("server");
|
||||
|
||||
BasicDBObject whereQuery = new BasicDBObject();
|
||||
Document whereQuery = new Document();
|
||||
whereQuery.put("shouldUpdate", true);
|
||||
DBCursor cursor = worlds.find(whereQuery);
|
||||
MongoCursor<Document> cursor = worlds.find(whereQuery).iterator();
|
||||
GameUniverse universe = GameServer.INSTANCE.getGameUniverse();
|
||||
while (cursor.hasNext()) {
|
||||
World w = World.deserialize(cursor.next());
|
||||
@ -212,19 +216,15 @@ public class GameServer implements Runnable {
|
||||
}
|
||||
|
||||
//Load users
|
||||
cursor = users.find();
|
||||
while (cursor.hasNext()) {
|
||||
try {
|
||||
universe.addUser(User.deserialize(cursor.next()));
|
||||
} catch (CancelledException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ArrayList<User> userList = userManager.getUsers();
|
||||
for (User user : userList) {
|
||||
universe.addUser(user);
|
||||
}
|
||||
|
||||
//Load misc server info
|
||||
cursor = server.find();
|
||||
cursor = server.find().iterator();
|
||||
if (cursor.hasNext()) {
|
||||
DBObject serverObj = cursor.next();
|
||||
Document serverObj = cursor.next();
|
||||
gameUniverse.setTime((long) serverObj.get("time"));
|
||||
gameUniverse.setNextObjectId((long) serverObj.get("nextObjectId"));
|
||||
}
|
||||
@ -233,49 +233,47 @@ public class GameServer implements Runnable {
|
||||
" | U:" + GameServer.INSTANCE.getGameUniverse().getUserCount());
|
||||
}
|
||||
|
||||
private void save() {
|
||||
public void save() {
|
||||
|
||||
LogManager.LOGGER.info("Saving to MongoDB | W:" + gameUniverse.getWorldCount() + " | U:" + gameUniverse.getUserCount());
|
||||
try{
|
||||
DB db = mongo.getDB("mar");
|
||||
MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname"));
|
||||
UpdateOptions updateOptions = new UpdateOptions();
|
||||
updateOptions.upsert(true);
|
||||
|
||||
int unloaded_worlds = 0;
|
||||
|
||||
DBCollection worlds = db.getCollection("world");
|
||||
DBCollection users = db.getCollection("user");
|
||||
DBCollection server = db.getCollection("server");
|
||||
MongoCollection<Document> worlds = db.getCollection("world");
|
||||
MongoCollection<Document> users = db.getCollection("user");
|
||||
MongoCollection<Document> server = db.getCollection("server");
|
||||
|
||||
int insertedWorlds = 0;
|
||||
GameUniverse universe = GameServer.INSTANCE.getGameUniverse();
|
||||
for (World w : universe.getWorlds()) {
|
||||
// LogManager.LOGGER.fine("Saving world "+w.getId()+" to mongodb");
|
||||
insertedWorlds++;
|
||||
worlds.save(w.mongoSerialise());
|
||||
worlds.replaceOne(new Document("_id", w.getId()), w.mongoSerialise(), updateOptions);
|
||||
|
||||
// If the world should unload, it is removed from the Universe after having been saved.
|
||||
//If the world should unload, it is removed from the Universe after having been saved.
|
||||
if (w.shouldUnload()){
|
||||
unloaded_worlds++;
|
||||
// LogManager.LOGGER.fine("Unloading world "+w.getId()+" from universe");
|
||||
universe.removeWorld(w);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (User u : GameServer.INSTANCE.getGameUniverse().getUsers()) {
|
||||
|
||||
if (!u.isGuest()) {
|
||||
users.save(u.mongoSerialise());
|
||||
users.replaceOne(new Document("_id", u.getUsername()), u.mongoSerialise(), updateOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BasicDBObject serverObj = new BasicDBObject();
|
||||
serverObj.put("_id","serverinfo"); // a constant id ensures only one entry is kept and updated, instead of a new entry created every save.
|
||||
Document serverObj = new Document();
|
||||
serverObj.put("time", gameUniverse.getTime());
|
||||
serverObj.put("nextObjectId", gameUniverse.getNextObjectId());
|
||||
server.save(serverObj);
|
||||
//A constant id ensures only one entry is kept and updated, instead of a new entry created every save.
|
||||
server.replaceOne(new Document("_id", "serverinfo"), serverObj, updateOptions);
|
||||
|
||||
LogManager.LOGGER.info(""+insertedWorlds+" worlds saved, "+unloaded_worlds+" unloaded");
|
||||
LogManager.LOGGER.info("Done!");
|
||||
LogManager.LOGGER.info("" + insertedWorlds + " worlds saved, " + unloaded_worlds + " unloaded");
|
||||
} catch (Exception e) {
|
||||
LogManager.LOGGER.severe("Problem happened during save function");
|
||||
e.printStackTrace();
|
||||
@ -297,4 +295,12 @@ public class GameServer implements Runnable {
|
||||
public DayNightCycle getDayNightCycle() {
|
||||
return dayNightCycle;
|
||||
}
|
||||
|
||||
public UserManager getUserManager() {
|
||||
return userManager;
|
||||
}
|
||||
|
||||
public UserStatsHelper getUserStatsHelper() {
|
||||
return userStatsHelper;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package net.simon987.server;
|
||||
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.webserver.SocketServer;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import net.simon987.server.web.WebServer;
|
||||
import spark.Spark;
|
||||
|
||||
|
||||
public class Main {
|
||||
@ -12,15 +11,14 @@ public class Main {
|
||||
ServerConfiguration config = new ServerConfiguration("config.properties");
|
||||
LogManager.initialize(config);
|
||||
|
||||
//Load
|
||||
GameServer.INSTANCE.load();
|
||||
|
||||
SocketServer socketServer = new SocketServer(new InetSocketAddress(config.getString("webSocket_host"),
|
||||
config.getInt("webSocket_port")), config);
|
||||
//Web server
|
||||
WebServer webServer = new WebServer(GameServer.INSTANCE.getConfig());
|
||||
|
||||
GameServer.INSTANCE.setSocketServer(socketServer);
|
||||
Spark.awaitInitialization();
|
||||
GameServer.INSTANCE.setSocketServer(webServer.getSocketServer());
|
||||
|
||||
(new Thread(socketServer)).start();
|
||||
(new Thread(GameServer.INSTANCE)).start();
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package net.simon987.server;
|
||||
|
||||
import net.simon987.server.logging.LogManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -61,7 +61,7 @@ public class Assembler {
|
||||
/**
|
||||
* Check for and save the origin
|
||||
*
|
||||
* @param line Current line. Assuming that the comments & labels are removed
|
||||
* @param line Current line. Assuming that the comments and labels are removed
|
||||
* @param result Current line number
|
||||
*/
|
||||
private static void checkForORGInstruction(String line, AssemblyResult result, int currentLine)
|
||||
@ -121,7 +121,7 @@ public class Assembler {
|
||||
/**
|
||||
* Parse the DW instruction (Define word). Handles DUP operator
|
||||
*
|
||||
* @param line Current line. assuming that comments & labels are removed
|
||||
* @param line Current line. assuming that comments and labels are removed
|
||||
* @param currentLine Current line number
|
||||
* @param labels Map of labels
|
||||
* @return Encoded instruction, null if the line is not a DW instruction
|
||||
@ -258,7 +258,7 @@ public class Assembler {
|
||||
/**
|
||||
* Parse the DW instruction (Define word). Handles DUP operator
|
||||
*
|
||||
* @param line Current line. assuming that comments & labels are removed
|
||||
* @param line Current line. assuming that comments and labels are removed
|
||||
* @param currentLine Current line number
|
||||
* @return Encoded instruction, null if the line is not a DW instruction
|
||||
*/
|
||||
@ -267,7 +267,7 @@ public class Assembler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for and handle section declarations (.text & .data)
|
||||
* Check for and handle section declarations (.text and .data)
|
||||
*
|
||||
* @param line Current line
|
||||
*/
|
||||
|
@ -1,26 +1,26 @@
|
||||
package net.simon987.server.assembly;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.assembly.exception.CancelledException;
|
||||
import net.simon987.server.assembly.instruction.*;
|
||||
import net.simon987.server.event.CpuInitialisationEvent;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.User;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CPU: Central Processing Unit. A CPU is capable of reading bytes from
|
||||
* a Memory object and execute them. A CPU object holds registers objects &
|
||||
* a Memory object and execute them. A CPU object holds registers objects and
|
||||
* a Memory object.
|
||||
*/
|
||||
public class CPU implements MongoSerialisable {
|
||||
public class CPU implements MongoSerializable {
|
||||
|
||||
/**
|
||||
*
|
||||
@ -160,7 +160,7 @@ public class CPU implements MongoSerialisable {
|
||||
}
|
||||
int elapsed = (int) (System.currentTimeMillis() - startTime);
|
||||
|
||||
LogManager.LOGGER.fine(counter + " instruction in " + elapsed + "ms : " + (double) counter / (elapsed / 1000) / 1000000 + "MHz");
|
||||
// LogManager.LOGGER.fine(counter + " instruction in " + elapsed + "ms : " + (double) counter / (elapsed / 1000) / 1000000 + "MHz");
|
||||
|
||||
|
||||
//Write execution cost and instruction count to memory
|
||||
@ -173,7 +173,6 @@ public class CPU implements MongoSerialisable {
|
||||
|
||||
public void executeInstruction(Instruction instruction, int source, int destination) {
|
||||
|
||||
|
||||
//Execute the instruction
|
||||
if (source == 0) {
|
||||
//No operand (assuming that destination is also null)
|
||||
@ -348,21 +347,21 @@ public class CPU implements MongoSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
public Document mongoSerialise() {
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("memory", memory.mongoSerialise());
|
||||
|
||||
dbObject.put("registerSet", registerSet.mongoSerialise());
|
||||
dbObject.put("codeSegmentOffset", codeSectionOffset);
|
||||
|
||||
BasicDBList hardwareList = new BasicDBList();
|
||||
List<Document> hardwareList = new ArrayList<>();
|
||||
|
||||
for (Integer address : attachedHardware.keySet()) {
|
||||
|
||||
CpuHardware hardware = attachedHardware.get(address);
|
||||
|
||||
BasicDBObject serialisedHw = hardware.mongoSerialise();
|
||||
Document serialisedHw = hardware.mongoSerialise();
|
||||
serialisedHw.put("address", address);
|
||||
hardwareList.add(serialisedHw);
|
||||
}
|
||||
@ -373,22 +372,22 @@ public class CPU implements MongoSerialisable {
|
||||
|
||||
}
|
||||
|
||||
public static CPU deserialize(DBObject obj, User user) throws CancelledException {
|
||||
public static CPU deserialize(Document obj, User user) throws CancelledException {
|
||||
|
||||
CPU cpu = new CPU(GameServer.INSTANCE.getConfig(), user);
|
||||
|
||||
cpu.codeSectionOffset = (int) obj.get("codeSegmentOffset");
|
||||
|
||||
BasicDBList hardwareList = (BasicDBList) obj.get("hardware");
|
||||
ArrayList hardwareList = (ArrayList) obj.get("hardware");
|
||||
|
||||
for (Object serialisedHw : hardwareList) {
|
||||
CpuHardware hardware = CpuHardware.deserialize((DBObject) serialisedHw);
|
||||
CpuHardware hardware = CpuHardware.deserialize((Document) serialisedHw);
|
||||
hardware.setCpu(cpu);
|
||||
cpu.attachHardware(hardware, (int) ((BasicDBObject) serialisedHw).get("address"));
|
||||
cpu.attachHardware(hardware, (int) ((Document) serialisedHw).get("address"));
|
||||
}
|
||||
|
||||
cpu.memory = Memory.deserialize((DBObject) obj.get("memory"));
|
||||
cpu.registerSet = RegisterSet.deserialize((DBObject) obj.get("registerSet"));
|
||||
cpu.memory = Memory.deserialize((Document) obj.get("memory"));
|
||||
cpu.registerSet = RegisterSet.deserialize((Document) obj.get("registerSet"));
|
||||
|
||||
return cpu;
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
package net.simon987.server.assembly;
|
||||
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.io.CpuHardwareDeserializer;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
|
||||
public abstract class CpuHardware implements MongoSerialisable {
|
||||
public abstract class CpuHardware implements MongoSerializable {
|
||||
|
||||
CPU cpu;
|
||||
|
||||
@ -26,7 +26,7 @@ public abstract class CpuHardware implements MongoSerialisable {
|
||||
|
||||
public abstract char getId();
|
||||
|
||||
public static CpuHardware deserialize(DBObject obj) {
|
||||
public static CpuHardware deserialize(Document obj) {
|
||||
|
||||
for (ServerPlugin plugin : GameServer.INSTANCE.getPluginManager().getPlugins()) {
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
package net.simon987.server.assembly;
|
||||
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -22,7 +21,7 @@ import java.util.zip.InflaterOutputStream;
|
||||
/**
|
||||
* Represents the available memory for a CPU in the game universe
|
||||
*/
|
||||
public class Memory implements Target, MongoSerialisable {
|
||||
public class Memory implements Target, MongoSerializable {
|
||||
|
||||
|
||||
/**
|
||||
@ -133,9 +132,9 @@ public class Memory implements Target, MongoSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
@ -154,7 +153,7 @@ public class Memory implements Target, MongoSerialisable {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
public static Memory deserialize(DBObject obj) {
|
||||
public static Memory deserialize(Document obj) {
|
||||
|
||||
Memory memory = new Memory(0);
|
||||
|
||||
|
@ -1,21 +1,20 @@
|
||||
package net.simon987.server.assembly;
|
||||
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A set of registers for a CPU
|
||||
*/
|
||||
public class RegisterSet implements Target, MongoSerialisable {
|
||||
public class RegisterSet implements Target, MongoSerializable {
|
||||
|
||||
/**
|
||||
* List of registers
|
||||
@ -145,10 +144,10 @@ public class RegisterSet implements Target, MongoSerialisable {
|
||||
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
BasicDBList registers = new BasicDBList();
|
||||
public Document mongoSerialise() {
|
||||
List<Document> registers = new ArrayList<>();
|
||||
for (Integer index : this.registers.keySet()) {
|
||||
JSONObject register = new JSONObject();
|
||||
Document register = new Document();
|
||||
|
||||
register.put("index", index);
|
||||
register.put("name", getRegister(index).getName());
|
||||
@ -157,24 +156,24 @@ public class RegisterSet implements Target, MongoSerialisable {
|
||||
registers.add(register);
|
||||
}
|
||||
|
||||
BasicDBObject obj = new BasicDBObject();
|
||||
Document obj = new Document();
|
||||
obj.put("registers", registers);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static RegisterSet deserialize(DBObject obj) {
|
||||
public static RegisterSet deserialize(Document obj) {
|
||||
|
||||
RegisterSet registerSet = new RegisterSet();
|
||||
|
||||
BasicDBList registers = (BasicDBList) obj.get("registers");
|
||||
List registers = (ArrayList) obj.get("registers");
|
||||
|
||||
for (Object sRegister : registers) {
|
||||
|
||||
Register register = new Register((String) ((DBObject) sRegister).get("name"));
|
||||
register.setValue((int) ((DBObject) sRegister).get("value"));
|
||||
Register register = new Register((String) ((Document) sRegister).get("name"));
|
||||
register.setValue((int) ((Document) sRegister).get("value"));
|
||||
|
||||
registerSet.registers.put((int) ((DBObject) sRegister).get("index"), register);
|
||||
registerSet.registers.put((int) ((Document) sRegister).get("index"), register);
|
||||
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,11 @@ import net.simon987.server.assembly.Util;
|
||||
|
||||
/**
|
||||
* AND two numbers together, the result is stored in the destination operand
|
||||
* <p>
|
||||
* <br>
|
||||
* AND A, B
|
||||
* A = A & B
|
||||
* </p>
|
||||
* <br>
|
||||
* {@literal A = A & B @}
|
||||
* <br>
|
||||
* FLAGS: OF=0 S=* Z=* X=0
|
||||
*/
|
||||
public class AndInstruction extends Instruction {
|
||||
|
@ -6,9 +6,9 @@ import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Target;
|
||||
|
||||
/**
|
||||
* Send hardware interupt
|
||||
* Used to interact with the World using hardware
|
||||
* </p>
|
||||
* Send hardware interrupt
|
||||
* <br>Used to interact with the World using hardware
|
||||
*
|
||||
*/
|
||||
public class HwiInstruction extends Instruction {
|
||||
|
||||
|
@ -6,9 +6,9 @@ import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Target;
|
||||
|
||||
/**
|
||||
* +---------------------+
|
||||
* | |
|
||||
* CF < 0<0<0<0<0<0<0<0 <-+
|
||||
*<br> +---------------------+
|
||||
*<br> | |
|
||||
*<br> {@literal CF < 0<0<0<0<0<0<0<0 <-+ @}
|
||||
*/
|
||||
public class RclInstruction extends Instruction {
|
||||
|
||||
|
@ -5,9 +5,9 @@ import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Target;
|
||||
|
||||
/**
|
||||
* +---------------------+
|
||||
* | |
|
||||
* CF < 0<0<0<0<0<0<0<0 <-+
|
||||
* <br> +---------------------+
|
||||
* <br> | |
|
||||
* <br> {@literal CF < 0<0<0<0<0<0<0<0 <-+ @}
|
||||
*/
|
||||
public class RcrInstruction extends Instruction {
|
||||
|
||||
|
@ -5,9 +5,9 @@ import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Target;
|
||||
|
||||
/**
|
||||
* +-----------------+
|
||||
* | |
|
||||
* CF < 0<0<0<0<0<0<0<0 <-+
|
||||
* <br> +-----------------+
|
||||
* <br> | |
|
||||
* <br> {@literal CF < 0<0<0<0<0<0<0<0 <-+ @}
|
||||
*/
|
||||
public class RolInstruction extends Instruction {
|
||||
|
||||
|
@ -5,9 +5,9 @@ import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Target;
|
||||
|
||||
/**
|
||||
* +-----------------+
|
||||
* | |
|
||||
* +-> 0>0>0>0>0>0>0>0 > CF
|
||||
* <br> +-----------------+
|
||||
* <br> | |
|
||||
* <br> {@literal +-> 0>0>0>0>0>0>0>0 > CF @}
|
||||
*/
|
||||
public class RorInstruction extends Instruction {
|
||||
|
||||
|
@ -23,10 +23,10 @@ public class RandomStringGenerator {
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
public static final String UPPER_ALPHA_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
public static final String LOWER_ALPHA_CHARSET = UPPER_ALPHA_CHARSET.toLowerCase(Locale.ROOT);
|
||||
public static final String NUMERIC_CHARSET = "0123456789";
|
||||
public static final String ALPHANUMERIC_CHARSET = UPPER_ALPHA_CHARSET + LOWER_ALPHA_CHARSET + NUMERIC_CHARSET;
|
||||
static final String UPPER_ALPHA_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static final String LOWER_ALPHA_CHARSET = UPPER_ALPHA_CHARSET.toLowerCase(Locale.ROOT);
|
||||
static final String NUMERIC_CHARSET = "0123456789";
|
||||
static final String ALPHANUMERIC_CHARSET = UPPER_ALPHA_CHARSET + LOWER_ALPHA_CHARSET + NUMERIC_CHARSET;
|
||||
|
||||
private final Random random;
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package net.simon987.server.event;
|
||||
|
||||
import net.simon987.server.webserver.OnlineUser;
|
||||
import net.simon987.server.websocket.OnlineUser;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DebugCommandEvent extends GameEvent {
|
||||
|
||||
private JSONObject command;
|
||||
@ -37,7 +39,11 @@ public class DebugCommandEvent extends GameEvent {
|
||||
response.put("t", "debug");
|
||||
response.put("message", message);
|
||||
|
||||
((OnlineUser) getSource()).getWebSocket().send(response.toJSONString());
|
||||
try {
|
||||
((OnlineUser) getSource()).getWebSocket().getRemote().sendString(response.toJSONString());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ public interface Enterable {
|
||||
* Called when an object attempts to walk directly into a Enterable object
|
||||
*
|
||||
* @param object The game object that attempted to enter
|
||||
* @return true if successful,
|
||||
* @return true if successful, false to block the object
|
||||
*/
|
||||
boolean enter(GameObject object);
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.simon987.server.game;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.io.GameObjectDeserializer;
|
||||
import net.simon987.server.io.JSONSerialisable;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.awt.*;
|
||||
@ -15,7 +15,7 @@ import java.util.ArrayList;
|
||||
* An INSTANCE of an object (e.g. a Tree, a character ...) inside the
|
||||
* game universe
|
||||
*/
|
||||
public abstract class GameObject implements JSONSerialisable, MongoSerialisable {
|
||||
public abstract class GameObject implements JSONSerialisable, MongoSerializable {
|
||||
|
||||
private boolean dead;
|
||||
/**
|
||||
@ -223,8 +223,8 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
public static GameObject deserialize(DBObject obj) {
|
||||
//
|
||||
public static GameObject deserialize(Document obj) {
|
||||
|
||||
for (ServerPlugin plugin : GameServer.INSTANCE.getPluginManager().getPlugins()) {
|
||||
|
||||
if (plugin instanceof GameObjectDeserializer) {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package net.simon987.server.game;
|
||||
|
||||
import com.mongodb.*;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.assembly.Assembler;
|
||||
@ -9,6 +12,7 @@ import net.simon987.server.assembly.CPU;
|
||||
import net.simon987.server.assembly.exception.CancelledException;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.User;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -55,13 +59,13 @@ public class GameUniverse {
|
||||
* @return World, null if not found
|
||||
*/
|
||||
private World loadWorld(int x, int y, String dimension) {
|
||||
|
||||
DB db = mongo.getDB("mar");
|
||||
DBCollection worlds = db.getCollection("world");
|
||||
|
||||
BasicDBObject whereQuery = new BasicDBObject();
|
||||
MongoDatabase db = mongo.getDatabase(GameServer.INSTANCE.getConfig().getString("mongo_dbname"));
|
||||
MongoCollection<Document> worlds = db.getCollection("world");
|
||||
|
||||
Document whereQuery = new Document();
|
||||
whereQuery.put("_id", World.idFromCoordinates(x, y, dimension));
|
||||
DBCursor cursor = worlds.find(whereQuery);
|
||||
MongoCursor<Document> cursor = worlds.find(whereQuery).iterator();
|
||||
if (cursor.hasNext()) {
|
||||
return World.deserialize(cursor.next());
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package net.simon987.server.game;
|
||||
|
||||
//Alpha: ±5cm
|
||||
//Beta: 10-20 feet
|
||||
//Gamma: 100+ feet
|
||||
|
||||
public interface Radioactive {
|
||||
|
||||
|
||||
}
|
@ -1,16 +1,15 @@
|
||||
package net.simon987.server.game;
|
||||
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.io.JSONSerialisable;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Random;
|
||||
import java.util.zip.Deflater;
|
||||
@ -19,7 +18,7 @@ import java.util.zip.DeflaterOutputStream;
|
||||
/**
|
||||
* A 2D map of Tile objects of size width*height
|
||||
*/
|
||||
public class TileMap implements JSONSerialisable, MongoSerialisable {
|
||||
public class TileMap implements JSONSerialisable, MongoSerializable {
|
||||
|
||||
public static final int VOID = -1;
|
||||
public static final int PLAIN_TILE = 0;
|
||||
@ -141,25 +140,34 @@ public class TileMap implements JSONSerialisable, MongoSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("tiles", tiles);
|
||||
//Flatten multi-dimensional array
|
||||
ArrayList<Integer> bsonTiles = new ArrayList<>();
|
||||
|
||||
for (int x = 0; x < this.width; x++) {
|
||||
for (int y = 0; y < this.height; y++) {
|
||||
bsonTiles.add(tiles[x][y]);
|
||||
}
|
||||
}
|
||||
|
||||
dbObject.put("tiles", bsonTiles);
|
||||
|
||||
return dbObject;
|
||||
|
||||
}
|
||||
|
||||
public static TileMap deserialize(DBObject object, int size) {
|
||||
public static TileMap deserialize(Document object, int size) {
|
||||
|
||||
BasicDBList terrain = (BasicDBList) object.get("tiles");
|
||||
ArrayList<Integer> terrain = (ArrayList<Integer>) object.get("tiles");
|
||||
|
||||
int[][] tiles = new int[size][size];
|
||||
|
||||
for (int x = 0; x < size; x++) {
|
||||
for (int y = 0; y < size; y++) {
|
||||
tiles[x][y] = (int) ((BasicDBList) terrain.get(x)).get(y);
|
||||
tiles[x][y] = terrain.get(x * size + y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,20 @@
|
||||
package net.simon987.server.game;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.WorldUpdateEvent;
|
||||
import net.simon987.server.game.pathfinding.Pathfinder;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class World implements MongoSerialisable {
|
||||
public class World implements MongoSerializable {
|
||||
|
||||
/**
|
||||
* Size of the side of this world
|
||||
@ -171,17 +170,15 @@ public class World implements MongoSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
BasicDBList objects = new BasicDBList();
|
||||
List<Document> objects = new ArrayList<>();
|
||||
for (GameObject obj : gameObjects.values()) {
|
||||
objects.add(obj.mongoSerialise());
|
||||
}
|
||||
|
||||
|
||||
dbObject.put("_id", getId());
|
||||
dbObject.put("dimension", getDimension());
|
||||
|
||||
dbObject.put("objects", objects);
|
||||
@ -214,7 +211,7 @@ public class World implements MongoSerialisable {
|
||||
|
||||
}
|
||||
|
||||
public static World deserialize(DBObject dbObject) {
|
||||
public static World deserialize(Document dbObject) {
|
||||
|
||||
World world = new World((int) dbObject.get("size"));
|
||||
world.x = (int) dbObject.get("x");
|
||||
@ -222,13 +219,13 @@ public class World implements MongoSerialisable {
|
||||
world.dimension = (String) dbObject.get("dimension");
|
||||
world.updatable = (int) dbObject.get("updatable");
|
||||
|
||||
world.tileMap = TileMap.deserialize((BasicDBObject) dbObject.get("terrain"), world.getWorldSize());
|
||||
world.tileMap = TileMap.deserialize((Document) dbObject.get("terrain"), world.getWorldSize());
|
||||
|
||||
BasicDBList objects = (BasicDBList) dbObject.get("objects");
|
||||
ArrayList<Document> objects = (ArrayList<Document>) dbObject.get("objects");
|
||||
|
||||
for (Object obj : objects) {
|
||||
|
||||
GameObject object = GameObject.deserialize((DBObject) obj);
|
||||
GameObject object = GameObject.deserialize((Document) obj);
|
||||
|
||||
object.setWorld(world);
|
||||
world.addObject(object);
|
||||
|
@ -42,5 +42,4 @@ public class HealObjCommandListener implements GameEventListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package net.simon987.server.game.debug;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.event.DebugCommandEvent;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.GameEventListener;
|
||||
|
||||
public class SaveGameCommandListener implements GameEventListener {
|
||||
|
||||
@Override
|
||||
public Class getListenedEventType() {
|
||||
return DebugCommandEvent.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameEvent event) {
|
||||
|
||||
DebugCommandEvent e = (DebugCommandEvent) event;
|
||||
|
||||
if (e.getName().equals("saveGame")) {
|
||||
|
||||
GameServer.INSTANCE.save();
|
||||
e.reply("Saved the game");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
package net.simon987.server.game.debug;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.util.JSON;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.event.DebugCommandEvent;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.GameEventListener;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.World;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -28,7 +27,7 @@ public class SpawnObjCommandListener implements GameEventListener {
|
||||
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
|
||||
false, e.getString("dimension"));
|
||||
|
||||
DBObject dbObj = (DBObject) JSON.parse(e.getString("data"));
|
||||
Document dbObj = Document.parse(e.getString("data"));
|
||||
dbObj.put("i", GameServer.INSTANCE.getGameUniverse().getNextObjectId());
|
||||
|
||||
GameObject object = GameObject.deserialize(dbObj);
|
||||
|
@ -1,10 +1,10 @@
|
||||
package net.simon987.server.io;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import org.bson.Document;
|
||||
|
||||
public interface CpuHardwareDeserializer {
|
||||
|
||||
|
||||
CpuHardware deserializeHardware(DBObject hwJson);
|
||||
CpuHardware deserializeHardware(Document hwJson);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package net.simon987.server.io;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import org.bson.Document;
|
||||
|
||||
public interface GameObjectDeserializer {
|
||||
|
||||
GameObject deserializeObject(DBObject object);
|
||||
GameObject deserializeObject(Document object);
|
||||
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
package net.simon987.server.io;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
|
||||
public interface MongoSerialisable {
|
||||
|
||||
BasicDBObject mongoSerialise();
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package net.simon987.server.io;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
public interface MongoSerializable {
|
||||
|
||||
Document mongoSerialise();
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package net.simon987.server.user;
|
||||
|
||||
public class RegistrationException extends Exception {
|
||||
|
||||
public RegistrationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +1,33 @@
|
||||
package net.simon987.server.user;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CPU;
|
||||
import net.simon987.server.assembly.exception.CancelledException;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.UserCreationEvent;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import net.simon987.server.io.MongoSerialisable;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Represents a User (or player) of the game
|
||||
*/
|
||||
public class User implements MongoSerialisable {
|
||||
public class User implements MongoSerializable {
|
||||
|
||||
private String username;
|
||||
|
||||
private String userCode;
|
||||
private String password;
|
||||
private String accessToken;
|
||||
|
||||
private CPU cpu;
|
||||
|
||||
private ControllableUnit controlledUnit;
|
||||
|
||||
private boolean guest;
|
||||
private boolean guest = false;
|
||||
private boolean moderator = false;
|
||||
|
||||
private UserStats stats;
|
||||
|
||||
public User() throws CancelledException {
|
||||
GameEvent event = new UserCreationEvent(this);
|
||||
@ -32,7 +36,7 @@ public class User implements MongoSerialisable {
|
||||
throw new CancelledException();
|
||||
}
|
||||
|
||||
|
||||
this.stats = new UserStats();
|
||||
}
|
||||
|
||||
public User(ControllableUnit unit) {
|
||||
@ -40,33 +44,38 @@ public class User implements MongoSerialisable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicDBObject mongoSerialise() {
|
||||
public Document mongoSerialise() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
Document dbObject = new Document();
|
||||
|
||||
dbObject.put("_id", username); // a constant id ensures only one entry per user is kept and updated, instead of a new entry created every save for every user.
|
||||
dbObject.put("username", username);
|
||||
dbObject.put("code", userCode);
|
||||
dbObject.put("controlledUnit", controlledUnit.getObjectId());
|
||||
dbObject.put("cpu", cpu.mongoSerialise());
|
||||
dbObject.put("password", password);
|
||||
dbObject.put("moderator", moderator);
|
||||
dbObject.put("stats", stats.mongoSerialise());
|
||||
|
||||
return dbObject;
|
||||
|
||||
}
|
||||
|
||||
public static User deserialize(DBObject obj) throws CancelledException {
|
||||
public static User deserialize(Document obj) throws CancelledException {
|
||||
|
||||
User user = new User((ControllableUnit) GameServer.INSTANCE.getGameUniverse().getObject((long) obj.get("controlledUnit")));
|
||||
user.username = (String) obj.get("username");
|
||||
user.userCode = (String) obj.get("code");
|
||||
user.password = (String) obj.get("password");
|
||||
user.moderator = (boolean) obj.get("moderator");
|
||||
user.stats = new UserStats((Document) obj.get("stats"));
|
||||
|
||||
user.getControlledUnit().setParent(user);
|
||||
|
||||
user.cpu = CPU.deserialize((DBObject) obj.get("cpu"), user);
|
||||
user.cpu = CPU.deserialize((Document) obj.get("cpu"), user);
|
||||
|
||||
return user;
|
||||
}
|
||||
//----
|
||||
|
||||
public String getUserCode() {
|
||||
return userCode;
|
||||
@ -107,4 +116,28 @@ public class User implements MongoSerialisable {
|
||||
public void setGuest(boolean guest) {
|
||||
this.guest = guest;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public boolean isModerator() {
|
||||
return moderator;
|
||||
}
|
||||
|
||||
public void setModerator(boolean moderator) {
|
||||
this.moderator = moderator;
|
||||
}
|
||||
|
||||
public UserStats getStats() {
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
161
Server/src/main/java/net/simon987/server/user/UserManager.java
Normal file
161
Server/src/main/java/net/simon987/server/user/UserManager.java
Normal file
@ -0,0 +1,161 @@
|
||||
package net.simon987.server.user;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.exception.CancelledException;
|
||||
import net.simon987.server.crypto.RandomStringGenerator;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
import org.springframework.security.crypto.bcrypt.BCrypt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UserManager {
|
||||
|
||||
private MongoCollection<Document> userCollection;
|
||||
|
||||
public UserManager(MongoCollection<Document> userCollection) {
|
||||
|
||||
this.userCollection = userCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and deserialise all users from mongo
|
||||
*
|
||||
* @return list of de-serialized users
|
||||
*/
|
||||
public ArrayList<User> getUsers() {
|
||||
|
||||
ArrayList<User> userList = new ArrayList<>();
|
||||
|
||||
MongoCursor<Document> cursor = userCollection.find().iterator();
|
||||
while (cursor.hasNext()) {
|
||||
try {
|
||||
userList.add(User.deserialize(cursor.next()));
|
||||
} catch (CancelledException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return userList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an user and initialises its controlled unit
|
||||
* @param username username
|
||||
* @param password plain password
|
||||
* @throws RegistrationException is username/password length is invalid
|
||||
*/
|
||||
public void registerUser(String username, String password) throws RegistrationException {
|
||||
|
||||
if (username.length() < 5 || username.length() > 20) {
|
||||
throw new RegistrationException("Username must be 5-20 characters");
|
||||
}
|
||||
if (password.length() < 8 || password.length() > 96) {
|
||||
throw new RegistrationException("Password must be 8-96 characters");
|
||||
}
|
||||
|
||||
//Check if exists
|
||||
Document where = new Document();
|
||||
where.put("_id", username);
|
||||
|
||||
if (userCollection.find(where).first() != null) {
|
||||
throw new RegistrationException("Username is already in use");
|
||||
}
|
||||
|
||||
try {
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getOrCreateUser(username, true);
|
||||
user.setUsername(username);
|
||||
|
||||
String salt = BCrypt.gensalt();
|
||||
String hashedPassword = BCrypt.hashpw(password, salt);
|
||||
user.setPassword(hashedPassword);
|
||||
|
||||
Document dbUser = user.mongoSerialise();
|
||||
|
||||
userCollection.insertOne(dbUser);
|
||||
} catch (Exception e) {
|
||||
throw new RegistrationException("An exception occurred while trying to create user: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a username/password combo
|
||||
* @param username username
|
||||
* @param password plain password
|
||||
* @return true if combo is valid
|
||||
*/
|
||||
public boolean validateUser(String username, String password) {
|
||||
|
||||
Document where = new Document();
|
||||
where.put("_id", username);
|
||||
|
||||
Document user = userCollection.find(where).first();
|
||||
return user != null && BCrypt.checkpw(password, (String) user.get("password"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the password of an user and immediately save it
|
||||
* @param username Username
|
||||
* @param newPassword New plain password
|
||||
* @throws RegistrationException When password length is invalid
|
||||
*/
|
||||
public void changePassword(String username, String newPassword) throws RegistrationException {
|
||||
|
||||
if (newPassword.length() < 8 || newPassword.length() > 96) {
|
||||
throw new RegistrationException("Password must be 8-96 characters");
|
||||
}
|
||||
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getUser(username);
|
||||
|
||||
String salt = BCrypt.gensalt();
|
||||
String hashedPassword = BCrypt.hashpw(newPassword, salt);
|
||||
user.setPassword(hashedPassword);
|
||||
|
||||
userCollection.replaceOne(new Document("_id", username), user.mongoSerialise()); //Save new password immediately
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and save a access token for websocket auth
|
||||
*
|
||||
* @param username Username
|
||||
* @return The generated token
|
||||
*/
|
||||
public String generateAndGetToken(String username) {
|
||||
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getUser(username);
|
||||
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RandomStringGenerator generator = new RandomStringGenerator(128);
|
||||
String token = generator.nextString();
|
||||
|
||||
user.setAccessToken(token); //Token is not saved in DB, and is erased when used
|
||||
|
||||
LogManager.LOGGER.fine("(Web) Generated access token for " + username);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an access token sent by the client
|
||||
* @param token 128-char accesss token
|
||||
* @return username of the corresponding user, null if not found
|
||||
*/
|
||||
public User validateAuthToken(String token) {
|
||||
|
||||
for (User user : GameServer.INSTANCE.getGameUniverse().getUsers()) {
|
||||
|
||||
if (user.getAccessToken() != null && user.getAccessToken().equals(token)) {
|
||||
user.setAccessToken(""); //Token is erased when used
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
102
Server/src/main/java/net/simon987/server/user/UserStats.java
Normal file
102
Server/src/main/java/net/simon987/server/user/UserStats.java
Normal file
@ -0,0 +1,102 @@
|
||||
package net.simon987.server.user;
|
||||
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UserStats implements MongoSerializable {
|
||||
|
||||
private Document stats;
|
||||
|
||||
UserStats() {
|
||||
this.stats = new Document();
|
||||
}
|
||||
|
||||
UserStats(Document stats) {
|
||||
if (stats != null) {
|
||||
this.stats = stats;
|
||||
} else {
|
||||
this.stats = new Document();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document mongoSerialise() {
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a stat n times
|
||||
*
|
||||
* @param name Name of the stat to increment
|
||||
* @param count Number of time to increment
|
||||
*/
|
||||
public void incrementStat(String name, int count) {
|
||||
|
||||
stats.putIfAbsent(name, 0);
|
||||
stats.put(name, stats.getInteger(name) + count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a stat
|
||||
*
|
||||
* @param name Name of the stat
|
||||
* @param value new value
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
|
||||
stats.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of at stat
|
||||
*
|
||||
* @param name Name of the value
|
||||
* @return The value of the stat. Returns 0 if not found
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return stats.getInteger(name, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an string item to a set
|
||||
*
|
||||
* @param name Name of the stat
|
||||
* @param value Value to add to the set
|
||||
*/
|
||||
public void addToStringSet(String name, String value) {
|
||||
|
||||
stats.putIfAbsent(name, new ArrayList<>());
|
||||
|
||||
try {
|
||||
((ArrayList<String>) stats.get(name)).add(value);
|
||||
} catch (ClassCastException e) {
|
||||
LogManager.LOGGER.severe("UserStats: cannot add to list because stat already exists and is not a list");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from a set
|
||||
*
|
||||
* @param name Name of the stat
|
||||
* @param value Value to remove from the set
|
||||
* @return true if the list contained the item
|
||||
*/
|
||||
public boolean removeFromSet(String name, String value) {
|
||||
|
||||
if (stats.putIfAbsent(name, new ArrayList()) != null) {
|
||||
return ((ArrayList) stats.get(name)).remove(value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ArrayList getSet(String name) {
|
||||
stats.putIfAbsent(name, new ArrayList());
|
||||
|
||||
return (ArrayList) stats.get(name);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package net.simon987.server.user;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import net.simon987.server.GameServer;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Retrieve user stats in a structured fashion
|
||||
*/
|
||||
public class UserStatsHelper {
|
||||
|
||||
/**
|
||||
* Database collection of users
|
||||
*/
|
||||
private MongoCollection<Document> users;
|
||||
|
||||
/**
|
||||
* @param users Database collection of users
|
||||
*/
|
||||
public UserStatsHelper(MongoCollection<Document> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top n players along with their stat value, in descending order
|
||||
*
|
||||
* @param statName Name of the stat
|
||||
* @param n Maximum number of players
|
||||
* @return Top n players, in User,value format, in descending order
|
||||
*/
|
||||
public ArrayList<Map.Entry<User, Integer>> getTopN(String statName, int n) {
|
||||
|
||||
ArrayList<Map.Entry<User, Integer>> rows = new ArrayList<>();
|
||||
|
||||
Document orderBy = new Document("$stats." + statName, -1);
|
||||
MongoCursor<Document> cursor = users.find().sort(orderBy).limit(n).iterator();
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
Document dbUser = cursor.next();
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getUser((String) dbUser.get("username"));
|
||||
rows.add(new AbstractMap.SimpleEntry<>(user, user.getStats().getInt(statName)));
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top n players along with the stat set, in descending order
|
||||
*
|
||||
* @param statName Name of the stat
|
||||
* @param n Maximum number of players
|
||||
* @return Top n players, in User,set format, in descending order
|
||||
*/
|
||||
public ArrayList<Map.Entry<User, ArrayList>> getTopNSetLength(String statName, int n) {
|
||||
|
||||
ArrayList<Map.Entry<User, ArrayList>> rows = new ArrayList<>();
|
||||
|
||||
List<Object> ifNullList = new ArrayList<>(2);
|
||||
ifNullList.add("$stats." + statName);
|
||||
ifNullList.add(new ArrayList());
|
||||
|
||||
Document project = new Document();
|
||||
project.put("setLength", new Document("$size", new Document("$ifNull", ifNullList)));
|
||||
project.put("username", 1);
|
||||
|
||||
|
||||
Iterator<Document> results = users.aggregate(Arrays.asList(
|
||||
new Document("$project", project),
|
||||
new Document("$sort", new Document("setLength", -1)),
|
||||
new Document("$limit", n))
|
||||
).iterator();
|
||||
|
||||
while (results.hasNext()) {
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getUser((String) results.next().get("username"));
|
||||
rows.add(new AbstractMap.SimpleEntry<>(user, user.getStats().getSet(statName)));
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.TemplateViewRoute;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountPage implements TemplateViewRoute {
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
model.put("session", request.session());
|
||||
|
||||
|
||||
if (request.session().attribute("username") != null) {
|
||||
model.put("user", GameServer.INSTANCE.getGameUniverse().getUser(request.session().attribute("username")));
|
||||
}
|
||||
|
||||
return new ModelAndView(model, "account.vm");
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
public class AlertMessage {
|
||||
|
||||
private String message;
|
||||
private AlertType type;
|
||||
|
||||
public AlertMessage(String message, AlertType type) {
|
||||
this.message = message;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public AlertType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
23
Server/src/main/java/net/simon987/server/web/AlertType.java
Normal file
23
Server/src/main/java/net/simon987/server/web/AlertType.java
Normal file
@ -0,0 +1,23 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
public enum AlertType {
|
||||
|
||||
SUCCESS("alert-success"),
|
||||
INFO("alert-info"),
|
||||
WARNING("alert-info"),
|
||||
DANGER("alert-danger"),
|
||||
PRIMARY("alert-primary"),
|
||||
SECONDARY("alert-secondary"),
|
||||
DARK("alert-dark");
|
||||
|
||||
public String name;
|
||||
|
||||
AlertType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.user.RegistrationException;
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
public class ChangePasswordRoute implements Route {
|
||||
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
String username = request.session().attribute("username");
|
||||
String currentPassword = request.queryParams("password");
|
||||
String newPassword = request.queryParams("new_password");
|
||||
String newPasswordRepeat = request.queryParams("new_password_repeat");
|
||||
|
||||
if (newPassword.equals(newPasswordRepeat)) {
|
||||
|
||||
if (username != null && GameServer.INSTANCE.getUserManager().validateUser(username, currentPassword)) {
|
||||
|
||||
try {
|
||||
GameServer.INSTANCE.getUserManager().changePassword(username, newPassword);
|
||||
AlertMessage[] messages = {new AlertMessage("Changed password", AlertType.SUCCESS)};
|
||||
request.session().attribute("messages", messages);
|
||||
} catch (RegistrationException e) {
|
||||
AlertMessage[] messages = {new AlertMessage(e.getMessage(), AlertType.DANGER)};
|
||||
request.session().attribute("messages", messages);
|
||||
}
|
||||
|
||||
} else {
|
||||
AlertMessage[] messages = {new AlertMessage("Invalid password", AlertType.DANGER)};
|
||||
request.session().attribute("messages", messages);
|
||||
}
|
||||
} else {
|
||||
AlertMessage[] messages = {new AlertMessage("Passwords did not match", AlertType.DANGER)};
|
||||
request.session().attribute("messages", messages);
|
||||
}
|
||||
|
||||
response.redirect("/account");
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
public class FloppyDownloadRoute implements Route {
|
||||
|
||||
@Override
|
||||
public Object handle(Request request, Response response) {
|
||||
|
||||
String username = request.session().attribute("username");
|
||||
|
||||
if (username != null) {
|
||||
|
||||
response.header("Content-Type", "application/octet-stream");
|
||||
response.header("Content-Disposition", "filename=\"floppy.bin\"");
|
||||
|
||||
try {
|
||||
return GameServer.INSTANCE.getGameUniverse().getUser(username).getControlledUnit().getFloppyData().getBytes();
|
||||
} catch (Exception e) {
|
||||
String message = "Encountered exception while reading floppy data: " + e.getMessage();
|
||||
|
||||
LogManager.LOGGER.severe(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
} else {
|
||||
response.status(403);
|
||||
return "Not logged in";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FloppyUploadRoute implements Route {
|
||||
|
||||
@Override
|
||||
public Object handle(Request request, Response response) {
|
||||
|
||||
String username = request.session().attribute("username");
|
||||
|
||||
if (username != null) {
|
||||
try {
|
||||
request.attribute("org.eclipse.jetty.multipartConfig",
|
||||
new MultipartConfigElement("/tmp_floppy", 1474560L, -1L, 0));
|
||||
|
||||
try (InputStream is = request.raw().getPart("floppyData").getInputStream()) {
|
||||
|
||||
if (is.available() == 1474560) {
|
||||
|
||||
byte[] bytes = new byte[1474560];
|
||||
int bytesRead = is.read(bytes);
|
||||
|
||||
if (bytesRead == 1474560) {
|
||||
|
||||
try {
|
||||
GameServer.INSTANCE.getGameUniverse().getUser(username).getControlledUnit().getFloppyData().setBytes(bytes);
|
||||
return "ok";
|
||||
} catch (Exception e) {
|
||||
String message = "Encountered exception while writing floppy data: " + e.getMessage();
|
||||
|
||||
LogManager.LOGGER.severe(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
} else {
|
||||
return "Couldn't read floppy file";
|
||||
}
|
||||
|
||||
} else {
|
||||
return "File size must be 1474560 bytes";
|
||||
}
|
||||
|
||||
} catch (IOException | ServletException e) {
|
||||
e.printStackTrace();
|
||||
return "Error reading floppy file: " + e.getMessage();
|
||||
}
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
return "File exceeds maximum size";
|
||||
}
|
||||
} else {
|
||||
response.status(403);
|
||||
return "Not logged in";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
21
Server/src/main/java/net/simon987/server/web/HomePage.java
Normal file
21
Server/src/main/java/net/simon987/server/web/HomePage.java
Normal file
@ -0,0 +1,21 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.TemplateViewRoute;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HomePage implements TemplateViewRoute {
|
||||
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) throws Exception {
|
||||
|
||||
Map<String, Object> model = new HashMap<>(1);
|
||||
model.put("session", request.session());
|
||||
|
||||
return new ModelAndView(model, "home.vm");
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.TemplateViewRoute;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LeaderBoardPage implements TemplateViewRoute {
|
||||
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
Map<String, Object> model = new HashMap<>(2);
|
||||
model.put("session", request.session());
|
||||
model.put("stats", GameServer.INSTANCE.getUserStatsHelper().getTopNSetLength("completedVaults", 25));
|
||||
return new ModelAndView(model, "leaderboard.vm");
|
||||
}
|
||||
}
|
32
Server/src/main/java/net/simon987/server/web/LoginRoute.java
Normal file
32
Server/src/main/java/net/simon987/server/web/LoginRoute.java
Normal file
@ -0,0 +1,32 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
public class LoginRoute implements Route {
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
String username = request.queryParams("username");
|
||||
String password = request.queryParams("password");
|
||||
|
||||
if (username != null && password != null) {
|
||||
if (GameServer.INSTANCE.getUserManager().validateUser(username, password)) {
|
||||
AlertMessage[] messages = {new AlertMessage("Logged in as " + username, AlertType.SUCCESS)};
|
||||
request.session().attribute("messages", messages);
|
||||
request.session().attribute("username", username);
|
||||
|
||||
LogManager.LOGGER.fine("(Web) " + username + " logged in");
|
||||
} else {
|
||||
AlertMessage[] messages = {new AlertMessage("Invalid username or password", AlertType.DANGER)};
|
||||
request.session().attribute("messages", messages);
|
||||
}
|
||||
}
|
||||
|
||||
response.redirect("/account");
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
public class LogoutRoute implements Route {
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
AlertMessage[] messages = {new AlertMessage("Logged out", AlertType.INFO)};
|
||||
request.session().attribute("messages", messages);
|
||||
request.session().removeAttribute("username");
|
||||
|
||||
response.redirect("/account");
|
||||
return null;
|
||||
}
|
||||
}
|
20
Server/src/main/java/net/simon987/server/web/PlayPage.java
Normal file
20
Server/src/main/java/net/simon987/server/web/PlayPage.java
Normal file
@ -0,0 +1,20 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.TemplateViewRoute;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayPage implements TemplateViewRoute {
|
||||
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
Map<String, Object> model = new HashMap<>(1);
|
||||
model.put("session", request.session());
|
||||
|
||||
return new ModelAndView(model, "play.vm");
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.RegistrationException;
|
||||
import spark.ModelAndView;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
public class RegisterRoute implements Route {
|
||||
|
||||
@Override
|
||||
public ModelAndView handle(Request request, Response response) {
|
||||
String username = request.queryParams("username");
|
||||
String password = request.queryParams("password");
|
||||
|
||||
if (username != null && password != null) {
|
||||
try {
|
||||
GameServer.INSTANCE.getUserManager().registerUser(username, password);
|
||||
|
||||
AlertMessage[] messages = {new AlertMessage("Successfully registered", AlertType.SUCCESS)};
|
||||
request.session().attribute("messages", messages);
|
||||
request.session().attribute("username", username);
|
||||
|
||||
LogManager.LOGGER.fine("(Web) " + username + " registered " + request.ip());
|
||||
} catch (RegistrationException e) {
|
||||
AlertMessage[] messages = {new AlertMessage(e.getMessage(), AlertType.DANGER)};
|
||||
request.session().attribute("messages", messages);
|
||||
}
|
||||
}
|
||||
|
||||
response.redirect("/account");
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import org.json.simple.JSONObject;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
public class ServerInfoRoute implements Route {
|
||||
|
||||
private String address;
|
||||
private String serverName;
|
||||
private int tickLength;
|
||||
|
||||
public ServerInfoRoute() {
|
||||
|
||||
//Info variables that don't change
|
||||
|
||||
if (GameServer.INSTANCE.getConfig().getInt("use_ssl") == 0) {
|
||||
address = "ws://" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_address") + ":" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_port") + "/socket";
|
||||
} else {
|
||||
address = "wss://" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_address") + ":" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_port") + "/socket";
|
||||
}
|
||||
|
||||
serverName = GameServer.INSTANCE.getConfig().getString("server_name");
|
||||
tickLength = GameServer.INSTANCE.getConfig().getInt("tick_length");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(Request request, Response response) {
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
String username = request.session().attribute("username");
|
||||
|
||||
if (username != null) {
|
||||
String token = GameServer.INSTANCE.getUserManager().generateAndGetToken(username);
|
||||
|
||||
json.put("token", token);
|
||||
json.put("username", username);
|
||||
|
||||
} else {
|
||||
|
||||
json.put("token",
|
||||
"00000000000000000000000000000000" +
|
||||
"00000000000000000000000000000000" +
|
||||
"00000000000000000000000000000000" +
|
||||
"00000000000000000000000000000000");
|
||||
json.put("username", "guest");
|
||||
}
|
||||
|
||||
json.put("address", address);
|
||||
json.put("serverName", serverName);
|
||||
json.put("tickLength", tickLength);
|
||||
|
||||
response.header("Content-Type", "application/json");
|
||||
|
||||
return json.toJSONString();
|
||||
}
|
||||
}
|
63
Server/src/main/java/net/simon987/server/web/WebServer.java
Normal file
63
Server/src/main/java/net/simon987/server/web/WebServer.java
Normal file
@ -0,0 +1,63 @@
|
||||
package net.simon987.server.web;
|
||||
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.websocket.SocketServer;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import spark.Spark;
|
||||
import spark.template.velocity.VelocityTemplateEngine;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class WebServer {
|
||||
|
||||
private SocketServer socketServer;
|
||||
|
||||
public WebServer(ServerConfiguration config) {
|
||||
|
||||
//Velocity config
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("file.resource.loader.path", "templates/");
|
||||
VelocityTemplateEngine templateEngine = new VelocityTemplateEngine(new VelocityEngine(properties));
|
||||
Spark.staticFiles.externalLocation("static");
|
||||
|
||||
//Spark config
|
||||
if (config.getInt("use_ssl") != 0) {
|
||||
|
||||
/*
|
||||
* Generate keystore from Let's Encrypt with command:
|
||||
* openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.jks -name muchassemblyrequired -CAfile chain.pem -caname root -password file:password.txt
|
||||
*
|
||||
* Certificates generated from Let's Encrypt are usually in /etc/letsencrypt/live/www.site.com
|
||||
*/
|
||||
|
||||
Spark.secure(
|
||||
config.getString("keyStore_path"),
|
||||
config.getString("keyStore_password"), null, null);
|
||||
LogManager.LOGGER.info("(Web) Enabled ssl");
|
||||
}
|
||||
|
||||
|
||||
socketServer = new SocketServer();
|
||||
Spark.webSocket("/socket", socketServer);
|
||||
|
||||
Spark.get("/", new HomePage(), templateEngine);
|
||||
Spark.get("/leaderboard", new LeaderBoardPage(), templateEngine);
|
||||
Spark.get("/play", new PlayPage(), templateEngine);
|
||||
Spark.get("/account", new AccountPage(), templateEngine);
|
||||
|
||||
Spark.post("/register", new RegisterRoute());
|
||||
Spark.post("/login", new LoginRoute());
|
||||
Spark.get("/logout", new LogoutRoute());
|
||||
Spark.post("/change_password", new ChangePasswordRoute());
|
||||
Spark.get("/server_info", new ServerInfoRoute());
|
||||
Spark.post("/floppy_upload", new FloppyUploadRoute());
|
||||
Spark.get("/floppy_download", new FloppyDownloadRoute());
|
||||
|
||||
Spark.after((request, response) -> response.header("Content-Encoding", "gzip"));
|
||||
}
|
||||
|
||||
public SocketServer getSocketServer() {
|
||||
return socketServer;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package net.simon987.server.webserver;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class FloppyHandler implements MessageHandler {
|
||||
|
||||
SocketServerDatabase db = new SocketServerDatabase(GameServer.INSTANCE.getConfig());
|
||||
|
||||
@Override
|
||||
public void handle(OnlineUser user, JSONObject json) {
|
||||
|
||||
if (json.get("t").equals("floppyDown")) {
|
||||
|
||||
LogManager.LOGGER.fine("(WS) Floppy download request from " + user.getUser().getUsername());
|
||||
|
||||
if (user.isGuest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.getUser().getControlledUnit().getFloppyData() != null) {
|
||||
byte[] bytes = user.getUser().getControlledUnit().getFloppyData().getBytes();
|
||||
user.getWebSocket().send(bytes);
|
||||
}
|
||||
|
||||
|
||||
} else if (json.get("t").equals("floppyUp")) {
|
||||
|
||||
LogManager.LOGGER.fine("(WS) Floppy upload request from " + user.getUser().getUsername());
|
||||
|
||||
//Check newly uploaded file on the database
|
||||
byte[] bytes = db.getFloppy(user.getUser().getUsername());
|
||||
|
||||
if (bytes != null) {
|
||||
user.getUser().getControlledUnit().getFloppyData().setBytes(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package net.simon987.server.webserver;
|
||||
|
||||
import org.java_websocket.exceptions.WebsocketNotConnectedException;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public interface MessageHandler {
|
||||
|
||||
void handle(OnlineUser user, JSONObject json) throws WebsocketNotConnectedException;
|
||||
|
||||
}
|
@ -1,323 +0,0 @@
|
||||
package net.simon987.server.webserver;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.User;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.DefaultSSLWebSocketServerFactory;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.BindException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class SocketServer extends WebSocketServer {
|
||||
|
||||
private OnlineUserManager userManager = new OnlineUserManager();
|
||||
|
||||
private SocketServerDatabase database;
|
||||
|
||||
private MessageDispatcher messageDispatcher = new MessageDispatcher();
|
||||
|
||||
public SocketServer(InetSocketAddress address, ServerConfiguration config) {
|
||||
super(address);
|
||||
|
||||
if (config.getInt("use_secure_webSocket") != 0) {
|
||||
|
||||
SSLContext context = getContext(config.getString("cert_path"));
|
||||
if (context != null) {
|
||||
setWebSocketFactory(new DefaultSSLWebSocketServerFactory(context));
|
||||
|
||||
LogManager.LOGGER.info("(WS) Enabled secure webSocket");
|
||||
} else {
|
||||
LogManager.LOGGER.severe("(WS) Failed to create SSL context");
|
||||
}
|
||||
}
|
||||
|
||||
setConnectionLostTimeout(120);
|
||||
setReuseAddr(true); //To avoid BindException
|
||||
|
||||
database = new SocketServerDatabase(config);
|
||||
|
||||
messageDispatcher.addHandler(new UserInfoRequestHandler());
|
||||
messageDispatcher.addHandler(new TerrainRequestHandler());
|
||||
messageDispatcher.addHandler(new ObjectsRequestHandler());
|
||||
messageDispatcher.addHandler(new CodeUploadHandler());
|
||||
messageDispatcher.addHandler(new CodeRequestHandler());
|
||||
messageDispatcher.addHandler(new KeypressHandler());
|
||||
messageDispatcher.addHandler(new FloppyHandler());
|
||||
messageDispatcher.addHandler(new DebugCommandHandler());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket conn, ClientHandshake handshake) {
|
||||
LogManager.LOGGER.info("(WS) New Websocket connection " + conn.getRemoteSocketAddress());
|
||||
userManager.add(new OnlineUser(conn));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
|
||||
LogManager.LOGGER.info("(WS) Closed " + conn.getRemoteSocketAddress() + " with exit code " + code + " additional info: " + reason);
|
||||
userManager.remove(userManager.getUser(conn));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket conn, String message) {
|
||||
OnlineUser onlineUser = userManager.getUser(conn);
|
||||
|
||||
if (onlineUser != null) {
|
||||
|
||||
if (onlineUser.isAuthenticated()) {
|
||||
|
||||
messageDispatcher.dispatch(onlineUser, message);
|
||||
|
||||
} else {
|
||||
LogManager.LOGGER.info("(WS) Received message from unauthenticated user " + conn.getRemoteSocketAddress());
|
||||
|
||||
//We expect a 128 characters long token
|
||||
if (message.length() == 128) {
|
||||
|
||||
String username = database.validateAuthToken(message);
|
||||
|
||||
if (username != null) {
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getOrCreateUser(username, true);
|
||||
|
||||
onlineUser.setModerator(database.isModerator(username));
|
||||
|
||||
LogManager.LOGGER.info("(WS) User was successfully authenticated: " + user.getUsername() +
|
||||
" moderator: " + onlineUser.isModerator());
|
||||
|
||||
onlineUser.setUser(user);
|
||||
onlineUser.setAuthenticated(true);
|
||||
|
||||
conn.send("{\"t\":\"auth\", \"m\":\"ok\"}");
|
||||
|
||||
} else {
|
||||
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getOrCreateUser(GameServer.INSTANCE.getGameUniverse().getGuestUsername(), false);
|
||||
onlineUser.setUser(user);
|
||||
onlineUser.setAuthenticated(true);
|
||||
onlineUser.setGuest(true);
|
||||
|
||||
LogManager.LOGGER.info("(WS) Created guest user " +
|
||||
onlineUser.getUser().getUsername() + conn.getRemoteSocketAddress());
|
||||
|
||||
conn.send("{\"t\":\"auth\", \"m\":\"ok\"}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
LogManager.LOGGER.severe("(WS) FIXME: SocketServer:onMessage");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket conn, ByteBuffer message) {
|
||||
//System.out.println("received ByteBuffer from " + conn.getRemoteSocketAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket conn, Exception ex) {
|
||||
|
||||
if (ex instanceof BindException) {
|
||||
|
||||
LogManager.LOGGER.severe("Address already in use");
|
||||
System.exit(-1);
|
||||
|
||||
} else {
|
||||
LogManager.LOGGER.severe("an error occurred on connection " + conn + ": " + ex);
|
||||
userManager.remove(userManager.getUser(conn));
|
||||
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
LogManager.LOGGER.info("(WS) Server started successfully");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick
|
||||
*/
|
||||
public void tick() {
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("t", "tick");
|
||||
|
||||
// LogManager.LOGGER.info("Notified " + userManager.getOnlineUsers().size() + " users");
|
||||
|
||||
ArrayList<OnlineUser> onlineUsers = new ArrayList<>(userManager.getOnlineUsers()); //Avoid ConcurrentModificationException
|
||||
for (OnlineUser user : onlineUsers) {
|
||||
|
||||
if (user.getWebSocket().isOpen()) {
|
||||
|
||||
if (user.isGuest()) {
|
||||
|
||||
json.remove("c");
|
||||
user.getWebSocket().send(json.toJSONString());
|
||||
|
||||
} else {
|
||||
try {
|
||||
ControllableUnit unit = user.getUser().getControlledUnit();
|
||||
|
||||
//Send keyboard updated buffer
|
||||
ArrayList<Integer> kbBuffer = unit.getKeyboardBuffer();
|
||||
JSONArray keys = new JSONArray();
|
||||
keys.addAll(kbBuffer);
|
||||
json.put("keys", keys);
|
||||
|
||||
//Send console buffer
|
||||
if (unit.getConsoleMessagesBuffer().size() > 0) {
|
||||
|
||||
JSONArray buff = new JSONArray();
|
||||
|
||||
for (char[] message : unit.getConsoleMessagesBuffer()) {
|
||||
buff.add(new String(message));
|
||||
}
|
||||
|
||||
json.put("c", buff);
|
||||
} else {
|
||||
json.remove("c");
|
||||
}
|
||||
|
||||
json.put("cm", unit.getConsoleMode());
|
||||
|
||||
|
||||
//Send tick message
|
||||
user.getWebSocket().send(json.toJSONString());
|
||||
} catch (NullPointerException e) {
|
||||
//User is online but not completely initialised
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public OnlineUserManager getUserManager() {
|
||||
return userManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See https://github.com/TooTallNate/Java-WebSocket/blob/master/src/main/example/SSLServerLetsEncryptExample.java
|
||||
*/
|
||||
/*
|
||||
* * Copyright (c) 2010-2017 Nathan Rajlich
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*/
|
||||
private static SSLContext getContext(String pathTo) {
|
||||
SSLContext context;
|
||||
String password = "MAR";
|
||||
try {
|
||||
context = SSLContext.getInstance("TLS");
|
||||
|
||||
byte[] certBytes = parseDERFromPEM(getBytes(new File(pathTo + File.separator + "cert.pem")),
|
||||
"-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----");
|
||||
byte[] keyBytes = parseDERFromPEM(getBytes(new File(pathTo + File.separator + "privkey.pem")),
|
||||
"-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----");
|
||||
|
||||
X509Certificate cert = generateCertificateFromDER(certBytes);
|
||||
RSAPrivateKey key = generatePrivateKeyFromDER(keyBytes);
|
||||
|
||||
KeyStore keystore = KeyStore.getInstance("JKS");
|
||||
keystore.load(null);
|
||||
keystore.setCertificateEntry("cert-alias", cert);
|
||||
keystore.setKeyEntry("key-alias", key, password.toCharArray(), new Certificate[]{cert});
|
||||
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(keystore, password.toCharArray());
|
||||
|
||||
KeyManager[] km = kmf.getKeyManagers();
|
||||
|
||||
context.init(km, null, null);
|
||||
} catch (Exception e) {
|
||||
context = null;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) {
|
||||
String data = new String(pem);
|
||||
String[] tokens = data.split(beginDelimiter);
|
||||
tokens = tokens[1].split(endDelimiter);
|
||||
return DatatypeConverter.parseBase64Binary(tokens[0]);
|
||||
}
|
||||
|
||||
private static RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
|
||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
|
||||
KeyFactory factory = KeyFactory.getInstance("RSA");
|
||||
|
||||
return (RSAPrivateKey) factory.generatePrivate(spec);
|
||||
}
|
||||
|
||||
private static X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException {
|
||||
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||
|
||||
return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes));
|
||||
}
|
||||
|
||||
private static byte[] getBytes(File file) {
|
||||
byte[] bytesArray = new byte[(int) file.length()];
|
||||
|
||||
FileInputStream fis;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
fis.read(bytesArray); //read file into bytes[]
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bytesArray;
|
||||
}
|
||||
}
|
@ -1,24 +1,26 @@
|
||||
package net.simon987.server.webserver;
|
||||
package net.simon987.server.websocket;
|
||||
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CodeRequestHandler implements MessageHandler {
|
||||
@Override
|
||||
public void handle(OnlineUser user, JSONObject json) {
|
||||
public void handle(OnlineUser user, JSONObject json) throws IOException {
|
||||
|
||||
if (json.get("t").equals("codeRequest")) {
|
||||
|
||||
LogManager.LOGGER.fine("(WS) Code request from " + user.getUser().getUsername());
|
||||
|
||||
if (user.isGuest()) {
|
||||
if (user.getUser().isGuest()) {
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
|
||||
response.put("t", "code");
|
||||
response.put("code", "; Create a free account to control your own Cubot with assembly language!"); //todo load from config
|
||||
|
||||
user.getWebSocket().send(response.toJSONString());
|
||||
user.getWebSocket().getRemote().sendString(response.toJSONString());
|
||||
|
||||
} else {
|
||||
|
||||
@ -27,7 +29,7 @@ public class CodeRequestHandler implements MessageHandler {
|
||||
response.put("t", "code");
|
||||
response.put("code", user.getUser().getUserCode());
|
||||
|
||||
user.getWebSocket().send(response.toJSONString());
|
||||
user.getWebSocket().getRemote().sendString(response.toJSONString());
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user