Completed Packet Handling Code

Finished implementing all the packet handling code. It could be improved
in the future to compress the initial packet sent to clients. With this,
the code is complete enough to run! Commands have not been fixed yet but
that will come in the future.
This commit is contained in:
SenseiKiwi
2013-09-03 17:25:58 -04:00
parent 3568d223ff
commit 4cd7d3c0ae
10 changed files with 162 additions and 72 deletions

View File

@@ -3,13 +3,12 @@ package StevenDimDoors.mod_pocketDim;
public class PacketConstants
{
private PacketConstants() { }
public static final String CHANNEL_NAME = "DimDoorsPackets";
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";
public static final byte DELETE_DIM_PACKET_ID = 3;
public static final byte CREATE_LINK_PACKET_ID = 4;
public static final byte DELETE_LINK_PACKET_ID = 5;
}

View File

@@ -23,7 +23,7 @@ public abstract class DimLink
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.");
}

View File

@@ -7,7 +7,7 @@ public class LinkTypes
public static final int ENUM_MIN = 0;
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 LIMBO = 1;

View File

@@ -167,6 +167,11 @@ public abstract class NewDimData
protected NewDimData(int id, NewDimData root)
{
// This constructor is meant for client-side code only
if (root == null)
{
throw new IllegalArgumentException("root cannot be null.");
}
this.id = id;
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
@@ -180,15 +185,7 @@ public abstract class NewDimData
this.dungeon = null;
this.linkWatcher = null;
this.depth = 0;
if (root != null)
{
this.root = root;
}
else
{
this.root = this;
}
this.root = root;
}
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.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
@@ -44,14 +45,54 @@ public class PocketManager
// This constructor is meant for client-side code only
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
super(id, null);
NewDimData dimension = getDimensionData(source.getDimension());
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);
}
}
private static int OVERWORLD_DIMENSION_ID = 0;
private static volatile boolean isLoading = false;
@@ -301,6 +342,30 @@ public class PocketManager
dimensionData.put(dimensionID, 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)
{
@@ -323,6 +388,11 @@ public class PocketManager
return dimension;
}
public static Iterable<? extends NewDimData> getDimensions()
{
return dimensionData.values();
}
public static void unload()
{
save();
@@ -376,6 +446,11 @@ public class PocketManager
{
return linkWatcher.unregisterReceiver(watcher);
}
public static void getWatchers(IUpdateSource updateSource)
{
updateSource.registerWatchers(new ClientDimWatcher(), new ClientLinkWatcher());
}
public static void writePacket(DataOutputStream output) throws IOException
{
@@ -398,8 +473,8 @@ public class PocketManager
// Set up fields
dimensionData = new HashMap<Integer, InnerDimData>();
dimWatcher = new UpdateWatcherProxy<ClientDimData>();
linkWatcher = new UpdateWatcherProxy<Point4D>();
dimWatcher = null; // Clients shouldn't need to watch dims
linkWatcher = null; // Clients shouldn't need to watch links
// Load compacted client-side dimension data
Compactor.readDimensions(input, new DimRegistrationCallback());
@@ -411,42 +486,4 @@ public class PocketManager
isLoaded = true;
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++)
{
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
//Register the other regular tick receivers as well
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);
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.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
public class RiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5;
private DDProperties properties;
public RiftRegenerator(IRegularTickSender sender, DDProperties properties)
public RiftRegenerator(IRegularTickSender sender)
{
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
this.properties = properties;
}
@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);
}