From 19e0628f270c6efbba16b0ad9531ac56d5016544 Mon Sep 17 00:00:00 2001 From: Olof Larsson Date: Sun, 13 Feb 2011 11:18:08 +0100 Subject: [PATCH] Multiworld support --- src/com/bukkit/mcteam/factions/Commands.java | 15 +-- .../mcteam/factions/entities/Board.java | 83 ++++++++++++----- .../mcteam/factions/entities/Coord.java | 4 - .../bukkit/mcteam/factions/entities/EM.java | 91 ++++++++++++++++++- .../mcteam/factions/entities/Faction.java | 2 +- .../mcteam/factions/entities/Follower.java | 6 +- .../listeners/FactionsBlockListener.java | 4 +- .../listeners/FactionsPlayerListener.java | 9 +- 8 files changed, 168 insertions(+), 46 deletions(-) diff --git a/src/com/bukkit/mcteam/factions/Commands.java b/src/com/bukkit/mcteam/factions/Commands.java index 748c51c2..74e992c4 100644 --- a/src/com/bukkit/mcteam/factions/Commands.java +++ b/src/com/bukkit/mcteam/factions/Commands.java @@ -444,6 +444,7 @@ public class Commands { public static void showMap(Follower me, String mapAutoUpdating) { + Board board = Board.get(me.getPlayer().getWorld()); if (mapAutoUpdating.length() > 0) { if (Conf.aliasTrue.contains(mapAutoUpdating.toLowerCase())) { // Turn on @@ -458,7 +459,7 @@ public class Commands { me.sendMessage(Conf.colorSystem + "Map auto update DISABLED."); } } else { - me.sendMessage(Board.getMap(me.getFaction(), Coord.from(me), me.getPlayer().getLocation().getYaw()), false); + me.sendMessage(board.getMap(me.getFaction(), Coord.from(me), me.getPlayer().getLocation().getYaw()), false); } } @@ -618,7 +619,8 @@ public class Commands { } Coord coord = Coord.from(me); - Faction otherFaction = coord.getFaction(); + Board board = Board.get(me.getPlayer().getWorld()); + Faction otherFaction = board.getFactionAt(coord); Faction myFaction = me.getFaction(); if (myFaction.equals(otherFaction)) { @@ -647,7 +649,7 @@ public class Commands { return; } - if ( ! Board.isBorderCoord(coord)) { + if ( ! board.isBorderCoord(coord)) { me.sendMessage(Conf.colorSystem+"You must start claiming land at the border of the territory."); return; } @@ -662,7 +664,7 @@ public class Commands { myFaction.sendMessage(me.getNameAndRelevant(myFaction)+Conf.colorSystem+" claimed some land from "+otherFaction.getTag(myFaction)); } - Board.claim(coord, myFaction); + board.claim(coord, myFaction); } public static void unclaim(Follower me) { @@ -677,13 +679,14 @@ public class Commands { } Coord coord = Coord.from(me.getPlayer()); + Board board = Board.get(me.getPlayer().getWorld()); - if ( ! me.getFaction().equals(coord.getFaction())) { + if ( me.getFaction() != board.getFactionAt(coord)) { me.sendMessage(Conf.colorSystem+"You don't own this land."); return; } - Board.unclaim(coord); + board.unclaim(coord); me.getFaction().sendMessage(me.getNameAndRelevant(me)+Conf.colorSystem+" unclaimed some land."); } diff --git a/src/com/bukkit/mcteam/factions/entities/Board.java b/src/com/bukkit/mcteam/factions/entities/Board.java index 7eb72c45..2548d91c 100644 --- a/src/com/bukkit/mcteam/factions/entities/Board.java +++ b/src/com/bukkit/mcteam/factions/entities/Board.java @@ -4,6 +4,7 @@ import java.util.*; import java.util.Map.Entry; import org.bukkit.ChatColor; +import org.bukkit.World; import com.bukkit.mcteam.factions.util.TextUtil; import com.bukkit.mcteam.util.AsciiCompass; @@ -11,16 +12,17 @@ import com.bukkit.mcteam.util.AsciiCompass; //import com.bukkit.mcteam.factions.util.*; public class Board { - protected static Map coordFactionIds; + public transient Long id; + protected Map coordFactionIds; - static { + public Board() { coordFactionIds = new HashMap(); } - public static Faction getFactionAt(Coord coord) { + public Faction getFactionAt(Coord coord) { return Faction.get(getFactionIdAt(coord)); } - public static int getFactionIdAt(Coord coord) { + public int getFactionIdAt(Coord coord) { Integer factionId = coordFactionIds.get(coord); if (factionId == null) { return 0; // No faction @@ -28,12 +30,12 @@ public class Board { return factionId; } - public static void unclaim(Coord coord) { + public void unclaim(Coord coord) { coordFactionIds.remove(coord); save(); } - public static void claim(Coord coord, Faction faction) { + public void claim(Coord coord, Faction faction) { coordFactionIds.put(coord, faction.id); save(); } @@ -41,19 +43,20 @@ public class Board { // Is this coord NOT completely surrounded by coords claimed by the same faction? // Simpler: Is there any nearby coord with a faction other than the faction here? - public static boolean isBorderCoord(Coord coord) { - Faction faction = Board.getFactionAt(coord); + public boolean isBorderCoord(Coord coord) { + Faction faction = getFactionAt(coord); Coord a = coord.getRelative(1, 0); Coord b = coord.getRelative(-1, 0); Coord c = coord.getRelative(0, 1); Coord d = coord.getRelative(0, -1); - return faction != a.getFaction() || faction != b.getFaction() || faction != c.getFaction() || faction != d.getFaction(); + return faction != this.getFactionAt(a) || faction != this.getFactionAt(b) || faction != this.getFactionAt(c) || faction != this.getFactionAt(d); } - public static void purgeFaction(Faction faction) { - purgeFaction(faction.id); - } - public static void purgeFaction(int factionId) { + //----------------------------------------------// + // Purge faction + //----------------------------------------------// + + public void purgeFaction(int factionId) { Iterator> iter = coordFactionIds.entrySet().iterator(); while (iter.hasNext()) { Entry entry = iter.next(); @@ -62,11 +65,24 @@ public class Board { } } } - - public static int getFactionCoordCount(Faction faction) { - return getFactionCoordCount(faction.id); + public void purgeFaction(Faction faction) { + purgeFaction(faction.id); } - public static int getFactionCoordCount(int factionId) { + + public static void purgeFactionFromAllBoards(int factionId) { + for (Board board : getAll()) { + board.purgeFaction(factionId); + } + } + public static void purgeFactionFromAllBoards(Faction faction) { + purgeFactionFromAllBoards(faction.id); + } + + //----------------------------------------------// + // Coord count + //----------------------------------------------// + + public int getFactionCoordCount(int factionId) { int ret = 0; for (int thatFactionId : coordFactionIds.values()) { if(thatFactionId == factionId) { @@ -75,6 +91,21 @@ public class Board { } return ret; } + public int getFactionCoordCount(Faction faction) { + return getFactionCoordCount(faction.id); + } + + public static int getFactionCoordCountAllBoards(int factionId) { + int ret = 0; + for (Board board : getAll()) { + ret += board.getFactionCoordCount(factionId); + } + return ret; + } + public static int getFactionCoordCountAllBoards(Faction faction) { + return getFactionCoordCountAllBoards(faction.id); + } + //----------------------------------------------// // Map generation @@ -85,9 +116,9 @@ public class Board { * north is in the direction of decreasing x * east is in the direction of decreasing z */ - public static ArrayList getMap(Faction faction, Coord coord, double inDegrees) { + public ArrayList getMap(Faction faction, Coord coord, double inDegrees) { ArrayList ret = new ArrayList(); - ret.add(TextUtil.titleize("("+coord+") "+coord.getFaction().getTag(faction))); + ret.add(TextUtil.titleize("("+coord+") "+this.getFactionAt(coord).getTag(faction))); int halfWidth = Conf.mapWidth / 2; int halfHeight = Conf.mapHeight / 2; @@ -104,7 +135,7 @@ public class Board { row += ChatColor.AQUA+"+"; } else { Coord coordHere = topLeft.getRelative(dx, dz); - Faction factionHere = coordHere.getFaction(); + Faction factionHere = this.getFactionAt(coordHere); if (factionHere.id == 0) { row += ChatColor.GRAY+"-"; } else { @@ -131,8 +162,16 @@ public class Board { // Persistance //----------------------------------------------// - public static boolean save() { - return EM.boardSave(); + public boolean save() { + return EM.boardSave(this.id); + } + + public static Board get(World world) { + return EM.boardGet(world); + } + + public static Collection getAll() { + return EM.boardGetAll(); } } diff --git a/src/com/bukkit/mcteam/factions/entities/Coord.java b/src/com/bukkit/mcteam/factions/entities/Coord.java index f5b4b499..82e97b08 100644 --- a/src/com/bukkit/mcteam/factions/entities/Coord.java +++ b/src/com/bukkit/mcteam/factions/entities/Coord.java @@ -46,10 +46,6 @@ public class Coord { public static Coord parseCoord(Block block) { return from(block.getX(), block.getZ()); } - - public Faction getFaction() { - return Board.getFactionAt(this); - } @Override public String toString() { diff --git a/src/com/bukkit/mcteam/factions/entities/EM.java b/src/com/bukkit/mcteam/factions/entities/EM.java index 70c76657..2844df12 100644 --- a/src/com/bukkit/mcteam/factions/entities/EM.java +++ b/src/com/bukkit/mcteam/factions/entities/EM.java @@ -4,6 +4,7 @@ import java.io.*; import java.lang.reflect.Modifier; import java.util.*; +import org.bukkit.World; import org.bukkit.entity.Player; import com.bukkit.mcteam.factions.Factions; @@ -19,6 +20,7 @@ import com.google.gson.*; public class EM { protected static Map followers = new HashMap(); // Where String is a lowercase playername protected static Map factions = new HashMap(); // Where Integer is a primary auto increment key + protected static Map boards = new HashMap(); // Where Long is the semi (sadly) unique world id. protected static int nextFactionId; // hardcoded config @@ -26,8 +28,8 @@ public class EM { protected final static File folderBase = Factions.folder; protected final static File folderFaction = new File(folderBase, "faction"); protected final static File folderFollower = new File(folderBase, "follower"); + protected final static File folderBoard = new File(folderBase, "board"); protected final static File fileConfig = new File(folderBase, "conf"+ext); - protected final static File fileBoard = new File(folderBase, "board"+ext); public final static Gson gson = new GsonBuilder() .setPrettyPrinting() @@ -39,7 +41,7 @@ public class EM { folderBase.mkdirs(); configLoad(); Log.threshold = Conf.logThreshold; - boardLoad(); + boardLoadAll(); followerLoadAll(); factionLoadAll(); } @@ -80,7 +82,7 @@ public class EM { //----------------------------------------------// // Board methods (load, save) //----------------------------------------------// - public static boolean boardLoad() { + /*public static boolean boardLoad() { if (fileBoard.exists()) { try { gson.fromJson(DiscUtil.read(fileBoard), Board.class); @@ -108,6 +110,85 @@ public class EM { Log.warn("Failed to save the board"); return false; } + }*/ + + //----------------------------------------------// + // Board methods (loadAll, get, save) + //----------------------------------------------// + + /** + * This method loads all boards from disc into memory. + */ + public static void boardLoadAll() { + Log.info("Loading all boards from disc..."); + folderBoard.mkdirs(); + + class jsonFileFilter implements FileFilter { + public boolean accept(File file) { + return (file.getName().toLowerCase().endsWith(ext) && file.isFile()); + } + } + + File[] jsonFiles = folderBoard.listFiles(new jsonFileFilter()); + + for (File jsonFile : jsonFiles) { + // Extract the name from the filename. The name is filename minus ".json" + String name = jsonFile.getName(); + name = name.substring(0, name.length() - ext.length()); + try { + Board board = gson.fromJson(DiscUtil.read(jsonFile), Board.class); + board.id = Long.parseLong(name); + boards.put(board.id, board); + Log.debug("loaded board "+name); + } catch (Exception e) { + e.printStackTrace(); + Log.warn("failed to load board "+name); + } + } + } + + public static Collection boardGetAll() { + return boards.values(); + } + + /** + * This method returns the board object for a world + * A new Board will be created if the world did not have one + */ + public static Board boardGet(World world) { + if (boards.containsKey(world.getId())) { + return boards.get(world.getId()); + } + + return boardCreate(world); + } + + public static boolean boardSave(long id) { + Object obj = boards.get(id); + if (obj == null) { + Log.warn("Could not save board "+id+" as it was not loaded"); + return false; + } + folderBoard.mkdirs(); + File file = new File(folderBoard, id+ext); + try { + DiscUtil.write(file, gson.toJson(obj)); + Log.debug("Saved the board "+id); + return true; + } catch (IOException e) { + e.printStackTrace(); + Log.warn("Failed to save the board "+id); + return false; + } + } + + protected static Board boardCreate(World world) { + Log.debug("Creating new board "+world.getId()); + Board board = new Board(); + board.id = world.getId(); + boards.put(board.id, board); + board.save(); + return board; } //----------------------------------------------// @@ -273,8 +354,8 @@ public class EM { // NOTE that this does not do any security checks. // Follower might get orphaned foreign id's - // purge from board - Board.purgeFaction(id); + // purge from all boards + Board.purgeFactionFromAllBoards(id); // Remove the file File file = new File(folderFaction, id+ext); diff --git a/src/com/bukkit/mcteam/factions/entities/Faction.java b/src/com/bukkit/mcteam/factions/entities/Faction.java index 48dfbe12..a1449317 100644 --- a/src/com/bukkit/mcteam/factions/entities/Faction.java +++ b/src/com/bukkit/mcteam/factions/entities/Faction.java @@ -98,7 +98,7 @@ public class Faction { } public int getLandRounded() { - return Board.getFactionCoordCount(this); + return Board.getFactionCoordCountAllBoards(this); } public boolean hasLandInflation() { diff --git a/src/com/bukkit/mcteam/factions/entities/Follower.java b/src/com/bukkit/mcteam/factions/entities/Follower.java index 5101519a..efcfcc90 100644 --- a/src/com/bukkit/mcteam/factions/entities/Follower.java +++ b/src/com/bukkit/mcteam/factions/entities/Follower.java @@ -257,11 +257,11 @@ public class Follower { // Territory //----------------------------------------------// public boolean isInOwnTerritory() { - return Board.getFactionAt(this.getCoord()) == this.getFaction(); + return Board.get(this.getPlayer().getWorld()).getFactionAt(this.getCoord()) == this.getFaction(); } public boolean isInOthersTerritory() { - Faction factionHere = Board.getFactionAt(this.getCoord()); + Faction factionHere = Board.get(this.getPlayer().getWorld()).getFactionAt(this.getCoord()); return factionHere.id != 0 && factionHere != this.getFaction(); } @@ -270,7 +270,7 @@ public class Follower { } public void sendFactionHereMessage() { - Faction factionHere = Board.getFactionAt(this.getCoord()); + Faction factionHere = Board.get(this.getPlayer().getWorld()).getFactionAt(this.getCoord()); String msg = Conf.colorSystem+" ~ "+factionHere.getTag(this); if (factionHere.id != 0) { msg += " - "+factionHere.getDescription(); diff --git a/src/com/bukkit/mcteam/factions/listeners/FactionsBlockListener.java b/src/com/bukkit/mcteam/factions/listeners/FactionsBlockListener.java index d7da005e..e515ce31 100644 --- a/src/com/bukkit/mcteam/factions/listeners/FactionsBlockListener.java +++ b/src/com/bukkit/mcteam/factions/listeners/FactionsBlockListener.java @@ -41,7 +41,7 @@ public class FactionsBlockListener extends BlockListener { public boolean playerCanBuildDestroyBlock(Player player, Block block, String action) { Coord coord = Coord.parseCoord(block); - Faction otherFaction = coord.getFaction(); + Faction otherFaction = Board.get(player.getWorld()).getFactionAt(coord); if (otherFaction.id == 0) { return true; // This is no faction territory. You may build or break stuff here. @@ -90,7 +90,7 @@ public class FactionsBlockListener extends BlockListener { Follower me = Follower.get(player); Faction myFaction = me.getFaction(); Coord blockCoord = Coord.from(block.getLocation()); - Faction otherFaction = blockCoord.getFaction(); + Faction otherFaction = Board.get(player.getWorld()).getFactionAt(blockCoord); if (otherFaction.id != 0 && myFaction != otherFaction) { me.sendMessage(Conf.colorSystem+"You can't use "+TextUtil.getMaterialName(material)+" in the territory of "+otherFaction.getTag(myFaction)); diff --git a/src/com/bukkit/mcteam/factions/listeners/FactionsPlayerListener.java b/src/com/bukkit/mcteam/factions/listeners/FactionsPlayerListener.java index 0f1ed8bd..9fe429ed 100644 --- a/src/com/bukkit/mcteam/factions/listeners/FactionsPlayerListener.java +++ b/src/com/bukkit/mcteam/factions/listeners/FactionsPlayerListener.java @@ -131,13 +131,16 @@ public class FactionsPlayerListener extends PlayerListener{ // Yes we did change coord (: Follower me = Follower.get(event.getPlayer()); + Board board = Board.get(event.getPlayer().getWorld()); + + Log.debug("Player "+me.getName()+" is in world: "+board.id); if (me.isMapAutoUpdating()) { - me.sendMessage(Board.getMap(me.getFaction(), Coord.from(me), me.getPlayer().getLocation().getYaw()), false); + me.sendMessage(board.getMap(me.getFaction(), Coord.from(me), me.getPlayer().getLocation().getYaw()), false); } else { // Did we change "host"(faction)? - Faction factionFrom = Board.getFactionAt(coordFrom); - Faction factionTo = Board.getFactionAt(coordTo); + Faction factionFrom = board.getFactionAt(coordFrom); + Faction factionTo = board.getFactionAt(coordTo); if ( factionFrom != factionTo) { me.sendFactionHereMessage(); }