diff --git a/StevenDimDoors/mod_pocketDim/CommonProxy.java b/StevenDimDoors/mod_pocketDim/CommonProxy.java index 951244e..ada7b95 100644 --- a/StevenDimDoors/mod_pocketDim/CommonProxy.java +++ b/StevenDimDoors/mod_pocketDim/CommonProxy.java @@ -1,10 +1,7 @@ package StevenDimDoors.mod_pocketDim; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; -import StevenDimDoors.mod_pocketDimClient.ClientTickHandler; - import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.CompressedStreamTools; @@ -47,7 +44,6 @@ public class CommonProxy implements IGuiHandler public void writeNBTToFile(World world) { boolean flag = true; - boolean secondTry = false; try { @@ -58,7 +54,6 @@ public class CommonProxy implements IGuiHandler if (!flag) { dirFolder.replace("saves/", FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName()); - secondTry = true; } File file = new File(dirFolder, "GGMData.dat"); @@ -91,7 +86,6 @@ public class CommonProxy implements IGuiHandler public void readNBTFromFile(World world) { boolean flag = true; - boolean secondTry = false; try { @@ -102,7 +96,6 @@ public class CommonProxy implements IGuiHandler if (!flag) { dirFolder.replace("saves/", FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName()); - secondTry = true; } File file = new File(dirFolder, "GGMData.dat"); @@ -117,12 +110,9 @@ public class CommonProxy implements IGuiHandler fileoutputstream.close(); } - FileInputStream fileinputstream = new FileInputStream(file); + /*FileInputStream fileinputstream = new FileInputStream(file); NBTTagCompound nbttagcompound = CompressedStreamTools.readCompressed(fileinputstream); - - - - fileinputstream.close(); + fileinputstream.close();*/ } catch (Exception exception) { diff --git a/StevenDimDoors/mod_pocketDim/ConnectionHandler.java b/StevenDimDoors/mod_pocketDim/ConnectionHandler.java index 7b855a5..0b13248 100644 --- a/StevenDimDoors/mod_pocketDim/ConnectionHandler.java +++ b/StevenDimDoors/mod_pocketDim/ConnectionHandler.java @@ -1,21 +1,25 @@ package StevenDimDoors.mod_pocketDim; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + import net.minecraft.network.INetworkManager; import net.minecraft.network.NetLoginHandler; import net.minecraft.network.packet.NetHandler; import net.minecraft.network.packet.Packet1Login; +import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.server.MinecraftServer; +import StevenDimDoors.mod_pocketDim.core.PocketManager; +import StevenDimDoors.mod_pocketDim.watcher.IOpaqueMessage; import cpw.mods.fml.common.network.IConnectionHandler; import cpw.mods.fml.common.network.Player; public class ConnectionHandler implements IConnectionHandler { @Override - public String connectionReceived(NetLoginHandler netHandler, INetworkManager manager) + public String connectionReceived(NetLoginHandler netHandler, INetworkManager manager) { - //Sends a packet to the client containing all the information about the dimensions and links. - //Lots of packets, actually. - PacketHandler.sendClientJoinPacket(manager); return null; } @@ -32,5 +36,27 @@ public class ConnectionHandler implements IConnectionHandler public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login) { } @Override - public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) { } + public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) + { + //Send information about all the registered dimensions and links to the client + try + { + IOpaqueMessage message = PocketManager.getState(); + Packet250CustomPayload packet = new Packet250CustomPayload(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + DataOutputStream writer = new DataOutputStream(buffer); + writer.writeByte(PacketConstants.CLIENT_JOIN_PACKET_ID); + message.writeToStream(writer); + writer.close(); + packet.channel = PacketConstants.CHANNEL_NAME; + packet.data = buffer.toByteArray(); + packet.length = packet.data.length; + manager.addToSendQueue(packet); + } + catch (IOException e) + { + //This shouldn't happen... + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/StevenDimDoors/mod_pocketDim/PacketConstants.java b/StevenDimDoors/mod_pocketDim/PacketConstants.java new file mode 100644 index 0000000..67d4e60 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/PacketConstants.java @@ -0,0 +1,15 @@ +package StevenDimDoors.mod_pocketDim; + +public class PacketConstants +{ + private PacketConstants() { } + + public static final byte CLIENT_JOIN_PACKET_ID = 1; + public static final byte CREATE_DIM_PACKET_ID = 2; + public static final byte UPDATE_DIM_PACKET_ID = 3; + public static final byte DELETE_DIM_PACKET_ID = 4; + public static final byte CREATE_LINK_PACKET_ID = 5; + public static final byte UPDATE_LINK_PACKET_ID = 6; + public static final byte DELETE_LINK_PACKET_ID = 7; + public static final String CHANNEL_NAME = "DimDoorsPackets"; +} diff --git a/StevenDimDoors/mod_pocketDim/Point3D.java b/StevenDimDoors/mod_pocketDim/Point3D.java index 4a8e72a..7a3d357 100644 --- a/StevenDimDoors/mod_pocketDim/Point3D.java +++ b/StevenDimDoors/mod_pocketDim/Point3D.java @@ -4,6 +4,8 @@ import java.io.Serializable; public class Point3D implements Serializable { + private static final long serialVersionUID = -9044026830605287190L; + private int x; private int y; private int z; diff --git a/StevenDimDoors/mod_pocketDim/ServerPacketHandler.java b/StevenDimDoors/mod_pocketDim/ServerPacketHandler.java index fff2079..310b84a 100644 --- a/StevenDimDoors/mod_pocketDim/ServerPacketHandler.java +++ b/StevenDimDoors/mod_pocketDim/ServerPacketHandler.java @@ -1,15 +1,93 @@ package StevenDimDoors.mod_pocketDim; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet250CustomPayload; +import StevenDimDoors.mod_pocketDim.core.PocketManager; +import StevenDimDoors.mod_pocketDim.watcher.IOpaqueMessage; +import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; import cpw.mods.fml.common.network.IPacketHandler; +import cpw.mods.fml.common.network.PacketDispatcher; import cpw.mods.fml.common.network.Player; public class ServerPacketHandler implements IPacketHandler { - @Override - public void onPacketData(INetworkManager manager, - Packet250CustomPayload packet, Player player) + public ServerPacketHandler() { + PocketManager.registerDimWatcher(new DimWatcher()); + PocketManager.registerLinkWatcher(new LinkWatcher()); } -} \ No newline at end of file + + @Override + public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) + { + + } + + private class DimWatcher implements IUpdateWatcher + { + @Override + public void onCreated(IOpaqueMessage message) + { + sendMessageToAllPlayers(PacketConstants.CREATE_DIM_PACKET_ID, message); + } + + @Override + public void onUpdated(IOpaqueMessage message) + { + sendMessageToAllPlayers(PacketConstants.UPDATE_DIM_PACKET_ID, message); + } + + @Override + public void onDeleted(IOpaqueMessage message) + { + sendMessageToAllPlayers(PacketConstants.DELETE_DIM_PACKET_ID, message); + } + } + + private class LinkWatcher implements IUpdateWatcher + { + @Override + public void onCreated(IOpaqueMessage message) + { + sendMessageToAllPlayers(PacketConstants.CREATE_LINK_PACKET_ID, message); + } + + @Override + public void onUpdated(IOpaqueMessage message) + { + sendMessageToAllPlayers(PacketConstants.UPDATE_LINK_PACKET_ID, message); + } + + @Override + public void onDeleted(IOpaqueMessage message) + { + sendMessageToAllPlayers(PacketConstants.DELETE_LINK_PACKET_ID, message); + } + } + + private static void sendMessageToAllPlayers(byte id, IOpaqueMessage message) + { + try + { + Packet250CustomPayload packet = new Packet250CustomPayload(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + DataOutputStream writer = new DataOutputStream(buffer); + writer.writeByte(id); + message.writeToStream(writer); + writer.close(); + packet.channel = PacketConstants.CHANNEL_NAME; + packet.data = buffer.toByteArray(); + packet.length = packet.data.length; + PacketDispatcher.sendPacketToAllPlayers(packet); + } + catch (IOException e) + { + //This shouldn't happen... + e.printStackTrace(); + } + } +} diff --git a/StevenDimDoors/mod_pocketDim/core/IDimLink.java b/StevenDimDoors/mod_pocketDim/core/IDimLink.java index cb62dc3..4ed15b0 100644 --- a/StevenDimDoors/mod_pocketDim/core/IDimLink.java +++ b/StevenDimDoors/mod_pocketDim/core/IDimLink.java @@ -1,10 +1,8 @@ package StevenDimDoors.mod_pocketDim.core; -import java.io.Serializable; - import StevenDimDoors.mod_pocketDim.util.Point4D; -public interface IDimLink extends Serializable +public interface IDimLink { public final int TYPE_ENUM_MIN = 0; public final int TYPE_ENUM_MAX = 8; @@ -26,5 +24,4 @@ public interface IDimLink extends Serializable public int childCount(); public IDimLink parent(); public int linkType(); - public IDimLink setDestination(int x, int y, int z, NewDimData dimension); } \ No newline at end of file diff --git a/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 40c3333..c7e0c2e 100644 --- a/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -1,5 +1,4 @@ package StevenDimDoors.mod_pocketDim.core; -import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -11,14 +10,15 @@ import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack; import StevenDimDoors.mod_pocketDim.util.Point4D; +import StevenDimDoors.mod_pocketDim.watcher.IOpaqueMessage; +import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; -public abstract class NewDimData implements Serializable +public abstract class NewDimData { private static class DimLink implements IDimLink { //DimLink is an inner class here to make it immutable to code outside NewDimData - private static final long serialVersionUID = 1462177151401498444L; private static final int EXPECTED_CHILDREN = 2; private Point4D source; @@ -66,16 +66,9 @@ public abstract class NewDimData implements Serializable return (tail.getDestination() != null); } - @Override - public IDimLink setDestination(int x, int y, int z, NewDimData dimension) + public void setDestination(int x, int y, int z, NewDimData dimension) { - if (dimension == null) - { - throw new IllegalArgumentException("dimension cannot be null."); - } - tail.setDestination(new Point4D(x, y, z, dimension.id())); - return this; } @Override @@ -179,9 +172,18 @@ public abstract class NewDimData implements Serializable { return source + " -> " + (hasDestination() ? destination() : ""); } - } - private static final long serialVersionUID = 89361974746997260L; + public IOpaqueMessage toMessage() + { + return null; + } + + public IOpaqueMessage toKey() + { + return null; + } + } + private static Random random = new Random(); private final int id; @@ -197,8 +199,11 @@ public abstract class NewDimData implements Serializable private Point4D origin; private int orientation; private DungeonData dungeon; + private final IUpdateWatcher dimWatcher; + private final IUpdateWatcher linkWatcher; - protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon) + protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon, + IUpdateWatcher dimWatcher, IUpdateWatcher linkWatcher) { //The isPocket flag is redundant. It's meant as an integrity safeguard. if (isPocket == (parent != null)) @@ -215,24 +220,33 @@ public abstract class NewDimData implements Serializable this.linkList = new ArrayList(); //Should be stored in oct tree -- temporary solution this.children = new ArrayList(); this.parent = parent; - this.root = (parent != null ? parent.root : this); - this.depth = (parent != null ? parent.depth + 1 : 0); this.packDepth = 0; this.isDungeon = isDungeon; this.isFilled = false; this.orientation = 0; this.origin = null; this.dungeon = null; + this.dimWatcher = dimWatcher; + this.linkWatcher = linkWatcher; //Register with parent - addChildDimension(this); + if (parent != null) + { + //We don't need to raise an update event for adding a child because the child's creation will be signaled. + this.root = parent.root; + this.depth = parent.depth + 1; + parent.children.add(this); + } + else + { + this.root = this; + this.depth = 0; + } } - private void addChildDimension(NewDimData child) - { - children.add(child); - } - + protected abstract IOpaqueMessage toMessage(); + protected abstract IOpaqueMessage toKey(); + public IDimLink findNearestRift(World world, int range, int x, int y, int z) { //TODO: Rewrite this later to use an octtree @@ -301,6 +315,8 @@ public abstract class NewDimData implements Serializable { link.overwrite(linkType); } + //Link created! + linkWatcher.onCreated(link.toMessage()); return link; } @@ -330,7 +346,8 @@ public abstract class NewDimData implements Serializable { link.overwrite(parent); } - + //Link created! + linkWatcher.onCreated(link.toMessage()); return link; } @@ -344,6 +361,8 @@ public abstract class NewDimData implements Serializable if (target != null) { linkList.remove(target); + //Raise deletion event + linkWatcher.onDeleted(target.toKey()); target.clear(); } return (target != null); @@ -356,6 +375,8 @@ public abstract class NewDimData implements Serializable if (target != null) { linkList.remove(target); + //Raise deletion event + linkWatcher.onDeleted(target.toKey()); target.clear(); } return (target != null); @@ -400,6 +421,8 @@ public abstract class NewDimData implements Serializable public void setFilled(boolean isFilled) { this.isFilled = isFilled; + //Raise the dim update event + dimWatcher.onUpdated(this.toMessage()); } public int id() @@ -457,7 +480,7 @@ public abstract class NewDimData implements Serializable return children; } - public void initializeDungeon(int originX, int originY, int originZ, int orientation, IDimLink link, DungeonData dungeon) + public void initializeDungeon(int originX, int originY, int originZ, int orientation, IDimLink incoming, DungeonData dungeon) { if (!isDungeon) { @@ -468,11 +491,13 @@ public abstract class NewDimData implements Serializable throw new IllegalStateException("The dimension has already been initialized."); } - link.setDestination(originX, originY, originZ, this); - this.origin = link.destination(); + setDestination(incoming, originX, originY, originZ); + this.origin = incoming.destination(); this.orientation = orientation; this.dungeon = dungeon; this.packDepth = calculatePackDepth(parent, dungeon); + //Raise the dim update event + dimWatcher.onUpdated(this.toMessage()); } private static int calculatePackDepth(NewDimData parent, DungeonData current) @@ -507,7 +532,7 @@ public abstract class NewDimData implements Serializable } } - public void initializePocket(int originX, int originY, int originZ, int orientation, IDimLink link) + public void initializePocket(int originX, int originY, int originZ, int orientation, IDimLink incoming) { if (!isPocketDimension()) { @@ -518,9 +543,19 @@ public abstract class NewDimData implements Serializable throw new IllegalStateException("The dimension has already been initialized."); } - link.setDestination(originX, originY, originZ, this); - this.origin = link.destination(); + setDestination(incoming, originX, originY, originZ); + this.origin = incoming.destination(); this.orientation = orientation; + //Raise the dim update event + dimWatcher.onUpdated(this.toMessage()); + } + + public void setDestination(IDimLink incoming, int x, int y, int z) + { + DimLink link = (DimLink) incoming; + link.setDestination(x, y, z, this); + //Raise update event + linkWatcher.onUpdated(link.toMessage()); } public IDimLink getRandomLink() diff --git a/StevenDimDoors/mod_pocketDim/core/PocketManager.java b/StevenDimDoors/mod_pocketDim/core/PocketManager.java index 09f2e61..3555915 100644 --- a/StevenDimDoors/mod_pocketDim/core/PocketManager.java +++ b/StevenDimDoors/mod_pocketDim/core/PocketManager.java @@ -1,9 +1,10 @@ package StevenDimDoors.mod_pocketDim.core; +import java.io.DataOutputStream; import java.io.File; -import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.ObjectOutputStream; +import java.io.IOException; import java.util.HashMap; import net.minecraft.entity.player.EntityPlayer; @@ -12,11 +13,12 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.DDProperties; -import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream; import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift; import StevenDimDoors.mod_pocketDim.util.Point4D; -import cpw.mods.fml.common.FMLCommonHandler; +import StevenDimDoors.mod_pocketDim.watcher.IOpaqueMessage; +import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; +import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy; /** * This class regulates all the operations involving the storage and manipulation of dimensions. It handles saving dim data, teleporting the player, and @@ -30,19 +32,35 @@ public class PocketManager //a public constructor from NewDimData. It's meant to stop us from constructing instances //of NewDimData without using PocketManager's functions. In turn, that enforces that any //link destinations must be real dimensions controlled by PocketManager. - - private static final long serialVersionUID = -3497038894870586232L; - public InnerDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon) + public InnerDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon, + IUpdateWatcher dimWatcher, IUpdateWatcher linkWatcher) { - super(id, parent, isPocket, isDungeon); + super(id, parent, isPocket, isDungeon, dimWatcher, linkWatcher); + } + + @Override + protected IOpaqueMessage toMessage() + { + // TODO Auto-generated method stub + return null; + } + + @Override + protected IOpaqueMessage toKey() + { + // TODO Auto-generated method stub + return null; } } private static int OVERWORLD_DIMENSION_ID = 0; - private static boolean isLoaded = false; - private static boolean isSaving = false; + private static volatile boolean isLoading = false; + private static volatile boolean isLoaded = false; + private static volatile boolean isSaving = false; + private static UpdateWatcherProxy linkWatcher = null; + private static UpdateWatcherProxy dimWatcher = null; //HashMap that maps all the dimension IDs registered with DimDoors to their DD data. private static HashMap dimensionData = new HashMap(); @@ -62,8 +80,17 @@ public class PocketManager { throw new IllegalStateException("Pocket dimensions have already been loaded!"); } + if (isLoading) + { + return; + } + + isLoading = true; + + //Set up watcher proxies + dimWatcher = new UpdateWatcherProxy(); + linkWatcher = new UpdateWatcherProxy(); - isLoaded = true; loadInternal(); //Register Limbo @@ -72,6 +99,9 @@ public class PocketManager //Register pocket dimensions registerPockets(properties); + + isLoaded = true; + isLoading = false; } public boolean clearPocket(NewDimData dimension) @@ -103,6 +133,9 @@ public class PocketManager File save = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id()); DeleteFolder.deleteFolder(save); } + //Raise the dim deleted event + dimWatcher.onDeleted(dimension.toKey()); + //dimension.implode()??? -- more like delete, but yeah return true; } else @@ -149,65 +182,6 @@ public class PocketManager } } - /** - * Function that saves all dim data in a hashMap. Calling too often can cause Concurrent modification exceptions, so be careful. - * @return - */ - public static void save() - { - //TODO change from saving serialized objects to just saving data for compatabilies sake. - //TODO If saving is multithreaded as the concurrent modification exception implies, you should be synchronizing access. ~SenseiKiwi - - if (!isLoaded) - { - return; - } - if (isSaving) - { - return; - } - World world = DimensionManager.getWorld(OVERWORLD_DIMENSION_ID); - if (world == null || world.isRemote) - { - return; - } - if (DimensionManager.getCurrentSaveRootDirectory() != null) - { - isSaving = true; - HashMap comboSave = new HashMap(); - comboSave.put("dimensionData", dimensionData); - - FileOutputStream saveFile = null; - try - { - String saveFileName=DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsDataTEMP"; - saveFile = new FileOutputStream(saveFileName); - - ObjectOutputStream save = new ObjectOutputStream(saveFile); - save.writeObject(comboSave); - save.close(); - saveFile.close(); - - if (new File(DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsDataOLD").exists()) - { - new File(DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsDataOLD").delete(); - } - new File(DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsData").renameTo(new File(DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsDataOLD")); - - new File(saveFileName).renameTo( new File(DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsData")); - } - catch(Exception e) - { - e.printStackTrace(); - System.err.println("Could not save data-- SEVERE"); - } - finally - { - isSaving = false; - } - } - } - /** * loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler * @return @@ -215,81 +189,68 @@ public class PocketManager @SuppressWarnings("unchecked") private static void loadInternal() { - //FIXME: There are a lot of things to fix here... First, we shouldn't be created so many File instances - //when we could just hold references and reuse them. Second, duplicate code is BAD. Loading stuff should - //be a function so that you can apply it to the save file first, then the "backup", instead of duplicating - //so much code. >_< + // SenseiKiwi: This is a temporary function for testing purposes. + // We'll move on to using a text-based format in the future. - boolean firstRun = false; - System.out.println("Loading DimDoors data"); - FileInputStream saveFile = null; - - if (!DimensionManager.getWorld(OVERWORLD_DIMENSION_ID).isRemote && DimensionManager.getCurrentSaveRootDirectory()!=null) + if (!DimensionManager.getWorld(OVERWORLD_DIMENSION_ID).isRemote && + DimensionManager.getCurrentSaveRootDirectory() != null) { - try - { - File dataStore = new File( DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsData"); - if (!dataStore.exists()) - { - if (!new File( DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsDataOLD").exists()) - { - firstRun=true; - } - } - saveFile = new FileInputStream(dataStore); - ObjectSaveInputStream save = new ObjectSaveInputStream(saveFile); - HashMap comboSave = (HashMap) save.readObject(); + System.out.println("Loading Dimensional Doors save data..."); + File saveFile = new File(DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat"); + //Missing code for converting the binary data in the file into an IOpaqueMessage + IOpaqueMessage saveData; + setState(saveData); + System.out.println("Loaded successfully!"); + } + } + + public static void save() + { + // SenseiKiwi: This is a temporary function for testing purposes. + // We'll move on to using a text-based format in the future. - try - { - dimensionData = (HashMap) comboSave.get("dimensionData"); - } - catch(Exception e) - { - System.out.println("Could not load pocket dimension list. Saves are probably lost, but repairable. Move the files from individual pocket dim files to active ones. See MC thread for details."); - } + if (!isLoaded) + { + return; + } + World world = DimensionManager.getWorld(OVERWORLD_DIMENSION_ID); + if (world == null || world.isRemote || DimensionManager.getCurrentSaveRootDirectory() != null) + { + return; + } + //Check this last to make sure we set the flag shortly after. + if (isSaving) + { + return; + } - save.close(); - saveFile.close(); - } - catch (Exception e) - { - try - { - if (!firstRun) - { - System.out.println("Save data damaged, trying backup..."); - } - World world=FMLCommonHandler.instance().getMinecraftServerInstance().worldServers[0]; - File dataStore =new File( world.getSaveHandler().getMapFileFromName("idcounts").getParentFile().getParent()+"/DimensionalDoorsDataOLD"); - - - saveFile = new FileInputStream(dataStore); - ObjectSaveInputStream save = new ObjectSaveInputStream(saveFile); - HashMap comboSave = (HashMap) save.readObject(); - - try - { - dimensionData = (HashMap) comboSave.get("dimensionData"); - } - catch (Exception e2) - { - System.out.println("Could not load pocket dim list. Saves probably lost, but repairable. Move the files from indivual pocket dim files to active ones. See MC thread for details."); - } - - save.close(); - saveFile.close(); - } - catch (Exception e2) - { - if (!firstRun) - { - System.err.println("Could not read data-- SEVERE"); - e2.printStackTrace(); - } - } - } - } + isSaving = true; + try + { + System.out.println("Writing Dimensional Doors save data..."); + String tempPath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.tmp"; + String savePath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat"; + File tempFile = new File(tempPath); + File saveFile = new File(savePath); + DataOutputStream writer = new DataOutputStream(new FileOutputStream(tempFile)); + getState().writeToStream(writer); + writer.close(); + saveFile.delete(); + tempFile.renameTo(saveFile); + System.out.println("Saved successfully!"); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + finally + { + isSaving = false; + } } public static boolean removeRift(World world, int x, int y, int z, int range, EntityPlayer player, ItemStack item) @@ -340,7 +301,7 @@ public class PocketManager throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered."); } - NewDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon); + NewDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, dimWatcher, linkWatcher); dimensionData.put(dimensionID, dimension); return dimension; } @@ -395,4 +356,38 @@ public class PocketManager return null; } } + + public static void registerDimWatcher(IUpdateWatcher watcher) + { + dimWatcher.registerReceiver(watcher); + } + + public static boolean unregisterDimWatcher(IUpdateWatcher watcher) + { + return dimWatcher.unregisterReceiver(watcher); + } + + public static void registerLinkWatcher(IUpdateWatcher watcher) + { + linkWatcher.registerReceiver(watcher); + } + + public static boolean unregisterLinkWatcher(IUpdateWatcher watcher) + { + return linkWatcher.unregisterReceiver(watcher); + } + + public static IOpaqueMessage getState() + { + + } + + public static void setState(IOpaqueMessage state) + { + if (isLoaded) + { + throw new IllegalStateException("Pocket dimensions have already been loaded!"); + } + + } } diff --git a/StevenDimDoors/mod_pocketDim/dungeon/DungeonData.java b/StevenDimDoors/mod_pocketDim/dungeon/DungeonData.java index 6d57e7d..7c298df 100644 --- a/StevenDimDoors/mod_pocketDim/dungeon/DungeonData.java +++ b/StevenDimDoors/mod_pocketDim/dungeon/DungeonData.java @@ -1,16 +1,13 @@ package StevenDimDoors.mod_pocketDim.dungeon; import java.io.FileNotFoundException; -import java.io.Serializable; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.schematic.InvalidSchematicException; -public class DungeonData implements Serializable +public class DungeonData { - private static final long serialVersionUID = -5624866366474710161L; - private final int weight; private final boolean isOpen; private final boolean isInternal; diff --git a/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java b/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java index 1c0663d..9426174 100644 --- a/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java +++ b/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java @@ -286,8 +286,8 @@ public class DungeonSchematic extends Schematic { { IDimLink link = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), IDimLink.TYPE_NORMAL); Point4D destination = link.source(); - link.setDestination(destination.getX(), destination.getY(), destination.getZ(), - PocketManager.getDimensionData(destination.getDimension())); + NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension()); + prevDim.setDestination(link, destination.getX(), destination.getY(), destination.getZ()); } private static void createExitDoorLink(NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter) diff --git a/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java b/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java index fc521bf..36c2757 100644 --- a/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java +++ b/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java @@ -68,8 +68,8 @@ public class ItemRiftSignature extends Item NewDimData destinationDimension = PocketManager.getDimensionData(world); IDimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), IDimLink.TYPE_NORMAL); IDimLink reverse = destinationDimension.createLink(x, y, z, IDimLink.TYPE_NORMAL); - link.setDestination(x, y, z, destinationDimension); - reverse.setDestination(source.getX(), source.getY(), source.getZ(), sourceDimension); + destinationDimension.setDestination(link, x, y, z); + sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ()); //Try placing a rift at the destination point if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z)) diff --git a/StevenDimDoors/mod_pocketDim/mod_pocketDim.java b/StevenDimDoors/mod_pocketDim/mod_pocketDim.java index bcac33e..cde2099 100644 --- a/StevenDimDoors/mod_pocketDim/mod_pocketDim.java +++ b/StevenDimDoors/mod_pocketDim/mod_pocketDim.java @@ -74,13 +74,11 @@ import cpw.mods.fml.relauncher.Side; @Mod(modid = mod_pocketDim.modid, name = "Dimensional Doors", version = mod_pocketDim.version) - -@NetworkMod(clientSideRequired = true, serverSideRequired = false, +@NetworkMod(clientSideRequired = true, serverSideRequired = false, connectionHandler=ConnectionHandler.class, clientPacketHandlerSpec = -@SidedPacketHandler(channels = {"pocketDim" }, packetHandler = ClientPacketHandler.class), +@SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ClientPacketHandler.class), serverPacketHandlerSpec = -@SidedPacketHandler(channels = {"pocketDim" }, packetHandler = ServerPacketHandler.class), -channels={"DimDoorPackets"}, packetHandler = PacketHandler.class, connectionHandler=ConnectionHandler.class) +@SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class)) public class mod_pocketDim { diff --git a/StevenDimDoors/mod_pocketDim/watcher/IOpaqueMessage.java b/StevenDimDoors/mod_pocketDim/watcher/IOpaqueMessage.java new file mode 100644 index 0000000..a3add2e --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/watcher/IOpaqueMessage.java @@ -0,0 +1,8 @@ +package StevenDimDoors.mod_pocketDim.watcher; + +import java.io.DataOutputStream; + +public interface IOpaqueMessage +{ + void writeToStream(DataOutputStream stream); +} diff --git a/StevenDimDoors/mod_pocketDim/watcher/IOpaqueReader.java b/StevenDimDoors/mod_pocketDim/watcher/IOpaqueReader.java new file mode 100644 index 0000000..8250094 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/watcher/IOpaqueReader.java @@ -0,0 +1,8 @@ +package StevenDimDoors.mod_pocketDim.watcher; + +import com.google.common.io.ByteArrayDataInput; + +public interface IOpaqueReader +{ + IOpaqueMessage read(ByteArrayDataInput source); +} diff --git a/StevenDimDoors/mod_pocketDim/watcher/IUpdateWatcher.java b/StevenDimDoors/mod_pocketDim/watcher/IUpdateWatcher.java new file mode 100644 index 0000000..31f5a85 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/watcher/IUpdateWatcher.java @@ -0,0 +1,8 @@ +package StevenDimDoors.mod_pocketDim.watcher; + +public interface IUpdateWatcher +{ + public void onCreated(IOpaqueMessage message); + public void onUpdated(IOpaqueMessage message); + public void onDeleted(IOpaqueMessage message); +} diff --git a/StevenDimDoors/mod_pocketDim/watcher/UpdateWatcherProxy.java b/StevenDimDoors/mod_pocketDim/watcher/UpdateWatcherProxy.java new file mode 100644 index 0000000..49874f2 --- /dev/null +++ b/StevenDimDoors/mod_pocketDim/watcher/UpdateWatcherProxy.java @@ -0,0 +1,51 @@ +package StevenDimDoors.mod_pocketDim.watcher; + +import java.util.ArrayList; +import java.util.List; + +public class UpdateWatcherProxy implements IUpdateWatcher +{ + private List watchers; + + public UpdateWatcherProxy() + { + watchers = new ArrayList(); + } + + @Override + public void onCreated(IOpaqueMessage message) + { + for (IUpdateWatcher receiver : watchers) + { + receiver.onCreated(message); + } + } + + @Override + public void onUpdated(IOpaqueMessage message) + { + for (IUpdateWatcher receiver : watchers) + { + receiver.onUpdated(message); + } + } + + @Override + public void onDeleted(IOpaqueMessage message) + { + for (IUpdateWatcher receiver : watchers) + { + receiver.onDeleted(message); + } + } + + public void registerReceiver(IUpdateWatcher receiver) + { + watchers.add(receiver); + } + + public boolean unregisterReceiver(IUpdateWatcher receiver) + { + return watchers.remove(receiver); + } +} diff --git a/StevenDimDoors/mod_pocketDimClient/ClientPacketHandler.java b/StevenDimDoors/mod_pocketDimClient/ClientPacketHandler.java index c86e15a..9100b78 100644 --- a/StevenDimDoors/mod_pocketDimClient/ClientPacketHandler.java +++ b/StevenDimDoors/mod_pocketDimClient/ClientPacketHandler.java @@ -1,23 +1,15 @@ - - -// This is my package declaration, do not mess with the standard (package net.minecraft.src;) like I did, -// Because I know what Im doing in this part, If you don't know what your doing keep it the normal (package net.minecraft.src;) package StevenDimDoors.mod_pocketDimClient; -// Theses are all the imports you need import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet250CustomPayload; import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.Player; -// Create a class and implement IPacketHandler -// This just handles the data packets in the server -public class ClientPacketHandler implements IPacketHandler{ - +public class ClientPacketHandler implements IPacketHandler +{ @Override - public void onPacketData(INetworkManager manager, - Packet250CustomPayload packet, Player player) { - // TODO Auto-generated method stub + public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) + { } }