Started Rewriting Packet Handling

Started rewriting our packet handling code. Deleted PacketHandler in
favor of using sided (Server-, Client-) packet handlers to make it
easier to follow what's going on in our code. Added some event-based
handling of updates which greatly simplified signaling that data needs
to be sent, but it's not completely done yet.
This commit is contained in:
SenseiKiwi
2013-09-01 22:01:17 -04:00
parent efa5b3eb4c
commit 62fed83e2f
17 changed files with 421 additions and 221 deletions

View File

@@ -1,10 +1,7 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import StevenDimDoors.mod_pocketDimClient.ClientTickHandler;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
@@ -47,7 +44,6 @@ public class CommonProxy implements IGuiHandler
public void writeNBTToFile(World world) public void writeNBTToFile(World world)
{ {
boolean flag = true; boolean flag = true;
boolean secondTry = false;
try try
{ {
@@ -58,7 +54,6 @@ public class CommonProxy implements IGuiHandler
if (!flag) if (!flag)
{ {
dirFolder.replace("saves/", FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName()); dirFolder.replace("saves/", FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName());
secondTry = true;
} }
File file = new File(dirFolder, "GGMData.dat"); File file = new File(dirFolder, "GGMData.dat");
@@ -91,7 +86,6 @@ public class CommonProxy implements IGuiHandler
public void readNBTFromFile(World world) public void readNBTFromFile(World world)
{ {
boolean flag = true; boolean flag = true;
boolean secondTry = false;
try try
{ {
@@ -102,7 +96,6 @@ public class CommonProxy implements IGuiHandler
if (!flag) if (!flag)
{ {
dirFolder.replace("saves/", FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName()); dirFolder.replace("saves/", FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName());
secondTry = true;
} }
File file = new File(dirFolder, "GGMData.dat"); File file = new File(dirFolder, "GGMData.dat");
@@ -117,12 +110,9 @@ public class CommonProxy implements IGuiHandler
fileoutputstream.close(); fileoutputstream.close();
} }
FileInputStream fileinputstream = new FileInputStream(file); /*FileInputStream fileinputstream = new FileInputStream(file);
NBTTagCompound nbttagcompound = CompressedStreamTools.readCompressed(fileinputstream); NBTTagCompound nbttagcompound = CompressedStreamTools.readCompressed(fileinputstream);
fileinputstream.close();*/
fileinputstream.close();
} }
catch (Exception exception) catch (Exception exception)
{ {

View File

@@ -1,10 +1,17 @@
package StevenDimDoors.mod_pocketDim; 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.INetworkManager;
import net.minecraft.network.NetLoginHandler; import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler; import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login; import net.minecraft.network.packet.Packet1Login;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.MinecraftServer; 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.IConnectionHandler;
import cpw.mods.fml.common.network.Player; import cpw.mods.fml.common.network.Player;
@@ -13,9 +20,6 @@ public class ConnectionHandler implements IConnectionHandler
@Override @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; return null;
} }
@@ -32,5 +36,27 @@ public class ConnectionHandler implements IConnectionHandler
public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login) { } public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login) { }
@Override @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();
}
}
} }

View File

@@ -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";
}

View File

@@ -4,6 +4,8 @@ import java.io.Serializable;
public class Point3D implements Serializable { public class Point3D implements Serializable {
private static final long serialVersionUID = -9044026830605287190L;
private int x; private int x;
private int y; private int y;
private int z; private int z;

View File

@@ -1,15 +1,93 @@
package StevenDimDoors.mod_pocketDim; 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.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload; 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.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player; import cpw.mods.fml.common.network.Player;
public class ServerPacketHandler implements IPacketHandler public class ServerPacketHandler implements IPacketHandler
{ {
@Override public ServerPacketHandler()
public void onPacketData(INetworkManager manager,
Packet250CustomPayload packet, Player player)
{ {
PocketManager.registerDimWatcher(new DimWatcher());
PocketManager.registerLinkWatcher(new LinkWatcher());
}
@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();
}
} }
} }

View File

@@ -1,10 +1,8 @@
package StevenDimDoors.mod_pocketDim.core; package StevenDimDoors.mod_pocketDim.core;
import java.io.Serializable;
import StevenDimDoors.mod_pocketDim.util.Point4D; 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_MIN = 0;
public final int TYPE_ENUM_MAX = 8; public final int TYPE_ENUM_MAX = 8;
@@ -26,5 +24,4 @@ public interface IDimLink extends Serializable
public int childCount(); public int childCount();
public IDimLink parent(); public IDimLink parent();
public int linkType(); public int linkType();
public IDimLink setDestination(int x, int y, int z, NewDimData dimension);
} }

View File

@@ -1,5 +1,4 @@
package StevenDimDoors.mod_pocketDim.core; package StevenDimDoors.mod_pocketDim.core;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -11,14 +10,15 @@ import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
import StevenDimDoors.mod_pocketDim.util.Point4D; 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 private static class DimLink implements IDimLink
{ {
//DimLink is an inner class here to make it immutable to code outside NewDimData //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 static final int EXPECTED_CHILDREN = 2;
private Point4D source; private Point4D source;
@@ -66,16 +66,9 @@ public abstract class NewDimData implements Serializable
return (tail.getDestination() != null); return (tail.getDestination() != null);
} }
@Override public void setDestination(int x, int y, int z, NewDimData dimension)
public IDimLink 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())); tail.setDestination(new Point4D(x, y, z, dimension.id()));
return this;
} }
@Override @Override
@@ -179,9 +172,18 @@ public abstract class NewDimData implements Serializable
{ {
return source + " -> " + (hasDestination() ? destination() : ""); return source + " -> " + (hasDestination() ? destination() : "");
} }
public IOpaqueMessage toMessage()
{
return null;
}
public IOpaqueMessage toKey()
{
return null;
}
} }
private static final long serialVersionUID = 89361974746997260L;
private static Random random = new Random(); private static Random random = new Random();
private final int id; private final int id;
@@ -197,8 +199,11 @@ public abstract class NewDimData implements Serializable
private Point4D origin; private Point4D origin;
private int orientation; private int orientation;
private DungeonData dungeon; 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. //The isPocket flag is redundant. It's meant as an integrity safeguard.
if (isPocket == (parent != null)) if (isPocket == (parent != null))
@@ -215,23 +220,32 @@ public abstract class NewDimData implements Serializable
this.linkList = new ArrayList<DimLink>(); //Should be stored in oct tree -- temporary solution this.linkList = new ArrayList<DimLink>(); //Should be stored in oct tree -- temporary solution
this.children = new ArrayList<NewDimData>(); this.children = new ArrayList<NewDimData>();
this.parent = parent; this.parent = parent;
this.root = (parent != null ? parent.root : this);
this.depth = (parent != null ? parent.depth + 1 : 0);
this.packDepth = 0; this.packDepth = 0;
this.isDungeon = isDungeon; this.isDungeon = isDungeon;
this.isFilled = false; this.isFilled = false;
this.orientation = 0; this.orientation = 0;
this.origin = null; this.origin = null;
this.dungeon = null; this.dungeon = null;
this.dimWatcher = dimWatcher;
this.linkWatcher = linkWatcher;
//Register with parent //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) protected abstract IOpaqueMessage toMessage();
{ protected abstract IOpaqueMessage toKey();
children.add(child);
}
public IDimLink findNearestRift(World world, int range, int x, int y, int z) public IDimLink findNearestRift(World world, int range, int x, int y, int z)
{ {
@@ -301,6 +315,8 @@ public abstract class NewDimData implements Serializable
{ {
link.overwrite(linkType); link.overwrite(linkType);
} }
//Link created!
linkWatcher.onCreated(link.toMessage());
return link; return link;
} }
@@ -330,7 +346,8 @@ public abstract class NewDimData implements Serializable
{ {
link.overwrite(parent); link.overwrite(parent);
} }
//Link created!
linkWatcher.onCreated(link.toMessage());
return link; return link;
} }
@@ -344,6 +361,8 @@ public abstract class NewDimData implements Serializable
if (target != null) if (target != null)
{ {
linkList.remove(target); linkList.remove(target);
//Raise deletion event
linkWatcher.onDeleted(target.toKey());
target.clear(); target.clear();
} }
return (target != null); return (target != null);
@@ -356,6 +375,8 @@ public abstract class NewDimData implements Serializable
if (target != null) if (target != null)
{ {
linkList.remove(target); linkList.remove(target);
//Raise deletion event
linkWatcher.onDeleted(target.toKey());
target.clear(); target.clear();
} }
return (target != null); return (target != null);
@@ -400,6 +421,8 @@ public abstract class NewDimData implements Serializable
public void setFilled(boolean isFilled) public void setFilled(boolean isFilled)
{ {
this.isFilled = isFilled; this.isFilled = isFilled;
//Raise the dim update event
dimWatcher.onUpdated(this.toMessage());
} }
public int id() public int id()
@@ -457,7 +480,7 @@ public abstract class NewDimData implements Serializable
return children; 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) if (!isDungeon)
{ {
@@ -468,11 +491,13 @@ public abstract class NewDimData implements Serializable
throw new IllegalStateException("The dimension has already been initialized."); throw new IllegalStateException("The dimension has already been initialized.");
} }
link.setDestination(originX, originY, originZ, this); setDestination(incoming, originX, originY, originZ);
this.origin = link.destination(); this.origin = incoming.destination();
this.orientation = orientation; this.orientation = orientation;
this.dungeon = dungeon; this.dungeon = dungeon;
this.packDepth = calculatePackDepth(parent, dungeon); this.packDepth = calculatePackDepth(parent, dungeon);
//Raise the dim update event
dimWatcher.onUpdated(this.toMessage());
} }
private static int calculatePackDepth(NewDimData parent, DungeonData current) 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()) if (!isPocketDimension())
{ {
@@ -518,9 +543,19 @@ public abstract class NewDimData implements Serializable
throw new IllegalStateException("The dimension has already been initialized."); throw new IllegalStateException("The dimension has already been initialized.");
} }
link.setDestination(originX, originY, originZ, this); setDestination(incoming, originX, originY, originZ);
this.origin = link.destination(); this.origin = incoming.destination();
this.orientation = orientation; 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() public IDimLink getRandomLink()

View File

@@ -1,9 +1,10 @@
package StevenDimDoors.mod_pocketDim.core; package StevenDimDoors.mod_pocketDim.core;
import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.ObjectOutputStream; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -12,11 +13,12 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream;
import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder; import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
import StevenDimDoors.mod_pocketDim.util.Point4D; 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 * This class regulates all the operations involving the storage and manipulation of dimensions. It handles saving dim data, teleporting the player, and
@@ -31,18 +33,34 @@ public class PocketManager
//of NewDimData without using PocketManager's functions. In turn, that enforces that any //of NewDimData without using PocketManager's functions. In turn, that enforces that any
//link destinations must be real dimensions controlled by PocketManager. //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,
IUpdateWatcher dimWatcher, IUpdateWatcher linkWatcher)
public InnerDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon)
{ {
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 int OVERWORLD_DIMENSION_ID = 0;
private static boolean isLoaded = false; private static volatile boolean isLoading = false;
private static boolean isSaving = 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. //HashMap that maps all the dimension IDs registered with DimDoors to their DD data.
private static HashMap<Integer, NewDimData> dimensionData = new HashMap<Integer, NewDimData>(); private static HashMap<Integer, NewDimData> dimensionData = new HashMap<Integer, NewDimData>();
@@ -62,8 +80,17 @@ public class PocketManager
{ {
throw new IllegalStateException("Pocket dimensions have already been loaded!"); 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(); loadInternal();
//Register Limbo //Register Limbo
@@ -72,6 +99,9 @@ public class PocketManager
//Register pocket dimensions //Register pocket dimensions
registerPockets(properties); registerPockets(properties);
isLoaded = true;
isLoading = false;
} }
public boolean clearPocket(NewDimData dimension) public boolean clearPocket(NewDimData dimension)
@@ -103,6 +133,9 @@ public class PocketManager
File save = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id()); File save = new File(DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(save); DeleteFolder.deleteFolder(save);
} }
//Raise the dim deleted event
dimWatcher.onDeleted(dimension.toKey());
//dimension.implode()??? -- more like delete, but yeah
return true; return true;
} }
else 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<String, Object> comboSave = new HashMap<String, Object>();
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 * loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler
* @return * @return
@@ -215,80 +189,67 @@ public class PocketManager
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static void loadInternal() private static void loadInternal()
{ {
//FIXME: There are a lot of things to fix here... First, we shouldn't be created so many File instances // SenseiKiwi: This is a temporary function for testing purposes.
//when we could just hold references and reuse them. Second, duplicate code is BAD. Loading stuff should // We'll move on to using a text-based format in the future.
//be a function so that you can apply it to the save file first, then the "backup", instead of duplicating
//so much code. >_<
boolean firstRun = false; if (!DimensionManager.getWorld(OVERWORLD_DIMENSION_ID).isRemote &&
System.out.println("Loading DimDoors data"); DimensionManager.getCurrentSaveRootDirectory() != null)
FileInputStream saveFile = null;
if (!DimensionManager.getWorld(OVERWORLD_DIMENSION_ID).isRemote && DimensionManager.getCurrentSaveRootDirectory()!=null)
{ {
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.
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;
}
isSaving = true;
try try
{ {
File dataStore = new File( DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsData"); System.out.println("Writing Dimensional Doors save data...");
if (!dataStore.exists()) 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)
{ {
if (!new File( DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoorsDataOLD").exists()) e.printStackTrace();
}
catch (IOException e)
{ {
firstRun=true; e.printStackTrace();
} }
} finally
saveFile = new FileInputStream(dataStore);
ObjectSaveInputStream save = new ObjectSaveInputStream(saveFile);
HashMap<String, Object> comboSave = (HashMap<String, Object>) save.readObject();
try
{ {
dimensionData = (HashMap<Integer, NewDimData>) comboSave.get("dimensionData"); isSaving = false;
}
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.");
}
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<String, Object> comboSave = (HashMap<String, Object>) save.readObject();
try
{
dimensionData = (HashMap<Integer, NewDimData>) 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();
}
}
}
} }
} }
@@ -340,7 +301,7 @@ public class PocketManager
throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered."); 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); dimensionData.put(dimensionID, dimension);
return dimension; return dimension;
} }
@@ -395,4 +356,38 @@ public class PocketManager
return null; 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!");
}
}
} }

View File

@@ -1,16 +1,13 @@
package StevenDimDoors.mod_pocketDim.dungeon; package StevenDimDoors.mod_pocketDim.dungeon;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.Serializable;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.schematic.InvalidSchematicException; 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 int weight;
private final boolean isOpen; private final boolean isOpen;
private final boolean isInternal; private final boolean isInternal;

View File

@@ -286,8 +286,8 @@ public class DungeonSchematic extends Schematic {
{ {
IDimLink link = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), IDimLink.TYPE_NORMAL); IDimLink link = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), IDimLink.TYPE_NORMAL);
Point4D destination = link.source(); Point4D destination = link.source();
link.setDestination(destination.getX(), destination.getY(), destination.getZ(), NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension());
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) private static void createExitDoorLink(NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)

View File

@@ -68,8 +68,8 @@ public class ItemRiftSignature extends Item
NewDimData destinationDimension = PocketManager.getDimensionData(world); NewDimData destinationDimension = PocketManager.getDimensionData(world);
IDimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), IDimLink.TYPE_NORMAL); IDimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), IDimLink.TYPE_NORMAL);
IDimLink reverse = destinationDimension.createLink(x, y, z, IDimLink.TYPE_NORMAL); IDimLink reverse = destinationDimension.createLink(x, y, z, IDimLink.TYPE_NORMAL);
link.setDestination(x, y, z, destinationDimension); destinationDimension.setDestination(link, x, y, z);
reverse.setDestination(source.getX(), source.getY(), source.getZ(), sourceDimension); sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
//Try placing a rift at the destination point //Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z)) if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z))

View File

@@ -74,13 +74,11 @@ import cpw.mods.fml.relauncher.Side;
@Mod(modid = mod_pocketDim.modid, name = "Dimensional Doors", version = mod_pocketDim.version) @Mod(modid = mod_pocketDim.modid, name = "Dimensional Doors", version = mod_pocketDim.version)
@NetworkMod(clientSideRequired = true, serverSideRequired = false, connectionHandler=ConnectionHandler.class,
@NetworkMod(clientSideRequired = true, serverSideRequired = false,
clientPacketHandlerSpec = clientPacketHandlerSpec =
@SidedPacketHandler(channels = {"pocketDim" }, packetHandler = ClientPacketHandler.class), @SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ClientPacketHandler.class),
serverPacketHandlerSpec = serverPacketHandlerSpec =
@SidedPacketHandler(channels = {"pocketDim" }, packetHandler = ServerPacketHandler.class), @SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class))
channels={"DimDoorPackets"}, packetHandler = PacketHandler.class, connectionHandler=ConnectionHandler.class)
public class mod_pocketDim public class mod_pocketDim
{ {

View File

@@ -0,0 +1,8 @@
package StevenDimDoors.mod_pocketDim.watcher;
import java.io.DataOutputStream;
public interface IOpaqueMessage
{
void writeToStream(DataOutputStream stream);
}

View File

@@ -0,0 +1,8 @@
package StevenDimDoors.mod_pocketDim.watcher;
import com.google.common.io.ByteArrayDataInput;
public interface IOpaqueReader
{
IOpaqueMessage read(ByteArrayDataInput source);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,51 @@
package StevenDimDoors.mod_pocketDim.watcher;
import java.util.ArrayList;
import java.util.List;
public class UpdateWatcherProxy implements IUpdateWatcher
{
private List<IUpdateWatcher> watchers;
public UpdateWatcherProxy()
{
watchers = new ArrayList<IUpdateWatcher>();
}
@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);
}
}

View File

@@ -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; package StevenDimDoors.mod_pocketDimClient;
// Theses are all the imports you need
import net.minecraft.network.INetworkManager; import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.network.packet.Packet250CustomPayload;
import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.Player; import cpw.mods.fml.common.network.Player;
// Create a class and implement IPacketHandler public class ClientPacketHandler implements IPacketHandler
// This just handles the data packets in the server {
public class ClientPacketHandler implements IPacketHandler{
@Override @Override
public void onPacketData(INetworkManager manager, public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
Packet250CustomPayload packet, Player player) { {
// TODO Auto-generated method stub
} }
} }