mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-12-13 14:49:03 +00:00
NPC Plugin rewrite.
Plugin-level data can be stored in DB
This commit is contained in:
@@ -18,6 +18,7 @@ import net.simon987.server.game.objects.GameRegistry;
|
||||
import net.simon987.server.game.world.*;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.PluginManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import net.simon987.server.user.User;
|
||||
import net.simon987.server.user.UserManager;
|
||||
import net.simon987.server.user.UserStatsHelper;
|
||||
@@ -221,11 +222,18 @@ public class GameServer implements Runnable {
|
||||
universe.addUser(user);
|
||||
}
|
||||
|
||||
//Load misc server info
|
||||
//Load server & plugin data
|
||||
cursor = server.find().iterator();
|
||||
if (cursor.hasNext()) {
|
||||
Document serverObj = cursor.next();
|
||||
gameUniverse.setTime((long) serverObj.get("time"));
|
||||
|
||||
Document plugins = (Document) serverObj.get("plugins");
|
||||
|
||||
for (String pluginName : plugins.keySet()) {
|
||||
ServerPlugin plugin = pluginManager.getPluginByName(pluginName);
|
||||
plugin.load((Document) plugins.get(pluginName));
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.LOGGER.info("Done loading! W:" + GameServer.INSTANCE.getGameUniverse().getWorldCount() +
|
||||
@@ -267,6 +275,13 @@ public class GameServer implements Runnable {
|
||||
|
||||
Document serverObj = new Document();
|
||||
serverObj.put("time", gameUniverse.getTime());
|
||||
|
||||
Document plugins = new Document();
|
||||
for (ServerPlugin plugin : pluginManager.getPlugins()) {
|
||||
plugins.put(plugin.getName(), plugin.mongoSerialise());
|
||||
}
|
||||
serverObj.put("plugins", plugins);
|
||||
|
||||
//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);
|
||||
|
||||
|
||||
@@ -115,6 +115,14 @@ public class GameUniverse {
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorld(String id, boolean createNew) {
|
||||
|
||||
String[] tokens = id.split("-");
|
||||
|
||||
return getWorld(Integer.decode(tokens[1]), Integer.decode(tokens[2]),
|
||||
createNew, tokens[0]);
|
||||
}
|
||||
|
||||
public World getLoadedWorld(int x, int y, String dimension) {
|
||||
// Wrapping coordinates around cyclically
|
||||
x %= maxWidth;
|
||||
|
||||
@@ -159,30 +159,30 @@ public abstract class GameObject implements JSONSerializable, MongoSerializable
|
||||
|
||||
int count = 0;
|
||||
|
||||
if (!getWorld().isTileBlocked(getX() + 1, getY())) {
|
||||
if (getWorld().getTileMap().isInBounds(x + 1, y) && !getWorld().isTileBlocked(x + 1, y)) {
|
||||
count++;
|
||||
}
|
||||
if (!getWorld().isTileBlocked(getX(), getY() + 1)) {
|
||||
if (getWorld().getTileMap().isInBounds(x, y + 1) && !getWorld().isTileBlocked(x, y + 1)) {
|
||||
count++;
|
||||
}
|
||||
if (!getWorld().isTileBlocked(getX() - 1, getY())) {
|
||||
if (getWorld().getTileMap().isInBounds(x - 1, y) && !getWorld().isTileBlocked(x - 1, y)) {
|
||||
count++;
|
||||
}
|
||||
if (!getWorld().isTileBlocked(getX(), getY() - 1)) {
|
||||
if (getWorld().getTileMap().isInBounds(x, y - 1) && !getWorld().isTileBlocked(x, y - 1)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (diagonals) {
|
||||
if (!getWorld().isTileBlocked(getX() + 1, getY() + 1)) {
|
||||
if (getWorld().getTileMap().isInBounds(x + 1, y + 1) && !getWorld().isTileBlocked(x + 1, y + 1)) {
|
||||
count++;
|
||||
}
|
||||
if (!getWorld().isTileBlocked(getX() - 1, getY() + 1)) {
|
||||
if (getWorld().getTileMap().isInBounds(x - 1, y + 1) && !getWorld().isTileBlocked(x - 1, y + 1)) {
|
||||
count++;
|
||||
}
|
||||
if (!getWorld().isTileBlocked(getX() + 1, getY() - 1)) {
|
||||
if (getWorld().getTileMap().isInBounds(x + 1, y - 1) && !getWorld().isTileBlocked(x + 1, y - 1)) {
|
||||
count++;
|
||||
}
|
||||
if (!getWorld().isTileBlocked(getX() - 1, getY() - 1)) {
|
||||
if (getWorld().getTileMap().isInBounds(x - 1, y - 1) && !getWorld().isTileBlocked(x - 1, y - 1)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.simon987.server.GameServer;
|
||||
import net.simon987.server.game.objects.GameRegistry;
|
||||
import net.simon987.server.io.JSONSerializable;
|
||||
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;
|
||||
@@ -87,7 +88,8 @@ public class TileMap implements JSONSerializable, MongoSerializable {
|
||||
*/
|
||||
public int getTileIdAt(int x, int y) {
|
||||
try {
|
||||
return tiles[x][y].getId();
|
||||
Tile tile = tiles[x][y];
|
||||
return tile == null ? -1 : tile.getId();
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return -1;
|
||||
}
|
||||
@@ -101,13 +103,18 @@ public class TileMap implements JSONSerializable, MongoSerializable {
|
||||
* @return the tile id at the specified position, null if out of bounds
|
||||
*/
|
||||
public Tile getTileAt(int x, int y) {
|
||||
try {
|
||||
if (isInBounds(x, y)) {
|
||||
return tiles[x][y];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
} else {
|
||||
LogManager.LOGGER.warning(String.format("ArrayIndexOutOfBoundsException in TileMap::getTileAt(%d, %d)", x, y));
|
||||
Thread.dumpStack();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInBounds(int x, int y) {
|
||||
return x >= 0 && x < width && y >= 0 && y < width;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class World implements MongoSerializable {
|
||||
* @return long
|
||||
*/
|
||||
public static String idFromCoordinates(int x, int y, String dimension) {
|
||||
return dimension + "0x" + Integer.toHexString(x) + "-" + "0x" + Integer.toHexString(y);
|
||||
return dimension + "-0x" + Integer.toHexString(x) + "-" + "0x" + Integer.toHexString(y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -425,28 +425,28 @@ public class World implements MongoSerializable {
|
||||
if (rTile != null) {
|
||||
int adjacentTiles = 0;
|
||||
|
||||
if (!isTileBlocked(rTile.x, rTile.y - 1)) {
|
||||
if (tileMap.isInBounds(rTile.x, rTile.y - 1) && !isTileBlocked(rTile.x, rTile.y - 1)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x + 1, rTile.y)) {
|
||||
if (tileMap.isInBounds(rTile.x + 1, rTile.y) && !isTileBlocked(rTile.x + 1, rTile.y)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x, rTile.y + 1)) {
|
||||
if (tileMap.isInBounds(rTile.x, rTile.y + 1) && !isTileBlocked(rTile.x, rTile.y + 1)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x - 1, rTile.y)) {
|
||||
if (tileMap.isInBounds(rTile.x - 1, rTile.y) && !isTileBlocked(rTile.x - 1, rTile.y)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x + 1, rTile.y + 1)) {
|
||||
if (tileMap.isInBounds(rTile.x + 1, rTile.y + 1) && !isTileBlocked(rTile.x + 1, rTile.y + 1)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x - 1, rTile.y + 1)) {
|
||||
if (tileMap.isInBounds(rTile.x - 1, rTile.y + 1) && !isTileBlocked(rTile.x - 1, rTile.y + 1)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x + 1, rTile.y - 1)) {
|
||||
if (tileMap.isInBounds(rTile.x + 1, rTile.y - 1) && !isTileBlocked(rTile.x + 1, rTile.y - 1)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
if (!isTileBlocked(rTile.x - 1, rTile.y - 1)) {
|
||||
if (tileMap.isInBounds(rTile.x - 1, rTile.y - 1) && !isTileBlocked(rTile.x - 1, rTile.y - 1)) {
|
||||
adjacentTiles++;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.simon987.server.game.world;
|
||||
|
||||
public class WorldGenerationException extends Exception {
|
||||
public WorldGenerationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,8 @@ public class WorldGenerator {
|
||||
private int minCopperCount;
|
||||
private int maxCopperCount;
|
||||
|
||||
private String dimension;
|
||||
|
||||
private static final int DEFAULT_WORLD_SIZE = 16;
|
||||
|
||||
/**
|
||||
@@ -48,6 +50,8 @@ public class WorldGenerator {
|
||||
|
||||
public WorldGenerator(ServerConfiguration config) {
|
||||
|
||||
dimension = config.getString("new_user_dimension");
|
||||
|
||||
centerPointCountMin = config.getInt("wg_centerPointCountMin");
|
||||
centerPointCountMax = config.getInt("wg_centerPointCountMax");
|
||||
wallPlainRatio = config.getInt("wg_wallPlainRatio");
|
||||
@@ -88,9 +92,9 @@ public class WorldGenerator {
|
||||
/**
|
||||
* Generates an empty World
|
||||
*/
|
||||
private static World generateEmptyWorld(int locX, int locY) {
|
||||
private static World generateEmptyWorld(int locX, int locY, String dimension) {
|
||||
|
||||
return new World(locX, locY, new TileMap(DEFAULT_WORLD_SIZE, DEFAULT_WORLD_SIZE), "w-");
|
||||
return new World(locX, locY, new TileMap(DEFAULT_WORLD_SIZE, DEFAULT_WORLD_SIZE), dimension);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +103,7 @@ public class WorldGenerator {
|
||||
public World generateWorld(int locX, int locY) throws CancelledException {
|
||||
Random random = new Random();
|
||||
|
||||
World world = generateEmptyWorld(locX, locY);
|
||||
World world = generateEmptyWorld(locX, locY, dimension);
|
||||
|
||||
centerPointsMap = new HashMap<>(16);
|
||||
|
||||
|
||||
@@ -152,6 +152,10 @@ public class PluginManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ServerPlugin getPluginByName(String name) {
|
||||
return PluginManager.getPluginByName(name, loadedPlugins);
|
||||
}
|
||||
|
||||
private boolean isLoaded(String name) {
|
||||
return getPluginByName(name, loadedPlugins) != null;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@ package net.simon987.server.plugin;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.event.GameEventListener;
|
||||
import net.simon987.server.io.MongoSerializable;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ServerPlugin {
|
||||
public abstract class ServerPlugin implements MongoSerializable {
|
||||
|
||||
/**
|
||||
* Name of the plugin
|
||||
@@ -49,4 +52,22 @@ public abstract class ServerPlugin {
|
||||
public List<GameEventListener> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document mongoSerialise() {
|
||||
Document document = new Document();
|
||||
|
||||
document.put("version", version);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public void load(Document document) {
|
||||
|
||||
LogManager.LOGGER.fine(String.format("(%s) Loading from database", name));
|
||||
if (!version.equals(document.getString("version"))) {
|
||||
LogManager.LOGGER.warning(String.format("(%s) Version mismatch with database!" +
|
||||
" This could cause problems. %s!=%s", name, version, document.getString("version")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ user_timeout=100
|
||||
#User creation
|
||||
new_user_worldX=32767
|
||||
new_user_worldY=32767
|
||||
new_user_dimension=w-
|
||||
new_user_dimension=w
|
||||
# Default user code
|
||||
new_user_code=; Welcome to Much Assembly required!\n\
|
||||
; You will find useful information on the game here: https://github.com/simon987/Much-Assembly-Required/wiki\n\
|
||||
|
||||
Reference in New Issue
Block a user