Debug commands are easier to add. Added comPortMsg command

This commit is contained in:
simon 2018-03-10 11:24:29 -05:00
parent dc19176dc8
commit 9cac665101
16 changed files with 518 additions and 312 deletions

View File

@ -3,8 +3,10 @@ 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.json.simple.JSONObject;
@ -25,6 +27,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
* Hit points
*/
private int hp;
private int maxHp;
private int shield;
private int maxShield;
private int heldItem;
@ -157,12 +160,15 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
cubot.setX((int) obj.get("x"));
cubot.setY((int) obj.get("y"));
cubot.hp = (int) obj.get("hp");
// cubot.shield = (int) obj.get("shield");
// cubot.maxShield = GameServer.INSTANCE.getConfig().getInt("max_shield");
cubot.shield = (int) obj.get("shield");
cubot.setDirection(Direction.getDirection((int) obj.get("direction")));
cubot.heldItem = (int) obj.get("heldItem");
cubot.energy = (int) obj.get("energy");
cubot.maxEnergy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy");
ServerConfiguration config = GameServer.INSTANCE.getConfig();
cubot.maxEnergy = config.getInt("battery_max_energy");
cubot.maxHp = config.getInt("cubot_max_hp");
cubot.maxShield = config.getInt("cubot_max_shield");
return cubot;
@ -368,41 +374,51 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Pr
@Override
public void setHealRate(int hp) {
//no op
}
@Override
public int getHp() {
return 0;
return hp;
}
@Override
public void setHp(int hp) {
this.hp = hp;
}
@Override
public int getMaxHp() {
return 0;
return maxHp;
}
@Override
public void setMaxHp(int hp) {
this.maxHp = hp;
}
@Override
public void heal(int amount) {
hp += amount;
//Can't heal above max
if (hp > maxHp) {
hp = maxHp;
}
}
@Override
public void damage(int amount) {
hp -= amount;
if (hp <= 0) {
setDead(true);
}
}
@Override
public boolean onDeadCallback() {
LogManager.LOGGER.severe("Cubot death");
return true; //always cancelled
}
}

View File

@ -3,17 +3,18 @@ package net.simon987.server;
import com.mongodb.*;
import net.simon987.server.assembly.exception.CancelledException;
import net.simon987.server.crypto.CryptoProvider;
import net.simon987.server.event.GameEvent;
import net.simon987.server.event.GameEventDispatcher;
import net.simon987.server.event.TickEvent;
import net.simon987.server.game.DayNightCycle;
import net.simon987.server.game.GameUniverse;
import net.simon987.server.game.World;
import net.simon987.server.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.crypto.CryptoProvider;
import java.io.File;
import java.net.UnknownHostException;
@ -79,6 +80,17 @@ public class GameServer implements Runnable {
eventDispatcher = new GameEventDispatcher(pluginManager);
eventDispatcher.getListeners().add(dayNightCycle);
//Debug command Listeners
eventDispatcher.getListeners().add(new ComPortMsgCommandListener());
eventDispatcher.getListeners().add(new CreateWorldCommandListener());
eventDispatcher.getListeners().add(new KillAllCommandListener());
eventDispatcher.getListeners().add(new MoveObjCommandListener());
eventDispatcher.getListeners().add(new ObjInfoCommandListener());
eventDispatcher.getListeners().add(new SetTileAtCommandListener());
eventDispatcher.getListeners().add(new SpawnObjCommandListener());
eventDispatcher.getListeners().add(new TpObjectCommandListener());
eventDispatcher.getListeners().add(new UserInfoCommandListener());
}
public GameUniverse getGameUniverse() {

View File

@ -0,0 +1,43 @@
package net.simon987.server.event;
import net.simon987.server.webserver.OnlineUser;
import org.json.simple.JSONObject;
public class DebugCommandEvent extends GameEvent {
private JSONObject command;
public DebugCommandEvent(JSONObject json, OnlineUser user) {
this.command = json;
this.setSource(user);
}
public String getName() {
return (String) command.get("command");
}
public String getString(String key) {
return (String) command.get(key);
}
public int getInt(String key) {
return (int) (long) command.get(key);
}
public long getLong(String key) {
return (long) command.get(key);
}
/**
* Send back a response to the command issuer
*/
public void reply(String message) {
JSONObject response = new JSONObject();
response.put("t", "debug");
response.put("message", message);
((OnlineUser) getSource()).getWebSocket().send(response.toJSONString());
}
}

View File

@ -0,0 +1,44 @@
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;
import net.simon987.server.game.GameObject;
import net.simon987.server.game.Programmable;
public class ComPortMsgCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("comPortMsg")) {
long objectId = e.getLong("objectId");
GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(objectId);
if (object != null) {
if (object instanceof Programmable) {
e.reply("Result: " + ((Programmable) object).sendMessage(e.getString("message").toCharArray()));
} else {
e.reply("Object " + objectId + " not Programmable");
}
} else {
e.reply("Object " + objectId + " not found");
}
}
}
}

View File

@ -0,0 +1,36 @@
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;
import net.simon987.server.game.World;
public class CreateWorldCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("createWorld")) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
true, e.getString("dimension"));
if (world != null) {
e.reply("Success");
} else {
e.reply("Couldn't create world");
}
}
}
}

View File

@ -0,0 +1,46 @@
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;
import net.simon987.server.game.GameObject;
import net.simon987.server.game.World;
import java.util.ArrayList;
import java.util.Arrays;
public class KillAllCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("killAll")) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
false, e.getString("dimension"));
try {
ArrayList<GameObject> objs = world.getGameObjectsAt(e.getInt("x"), e.getInt("y"));
for (GameObject o : objs) {
o.setDead(true);
}
} catch (Exception ex) {
String message = ex.getMessage();
message += "\n " + Arrays.toString(ex.getStackTrace()).replaceAll(", ", "\n");
e.reply(message);
}
}
}
}

View File

@ -0,0 +1,37 @@
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;
import net.simon987.server.game.GameObject;
public class MoveObjCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("moveObj")) {
GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(e.getLong("objectId"));
if (object != null) {
object.setX(e.getInt("x"));
object.setY(e.getInt("y"));
e.reply("Success");
} else {
e.reply("Object not found: " + e.getLong("objectId"));
}
}
}
}

View File

@ -0,0 +1,54 @@
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;
import net.simon987.server.game.GameObject;
import net.simon987.server.game.World;
import java.util.Arrays;
import java.util.Collection;
public class ObjInfoCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("objInfo")) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
false, e.getString("dimension"));
try {
Collection<GameObject> objs = world.getGameObjects();
String str = objs.size() + "\n";
for (GameObject obj : objs) {
if (obj.isAt(e.getInt("x"), e.getInt("y")) || (obj.getX() == e.getInt("x") &&
obj.getY() == e.getInt("y"))) {
str += "Mongo:" + obj.mongoSerialise() + "\n";
str += "JSON :" + obj.serialise().toJSONString() + "\n\n";
}
}
e.reply(str);
} catch (Exception ex) {
String message = ex.getMessage();
message += "\n " + Arrays.toString(ex.getStackTrace()).replaceAll(", ", "\n");
e.reply(message);
}
}
}
}

View File

@ -0,0 +1,36 @@
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;
import net.simon987.server.game.World;
public class SetTileAtCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("setTileAt")) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
false, e.getString("dimension"));
if (world != null) {
world.getTileMap().setTileAt(e.getInt("newTile"), e.getInt("x"), e.getInt("y"));
e.reply("Success");
} else {
e.reply("Error: World is uncharted");
}
}
}
}

View File

@ -0,0 +1,56 @@
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 java.util.Arrays;
public class SpawnObjCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("spawnObj")) {
try {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
false, e.getString("dimension"));
DBObject dbObj = (DBObject) JSON.parse(e.getString("data"));
dbObj.put("i", GameServer.INSTANCE.getGameUniverse().getNextObjectId());
GameObject object = GameObject.deserialize(dbObj);
if (object != null) {
world.addObject(object);
object.setWorld(world);
object.initialize();
e.reply("Created object " + object.getObjectId());
} else {
e.reply("Couldn't deserialise the object");
}
} catch (Exception ex) {
String message = ex.getMessage();
message += "\n " + Arrays.toString(ex.getStackTrace()).replaceAll(", ", "\n");
e.reply(message);
}
}
}
}

View File

@ -0,0 +1,58 @@
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;
import net.simon987.server.game.GameObject;
import net.simon987.server.game.Updatable;
import net.simon987.server.game.World;
public class TpObjectCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("tpObj")) {
GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(e.getLong("objectId"));
World world = GameServer.INSTANCE.getGameUniverse().getWorld(e.getInt("worldX"), e.getInt("worldY"),
false, e.getString("dimension"));
if (object != null) {
if (world != null) {
if (object instanceof Updatable) {
object.getWorld().decUpdatable();
world.incUpdatable();
}
object.getWorld().removeObject(object);
world.addObject(object);
object.setWorld(world);
object.setX(e.getInt("x"));
object.setY(e.getInt("y"));
e.reply("Success");
} else {
e.reply("World not found");
}
} else {
e.reply("Object not found");
}
}
}
}

View File

@ -0,0 +1,47 @@
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;
import net.simon987.server.game.ControllableUnit;
import net.simon987.server.user.User;
public class UserInfoCommandListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return DebugCommandEvent.class;
}
@Override
public void handle(GameEvent event) {
DebugCommandEvent e = (DebugCommandEvent) event;
if (e.getName().equals("userInfo")) {
User user = GameServer.INSTANCE.getGameUniverse().getUser(e.getString("username"));
if (user != null) {
String message = "Showing information for user " + e.getString("username") + "\n";
message += "isGuest: " + user.isGuest() + "\n";
ControllableUnit unit = user.getControlledUnit();
message += "ControlledUnit: " + unit.getObjectId() + " at (" + unit.getX() + ", " + unit.getY() + ")\n";
message += "CPU:" + user.getCpu() + "\n";
message += "Code: " + user.getUserCode();
e.reply(message);
} else {
e.reply("User not found");
}
}
}
}

View File

@ -0,0 +1,21 @@
package net.simon987.server.webserver;
import net.simon987.server.GameServer;
import net.simon987.server.event.DebugCommandEvent;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.json.simple.JSONObject;
public class DebugCommandHandler implements MessageHandler {
@Override
public void handle(OnlineUser user, JSONObject json) throws WebsocketNotConnectedException {
if (json.get("t").equals("debug") && user.isModerator()) {
DebugCommandEvent e = new DebugCommandEvent(json, user);
GameServer.INSTANCE.getEventDispatcher().dispatch(e);
}
}
}

View File

@ -1,301 +0,0 @@
package net.simon987.server.webserver;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
import net.simon987.server.GameServer;
import net.simon987.server.game.ControllableUnit;
import net.simon987.server.game.GameObject;
import net.simon987.server.game.Updatable;
import net.simon987.server.game.World;
import net.simon987.server.logging.LogManager;
import net.simon987.server.user.User;
import org.json.simple.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class DebugHandler implements MessageHandler {
@Override
public void handle(OnlineUser user, JSONObject json) {
if (json.get("t").equals("debug") && user.isModerator()) {
LogManager.LOGGER.fine("(WS) Debug command from " + user.getUser().getUsername());
String command = (String) json.get("command");
if (json.containsKey("command")) {
JSONObject response = new JSONObject();
response.put("t", "debug");
switch (command) {
case "setTileAt":
response.put("message", setTileAt(
(int) (long) json.get("x"),
(int) (long) json.get("y"),
(int) (long) json.get("newTile"),
(int) (long) json.get("worldX"),
(int) (long) json.get("worldY"),
(String) json.get("dimension")));
break;
case "createWorld":
response.put("message", createWorld(
(int) (long) json.get("worldX"),
(int) (long) json.get("worldY"),
(String) json.get("dimension")));
break;
case "killAll":
response.put("message", killAll(
(int) (long) json.get("x"),
(int) (long) json.get("y"),
(int) (long) json.get("worldX"),
(int) (long) json.get("worldY"),
(String) json.get("dimension")));
break;
case "objInfo":
response.put("message", objInfo(
(int) (long) json.get("x"),
(int) (long) json.get("y"),
(int) (long) json.get("worldX"),
(int) (long) json.get("worldY"),
(String) json.get("dimension")));
break;
case "userInfo":
response.put("message", userInfo((String) json.get("username")));
break;
case "moveObj":
response.put("message", moveObj(
(long) json.get("objectId"),
(int) (long) json.get("x"),
(int) (long) json.get("y")));
break;
case "spawnObj":
response.put("message", spawnObj(
(int) (long) json.get("worldX"),
(int) (long) json.get("worldY"),
(String) json.get("data"),
(String) json.get("dimension")));
break;
case "tpObj":
response.put("message", moveObj(
(long) json.get("objectId"),
(int) (long) json.get("x"),
(int) (long) json.get("y"),
(int) (long) json.get("worldX"),
(int) (long) json.get("worldY"),
(String) json.get("dimension")));
break;
default:
LogManager.LOGGER.severe("Unknown command: " + command);
response.put("message", "Unknown command " + command);
}
user.getWebSocket().send(response.toJSONString());
}
}
}
/**
* Create a world at coordinates
*/
private String createWorld(int worldX, int worldY, String dimension) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(worldX, worldY, true, dimension);
if (world != null) {
return "Success";
} else {
return "Couldn't create world";
}
}
/**
* Change the tile at coordinate
*/
private String setTileAt(int x, int y, int newTile, int worldX, int worldY, String dimension) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(worldX, worldY, false, dimension);
if (world != null) {
world.getTileMap().setTileAt(newTile, x, y);
return "Success";
} else {
return "Error: World is uncharted";
}
}
private String spawnObj(int worldX, int worldY, String data, String dimension) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(worldX, worldY, false, dimension);
try {
DBObject dbObj = (DBObject) JSON.parse(data);
dbObj.put("i", GameServer.INSTANCE.getGameUniverse().getNextObjectId());
GameObject object = GameObject.deserialize(dbObj);
if (object != null) {
world.addObject(object);
object.setWorld(world);
object.initialize();
return "Created object " + object.getObjectId();
} else {
return "Couldn't deserialise the object";
}
} catch (Exception e) {
String message = e.getMessage();
message += "\n " + Arrays.toString(e.getStackTrace()).replaceAll(", ", "\n");
return message;
}
}
private String killAll(int x, int y, int worldX, int worldY, String dimension) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(worldX, worldY, false, dimension);
try {
ArrayList<GameObject> objs = world.getGameObjectsAt(x, y);
for (GameObject o : objs) {
o.setDead(true);
}
return "Killed " + objs.size() + " objects";
} catch (Exception e) {
return Arrays.toString(e.getStackTrace()).replaceAll(", ", "\n");
}
}
private String objInfo(int x, int y, int worldX, int worldY, String dimension) {
World world = GameServer.INSTANCE.getGameUniverse().getWorld(worldX, worldY, false, dimension);
try {
Collection<GameObject> objs = world.getGameObjects();
String str = objs.size() + "\n";
for (GameObject obj : objs) {
if (obj.isAt(x, y) || (obj.getX() == x && obj.getY() == y)) {
str += "Mongo:" + obj.mongoSerialise() + "\n";
str += "JSON :" + obj.serialise().toJSONString() + "\n\n";
}
}
return str;
} catch (Exception e) {
String message = e.getMessage();
message += "\n " + Arrays.toString(e.getStackTrace()).replaceAll(", ", "\n");
return message;
}
}
private String moveObj(long objectId, int x, int y) {
GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(objectId);
if (object != null) {
object.setX(x);
object.setY(y);
return "Success";
} else {
return "Object not found: " + objectId;
}
}
private String moveObj(long objectId, int x, int y, int worldX, int worldY, String dimension) {
GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(objectId);
World world = GameServer.INSTANCE.getGameUniverse().getWorld(worldX, worldY, false, dimension);
if (object != null) {
if (world != null) {
if (object instanceof Updatable) {
object.getWorld().decUpdatable();
world.incUpdatable();
}
object.getWorld().removeObject(object);
world.addObject(object);
object.setWorld(world);
object.setX(x);
object.setY(y);
return "Success";
} else {
return "World not found: " + World.idFromCoordinates(worldX, worldY, dimension);
}
} else {
return "Object not found: " + objectId;
}
}
private String userInfo(String username) {
User user = GameServer.INSTANCE.getGameUniverse().getUser(username);
if (user != null) {
String str = "Showing information for user " + username + "\n";
str += "isGuest: " + user.isGuest() + "\n";
ControllableUnit unit = user.getControlledUnit();
str += "ControlledUnit: " + unit.getObjectId() + " at (" + unit.getX() + ", " + unit.getY() + ")\n";
str += "CPU:" + user.getCpu() + "\n";
str += "Code: " + user.getUserCode();
return str;
} else {
return "User not found";
}
}
}

View File

@ -71,7 +71,7 @@ public class SocketServer extends WebSocketServer {
messageEventDispatcher.addHandler(new CodeRequestHandler());
messageEventDispatcher.addHandler(new KeypressHandler());
messageEventDispatcher.addHandler(new FloppyHandler());
messageEventDispatcher.addHandler(new DebugHandler());
messageEventDispatcher.addHandler(new DebugCommandHandler());
}

View File

@ -50,7 +50,8 @@ biomassEnergyValue=4000
# Maximum energy of the battery hardware in kJ
battery_max_energy=60000
# Maximum shield power
max_shield=100
cubot_max_shield=100
cubot_max_hp=250
# Energy cost per unit to charge shield
shield_energy_cost=50
# Time for biomass respawn in ticks