Rewrote All the Things #81

Merged
SenseiKiwi merged 8 commits from rewrite into DevBranch 2013-09-04 03:26:52 +00:00
10 changed files with 162 additions and 72 deletions
Showing only changes of commit 4cd7d3c0ae - Show all commits

View File

@@ -4,12 +4,11 @@ public class PacketConstants
{ {
private PacketConstants() { } private PacketConstants() { }
public static final String CHANNEL_NAME = "DimDoorsPackets";
public static final byte CLIENT_JOIN_PACKET_ID = 1; public static final byte CLIENT_JOIN_PACKET_ID = 1;
public static final byte CREATE_DIM_PACKET_ID = 2; 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 = 3;
public static final byte DELETE_DIM_PACKET_ID = 4; public static final byte CREATE_LINK_PACKET_ID = 4;
public static final byte CREATE_LINK_PACKET_ID = 5; public static final byte DELETE_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

@@ -23,7 +23,7 @@ public abstract class DimLink
protected DimLink(Point4D source, int linkType) protected DimLink(Point4D source, int linkType)
{ {
if (linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX && linkType != LinkTypes.UNKNOWN) if (linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX && linkType != LinkTypes.CLIENT_SIDE)
{ {
throw new IllegalArgumentException("The specified link type is invalid."); throw new IllegalArgumentException("The specified link type is invalid.");
} }

View File

@@ -7,7 +7,7 @@ public class LinkTypes
public static final int ENUM_MIN = 0; public static final int ENUM_MIN = 0;
public static final int ENUM_MAX = 8; public static final int ENUM_MAX = 8;
public static final int UNKNOWN = -1337; public static final int CLIENT_SIDE = -1337;
public static final int NORMAL = 0; public static final int NORMAL = 0;
public static final int LIMBO = 1; public static final int LIMBO = 1;

View File

@@ -167,6 +167,11 @@ public abstract class NewDimData
protected NewDimData(int id, NewDimData root) protected NewDimData(int id, NewDimData root)
{ {
// This constructor is meant for client-side code only // This constructor is meant for client-side code only
if (root == null)
{
throw new IllegalArgumentException("root cannot be null.");
}
this.id = id; this.id = id;
this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution
this.linkList = new ArrayList<InnerDimLink>(); //Should be stored in oct tree -- temporary solution this.linkList = new ArrayList<InnerDimLink>(); //Should be stored in oct tree -- temporary solution
@@ -180,15 +185,7 @@ public abstract class NewDimData
this.dungeon = null; this.dungeon = null;
this.linkWatcher = null; this.linkWatcher = null;
this.depth = 0; this.depth = 0;
if (root != null) this.root = root;
{
this.root = root;
}
else
{
this.root = this;
}
} }
public DimLink findNearestRift(World world, int range, int x, int y, int z) public DimLink findNearestRift(World world, int range, int x, int y, int z)

View File

@@ -17,6 +17,7 @@ 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 StevenDimDoors.mod_pocketDim.watcher.ClientDimData; import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy; import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
@@ -44,11 +45,51 @@ public class PocketManager
// This constructor is meant for client-side code only // This constructor is meant for client-side code only
super(id, root); super(id, root);
} }
}
public InnerDimData(int id) private static class ClientLinkWatcher implements IUpdateWatcher<Point4D>
{
@Override
public void onCreated(Point4D source)
{ {
// This constructor is meant for client-side code only NewDimData dimension = getDimensionData(source.getDimension());
super(id, null); dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE);
}
@Override
public void onDeleted(Point4D source)
{
NewDimData dimension = getDimensionData(source.getDimension());
dimension.deleteLink(source.getX(), source.getY(), source.getZ());
}
}
private static class ClientDimWatcher implements IUpdateWatcher<ClientDimData>
{
@Override
public void onCreated(ClientDimData data)
{
registerClientDimension(data.ID, data.RootID);
}
@Override
public void onDeleted(ClientDimData data)
{
deletePocket(getDimensionData(data.ID), false);
}
}
private static class DimRegistrationCallback implements IDimRegistrationCallback
{
// We use this class to provide Compactor with the ability to send us dim data without
// having to instantiate a bunch of data containers and without exposing an "unsafe"
// creation method for anyone to call. Integrity protection for the win! It's like
// exposing a private constructor ONLY to a very specific trusted class.
@Override
public NewDimData registerDimension(int dimensionID, int rootID)
{
return registerClientDimension(dimensionID, rootID);
} }
} }
@@ -302,6 +343,30 @@ public class PocketManager
return dimension; return dimension;
} }
private static NewDimData registerClientDimension(int dimensionID, int rootID)
{
// No need to raise events here since this code should only run on the client side
// getDimensionData() always handles root dimensions properly, even if the weren't defined before
InnerDimData root = (InnerDimData) getDimensionData(rootID);
InnerDimData dimension;
if (rootID != dimensionID)
{
dimension = dimensionData.get(dimensionID);
if (dimension == null)
{
dimension = new InnerDimData(dimensionID, root);
dimensionData.put(dimension.id(), dimension);
}
}
else
{
dimension = root;
}
return dimension;
}
public static NewDimData getDimensionData(World world) public static NewDimData getDimensionData(World world)
{ {
return getDimensionData(world.provider.dimensionId); return getDimensionData(world.provider.dimensionId);
@@ -323,6 +388,11 @@ public class PocketManager
return dimension; return dimension;
} }
public static Iterable<? extends NewDimData> getDimensions()
{
return dimensionData.values();
}
public static void unload() public static void unload()
{ {
save(); save();
@@ -377,6 +447,11 @@ public class PocketManager
return linkWatcher.unregisterReceiver(watcher); return linkWatcher.unregisterReceiver(watcher);
} }
public static void getWatchers(IUpdateSource updateSource)
{
updateSource.registerWatchers(new ClientDimWatcher(), new ClientLinkWatcher());
}
public static void writePacket(DataOutputStream output) throws IOException public static void writePacket(DataOutputStream output) throws IOException
{ {
// Write a very compact description of our dimensions and links to be sent to a client // Write a very compact description of our dimensions and links to be sent to a client
@@ -398,8 +473,8 @@ public class PocketManager
// Set up fields // Set up fields
dimensionData = new HashMap<Integer, InnerDimData>(); dimensionData = new HashMap<Integer, InnerDimData>();
dimWatcher = new UpdateWatcherProxy<ClientDimData>(); dimWatcher = null; // Clients shouldn't need to watch dims
linkWatcher = new UpdateWatcherProxy<Point4D>(); linkWatcher = null; // Clients shouldn't need to watch links
// Load compacted client-side dimension data // Load compacted client-side dimension data
Compactor.readDimensions(input, new DimRegistrationCallback()); Compactor.readDimensions(input, new DimRegistrationCallback());
@@ -411,42 +486,4 @@ public class PocketManager
isLoaded = true; isLoaded = true;
isLoading = false; isLoading = false;
} }
private static class DimRegistrationCallback implements IDimRegistrationCallback
{
// We use this class to provide Compactor with the ability to send us dim data without
// having to instantiate a bunch of data containers and without exposing an "unsafe"
// creation method for anyone to call. Integrity protection for the win! It's like
// exposing a private constructor ONLY to a very specific trusted class.
@Override
public NewDimData registerDimension(int dimensionID, int rootID)
{
// No need to raise events here since this code should only run on the client side
// We assume that the root dimension has already been registered to avoid dependency issues
InnerDimData root = dimensionData.get(rootID);
InnerDimData dimension;
if (rootID != dimensionID)
{
dimension = dimensionData.get(dimensionID);
if (dimension == null)
{
dimension = new InnerDimData(dimensionID, root);
dimensionData.put(dimension.id(), dimension);
}
}
else
{
if (root == null)
{
root = new InnerDimData(rootID);
dimensionData.put(root.id(), root);
}
dimension = root;
}
return dimension;
}
}
} }

View File

@@ -76,7 +76,7 @@ public class Compactor
for (int h = 0; h < linkCount; h++) for (int h = 0; h < linkCount; h++)
{ {
Point4D source = Point4D.read(input); Point4D source = Point4D.read(input);
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.UNKNOWN); dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE);
} }
} }
} }

View File

@@ -164,7 +164,7 @@ public class mod_pocketDim
//MonolithSpawner should be initialized before any provider instances are created //MonolithSpawner should be initialized before any provider instances are created
//Register the other regular tick receivers as well //Register the other regular tick receivers as well
spawner = new MonolithSpawner(commonTickHandler, properties); spawner = new MonolithSpawner(commonTickHandler, properties);
new RiftRegenerator(commonTickHandler, properties); //No need to store the reference new RiftRegenerator(commonTickHandler); //No need to store the reference
LimboDecay decay = new LimboDecay(commonTickHandler, properties); LimboDecay decay = new LimboDecay(commonTickHandler, properties);
transientDoor = (new TransientDoor(properties.TransientDoorID, Material.iron)).setHardness(1.0F) .setUnlocalizedName("transientDoor"); transientDoor = (new TransientDoor(properties.TransientDoorID, Material.iron)).setHardness(1.0F) .setUnlocalizedName("transientDoor");

View File

@@ -7,22 +7,16 @@ import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
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 cpw.mods.fml.relauncher.Side;
public class RiftRegenerator implements IRegularTickReceiver { public class RiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5; private static final int RIFTS_REGENERATED_PER_DIMENSION = 5;
private DDProperties properties; public RiftRegenerator(IRegularTickSender sender)
public RiftRegenerator(IRegularTickSender sender, DDProperties properties)
{ {
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false); sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
this.properties = properties;
} }
@Override @Override

View File

@@ -0,0 +1,8 @@
package StevenDimDoors.mod_pocketDim.watcher;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public interface IUpdateSource
{
public void registerWatchers(IUpdateWatcher<ClientDimData> dimWatcher, IUpdateWatcher<Point4D> linkWatcher);
}

View File

@@ -1,15 +1,70 @@
package StevenDimDoors.mod_pocketDimClient; package StevenDimDoors.mod_pocketDimClient;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
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.PacketConstants;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource;
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.Player; import cpw.mods.fml.common.network.Player;
public class ClientPacketHandler implements IPacketHandler public class ClientPacketHandler implements IPacketHandler, IUpdateSource
{ {
private IUpdateWatcher<Point4D> linkWatcher;
private IUpdateWatcher<ClientDimData> dimWatcher;
public ClientPacketHandler()
{
PocketManager.getWatchers(this);
}
@Override
public void registerWatchers(IUpdateWatcher<ClientDimData> dimWatcher, IUpdateWatcher<Point4D> linkWatcher)
{
this.dimWatcher = dimWatcher;
this.linkWatcher = linkWatcher;
}
@Override @Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
{ {
// TODO: Is this even necessary? I'm not convinced we can receive packets from other channels anyway!
if (!packet.channel.equals(PacketConstants.CHANNEL_NAME))
return;
try
{
DataInputStream input = new DataInputStream(new ByteArrayInputStream(packet.data));
byte packetID = input.readByte();
switch (packetID)
{
case PacketConstants.CLIENT_JOIN_PACKET_ID:
PocketManager.readPacket(input);
break;
case PacketConstants.CREATE_DIM_PACKET_ID:
dimWatcher.onCreated( ClientDimData.read(input) );
break;
case PacketConstants.CREATE_LINK_PACKET_ID:
linkWatcher.onCreated( Point4D.read(input) );
break;
case PacketConstants.DELETE_DIM_PACKET_ID:
dimWatcher.onDeleted( ClientDimData.read(input) );
break;
case PacketConstants.DELETE_LINK_PACKET_ID:
linkWatcher.onDeleted( Point4D.read(input) );
break;
}
}
catch (Exception e)
{
System.err.println("An exception occurred while processing a data packet:");
e.printStackTrace();
}
} }
} }