fix builder packet spam, rewrite network API - kill serializers, network data, replace RPC with PacketCommand

This commit is contained in:
asiekierka 2014-11-22 14:48:44 +01:00
parent ee0c036f19
commit bceb1b375e
100 changed files with 1703 additions and 3474 deletions

View file

@ -8,12 +8,12 @@
*/
package buildcraft.api.core;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.io.IOException;
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface NetworkData {
import io.netty.buffer.ByteBuf;
import net.minecraft.network.Packet;
public interface ISerializable {
void readData(ByteBuf stream);
void writeData(ByteBuf stream);
}

View file

@ -8,17 +8,15 @@
*/
package buildcraft.api.core;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
public class Position {
public class Position implements ISerializable {
@NetworkData
public double x, y, z;
@NetworkData
public ForgeDirection orientation;
public Position() {
@ -178,4 +176,20 @@ public class Position {
return !(sqrDis > f * f);
}
@Override
public void readData(ByteBuf stream) {
x = stream.readDouble();
y = stream.readDouble();
z = stream.readDouble();
orientation = ForgeDirection.getOrientation(stream.readByte());
}
@Override
public void writeData(ByteBuf stream) {
stream.writeDouble(x);
stream.writeDouble(y);
stream.writeDouble(z);
stream.writeByte(orientation.ordinal());
}
}

View file

@ -6,6 +6,6 @@
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
@API(apiVersion = "1.0", owner = "BuildCraft|Core", provides = "BuildCraftAPI|core")
@API(apiVersion = "1.1", owner = "BuildCraft|Core", provides = "BuildCraftAPI|core")
package buildcraft.api.core;
import cpw.mods.fml.common.API;

View file

@ -90,7 +90,6 @@ import buildcraft.core.Version;
import buildcraft.core.blueprints.SchematicRegistry;
import buildcraft.core.network.BuildCraftChannelHandler;
import buildcraft.core.network.EntityIds;
import buildcraft.core.network.NetworkIdRegistry;
import buildcraft.core.network.PacketHandler;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.proxy.CoreProxy;
@ -340,8 +339,6 @@ public class BuildCraftCore extends BuildCraftMod {
channels = NetworkRegistry.INSTANCE.newChannel
(DefaultProps.NET_CHANNEL_NAME + "-CORE", new BuildCraftChannelHandler(), new PacketHandler());
NetworkIdRegistry.instance = new NetworkIdRegistry();
// BuildCraft 6.1.4 and below - migration only
StatementManager.registerParameterClass("buildcraft:stackTrigger", StatementParameterItemStack.class);
StatementManager.registerParameterClass("buildcraft:stackAction", StatementParameterItemStack.class);

View file

@ -13,6 +13,7 @@ import java.util.EnumMap;
import org.apache.logging.log4j.Level;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.FMLEmbeddedChannel;
import cpw.mods.fml.common.network.FMLOutboundHandler;
@ -20,6 +21,7 @@ import cpw.mods.fml.common.network.FMLOutboundHandler.OutboundTarget;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.relauncher.Side;
import buildcraft.api.core.BCLog;
import buildcraft.core.DefaultProps;
import buildcraft.core.network.BuildCraftPacket;
public class BuildCraftMod {
@ -37,6 +39,14 @@ public class BuildCraftMod {
}
}
public void sendToPlayersNear(BuildCraftPacket packet, TileEntity tileEntity, int maxDistance) {
sendToPlayers(packet, tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, maxDistance);
}
public void sendToPlayersNear(BuildCraftPacket packet, TileEntity tileEntity) {
sendToPlayersNear(packet, tileEntity, DefaultProps.NETWORK_UPDATE_RANGE);
}
public void sendToWorld(BuildCraftPacket packet, World world) {
try {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET)

View file

@ -11,6 +11,7 @@ package buildcraft.builders;
import java.util.ArrayList;
import java.util.LinkedList;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@ -19,11 +20,12 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import cpw.mods.fml.relauncher.Side;
import net.minecraftforge.common.util.Constants;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.Position;
import buildcraft.core.Box;
import buildcraft.core.Box.Kind;
@ -33,22 +35,19 @@ import buildcraft.core.TileBuildCraft;
import buildcraft.core.blueprints.BlueprintReadConfiguration;
import buildcraft.core.blueprints.RecursiveBlueprintReader;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
public class TileArchitect extends TileBuildCraft implements IInventory, IBoxProvider {
public class TileArchitect extends TileBuildCraft implements IInventory, IBoxProvider, ICommandReceiver {
public String currentAuthorName = "";
@NetworkData
public Box box = new Box();
@NetworkData
public String name = "";
@NetworkData
public BlueprintReadConfiguration readConfiguration = new BlueprintReadConfiguration();
@NetworkData
public LinkedList<LaserData> subLasers = new LinkedList<LaserData>();
public ArrayList<BlockIndex> subBlueprints = new ArrayList<BlockIndex>();
@ -94,17 +93,6 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
}
}
@RPC (RPCSide.SERVER)
public void handleClientSetName(String nameSet) {
name = nameSet;
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "setName", name);
}
@RPC
public void setName (String name) {
this.name = name;
}
@Override
public int getSizeInventory() {
return 2;
@ -211,6 +199,30 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
nbt.setTag("subBlueprints", subBptList);
}
@Override
public void writeData(ByteBuf stream) {
box.writeData(stream);
Utils.writeUTF(stream, name);
readConfiguration.writeData(stream);
stream.writeShort(subLasers.size());
for (LaserData ld: subLasers) {
ld.writeData(stream);
}
}
@Override
public void readData(ByteBuf stream) {
box.readData(stream);
name = Utils.readUTF(stream);
readConfiguration.readData(stream);
int size = stream.readUnsignedShort();
subLasers.clear();
for (int i = 0; i < size; i++) {
LaserData ld = new LaserData();
ld.readData(stream);
subLasers.add(ld);
}
}
@Override
public void invalidate() {
super.invalidate();
@ -267,15 +279,39 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
return completeBox.getBoundingBox();
}
@RPC (RPCSide.SERVER)
private void setReadConfiguration (BlueprintReadConfiguration conf) {
readConfiguration = conf;
sendNetworkUpdate();
public BuildCraftPacket getPacketSetName() {
return new PacketCommand(this, "setName") {
@Override
public void writeData(ByteBuf data) {
Utils.writeUTF(data, name);
}
};
}
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (command.equals("setName")) {
this.name = Utils.readUTF(stream);
if (side.isServer()) {
BuildCraftCore.instance.sendToPlayersNear(getPacketSetName(), this);
}
} else if (side.isServer()) {
if (command.equals("setReadConfiguration")) {
readConfiguration.readData(stream);
sendNetworkUpdate();
}
}
}
public void rpcSetConfiguration (BlueprintReadConfiguration conf) {
readConfiguration = conf;
RPCHandler.rpcServer(this, "setReadConfiguration", conf);
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "setReadConfiguration"){
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
readConfiguration.writeData(data);
}
});
}
public void addSubBlueprint(TileEntity sub) {

View file

@ -11,6 +11,7 @@ package buildcraft.builders;
import java.io.IOException;
import java.util.ArrayList;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@ -18,22 +19,24 @@ import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTSizeTracker;
import net.minecraft.nbt.NBTTagCompound;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftBuilders;
import buildcraft.BuildCraftCore;
import buildcraft.builders.blueprints.BlueprintId;
import buildcraft.builders.blueprints.BlueprintId.Kind;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.blueprints.BlueprintBase;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
/**
* In this implementation, the blueprint library is the interface to the
* *local* player blueprint. The player will be able to load blueprint on his
* environment, and save blueprints to the server environment.
*/
public class TileBlueprintLibrary extends TileBuildCraft implements IInventory {
public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, ICommandReceiver {
private static final int PROGRESS_TIME = 100;
public SimpleInventory inv = new SimpleInventory(4, "Blueprint Library", 1);
@ -221,17 +224,23 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory {
setInventorySlotContents(1, getStackInSlot(0));
setInventorySlotContents(0, null);
BlueprintBase bpt = ItemBlueprint.loadBlueprint(getStackInSlot(1));
final BlueprintBase bpt = ItemBlueprint.loadBlueprint(getStackInSlot(1));
if (bpt != null && uploadingPlayer != null) {
RPCHandler.rpcPlayer(uploadingPlayer, this, "downloadBlueprintToClient",
bpt.id, bpt.getData());
BuildCraftCore.instance.sendToPlayer(uploadingPlayer, new PacketCommand(this, "downloadBlueprintToClient") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
bpt.id.writeData(data);
Utils.writeByteArray(data, bpt.getData());
}
});
uploadingPlayer = null;
}
}
if (progressOut == 100 && getStackInSlot(3) == null) {
RPCHandler.rpcPlayer(downloadingPlayer, this, "requestSelectedBlueprint");
BuildCraftCore.instance.sendToPlayer(downloadingPlayer, new PacketCommand(this, "requestSelectedBlueprint"));
progressOut = 0;
}
}
@ -241,58 +250,69 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory {
return false;
}
@RPC (RPCSide.CLIENT)
public void requestSelectedBlueprint () {
if (isOutputConsistent()) {
if (selected > -1 && selected < currentPage.size()) {
BlueprintBase bpt = BuildCraftBuilders.clientDB
.load(currentPage.get(selected));
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isClient()) {
if (command.equals("requestSelectedBlueprint")) {
if (isOutputConsistent()) {
if (selected > -1 && selected < currentPage.size()) {
final BlueprintBase bpt = BuildCraftBuilders.clientDB
.load(currentPage.get(selected));
RPCHandler.rpcServer(this, "uploadBlueprintToServer", bpt.id,
bpt.getData());
} else {
RPCHandler.rpcServer(this, "uploadBlueprintToServer", null,
null);
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadBlueprintToServer") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
bpt.id.writeData(data);
Utils.writeByteArray(data, bpt.getData());
}
});
} else {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadNothingToServer"));
}
}
} else if (command.equals("downloadBlueprintToClient")) {
BlueprintId id = new BlueprintId();
id.readData(stream);
byte[] data = Utils.readByteArray(stream);
try {
NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a);
BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt);
bpt.setData(data);
bpt.id = id;
BuildCraftBuilders.clientDB.add(bpt);
setCurrentPage(BuildCraftBuilders.clientDB.getPage(pageId));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@RPC (RPCSide.SERVER)
public void uploadBlueprintToServer (BlueprintId id, byte [] data) {
try {
if (data != null) {
NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a);
BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt);
bpt.setData(data);
bpt.id = id;
BuildCraftBuilders.serverDB.add(bpt);
setInventorySlotContents(3, bpt.getStack());
} else {
} else if (side.isServer()) {
if (command.equals("uploadNothingToServer")) {
setInventorySlotContents(3, getStackInSlot(2));
setInventorySlotContents(2, null);
downloadingPlayer = null;
} else if (command.equals("uploadBlueprintToServer")) {
BlueprintId id = new BlueprintId();
id.readData(stream);
byte[] data = Utils.readByteArray(stream);
try {
NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a);
BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt);
bpt.setData(data);
bpt.id = id;
BuildCraftBuilders.serverDB.add(bpt);
setInventorySlotContents(3, bpt.getStack());
setInventorySlotContents(2, null);
} catch(Exception e) {
e.printStackTrace();
}
downloadingPlayer = null;
}
setInventorySlotContents(2, null);
downloadingPlayer = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@RPC (RPCSide.CLIENT)
public void downloadBlueprintToClient (BlueprintId id, byte [] data) {
try {
NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a);
BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt);
bpt.setData(data);
bpt.id = id;
BuildCraftBuilders.clientDB.add(bpt);
setCurrentPage(BuildCraftBuilders.clientDB.getPage(pageId));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

View file

@ -13,6 +13,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@ -20,6 +21,7 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.WorldSettings.GameType;
import cpw.mods.fml.relauncher.Side;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
@ -28,9 +30,9 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftBuilders;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.Position;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
@ -54,18 +56,16 @@ import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.robots.ResourceIdRequest;
import buildcraft.core.robots.RobotRegistry;
import buildcraft.core.utils.Utils;
public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluidHandler, IRequestProvider {
private static int POWER_ACTIVATION = 500;
@NetworkData
public Box box = new Box();
public PathIterator currentPathIterator;
public Tank[] fluidTanks = new Tank[] {
@ -74,7 +74,6 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
new Tank("fluid3", FluidContainerRegistry.BUCKET_VOLUME * 8, this),
new Tank("fluid4", FluidContainerRegistry.BUCKET_VOLUME * 8, this)
};
@NetworkData
public TankManager<Tank> fluidTank = new TankManager<Tank>(fluidTanks);
private SimpleInventory inv = new SimpleInventory(28, "Builder", 64);
@ -439,8 +438,7 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
if (!worldObj.isRemote) {
if (i == 0) {
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "setItemRequirements",
null, null);
BuildCraftCore.instance.sendToWorld(new PacketCommand(this, "clearItemRequirements"), worldObj);
iterateBpt(false);
}
}
@ -623,33 +621,49 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
return requiredToBuild;
}
@RPC (RPCSide.CLIENT)
public void setItemRequirements(ArrayList<ItemStack> rq, ArrayList<Integer> realSizes) {
// Item stack serialized are represented through bytes, so 0-255. In
// order to get the real amounts, we need to pass the real sizes of the
// stacks as a separate list.
requiredToBuild = rq;
if (rq != null && rq.size() > 0) {
Iterator<ItemStack> itStack = rq.iterator();
Iterator<Integer> size = realSizes.iterator();
while (true) {
ItemStack stack = itStack.next();
stack.stackSize = size.next();
if (stack.stackSize > 999) {
stack.stackSize = 999;
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isClient()) {
if (command.equals("clearItemRequirements")) {
requiredToBuild = null;
} else if (command.equals("setItemRequirements")) {
int size = stream.readUnsignedShort();
requiredToBuild = new ArrayList<ItemStack>();
for (int i = 0; i < size; i++) {
ItemStack stack = Utils.readStack(stream);
stack.stackSize = Math.min(999, stream.readUnsignedShort());
requiredToBuild.add(stack);
}
if (!itStack.hasNext()) {
break;
}
} else if (side.isServer()) {
EntityPlayer player = (EntityPlayer) sender;
if (command.equals("eraseFluidTank")) {
int id = stream.readInt();
if (id < 0 || id >= fluidTanks.length) {
return;
}
if (isUseableByPlayer(player) && player.getDistanceSq(xCoord, yCoord, zCoord) <= 64) {
fluidTanks[id].setFluid(null);
sendNetworkUpdate();
}
}
}
}
private BuildCraftPacket getItemRequirementsPacket(final ArrayList<ItemStack> items) {
return new PacketCommand(this, "setItemRequirements") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeShort(items.size());
for (ItemStack rb: items) {
Utils.writeStack(data, rb);
data.writeShort(rb.stackSize);
}
}
};
}
@Override
public boolean isBuildingMaterialSlot(int i) {
return i != 0;
@ -695,46 +709,23 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
}
public void updateRequirements() {
if (guiWatchers.size() == 0) {
// Nobody watching, do not update.
return;
}
ArrayList<ItemStack> reqCopy = null;
ArrayList<Integer> realSize = null;
if (currentBuilder instanceof BptBuilderBlueprint) {
reqCopy = new ArrayList<ItemStack>();
realSize = new ArrayList<Integer>();
for (ItemStack stack : ((BptBuilderBlueprint) currentBuilder).neededItems) {
realSize.add(stack.stackSize);
ItemStack newStack = stack.copy();
newStack.stackSize = 0;
reqCopy.add(newStack);
}
reqCopy = ((BptBuilderBlueprint) currentBuilder).neededItems;
}
for (EntityPlayer p : guiWatchers) {
RPCHandler.rpcPlayer(p, this, "setItemRequirements", reqCopy, realSize);
BuildCraftCore.instance.sendToPlayer(p, getItemRequirementsPacket(reqCopy));
}
}
public void updateRequirements(EntityPlayer caller) {
ArrayList<ItemStack> reqCopy = null;
ArrayList<Integer> realSize = null;
if (currentBuilder instanceof BptBuilderBlueprint) {
reqCopy = new ArrayList<ItemStack>();
realSize = new ArrayList<Integer>();
for (ItemStack stack : ((BptBuilderBlueprint) currentBuilder).neededItems) {
realSize.add(stack.stackSize);
ItemStack newStack = stack.copy();
newStack.stackSize = 0;
reqCopy.add(newStack);
}
reqCopy = ((BptBuilderBlueprint) currentBuilder).neededItems;
}
RPCHandler.rpcPlayer(caller, this, "setItemRequirements", reqCopy, realSize);
BuildCraftCore.instance.sendToPlayer(caller, getItemRequirementsPacket(reqCopy));
}
public BptBuilderBase getBlueprint () {
@ -814,17 +805,6 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
return fluidTank.getTankInfo(from);
}
@RPC(RPCSide.SERVER)
public void eraseFluidTank(int id, RPCMessageInfo info) {
if (id < 0 || id >= fluidTanks.length) {
return;
}
if (isUseableByPlayer(info.sender) && info.sender.getDistanceSq(xCoord, yCoord, zCoord) <= 64) {
fluidTanks[id].setFluid(null);
sendNetworkUpdate();
}
}
@Override
public int getNumberOfRequests() {
if (currentBuilder == null) {
@ -936,4 +916,18 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid
return left;
}
@Override
public void writeData(ByteBuf stream) {
super.writeData(stream);
box.writeData(stream);
fluidTank.writeData(stream);
}
@Override
public void readData(ByteBuf stream) {
super.readData(stream);
box.readData(stream);
fluidTank.readData(stream);
}
}

View file

@ -11,14 +11,18 @@ package buildcraft.builders;
import java.util.ArrayList;
import java.util.HashSet;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import cpw.mods.fml.relauncher.Side;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.NetworkData;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.Position;
import buildcraft.core.Box;
import buildcraft.core.Box.Kind;
import buildcraft.core.DefaultProps;
import buildcraft.core.IBoxProvider;
import buildcraft.core.LaserData;
import buildcraft.core.TileBuildCraft;
@ -29,24 +33,19 @@ import buildcraft.core.blueprints.BptBuilderBlueprint;
import buildcraft.core.blueprints.BptContext;
import buildcraft.core.builders.BuildingItem;
import buildcraft.core.builders.IBuildingItemsProvider;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
public class TileConstructionMarker extends TileBuildCraft implements IBuildingItemsProvider, IBoxProvider {
public class TileConstructionMarker extends TileBuildCraft implements IBuildingItemsProvider, IBoxProvider, ICommandReceiver {
public static HashSet<TileConstructionMarker> currentMarkers = new HashSet<TileConstructionMarker>();
public ForgeDirection direction = ForgeDirection.UNKNOWN;
@NetworkData
public LaserData laser;
@NetworkData
public ItemStack itemBlueprint;
@NetworkData
public Box box = new Box();
public BptBuilderBase bluePrintBuilder;
@ -56,14 +55,25 @@ public class TileConstructionMarker extends TileBuildCraft implements IBuildingI
private NBTTagCompound initNBT;
@Override
public void initialize() {
public void initialize () {
super.initialize();
box.kind = Kind.BLUE_STRIPES;
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "uploadBuildersInAction");
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadBuildersInAction"));
}
}
private BuildCraftPacket createLaunchItemPacket(final BuildingItem i) {
return new PacketCommand(this, "launchItem") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
i.writeData(data);
}
};
}
@Override
public void updateEntity() {
super.updateEntity();
@ -186,12 +196,21 @@ public class TileConstructionMarker extends TileBuildCraft implements IBuildingI
@Override
public void addAndLaunchBuildingItem(BuildingItem item) {
buildersInAction.add(item);
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "launchItem", item);
BuildCraftCore.instance.sendToPlayersNear(createLaunchItemPacket(item), this);
}
@RPC(RPCSide.CLIENT)
private void launchItem(BuildingItem item) {
buildersInAction.add(item);
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer() && command.equals("uploadBuildersInAction")) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadBuildersInAction"));
for (BuildingItem i : buildersInAction) {
BuildCraftCore.instance.sendToPlayer((EntityPlayer) sender, createLaunchItemPacket(i));
}
} else if (side.isClient() && command.equals("launchItem")) {
BuildingItem item = new BuildingItem();
item.readData(stream);
buildersInAction.add(item);
}
}
@Override
@ -206,10 +225,32 @@ public class TileConstructionMarker extends TileBuildCraft implements IBuildingI
return renderBox.expand(50).getBoundingBox();
}
@RPC(RPCSide.SERVER)
private void uploadBuildersInAction(RPCMessageInfo info) {
for (BuildingItem i : buildersInAction) {
RPCHandler.rpcPlayer(info.sender, this, "launchItem", i);
@Override
public void writeData(ByteBuf stream) {
box.writeData(stream);
stream.writeByte((laser != null ? 1 : 0) | (itemBlueprint != null ? 2 : 0));
if (laser != null) {
laser.writeData(stream);
}
if (itemBlueprint != null) {
Utils.writeStack(stream, itemBlueprint);
}
}
@Override
public void readData(ByteBuf stream) {
box.readData(stream);
int flags = stream.readUnsignedByte();
if ((flags & 1) != 0) {
laser = new LaserData();
laser.readData(stream);
} else {
laser = null;
}
if ((flags & 2) != 0) {
itemBlueprint = Utils.readStack(stream);
} else {
itemBlueprint = null;
}
}
}

View file

@ -8,13 +8,13 @@
*/
package buildcraft.builders;
import java.io.IOException;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.filler.FillerManager;
import buildcraft.api.tiles.IControllable;
@ -27,14 +27,11 @@ import buildcraft.core.builders.TileAbstractBuilder;
import buildcraft.core.builders.patterns.FillerPattern;
import buildcraft.core.builders.patterns.PatternFill;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
public class TileFiller extends TileAbstractBuilder implements IHasWork, IControllable {
public class TileFiller extends TileAbstractBuilder implements IHasWork, IControllable, ICommandReceiver {
private static int POWER_ACTIVATION = 500;
@ -253,37 +250,21 @@ public class TileFiller extends TileAbstractBuilder implements IHasWork, IContro
}
@Override
public PacketPayload getPacketPayload() {
PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
@Override
public void writeData(ByteBuf data) {
box.writeToStream(data);
data.writeBoolean(done);
Utils.writeUTF(data, currentPattern.getUniqueTag());
}
});
return payload;
public void writeData(ByteBuf data) {
box.writeData(data);
data.writeBoolean(done);
Utils.writeUTF(data, currentPattern.getUniqueTag());
}
public void handlePacketPayload(ByteBuf data) {
box.readFromStream(data);
@Override
public void readData(ByteBuf data) {
box.readData(data);
done = data.readBoolean();
setPattern((FillerPattern) FillerManager.registry.getPattern(Utils.readUTF(data)));
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override
public void handleDescriptionPacket(PacketUpdate packet) throws IOException {
handlePacketPayload(packet.payload.stream);
}
@Override
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
handlePacketPayload(packet.payload.stream);
}
@Override
public boolean hasWork() {
return !done && lastMode != Mode.Off;
@ -302,13 +283,22 @@ public class TileFiller extends TileAbstractBuilder implements IHasWork, IContro
return true;
}
public void rpcSetPatternFromString (String name) {
RPCHandler.rpcServer(this, "setPatternFromString", name);
public void rpcSetPatternFromString (final String name) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "set") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeUTF(data, name);
}
});
}
@RPC (RPCSide.SERVER)
public void setPatternFromString (String name) {
setPattern((FillerPattern) FillerManager.registry.getPattern(name));
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer() && command.equals("set")) {
String name = Utils.readUTF(stream);
setPattern((FillerPattern) FillerManager.registry.getPattern(name));
}
}
@Override

View file

@ -8,6 +8,7 @@
*/
package buildcraft.builders;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
@ -15,7 +16,7 @@ import net.minecraft.world.World;
import buildcraft.BuildCraftBuilders;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.Position;
import buildcraft.core.EntityBlock;
import buildcraft.core.LaserKind;
@ -27,9 +28,8 @@ import buildcraft.core.utils.Utils;
public class TileMarker extends TileBuildCraft implements IAreaProvider {
private static int maxSize = 64;
public static class TileWrapper {
public static class TileWrapper implements ISerializable {
@NetworkData
public int x, y, z;
private TileMarker marker;
@ -69,24 +69,66 @@ public class TileMarker extends TileBuildCraft implements IAreaProvider {
y = Integer.MAX_VALUE;
z = Integer.MAX_VALUE;
}
@Override
public void readData(ByteBuf stream) {
x = stream.readInt();
if (isSet()) {
y = stream.readShort();
z = stream.readInt();
}
}
@Override
public void writeData(ByteBuf stream) {
stream.writeInt(x);
if (isSet()) {
// Only X is used for checking if a vector is set, so we can save space on the Y coordinate.
stream.writeShort(y);
stream.writeInt(z);
}
}
}
public static class Origin {
@NetworkData
public static class Origin implements ISerializable {
public TileWrapper vectO = new TileWrapper();
@NetworkData
public TileWrapper[] vect = {new TileWrapper(), new TileWrapper(), new TileWrapper()};
@NetworkData
public int xMin, yMin, zMin, xMax, yMax, zMax;
public boolean isSet() {
return vectO.isSet();
}
@Override
public void writeData(ByteBuf stream) {
vectO.writeData(stream);
for (TileWrapper tw : vect) {
tw.writeData(stream);
}
stream.writeInt(xMin);
stream.writeShort(yMin);
stream.writeInt(zMin);
stream.writeInt(xMax);
stream.writeShort(yMax);
stream.writeInt(zMax);
}
@Override
public void readData(ByteBuf stream) {
vectO.readData(stream);
for (TileWrapper tw : vect) {
tw.readData(stream);
}
xMin = stream.readInt();
yMin = stream.readShort();
zMin = stream.readInt();
xMax = stream.readInt();
yMax = stream.readShort();
zMax = stream.readInt();
}
}
@NetworkData
public Origin origin = new Origin();
@NetworkData
public boolean showSignals = false;
private Position initVectO;
@ -465,8 +507,15 @@ public class TileMarker extends TileBuildCraft implements IAreaProvider {
}
@Override
public void postPacketHandling(PacketUpdate packet) {
super.postPacketHandling(packet);
public void writeData(ByteBuf stream) {
origin.writeData(stream);
stream.writeBoolean(showSignals);
}
@Override
public void readData(ByteBuf stream) {
origin.readData(stream);
showSignals = stream.readBoolean();
switchSignals();

View file

@ -8,20 +8,18 @@
*/
package buildcraft.builders;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeSet;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.Position;
import buildcraft.core.LaserData;
import buildcraft.core.network.PacketUpdate;
public class TilePathMarker extends TileMarker {
@ -36,10 +34,7 @@ public class TilePathMarker extends TileMarker {
public boolean loadLink0 = false;
public boolean loadLink1 = false;
@NetworkData
public LaserData[] lasers = new LaserData[2];
@NetworkData
public boolean tryingToConnect = false;
public TilePathMarker[] links = new TilePathMarker[2];
@ -296,13 +291,38 @@ public class TilePathMarker extends TileMarker {
}
@Override
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
public void readData(ByteBuf data) {
boolean previousState = tryingToConnect;
super.handleUpdatePacket(packet);
int flags = data.readUnsignedByte();
if ((flags & 1) != 0) {
lasers[0] = new LaserData();
lasers[0].readData(data);
} else {
lasers[0] = null;
}
if ((flags & 2) != 0) {
lasers[1] = new LaserData();
lasers[1].readData(data);
} else {
lasers[1] = null;
}
tryingToConnect = (flags & 4) != 0;
if (previousState != tryingToConnect) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
@Override
public void writeData(ByteBuf data) {
int flags = (lasers[0] != null ? 1 : 0) | (lasers[1] != null ? 2 : 0) | (tryingToConnect ? 4 : 0);
data.writeByte(flags);
if (lasers[0] != null) {
lasers[0].writeData(data);
}
if (lasers[1] != null) {
lasers[1].writeData(data);
}
}
}

View file

@ -14,24 +14,20 @@ import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.BuildCraftBuilders;
import buildcraft.api.core.NetworkData;
public final class BlueprintId implements Comparable<BlueprintId> {
import buildcraft.api.core.ISerializable;
import buildcraft.core.utils.Utils;
public final class BlueprintId implements Comparable<BlueprintId>, ISerializable {
public enum Kind {
Template, Blueprint
};
@NetworkData
public byte[] uniqueId;
@NetworkData
public String name = "";
@NetworkData
public Kind kind = Kind.Blueprint;
public String completeId;
@ -140,4 +136,18 @@ public final class BlueprintId implements Comparable<BlueprintId> {
return result;
}
@Override
public void readData(ByteBuf stream) {
uniqueId = Utils.readByteArray(stream);
name = Utils.readUTF(stream);
kind = Kind.values()[stream.readUnsignedByte()];
}
@Override
public void writeData(ByteBuf stream) {
Utils.writeByteArray(stream, uniqueId);
Utils.writeUTF(stream, name);
stream.writeByte(kind.ordinal());
}
}

View file

@ -11,11 +11,13 @@ package buildcraft.builders.gui;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import buildcraft.BuildCraftBuilders;
import buildcraft.BuildCraftCore;
import buildcraft.builders.TileArchitect;
import buildcraft.core.DefaultProps;
import buildcraft.core.blueprints.BlueprintReadConfiguration;
@ -23,8 +25,9 @@ import buildcraft.core.gui.GuiBuildCraft;
import buildcraft.core.gui.buttons.GuiBetterButton;
import buildcraft.core.gui.tooltips.ToolTip;
import buildcraft.core.gui.tooltips.ToolTipLine;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.StringUtils;
import buildcraft.core.utils.Utils;
public class GuiArchitect extends GuiBuildCraft {
@ -161,7 +164,14 @@ public class GuiArchitect extends GuiBuildCraft {
textField.setFocused(false);
} else {
textField.textboxKeyTyped(c, i);
RPCHandler.rpcServer(architect, "handleClientSetName", textField.getText());
final String text = textField.getText();
BuildCraftCore.instance.sendToServer(new PacketCommand(architect, "setName") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeUTF(data, text);
}
});
}
} else {
super.keyTyped(c, i);

View file

@ -12,19 +12,21 @@ import java.util.Collection;
import org.lwjgl.opengl.GL11;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import buildcraft.BuildCraftCore;
import buildcraft.builders.TileBuilder;
import buildcraft.core.DefaultProps;
import buildcraft.core.fluids.Tank;
import buildcraft.core.gui.AdvancedSlot;
import buildcraft.core.gui.GuiAdvancedInterface;
import buildcraft.core.gui.ItemSlot;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.StringUtils;
public class GuiBuilder extends GuiAdvancedInterface {
@ -131,7 +133,13 @@ public class GuiBuilder extends GuiAdvancedInterface {
if (super.mousePressed(mc, x, y)) {
selectedButton = this;
clicked = true;
RPCHandler.rpcServer(builder, "eraseFluidTank", id);
BuildCraftCore.instance.sendToServer(new PacketCommand(builder, "eraseFluidTank") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeInt(id);
}
});
return true;
} else {
return false;

View file

@ -8,15 +8,13 @@
*/
package buildcraft.builders.urbanism;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.core.Box;
public class AnchoredBox {
@NetworkData
public class AnchoredBox implements ISerializable {
public Box box = new Box();
@NetworkData
public int x1, y1, z1;
public void setP2 (int x2, int y2, int z2) {
@ -38,4 +36,20 @@ public class AnchoredBox {
box.initialize(nbt);
}
@Override
public void readData(ByteBuf stream) {
box.readData(stream);
x1 = stream.readInt();
y1 = stream.readShort();
z1 = stream.readInt();
}
@Override
public void writeData(ByteBuf stream) {
box.writeData(stream);
stream.writeInt(x1);
stream.writeShort(y1);
stream.writeInt(z1);
}
}

View file

@ -10,6 +10,7 @@ package buildcraft.builders.urbanism;
import java.util.ArrayList;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
@ -19,20 +20,21 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import buildcraft.api.core.NetworkData;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.core.Box;
import buildcraft.core.Box.Kind;
import buildcraft.core.IBoxesProvider;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesProvider {
public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesProvider, ICommandReceiver {
public EntityUrbanist urbanist;
@NetworkData
public ArrayList<AnchoredBox> frames = new ArrayList<AnchoredBox>();
private EntityLivingBase player;
@ -81,21 +83,51 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
super.updateEntity();
}
@RPC (RPCSide.SERVER)
public void setBlock (int x, int y, int z) {
worldObj.setBlock(x, y, z, Blocks.brick_block);
private BuildCraftPacket createXYZPacket(String name, final int x, final int y, final int z) {
return new PacketCommand(this, name) {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeInt(x);
data.writeShort(y);
data.writeInt(z);
}
};
}
@RPC (RPCSide.SERVER)
public void eraseBlock (int x, int y, int z) {
// tasks.add(new UrbanistTaskErase(this, x, y, z));
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
// Non-XYZ commands go here
if (side.isClient() && command.equals("setFrameKind")) {
setFrameKind(stream.readInt(), stream.readInt());
} else if (side.isServer() && command.equals("startFiller")) {
String fillerTag = Utils.readUTF(stream);
Box box = new Box();
box.readData(stream);
startFiller(fillerTag, box);
} else {
// XYZ commands go here
int x = stream.readInt();
int y = stream.readInt();
int z = stream.readInt();
if (side.isServer() && command.equals("setBlock")) {
worldObj.setBlock(x, y, z, Blocks.brick_block);
} else if (side.isServer() && command.equals("eraseBlock")) {
// tasks.add(new UrbanistTaskErase(this, x, y, z));
} else if (command.equals("createFrame")) {
createFrame(x, y, z);
} else if (command.equals("moveFrame")) {
moveFrame(x, y, z);
}
}
}
public void rpcEraseBlock (int x, int y, int z) {
RPCHandler.rpcServer(this, "eraseBlock", x, y, z);
BuildCraftCore.instance.sendToServer(createXYZPacket("eraseBlock", x, y, z));
}
@RPC (RPCSide.BOTH)
public void createFrame (int x, int y, int z) {
isCreatingFrame = true;
AnchoredBox a = new AnchoredBox();
@ -114,10 +146,9 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
// TODO: this is OK in SMP, but the frame actually needs to be
// broadcasted to all players
createFrame(x, y, z);
RPCHandler.rpcServer(this, "createFrame", x, y, z);
BuildCraftCore.instance.sendToServer(createXYZPacket("createFrame", x, y, z));
}
@RPC (RPCSide.BOTH)
public void moveFrame (int x, int y, int z) {
if (isCreatingFrame) {
if (frames.size() > 0) {
@ -135,7 +166,7 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
// TODO: this is OK in SMP, but the frame actually needs to be
// broadcasted to all players
moveFrame(x, y, z);
RPCHandler.rpcServer(this, "moveFrame", x, y, z);
BuildCraftCore.instance.sendToServer(createXYZPacket("moveFrame", x, y, z));
}
}
@ -152,7 +183,6 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
}
}
@RPC (RPCSide.CLIENT)
public void setFrameKind (int id, int kind) {
if (id < frames.size()) {
AnchoredBox b = frames.get(id);
@ -162,8 +192,6 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
}
}
}
@RPC (RPCSide.SERVER)
public void startFiller (String fillerTag, Box box) {
// TODO: This need to be updated to the new blueprint system
/*BptBuilderBase builder = FillerPattern.patterns.get(fillerTag).getBlueprint(box, worldObj);
@ -186,8 +214,15 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
}*/
}
public void rpcStartFiller (String fillerTag, Box box) {
RPCHandler.rpcServer(this, "startFiller", fillerTag, box);
public void rpcStartFiller (final String fillerTag, final Box box) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "startFiller") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeUTF(data, fillerTag);
box.writeData(data);
}
});
}
public void destroyUrbanistEntity() {
@ -299,6 +334,26 @@ public class TileUrbanist extends TileBuildCraft implements IInventory, IBoxesPr
}
@Override
public void writeData(ByteBuf stream) {
stream.writeShort(frames.size());
for (AnchoredBox b : frames) {
b.writeData(stream);
}
}
@Override
public void readData(ByteBuf stream) {
frames.clear();
int size = stream.readUnsignedShort();
for (int i = 0; i < size; i++) {
AnchoredBox b = new AnchoredBox();
b.readData(stream);
frames.add(b);
}
}
@Override
public ArrayList<Box> getBoxes() {
ArrayList<Box> result = new ArrayList<Box>();

View file

@ -8,18 +8,20 @@
*/
package buildcraft.commander;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.core.gui.BuildCraftContainer;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
public class ContainerRequester extends BuildCraftContainer {
public class ContainerRequester extends BuildCraftContainer implements ICommandReceiver {
public GuiRequester gui;
@ -56,22 +58,32 @@ public class ContainerRequester extends BuildCraftContainer {
}
public void getRequestList() {
RPCHandler.rpcServer(this, "rpcGetRequestList");
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "getRequestList"));
}
@RPC(RPCSide.SERVER)
public void rpcGetRequestList(RPCMessageInfo info) {
ItemStack[] stacks = new ItemStack[TileRequester.NB_ITEMS];
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer() && command.equals("getRequestList")) {
final ItemStack[] stacks = new ItemStack[TileRequester.NB_ITEMS];
for (int i = 0; i < TileRequester.NB_ITEMS; ++i) {
stacks[i] = requester.getRequest(i);
for (int i = 0; i < TileRequester.NB_ITEMS; ++i) {
stacks[i] = requester.getRequest(i);
}
BuildCraftCore.instance.sendToPlayer((EntityPlayer) sender, new PacketCommand(this, "receiveRequestList") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
for (ItemStack s : stacks) {
Utils.writeStack(data, s);
}
}
});
} else if (side.isClient() && command.equals("receiveRequestList")) {
requests = new ItemStack[TileRequester.NB_ITEMS];
for (int i = 0; i < TileRequester.NB_ITEMS; i++) {
requests[i] = Utils.readStack(stream);
}
}
RPCHandler.rpcPlayer(info.sender, this, "rpcReceiveRequestList", stacks, null);
}
@RPC(RPCSide.CLIENT)
public void rpcReceiveRequestList(ItemStack[] items, Object dummy) {
requests = items;
}
}

View file

@ -8,21 +8,22 @@
*/
package buildcraft.commander;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.material.MapColor;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.core.BCDynamicTexture;
import buildcraft.core.ZonePlan;
import buildcraft.core.gui.BuildCraftContainer;
import buildcraft.core.gui.slots.SlotOutput;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
public class ContainerZonePlan extends BuildCraftContainer {
public class ContainerZonePlan extends BuildCraftContainer implements ICommandReceiver {
public BCDynamicTexture mapTexture;
public ZonePlan currentAreaSelection;
@ -55,32 +56,64 @@ public class ContainerZonePlan extends BuildCraftContainer {
return true;
}
public void loadArea(int index) {
RPCHandler.rpcServer(this, "rpcLoadArea", index);
public void loadArea(final int index) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "loadArea") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(index);
}
});
}
public void saveArea(int index) {
RPCHandler.rpcServer(this, "rpcSaveArea", index, currentAreaSelection);
public void saveArea(final int index) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "loadArea") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(index);
currentAreaSelection.writeData(data);
}
});
}
@RPC(RPCSide.SERVER)
private void rpcLoadArea(int index, RPCMessageInfo info) {
RPCHandler.rpcPlayer(info.sender, this, "rpcAreaLoaded", map.selectArea(index));
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isClient()) {
if (command.equals("areaLoaded")) {
currentAreaSelection = new ZonePlan();
currentAreaSelection.readData(stream);
gui.refreshSelectedArea();
} else if (command.equals("receiveImage")) {
int size = stream.readUnsignedShort();
for (int i = 0; i < size; ++i) {
mapTexture.colorMap[i] = stream.readInt();
}
}
} else if (side.isServer()) {
if (command.equals("loadArea")) {
final int index = stream.readUnsignedByte();
BuildCraftCore.instance.sendToPlayer((EntityPlayer) sender, new PacketCommand(this, "areaLoaded") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
map.selectArea(index).writeData(data);
}
});
} else if (command.equals("saveArea")) {
final int index = stream.readUnsignedByte();
ZonePlan plan = new ZonePlan();
plan.readData(stream);
map.setArea(index, plan);
} else if (command.equals("computeMap")) {
computeMap(stream.readInt(), stream.readInt(),
stream.readUnsignedShort(), stream.readUnsignedShort(),
stream.readUnsignedByte(), (EntityPlayer) sender);
}
}
}
@RPC(RPCSide.SERVER)
private void rpcSaveArea(int index, ZonePlan area) {
map.setArea(index, area);
}
@RPC(RPCSide.CLIENT)
private void rpcAreaLoaded(ZonePlan areaSelection) {
currentAreaSelection = areaSelection;
gui.refreshSelectedArea();
}
@RPC(RPCSide.SERVER)
private void computeMap(int cx, int cz, int width, int height, int blocksPerPixel, RPCMessageInfo info) {
private void computeMap(int cx, int cz, int width, int height, int blocksPerPixel, EntityPlayer player) {
mapTexture = new BCDynamicTexture(width, height);
int startX = cx - width * blocksPerPixel / 2;
@ -121,13 +154,15 @@ public class ContainerZonePlan extends BuildCraftContainer {
}
}
RPCHandler.rpcPlayer(info.sender, this, "receiveImage", mapTexture.colorMap);
}
@RPC(RPCSide.CLIENT)
private void receiveImage(int[] colors) {
for (int i = 0; i < colors.length; ++i) {
mapTexture.colorMap[i] = colors[i];
}
BuildCraftCore.instance.sendToPlayer(player, new PacketCommand(this, "receiveImage") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeShort(mapTexture.colorMap.length);
for (int i = 0; i < mapTexture.colorMap.length; i++) {
data.writeInt(mapTexture.colorMap[i]);
}
}
});
}
}

View file

@ -13,10 +13,12 @@ import java.util.List;
import org.lwjgl.opengl.GL11;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.inventory.IInventory;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.EnumColor;
import buildcraft.core.BCDynamicTexture;
import buildcraft.core.DefaultProps;
@ -26,7 +28,7 @@ import buildcraft.core.gui.GuiAdvancedInterface;
import buildcraft.core.gui.buttons.GuiBetterButton;
import buildcraft.core.gui.tooltips.ToolTip;
import buildcraft.core.gui.tooltips.ToolTipLine;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.StringUtils;
public class GuiZonePlan extends GuiAdvancedInterface {
@ -141,9 +143,17 @@ public class GuiZonePlan extends GuiAdvancedInterface {
}
private void uploadMap() {
RPCHandler.rpcServer(getContainer(), "computeMap", cx, cz, getContainer().mapTexture.width,
getContainer().mapTexture.height,
zoomLevel);
BuildCraftCore.instance.sendToServer(new PacketCommand(getContainer(), "computeMap") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeInt(cx);
data.writeInt(cz);
data.writeShort(getContainer().mapTexture.width);
data.writeShort(getContainer().mapTexture.height);
data.writeByte(zoomLevel);
}
});
}
@Override

View file

@ -8,25 +8,27 @@
*/
package buildcraft.commander;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IRequestProvider;
import buildcraft.api.robots.StackRequest;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.robots.ResourceIdRequest;
import buildcraft.core.robots.RobotRegistry;
import buildcraft.core.utils.Utils;
public class TileRequester extends TileBuildCraft implements IInventory, IRequestProvider {
public class TileRequester extends TileBuildCraft implements IInventory, IRequestProvider, ICommandReceiver {
public static final int NB_ITEMS = 20;
private SimpleInventory inv = new SimpleInventory(NB_ITEMS, "items", 64);
@ -36,14 +38,26 @@ public class TileRequester extends TileBuildCraft implements IInventory, IReques
}
@RPC(RPCSide.SERVER)
public void setRequest(int index, ItemStack stack) {
public void setRequest(final int index, final ItemStack stack) {
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "setRequest", index, stack);
return;
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "setRequest") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(index);
Utils.writeStack(data, stack);
}
});
} else {
requests.setInventorySlotContents(index, stack);
}
}
requests.setInventorySlotContents(index, stack);
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer() && command.equals("setRequest")) {
setRequest(stream.readUnsignedByte(), Utils.readStack(stream));
}
}
public ItemStack getRequest(int index) {

View file

@ -8,13 +8,13 @@
*/
package buildcraft.commander;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.chunk.Chunk;
import buildcraft.api.core.NetworkData;
import buildcraft.core.ItemMapLocation;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.ZonePlan;
@ -29,8 +29,7 @@ public class TileZonePlan extends TileBuildCraft implements IInventory {
public int chunkStartX, chunkStartZ;
public byte[] colors = new byte[RESOLUTION * RESOLUTION];
@NetworkData
public int progress = 0;
public short progress = 0;
private boolean scan = false;
private int chunkIt = 0;
@ -210,7 +209,17 @@ public class TileZonePlan extends TileBuildCraft implements IInventory {
}
}
public Object selectArea(int index) {
@Override
public void writeData(ByteBuf stream) {
stream.writeShort(progress);
}
@Override
public void readData(ByteBuf stream) {
progress = stream.readShort();
}
public ZonePlan selectArea(int index) {
if (selectedAreas[index] == null) {
selectedAreas[index] = new ZonePlan();
}

View file

@ -21,12 +21,11 @@ import net.minecraft.util.AxisAlignedBB;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.core.IBox;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.Position;
import buildcraft.core.utils.Utils;
public class Box implements IBox {
public class Box implements IBox, ISerializable {
public enum Kind {
LASER_RED,
LASER_YELLOW,
@ -36,16 +35,9 @@ public class Box implements IBox {
BLUE_STRIPES,
}
@NetworkData
public Kind kind = Kind.LASER_RED;
@NetworkData
public int xMin, yMin, zMin, xMax, yMax, zMax;
@NetworkData
public boolean initialized;
@NetworkData
public boolean isVisible = true;
public LaserData[] lasersData;
@ -250,30 +242,6 @@ public class Box implements IBox {
lasersData = Utils.createLaserDataBox(xMin, yMin, zMin, xMax, yMax, zMax);
}
public void writeToStream(ByteBuf stream) {
stream.writeBoolean(initialized);
stream.writeInt(xMin);
stream.writeInt(yMin);
stream.writeInt(zMin);
stream.writeInt(xMax);
stream.writeInt(yMax);
stream.writeInt(zMax);
}
public void readFromStream(ByteBuf stream) {
initialized = stream.readBoolean();
xMin = stream.readInt();
yMin = stream.readInt();
zMin = stream.readInt();
xMax = stream.readInt();
yMax = stream.readInt();
zMax = stream.readInt();
}
public void writeToNBT(NBTTagCompound nbttagcompound) {
nbttagcompound.setByte("kind", (byte) kind.ordinal());
@ -402,4 +370,32 @@ public class Box implements IBox {
return new BlockIndex(x, y, z);
}
@Override
public void readData(ByteBuf stream) {
kind = Kind.values()[stream.readByte()];
xMin = stream.readInt();
yMin = stream.readShort();
zMin = stream.readInt();
xMax = stream.readInt();
yMax = stream.readShort();
zMax = stream.readInt();
byte flags = stream.readByte();
initialized = (flags & 1) != 0;
isVisible = (flags & 2) != 0;
}
@Override
public void writeData(ByteBuf stream) {
stream.writeByte(kind.ordinal());
stream.writeInt(xMin);
stream.writeShort(yMin);
stream.writeInt(zMin);
stream.writeInt(xMax);
stream.writeShort(yMax);
stream.writeInt(zMax);
stream.writeByte((initialized ? 1 : 0) | (isVisible ? 2 : 0));
}
}

View file

@ -8,13 +8,11 @@
*/
package buildcraft.core;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.NetworkData;
public class ChunkIndex {
@NetworkData
public class ChunkIndex implements ISerializable {
public int x, z;
public ChunkIndex() {
@ -52,4 +50,16 @@ public class ChunkIndex {
x = nbt.getInteger("x");
z = nbt.getInteger("z");
}
@Override
public void readData(ByteBuf stream) {
x = stream.readInt();
z = stream.readInt();
}
@Override
public void writeData(ByteBuf stream) {
stream.writeInt(x);
stream.writeInt(z);
}
}

View file

@ -8,18 +8,15 @@
*/
package buildcraft.core;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.Position;
public class LaserData {
@NetworkData
public class LaserData implements ISerializable {
public Position head = new Position(0, 0, 0);
@NetworkData
public Position tail = new Position(0, 0, 0);
@NetworkData
public boolean isVisible = true;
public double renderSize = 1.0 / 16.0;
@ -78,4 +75,18 @@ public class LaserData {
tail.readFromNBT(nbt.getCompoundTag("tail"));
isVisible = nbt.getBoolean("isVisible");
}
@Override
public void readData(ByteBuf stream) {
head.readData(stream);
tail.readData(stream);
isVisible = stream.readBoolean();
}
@Override
public void writeData(ByteBuf stream) {
head.writeData(stream);
tail.writeData(stream);
stream.writeBoolean(isVisible);
}
}

View file

@ -8,14 +8,24 @@
*/
package buildcraft.core;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.Position;
import buildcraft.core.utils.Utils;
public class StackAtPosition {
@NetworkData
public class StackAtPosition implements ISerializable {
public ItemStack stack;
public Position pos;
public boolean display;
@Override
public void readData(ByteBuf stream) {
stack = Utils.readStack(stream);
}
@Override
public void writeData(ByteBuf stream) {
Utils.writeStack(stream, stack);
}
}

View file

@ -8,11 +8,9 @@
*/
package buildcraft.core;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
@ -23,42 +21,20 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import cofh.api.energy.IEnergyHandler;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.ISerializable;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ISynchronizedTile;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketTileUpdate;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.TilePacketWrapper;
import buildcraft.core.utils.Utils;
public abstract class TileBuildCraft extends TileEntity implements ISynchronizedTile, IEnergyHandler {
@SuppressWarnings("rawtypes")
private static Map<Class, TilePacketWrapper> updateWrappers = new HashMap<Class, TilePacketWrapper>();
@SuppressWarnings("rawtypes")
private static Map<Class, TilePacketWrapper> descriptionWrappers = new HashMap<Class, TilePacketWrapper>();
public abstract class TileBuildCraft extends TileEntity implements IEnergyHandler, ISynchronizedTile, ISerializable {
protected TileBuffer[] cache;
protected HashSet<EntityPlayer> guiWatchers = new HashSet<EntityPlayer>();
private final TilePacketWrapper descriptionPacket;
private final TilePacketWrapper updatePacket;
private boolean init = false;
private String owner = "[BuildCraft]";
private RFBattery battery;
public TileBuildCraft() {
if (!updateWrappers.containsKey(this.getClass())) {
updateWrappers.put(this.getClass(), new TilePacketWrapper(this.getClass()));
}
if (!descriptionWrappers.containsKey(this.getClass())) {
descriptionWrappers.put(this.getClass(), new TilePacketWrapper(this.getClass()));
}
updatePacket = updateWrappers.get(this.getClass());
descriptionPacket = descriptionWrappers.get(this.getClass());
}
public String getOwner() {
return owner;
}
@ -83,6 +59,10 @@ public abstract class TileBuildCraft extends TileEntity implements ISynchronized
}
}
public void initialize() {
}
@Override
public void validate() {
super.validate();
@ -96,10 +76,6 @@ public abstract class TileBuildCraft extends TileEntity implements ISynchronized
cache = null;
}
public void initialize() {
Utils.handleBufferedDescription(this);
}
public void onBlockPlacedBy(EntityLivingBase entity, ItemStack stack) {
if (entity instanceof EntityPlayer) {
owner = ((EntityPlayer) entity).getDisplayName();
@ -112,38 +88,30 @@ public abstract class TileBuildCraft extends TileEntity implements ISynchronized
public void sendNetworkUpdate() {
if (worldObj != null && !worldObj.isRemote) {
BuildCraftCore.instance.sendToPlayers(getUpdatePacket(), worldObj,
BuildCraftCore.instance.sendToPlayers(getPacketUpdate(), worldObj,
xCoord, yCoord, zCoord, DefaultProps.NETWORK_UPDATE_RANGE);
}
}
@Override
public Packet getDescriptionPacket() {
return Utils.toPacket(getUpdatePacket(), 0);
public void writeData(ByteBuf stream) {
}
@Override
public PacketPayload getPacketPayload() {
return updatePacket.toPayload(this);
public void readData(ByteBuf stream) {
}
@Override
public BuildCraftPacket getUpdatePacket() {
public BuildCraftPacket getPacketUpdate() {
return new PacketTileUpdate(this);
}
@Override
public void handleDescriptionPacket(PacketUpdate packet) throws IOException {
descriptionPacket.fromPayload(this, packet.payload);
public BuildCraftPacket getPacketDescription() {
return getPacketUpdate();
}
@Override
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
updatePacket.fromPayload(this, packet.payload);
}
@Override
public void postPacketHandling(PacketUpdate packet) {
public Packet getDescriptionPacket() {
return Utils.toPacket(getPacketDescription(), 0);
}
@Override

View file

@ -11,17 +11,16 @@ package buildcraft.core;
import java.util.BitSet;
import java.util.Random;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.core.utils.BitSetUtils;
import buildcraft.core.utils.Utils;
public class ZoneChunk {
public class ZoneChunk implements ISerializable {
@NetworkData
public BitSet property;
@NetworkData
private boolean fullSet = false;
public ZoneChunk() {
@ -109,4 +108,16 @@ public class ZoneChunk {
public boolean isEmpty() {
return !fullSet && property.isEmpty();
}
@Override
public void readData(ByteBuf stream) {
property = BitSetUtils.fromByteArray(Utils.readByteArray(stream));
fullSet = stream.readBoolean();
}
@Override
public void writeData(ByteBuf stream) {
Utils.writeByteArray(stream, BitSetUtils.toByteArray(property));
stream.writeBoolean(fullSet);
}
}

View file

@ -12,18 +12,17 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.IZone;
import buildcraft.api.core.NetworkData;
public class ZonePlan implements IZone {
@NetworkData
public class ZonePlan implements IZone, ISerializable {
private HashMap<ChunkIndex, ZoneChunk> chunkMapping = new HashMap<ChunkIndex, ZoneChunk>();
public boolean get(int x, int z) {
@ -144,4 +143,26 @@ public class ZonePlan implements IZone {
return null;
}
@Override
public void readData(ByteBuf stream) {
chunkMapping.clear();
int size = stream.readInt();
for (int i = 0; i < size; i++) {
ChunkIndex key = new ChunkIndex();
ZoneChunk value = new ZoneChunk();
key.readData(stream);
value.readData(stream);
chunkMapping.put(key, value);
}
}
@Override
public void writeData(ByteBuf stream) {
stream.writeInt(chunkMapping.size());
for (Map.Entry<ChunkIndex, ZoneChunk> e : chunkMapping.entrySet()) {
e.getKey().writeData(stream);
e.getValue().writeData(stream);
}
}
}

View file

@ -8,18 +8,13 @@
*/
package buildcraft.core.blueprints;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
public class BlueprintReadConfiguration {
@NetworkData
public class BlueprintReadConfiguration implements ISerializable {
public boolean rotate = true;
@NetworkData
public boolean excavate = true;
@NetworkData
public boolean allowCreative = false;
public void writeToNBT(NBTTagCompound nbttagcompound) {
@ -34,4 +29,20 @@ public class BlueprintReadConfiguration {
allowCreative = nbttagcompound.getBoolean("allowCreative");
}
@Override
public void readData(ByteBuf stream) {
int flags = stream.readUnsignedByte();
rotate = (flags & 1) != 0;
excavate = (flags & 2) != 0;
allowCreative = (flags & 4) != 0;
}
@Override
public void writeData(ByteBuf stream) {
stream.writeByte(
(rotate ? 1 : 0) |
(excavate ? 2 : 0) |
(allowCreative ? 4 : 0)
);
}
}

View file

@ -11,6 +11,7 @@ package buildcraft.core.builders;
import java.util.Date;
import java.util.LinkedList;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@ -20,18 +21,15 @@ import buildcraft.BuildCraftBuilders;
import buildcraft.api.blueprints.IBuilderContext;
import buildcraft.api.blueprints.MappingNotFoundException;
import buildcraft.api.blueprints.MappingRegistry;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.Position;
import buildcraft.core.StackAtPosition;
public class BuildingItem implements IBuildingItem {
public class BuildingItem implements IBuildingItem, ISerializable {
public static int ITEMS_SPACE = 2;
@NetworkData
public Position origin, destination;
@NetworkData
public LinkedList<StackAtPosition> stacksToDisplay = new LinkedList<StackAtPosition>();
public Position posDisplay = new Position();
@ -48,8 +46,6 @@ public class BuildingItem implements IBuildingItem {
private boolean initialized = false;
private double vx, vy, vz;
private double maxHeight;
@NetworkData
private double lifetime = 0;
public void initialize () {
@ -290,4 +286,31 @@ public class BuildingItem implements IBuildingItem {
}
}
}
@Override
public void readData(ByteBuf stream) {
origin = new Position();
destination = new Position();
origin.readData(stream);
destination.readData(stream);
lifetime = stream.readDouble();
stacksToDisplay.clear();
int size = stream.readUnsignedShort();
for (int i = 0; i < size; i++) {
StackAtPosition e = new StackAtPosition();
e.readData(stream);
stacksToDisplay.add(e);
}
}
@Override
public void writeData(ByteBuf stream) {
origin.writeData(stream);
destination.writeData(stream);
stream.writeDouble(lifetime);
stream.writeShort(stacksToDisplay.size());
for (StackAtPosition s: stacksToDisplay) {
s.writeData(stream);
}
}
}

View file

@ -11,22 +11,25 @@ package buildcraft.core.builders;
import java.util.ArrayList;
import java.util.LinkedList;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.nbt.NBTTagCompound;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.api.blueprints.BuilderAPI;
import buildcraft.api.blueprints.ITileBuilder;
import buildcraft.api.core.NetworkData;
import buildcraft.core.DefaultProps;
import buildcraft.core.IBoxProvider;
import buildcraft.core.LaserData;
import buildcraft.core.RFBattery;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
public abstract class TileAbstractBuilder extends TileBuildCraft implements ITileBuilder, IInventory, IBoxProvider,
IBuildingItemsProvider {
IBuildingItemsProvider, ICommandReceiver {
/**
* Computes the maximum amount of energy required to build a full chest,
@ -35,7 +38,6 @@ public abstract class TileAbstractBuilder extends TileBuildCraft implements ITil
*/
private static final int FULL_CHEST_ENERGY = 9 * 3 * 64 * BuilderAPI.BUILD_ENERGY + 10000;
@NetworkData
public LinkedList<LaserData> pathLasers = new LinkedList<LaserData> ();
public ArrayList<BuildingItem> buildersInAction = new ArrayList<BuildingItem>();
@ -52,14 +54,31 @@ public abstract class TileAbstractBuilder extends TileBuildCraft implements ITil
super.initialize();
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "uploadBuildersInAction");
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadBuildersInAction"));
}
}
@RPC (RPCSide.SERVER)
private void uploadBuildersInAction (RPCMessageInfo info) {
for (BuildingItem i : buildersInAction) {
RPCHandler.rpcPlayer(info.sender, this, "launchItem", i);
private BuildCraftPacket createLaunchItemPacket(final BuildingItem i) {
return new PacketCommand(this, "launchItem") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
i.writeData(data);
}
};
}
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer() && command.equals("uploadBuildersInAction")) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadBuildersInAction"));
for (BuildingItem i : buildersInAction) {
BuildCraftCore.instance.sendToPlayer((EntityPlayer) sender, createLaunchItemPacket(i));
}
} else if (side.isClient() && command.equals("launchItem")) {
BuildingItem item = new BuildingItem();
item.readData(stream);
buildersInAction.add(item);
}
}
@ -115,15 +134,10 @@ public abstract class TileAbstractBuilder extends TileBuildCraft implements ITil
return pathLasers;
}
@RPC (RPCSide.CLIENT)
public void launchItem (BuildingItem item) {
buildersInAction.add(item);
}
@Override
public void addAndLaunchBuildingItem(BuildingItem item) {
buildersInAction.add(item);
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "launchItem", item);
BuildCraftCore.instance.sendToPlayersNear(createLaunchItemPacket(item), this);
}
public final int energyAvailable() {
@ -147,6 +161,25 @@ public abstract class TileAbstractBuilder extends TileBuildCraft implements ITil
rfUnchangedCycles = 0;
}
@Override
public void readData(ByteBuf stream) {
int size = stream.readUnsignedShort();
pathLasers.clear();
for (int i = 0; i < size; i++) {
LaserData ld = new LaserData();
ld.readData(stream);
pathLasers.add(ld);
}
}
@Override
public void writeData(ByteBuf stream) {
stream.writeShort(pathLasers.size());
for (LaserData ld : pathLasers) {
ld.writeData(stream);
}
}
@Override
public double getMaxRenderDistanceSquared() {
return Double.MAX_VALUE;

View file

@ -8,16 +8,19 @@
*/
package buildcraft.core.gui;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.core.ItemList;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
public class ContainerList extends BuildCraftContainer {
public class ContainerList extends BuildCraftContainer implements ICommandReceiver {
public ItemList.StackLine[] lines;
private EntityPlayer player;
@ -45,18 +48,24 @@ public class ContainerList extends BuildCraftContainer {
return true;
}
@RPC(RPCSide.SERVER)
public void setStack(int lineIndex, int slotIndex, ItemStack stack) {
public void setStack(final int lineIndex, final int slotIndex, final ItemStack stack) {
lines[lineIndex].setStack(slotIndex, stack);
ItemList.saveLine(player.getCurrentEquippedItem(), lines[lineIndex], lineIndex);
if (player.worldObj.isRemote) {
RPCHandler.rpcServer(this, "setStack", lineIndex, slotIndex, stack);
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "switchButton") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(lineIndex);
data.writeByte(slotIndex);
Utils.writeStack(data, stack);
}
});
}
}
@RPC(RPCSide.SERVER)
public void switchButton(int lineIndex, int button) {
public void switchButton(final int lineIndex, final int button) {
if (button == 0) {
lines[lineIndex].oreWildcard = false;
lines[lineIndex].subitemsWildcard = !lines[lineIndex].subitemsWildcard;
@ -68,16 +77,41 @@ public class ContainerList extends BuildCraftContainer {
ItemList.saveLine(player.getCurrentEquippedItem(), lines[lineIndex], lineIndex);
if (player.worldObj.isRemote) {
RPCHandler.rpcServer(this, "switchButton", lineIndex, button);
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "switchButton") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(lineIndex);
data.writeByte(button);
}
});
}
}
@RPC(RPCSide.SERVER)
public void setLabel(String text) {
public void setLabel(final String text) {
ItemList.saveLabel(player.getCurrentEquippedItem(), text);
if (player.worldObj.isRemote) {
RPCHandler.rpcServer(this, "setLabel", text);
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "setLabel") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeUTF(data, text);
}
});
}
}
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer()) {
if (command.equals("setLabel")) {
setLabel(Utils.readUTF(stream));
} else if (command.equals("switchButton")) {
switchButton(stream.readUnsignedByte(), stream.readUnsignedByte());
} else if (command.equals("setStack")) {
setStack(stream.readUnsignedByte(), stream.readUnsignedByte(), Utils.readStack(stream));
}
}
}
}

View file

@ -34,12 +34,7 @@ public class BuildCraftChannelHandler extends FMLIndexedMessageToMessageCodec<Bu
addDiscriminator(9, PacketPipeTransportItemStackRequest.class);
addDiscriminator(10, PacketPipeTransportTraveler.class);
addDiscriminator(11, PacketUpdate.class);
addDiscriminator(12, PacketRPCTile.class);
addDiscriminator(13, PacketRPCPipe.class);
addDiscriminator(14, PacketRPCGui.class);
addDiscriminator(15, PacketRPCEntity.class);
addDiscriminator(16, PacketRPCStatic.class);
addDiscriminator(17, PacketRPCPart.class);
addDiscriminator(12, PacketCommand.class);
}
@Override

View file

@ -0,0 +1,11 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
public abstract class CommandTarget {
public abstract Class getHandledClass();
public abstract ICommandReceiver handle(EntityPlayer player, ByteBuf data, World world);
public abstract void write(ByteBuf data, Object target);
}

View file

@ -0,0 +1,26 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.world.World;
public class CommandTargetContainer extends CommandTarget {
@Override
public Class getHandledClass() {
return Container.class;
}
@Override
public ICommandReceiver handle(EntityPlayer player, ByteBuf data, World world) {
Container container = player.openContainer;
if (container != null && container instanceof ICommandReceiver) {
return (ICommandReceiver) container;
}
return null;
}
@Override
public void write(ByteBuf data, Object target) {
}
}

View file

@ -0,0 +1,29 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
public class CommandTargetEntity extends CommandTarget {
@Override
public Class getHandledClass() {
return Entity.class;
}
@Override
public void write(ByteBuf data, Object target) {
Entity entity = (Entity) target;
data.writeInt(entity.getEntityId());
}
@Override
public ICommandReceiver handle(EntityPlayer player, ByteBuf data, World world) {
int id = data.readInt();
Entity entity = world.getEntityByID(id);
if (entity != null && entity instanceof ICommandReceiver) {
return (ICommandReceiver) entity;
}
return null;
}
}

View file

@ -0,0 +1,35 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class CommandTargetTile extends CommandTarget {
@Override
public Class getHandledClass() {
return TileEntity.class;
}
@Override
public void write(ByteBuf data, Object target) {
TileEntity tile = (TileEntity) target;
data.writeInt(tile.xCoord);
data.writeShort(tile.yCoord);
data.writeInt(tile.zCoord);
}
@Override
public ICommandReceiver handle(EntityPlayer player, ByteBuf data, World world) {
int posX = data.readInt();
int posY = data.readShort();
int posZ = data.readInt();
if (world.blockExists(posX, posY, posZ)) {
TileEntity tile = world.getTileEntity(posX, posY, posZ);
if (tile instanceof ICommandReceiver) {
return (ICommandReceiver) tile;
}
}
return null;
}
}

View file

@ -0,0 +1,8 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import cpw.mods.fml.relauncher.Side;
public interface ICommandReceiver {
void receiveCommand(String command, Side side, Object sender, ByteBuf stream);
}

View file

@ -1,28 +1,6 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import java.io.IOException;
import net.minecraft.network.Packet;
public interface ISynchronizedTile {
void handleDescriptionPacket(PacketUpdate packet) throws IOException;
void handleUpdatePacket(PacketUpdate packet) throws IOException;
void postPacketHandling(PacketUpdate packet);
BuildCraftPacket getUpdatePacket();
Packet getDescriptionPacket();
PacketPayload getPacketPayload();
BuildCraftPacket getPacketUpdate();
BuildCraftPacket getPacketDescription();
}

View file

@ -1,160 +0,0 @@
package buildcraft.core.network;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent;
import cpw.mods.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent;
import cpw.mods.fml.common.network.FMLNetworkEvent.ServerConnectionFromClientEvent;
import buildcraft.core.utils.Utils;
public class NetworkIdRegistry {
public static NetworkIdRegistry instance;
private static boolean isLocal = false;
private static boolean isMaster = false;
private static BiMap<String, Integer> idMap = HashBiMap.create();
private static LinkedList<EntityPlayerMP> playersToInitialize = new LinkedList<EntityPlayerMP>();
public NetworkIdRegistry() {
FMLCommonHandler.instance().bus().register(this);
}
public static void write(ByteBuf buf, String strId) {
if (!isMaster) {
if (!idMap.containsKey(strId)) {
buf.writeInt(-1);
Utils.writeUTF(buf, strId);
} else {
buf.writeInt(idMap.get(strId));
}
} else {
if (!idMap.containsKey(strId)) {
idMap.put(strId, idMap.size());
if (!isLocal) {
RPCHandler.rpcBroadcastAllPlayers(NetworkIdRegistry.class, "receiveId", strId, idMap.size() - 1);
}
}
buf.writeInt(idMap.get(strId));
}
}
public static String read(ByteBuf buf) {
int id = buf.readInt();
if (!isMaster) {
if (!idMap.inverse().containsKey(id)) {
RPCHandler.rpcServer(NetworkIdRegistry.class, "requestId", id);
throw new IllegalArgumentException("Id " + id + " unknown by the registry.");
} else {
return idMap.inverse().get(id);
}
} else {
if (id == -1) {
String str = Utils.readUTF(buf);
if (!idMap.containsKey(str)) {
idMap.put(str, idMap.size());
}
return str;
} else {
return idMap.inverse().get(id);
}
}
}
@RPC(RPCSide.SERVER)
private static void requestId(int id, RPCMessageInfo info) {
if (!idMap.inverse().containsKey(id)) {
throw new IllegalArgumentException("Id " + id + " unknown by the registry.");
} else {
RPCHandler.rpcPlayer(info.sender, NetworkIdRegistry.class, "receiveId", idMap.inverse().get(id), id);
}
}
@RPC(RPCSide.SERVER)
private static void receiveId(String str, int id) {
idMap.put(str, id);
}
private static void sendAllIdsTo(EntityPlayerMP player) {
ArrayList<String> idStr = new ArrayList<String>();
ArrayList<Integer> ids = new ArrayList<Integer>();
for (Map.Entry<String, Integer> e : idMap.entrySet()) {
idStr.add(e.getKey());
ids.add(e.getValue());
}
RPCHandler.rpcPlayer(player, NetworkIdRegistry.class, "receiveAllIds", idStr, ids);
}
@RPC(RPCSide.CLIENT)
private static void receiveAllIds(ArrayList<String> idStr, ArrayList<Integer> ids) {
idMap.clear();
for (int i = 0; i < idStr.size(); ++i) {
if (!idMap.containsKey(idStr.get(i))) {
System.out.println("INIT " + ids.get(i) + " => " + idStr.get(i));
idMap.put(idStr.get(i), ids.get(i));
}
}
}
@SubscribeEvent
public void serverConnected(ServerConnectionFromClientEvent evt) {
isMaster = true;
if (evt.isLocal) {
isLocal = true;
} else {
isLocal = false;
// the server cannot send messages to the client at this stage, so
// cache the new client to receive ids on the next tick.
playersToInitialize.add(((NetHandlerPlayServer) evt.handler).playerEntity);
}
}
@SubscribeEvent
public void serverConnected(ClientConnectedToServerEvent evt) {
if (!evt.isLocal) {
isMaster = false;
isLocal = false;
}
}
@SubscribeEvent
public void tick(ServerTickEvent evt) {
for (EntityPlayerMP player : playersToInitialize) {
sendAllIdsTo(player);
}
playersToInitialize.clear();
}
static {
// The ids below are the minimal ids necessary to initialize properly
// the server. They are aimed at supporting the provide of receiveAllIds
idMap.put("", 0);
idMap.put(NetworkIdRegistry.class.getCanonicalName(), 1);
idMap.put(String.class.getCanonicalName(), 2);
idMap.put(Integer.class.getCanonicalName(), 3);
}
}

View file

@ -0,0 +1,73 @@
package buildcraft.core.network;
import java.io.IOException;
import java.util.ArrayList;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler;
import buildcraft.core.utils.Utils;
public class PacketCommand extends BuildCraftPacket {
public static final ArrayList<CommandTarget> targets;
public ByteBuf stream;
public String command;
public Object target;
public CommandTarget handler;
static {
targets = new ArrayList<CommandTarget>();
targets.add(new CommandTargetTile());
targets.add(new CommandTargetEntity());
targets.add(new CommandTargetContainer());
}
public PacketCommand() {
}
public PacketCommand(Object target, String command) {
super();
this.target = target;
this.command = command;
// Find the valid handler
for (CommandTarget c : targets) {
if (c.getHandledClass().isAssignableFrom(target.getClass())) {
this.handler = c;
break;
}
}
}
public void handle(EntityPlayer player) {
System.out.println("Handling packet '" + command + "'");
if (handler != null) {
System.out.println("2");
ICommandReceiver receiver = (ICommandReceiver) handler.handle(player, stream, player.worldObj);
if (receiver != null) {
receiver.receiveCommand(command, FMLCommonHandler.instance().getEffectiveSide(), player, stream);
}
}
}
@Override
public void writeData(ByteBuf data) {
Utils.writeUTF(data, command);
data.writeByte(targets.indexOf(handler));
handler.write(data, target);
}
@Override
public void readData(ByteBuf data) {
command = Utils.readUTF(data);
handler = targets.get(data.readUnsignedByte());
stream = data; // for further reading
}
@Override
public int getID() {
return PacketIds.COMMAND;
}
}

View file

@ -32,7 +32,7 @@ public abstract class PacketCoordinates extends BuildCraftPacket {
public void writeData(ByteBuf data) {
data.writeByte(id);
data.writeInt(posX);
data.writeInt(posY);
data.writeShort(posY);
data.writeInt(posZ);
}
@ -40,7 +40,7 @@ public abstract class PacketCoordinates extends BuildCraftPacket {
public void readData(ByteBuf data) {
id = data.readByte ();
posX = data.readInt();
posY = data.readInt();
posY = data.readShort();
posZ = data.readInt();
}

View file

@ -19,8 +19,10 @@ import net.minecraft.network.INetHandler;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import buildcraft.api.core.ISerializable;
import buildcraft.core.proxy.CoreProxy;
@Sharable
@ -34,13 +36,12 @@ public class PacketHandler extends SimpleChannelInboundHandler<BuildCraftPacket>
TileEntity entity = packet.getTarget(world);
if (!(entity instanceof ISynchronizedTile)) {
if (!(entity instanceof ISerializable)) {
return;
}
ISynchronizedTile tile = (ISynchronizedTile) entity;
tile.handleUpdatePacket(packet);
tile.postPacketHandling(packet);
ISerializable tile = (ISerializable) entity;
tile.readData(packet.stream);
}
@Override
@ -52,72 +53,40 @@ public class PacketHandler extends SimpleChannelInboundHandler<BuildCraftPacket>
int packetID = packet.getID();
switch (packetID) {
case PacketIds.TILE_UPDATE: {
onTileUpdate(player, (PacketTileUpdate) packet);
break;
}
case PacketIds.STATE_UPDATE: {
PacketTileState pkt = (PacketTileState) packet;
World world = player.worldObj;
TileEntity tile = world.getTileEntity(pkt.posX, pkt.posY, pkt.posZ);
if (tile instanceof ISyncedTile) {
pkt.applyStates((ISyncedTile) tile);
case PacketIds.TILE_UPDATE: {
onTileUpdate(player, (PacketTileUpdate) packet);
break;
}
case PacketIds.COMMAND: {
((PacketCommand) packet).handle(player);
break;
}
break;
}
case PacketIds.STATE_UPDATE: {
PacketTileState pkt = (PacketTileState) packet;
World world = player.worldObj;
case PacketIds.GUI_RETURN: {
// action will have happened already at read time
break;
}
TileEntity tile = world.getTileEntity(pkt.posX, pkt.posY, pkt.posZ);
case PacketIds.GUI_WIDGET: {
// action will have happened already at read time
break;
}
if (tile instanceof ISyncedTile) {
pkt.applyStates((ISyncedTile) tile);
}
case PacketIds.RPC: {
((PacketRPC) packet).call(player);
break;
}
break;
}
case PacketIds.RPC_PIPE: {
// TODO: RPC pipes are not used right now. Ressurect this
// code if needed later.
/*
* PacketRPCPipe rpc = new PacketRPCPipe(); rpc.sender = player;
*
* int dimId = data.readShort(); World world = null;
*
* if (!rpc.sender.worldObj.isRemote) { // if this is a server,
* then get the world
*
* world = DimensionManager.getProvider(dimId).worldObj; } else
* if (rpc.sender.worldObj.provider.dimensionId == dimId) { //
* if the player is on this world, then synchronize things
*
* world = rpc.sender.worldObj; }
*
* if (world != null) { int x = data.readInt(); int y =
* data.readInt(); int z = data.readInt();
*
* TileEntity tile = world.getTileEntity(x, y, z);
*
* if (tile instanceof TileGenericPipe) { rpc.setPipe
* (((TileGenericPipe) tile).pipe); rpc.readData(data); } }
*/
break;
case PacketIds.GUI_RETURN: {
// action will have happened already at read time
break;
}
case PacketIds.GUI_WIDGET: {
// action will have happened already at read time
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View file

@ -11,7 +11,7 @@ package buildcraft.core.network;
public final class PacketIds {
public static final int TILE_UPDATE = 0;
// public static final int PIPE_DESCRIPTION = 1;
public static final int COMMAND = 1;
public static final int PIPE_TRAVELER = 2;
public static final int PIPE_LIQUID = 3;
public static final int PIPE_POWER = 4;
@ -24,16 +24,12 @@ public final class PacketIds {
public static final int REFINERY_FILTER_SET = 50;
public static final int ADVANCED_WORKBENCH_SETSLOT = 70;
public static final int SELECTION_ADVANCED_WORKBENCH = 71;
public static final int GUI_RETURN = 80;
public static final int GUI_WIDGET = 81;
public static final int STATE_UPDATE = 100;
public static final int RPC = 110;
public static final int RPC_PIPE = 111;
/**
* Deactivate constructor
*/

View file

@ -1,36 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
public class PacketPayload {
public ByteBuf stream;
private StreamWriter handler;
public interface StreamWriter {
void writeData(ByteBuf data);
}
public PacketPayload() {
}
public PacketPayload(StreamWriter handler) {
this.handler = handler;
}
public void writeData(ByteBuf data) {
handler.writeData(data);
}
public void readData(ByteBuf data) {
stream = data;
}
}

View file

@ -1,98 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer;
public abstract class PacketRPC extends BuildCraftPacket {
public static HashMap<Integer, ByteBuf> bufferedPackets = new HashMap<Integer, ByteBuf>();
public static int GLOBAL_ID = new Random(new Date().getTime()).nextInt();
protected int id;
protected ByteBuf contents;
public PacketRPC() {
id = GLOBAL_ID++;
}
@Override
public final int getID() {
return PacketIds.RPC;
}
public void call(EntityPlayer sender) {
if (bufferedPackets.containsKey(id)) {
ByteBuf data = bufferedPackets.remove(id);
if (data != null) {
contents = data.writeBytes(contents);
}
}
}
public ArrayList<PacketRPC> breakIntoSmallerPackets(int maxSize) {
ArrayList<PacketRPC> messages = new ArrayList<PacketRPC>();
if (contents.readableBytes() < maxSize) {
messages.add(this);
return messages;
}
int start = 0;
while (true) {
ByteBuf subContents = contents.readBytes(contents.readableBytes() > maxSize ? maxSize : contents
.readableBytes());
PacketRPCPart subPacket = new PacketRPCPart();
subPacket.id = id;
subPacket.contents = subContents;
messages.add(subPacket);
start += maxSize;
if (contents.readableBytes() == 0) {
break;
}
}
contents = Unpooled.buffer();
messages.add(this);
return messages;
}
@Override
public void readData(ByteBuf data) {
id = data.readInt();
int length = data.readInt();
contents = Unpooled.buffer(length);
data.readBytes(contents, length);
}
@Override
public void writeData(ByteBuf data) {
data.writeInt(id);
data.writeInt(contents.readableBytes());
data.writeBytes(contents);
}
}

View file

@ -1,55 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
public class PacketRPCEntity extends PacketRPC {
private Entity entity;
private int entityId;
public PacketRPCEntity() {
}
public PacketRPCEntity(Entity iEntity, ByteBuf bytes) {
entity = iEntity;
contents = bytes;
}
@Override
public void call(EntityPlayer sender) {
super.call(sender);
RPCMessageInfo info = new RPCMessageInfo();
info.sender = sender;
entity = sender.worldObj.getEntityByID(entityId);
if (entity != null) {
RPCHandler.receiveRPC(entity, info, contents);
}
}
@Override
public void readData(ByteBuf data) {
super.readData(data);
entityId = data.readInt();
}
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeInt(entity.getEntityId());
}
}

View file

@ -1,21 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import net.minecraft.entity.player.EntityPlayer;
public class PacketRPCPart extends PacketRPC {
@Override
public void call(EntityPlayer sender) {
super.call(sender);
bufferedPackets.put(id, contents);
}
}

View file

@ -1,53 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import buildcraft.transport.Pipe;
// TODO: This is not yet used
public class PacketRPCPipe extends BuildCraftPacket {
public Pipe<?> pipe;
public EntityPlayer sender;
private byte[] contents;
public PacketRPCPipe() {
}
public PacketRPCPipe(byte[] bytes) {
contents = bytes;
}
public void setPipe(Pipe<?> aPipe) {
pipe = aPipe;
}
@Override
public int getID() {
return PacketIds.RPC_PIPE;
}
@Override
public void readData(ByteBuf data) {
RPCMessageInfo info = new RPCMessageInfo();
info.sender = sender;
RPCHandler.receiveRPC(pipe, info, data);
}
@Override
public void writeData(ByteBuf data) {
data.writeBytes(contents);
}
}

View file

@ -1,54 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
public class PacketRPCStatic extends PacketRPC {
private String classId;
private Class<?> clas;
public PacketRPCStatic() {
}
public PacketRPCStatic(Class iClass, ByteBuf bytes) {
contents = bytes;
clas = iClass;
}
@Override
public void readData(ByteBuf data) {
super.readData(data);
classId = NetworkIdRegistry.read(data);
}
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
NetworkIdRegistry.write(data, clas.getCanonicalName());
}
@Override
public void call (EntityPlayer sender) {
super.call(sender);
RPCMessageInfo info = new RPCMessageInfo();
info.sender = sender;
try {
RPCHandler.receiveStaticRPC(Class.forName(classId), info, contents);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

View file

@ -1,84 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
public class PacketRPCTile extends PacketRPC {
public TileEntity tile;
int dimId;
int x, y, z;
public PacketRPCTile () {
}
public PacketRPCTile(TileEntity tile, ByteBuf bytes) {
this.tile = tile;
contents = bytes;
}
public void setTile (TileEntity aTile) {
tile = aTile;
}
@Override
public void readData(ByteBuf data) {
super.readData(data);
dimId = data.readShort();
x = data.readInt();
y = data.readShort();
z = data.readInt();
}
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
// In order to save space on message, we assuming dimensions ids
// small. Maybe worth using a varint instead
data.writeShort(tile.getWorldObj().provider.dimensionId);
data.writeInt(tile.xCoord);
data.writeShort(tile.yCoord);
data.writeInt(tile.zCoord);
}
@Override
public void call (EntityPlayer sender) {
World world = null;
if (!sender.worldObj.isRemote) {
// if this is a server, then get the world
world = DimensionManager.getProvider(dimId).worldObj;
} else if (sender.worldObj.provider.dimensionId == dimId) {
// if the player is on this world, then synchronize things
world = sender.worldObj;
}
TileEntity localTile = world.getTileEntity(x, y, z);
setTile (localTile);
RPCMessageInfo info = new RPCMessageInfo();
info.sender = sender;
RPCHandler.receiveRPC(localTile, info, contents);
}
}

View file

@ -10,6 +10,7 @@ package buildcraft.core.network;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import buildcraft.api.core.ISerializable;
public class PacketTileUpdate extends PacketUpdate {
@ -17,18 +18,16 @@ public class PacketTileUpdate extends PacketUpdate {
super(PacketIds.TILE_UPDATE);
}
public PacketTileUpdate(ISynchronizedTile tile) {
public PacketTileUpdate(ISerializable tile) {
super(PacketIds.TILE_UPDATE);
payload = tile.getPacketPayload();
TileEntity entity = (TileEntity) tile;
posX = entity.xCoord;
posY = entity.yCoord;
posZ = entity.zCoord;
this.isChunkDataPacket = true;
this.payload = tile;
}
public boolean targetExists(World world) {

View file

@ -9,24 +9,26 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import buildcraft.api.core.ISerializable;
public class PacketUpdate extends BuildCraftPacket {
public int posX;
public int posY;
public int posZ;
public PacketPayload payload;
public ByteBuf stream;
public ISerializable payload;
private int packetId;
public PacketUpdate() {
}
public PacketUpdate(int packetId, PacketPayload payload) {
public PacketUpdate(int packetId, ISerializable payload) {
this(packetId, 0, 0, 0, payload);
}
public PacketUpdate(int packetId, int posX, int posY, int posZ, PacketPayload payload) {
public PacketUpdate(int packetId, int posX, int posY, int posZ, ISerializable payload) {
this(packetId);
this.posX = posX;
@ -60,13 +62,7 @@ public class PacketUpdate extends BuildCraftPacket {
posY = data.readShort();
posZ = data.readInt();
if (data.isReadable()) {
payload = new PacketPayload();
if (payload != null) {
payload.readData(data);
}
}
stream = data; // for further reading
}
@Override

View file

@ -9,24 +9,22 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import buildcraft.api.core.ISerializable;
import net.minecraft.entity.player.EntityPlayer;
public class PacketWrapper implements ISerializable {
private final ISerializable wrapped;
public class PacketRPCGui extends PacketRPC {
public PacketRPCGui() {
}
public PacketRPCGui(ByteBuf bytes) {
contents = bytes;
public PacketWrapper(ISerializable wrapped) {
this.wrapped = wrapped;
}
@Override
public void call (EntityPlayer sender) {
super.call(sender);
public void readData(ByteBuf stream) {
wrapped.readData(stream);
}
RPCMessageInfo info = new RPCMessageInfo();
info.sender = sender;
RPCHandler.receiveRPC(sender.openContainer, info, contents);
@Override
public void writeData(ByteBuf stream) {
wrapped.writeData(stream);
}
}

View file

@ -1,21 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RPC {
//FIXME: Take into account side constraints when making calls to check
// they're correclyt made
RPCSide value() default RPCSide.BOTH;
}

View file

@ -1,382 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.JavaTools;
import buildcraft.core.DefaultProps;
import buildcraft.core.network.serializers.ClassMapping;
import buildcraft.core.network.serializers.ClassSerializer;
import buildcraft.core.network.serializers.SerializationContext;
import buildcraft.core.utils.Utils;
import buildcraft.transport.Pipe;
/**
* This is a first implementation of a RPC connector, using the regular tile
* synchronization layers as a communication protocol. As a result, these
* RPCs must be sent and received by a tile entity.
*/
public final class RPCHandler {
public static int MAX_PACKET_SIZE = 30 * 1024;
private static Map<String, RPCHandler> handlers = new TreeMap<String, RPCHandler>();
private Class<? extends Object> handledClass;
private Map<String, Integer> methodsMap = new TreeMap<String, Integer>();
class MethodMapping {
Method method;
Class<?>[] parameters;
ClassSerializer[] mappings;
boolean hasInfo = false;
}
private MethodMapping[] methods;
private RPCHandler(Class<? extends Object> c) {
handledClass = c;
Method[] sortedMethods = JavaTools.getAllMethods(c).toArray(new Method[0]);
LinkedList<MethodMapping> mappings = new LinkedList<MethodMapping>();
Arrays.sort(sortedMethods, new Comparator<Method>() {
@Override
public int compare(Method o1, Method o2) {
return o1.getName().compareTo(o2.getName());
}
});
LinkedList<Method> rpcMethods = new LinkedList<Method>();
for (Method sortedMethod : sortedMethods) {
if (sortedMethod.getAnnotation(RPC.class) != null) {
sortedMethod.setAccessible(true);
methodsMap.put(sortedMethod.getName(), rpcMethods.size());
rpcMethods.add(sortedMethod);
MethodMapping mapping = new MethodMapping();
mapping.method = sortedMethod;
mapping.parameters = sortedMethod.getParameterTypes();
mapping.mappings = new ClassSerializer[mapping.parameters.length];
for (int j = 0; j < mapping.parameters.length; ++j) {
if (mapping.parameters[j].equals(RPCMessageInfo.class)) {
mapping.hasInfo = true;
} else {
mapping.mappings [j] = ClassMapping.get(mapping.parameters [j]);
}
}
mappings.add(mapping);
}
}
methods = mappings.toArray(new MethodMapping [mappings.size()]);
}
private static RPCHandler getHandler(Object object) {
Class<?> clas;
if (object instanceof Class<?>) {
clas = (Class<?>) object;
} else {
clas = object.getClass();
}
if (!handlers.containsKey(clas.getName())) {
handlers.put(clas.getName(), new RPCHandler(clas));
}
return handlers.get(clas.getName());
}
public static void rpcServer(Object object, String method, Object... actuals) {
PacketRPC packet = createPacket(object, method, actuals);
if (packet != null) {
for (PacketRPC p : packet.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
BuildCraftCore.instance.sendToServer(p);
}
}
}
public static void rpcPlayer(EntityPlayer player, Object object, String method, Object... actuals) {
PacketRPC packet = createPacket(object, method, actuals);
if (packet != null) {
for (PacketRPC p : packet.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
BuildCraftCore.instance.sendToPlayer(player, p);
}
}
}
public static void rpcBroadcastWorldPlayers(World world, Object object, String method, Object... actuals) {
RPCHandler.rpcBroadcastPlayersAtDistance(world, object, method, DefaultProps.NETWORK_UPDATE_RANGE, actuals);
}
public static void rpcBroadcastPlayersAtDistance(World world, Object object, String method, int maxDistance,
Object... actuals) {
PacketRPC packet = createPacket(object, method, actuals);
if (packet != null) {
if (packet instanceof PacketRPCTile) {
TileEntity tile = (TileEntity) object;
for (PacketRPC p : packet.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
BuildCraftCore.instance.sendToPlayers(p, world, tile.xCoord, tile.yCoord, tile.zCoord, maxDistance);
}
} else {
for (PacketRPC p : packet.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
BuildCraftCore.instance.sendToWorld(p, world);
}
}
}
}
public static void rpcBroadcastAllPlayers(Object object, String method, Object... actuals) {
PacketRPC packet = createPacket(object, method, actuals);
if (packet != null) {
for (PacketRPC p : packet.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
BuildCraftCore.instance.sendToAll(p);
}
}
}
public static void receiveStaticRPC(Class clas, RPCMessageInfo info, ByteBuf data) {
if (clas != null) {
getHandler(clas).internalRpcReceive(clas, info, data);
}
}
public static void receiveRPC(Object obj, RPCMessageInfo info, ByteBuf data) {
if (obj != null) {
getHandler(obj.getClass()).internalRpcReceive(obj, info, data);
}
}
private PacketRPCPipe createRCPPacketPipe(Pipe<?> pipe, String method, Object ... actuals) {
ByteBuf data = Unpooled.buffer();
try {
TileEntity tile = pipe.container;
// In order to save space on message, we assuming dimensions ids
// small. Maybe worth using a varint instead
data.writeShort(tile.getWorldObj().provider.dimensionId);
data.writeInt(tile.xCoord);
data.writeInt(tile.yCoord);
data.writeInt(tile.zCoord);
writeParameters(method, data, actuals);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
byte [] bytes = new byte [data.readableBytes()];
data.readBytes(bytes);
return new PacketRPCPipe(bytes);
}
private static PacketRPC createPacket(Object object, String method, Object... actuals) {
PacketRPC packet = null;
if (object instanceof Container) {
packet = getHandler(object).createRCPPacketContainer(method, actuals);
} else if (object instanceof TileEntity) {
packet = getHandler(object).createRCPPacketTile((TileEntity) object, method, actuals);
} else if (object instanceof Entity) {
packet = getHandler(object).createRCPPacketEntity((Entity) object, method, actuals);
} else if (object instanceof Class<?>) {
packet = getHandler(object).createRCPPacketStatic((Class<?>) object, method, actuals);
}
return packet;
}
private ByteBuf getBytes(String method, Object... actuals) {
ByteBuf data = Unpooled.buffer();
try {
writeParameters(method, data, actuals);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return data;
}
private PacketRPCTile createRCPPacketTile(TileEntity tile, String method, Object... actuals) {
return new PacketRPCTile(tile, getBytes(method, actuals));
}
private PacketRPCGui createRCPPacketContainer(String method, Object... actuals) {
return new PacketRPCGui(getBytes(method, actuals));
}
private PacketRPCEntity createRCPPacketEntity(Entity entity, String method, Object... actuals) {
return new PacketRPCEntity(entity, getBytes(method, actuals));
}
private PacketRPC createRCPPacketStatic(Class<?> clas, String method, Object[] actuals) {
return new PacketRPCStatic(clas, getBytes(method, actuals));
}
private void writeParameters(String method, ByteBuf data, Object... actuals)
throws IOException, IllegalArgumentException,
IllegalAccessException {
if (!methodsMap.containsKey(method)) {
throw new RuntimeException(method + " is not a callable method of "
+ handledClass.getName());
}
int methodIndex = methodsMap.get(method);
MethodMapping m = methods[methodIndex];
Class<?>[] formals = m.parameters;
int expectedParameters = m.hasInfo ? formals.length - 1
: formals.length;
if (expectedParameters != actuals.length) {
// We accept formals + 1 as an argument, in order to support the
// special last argument RPCMessageInfo
throw new RuntimeException(getClass().getName() + "." + method
+ " expects " + m.parameters.length + " parameters, not "
+ actuals.length);
}
data.writeShort(methodIndex);
SerializationContext context = new SerializationContext();
for (int i = 0; i < actuals.length; ++i) {
if (!writePrimitive(data, formals[i], actuals[i])) {
m.mappings[i].write(data, actuals[i], context);
}
}
}
private boolean writePrimitive(ByteBuf data, Class<?> formal, Object actual) {
if (int.class.equals(formal)) {
data.writeInt((Integer) actual);
} else if (float.class.equals(formal)) {
data.writeFloat((Float) actual);
} else if (double.class.equals(formal)) {
data.writeDouble((Double) actual);
} else if (char.class.equals(formal)) {
data.writeChar((Character) actual);
} else if (boolean.class.equals(formal)) {
data.writeBoolean((Boolean) actual);
} else if (String.class.equals(formal)) {
Utils.writeUTF(data, (String) actual);
} else if (Enum.class.isAssignableFrom(formal)) {
data.writeByte((byte) ((Enum) actual).ordinal());
} else {
return false;
}
return true;
}
private void internalRpcReceive (Object o, RPCMessageInfo info, ByteBuf data) {
if (data.readableBytes() <= 0) {
// This seems to happen from time to time on the client side.
// TODO: Find out why. (Someone suggests WAILA might have something to do
// with it)
return;
}
try {
short methodIndex = data.readShort();
MethodMapping m = methods [methodIndex];
Class<?>[] formals = m.parameters;
Object[] actuals = new Object [formals.length];
int expectedParameters = m.hasInfo ? formals.length - 1 : formals.length;
SerializationContext context = new SerializationContext();
for (int i = 0; i < expectedParameters; ++i) {
if (!readPrimitive(data, formals[i], actuals, i)) {
actuals [i] = m.mappings [i].read (data, actuals [i], context);
}
}
if (m.hasInfo) {
actuals [actuals.length - 1] = info;
}
m.method.invoke(o, actuals);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private boolean readPrimitive(ByteBuf data, Class<?> formal, Object[] actuals, int i) {
if (int.class.equals(formal)) {
actuals[i] = data.readInt();
} else if (float.class.equals(formal)) {
actuals[i] = data.readFloat();
} else if (double.class.equals(formal)) {
actuals[i] = data.readDouble();
} else if (char.class.equals(formal)) {
actuals[i] = data.readChar();
} else if (boolean.class.equals(formal)) {
actuals[i] = data.readBoolean();
} else if (String.class.equals(formal)) {
actuals[i] = Utils.readUTF(data);
} else if (Enum.class.isAssignableFrom(formal)) {
actuals[i] = ((Class) formal).getEnumConstants()[data.readByte()];
} else {
return false;
}
return true;
}
}

View file

@ -1,15 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import net.minecraft.entity.player.EntityPlayer;
public class RPCMessageInfo {
public EntityPlayer sender;
}

View file

@ -1,13 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
public enum RPCSide {
CLIENT, SERVER, BOTH
}

View file

@ -0,0 +1,16 @@
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import buildcraft.api.core.ISerializable;
public class Serializable implements ISerializable {
@Override
public void readData(ByteBuf stream) {
}
@Override
public void writeData(ByteBuf stream) {
}
}

View file

@ -1,107 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.tileentity.TileEntity;
import buildcraft.core.network.serializers.ClassMapping;
import buildcraft.core.network.serializers.ClassSerializer;
import buildcraft.core.network.serializers.SerializationContext;
public class TilePacketWrapper {
ClassSerializer[] rootMappings;
@SuppressWarnings("rawtypes")
public TilePacketWrapper(Class c) {
this(new Class[] {c});
}
@SuppressWarnings({ "rawtypes" })
public TilePacketWrapper(Class[] c) {
rootMappings = new ClassSerializer [c.length];
for (int i = 0; i < c.length; ++i) {
rootMappings[i] = ClassMapping.get (c[i]);
}
}
public PacketPayload toPayload(final TileEntity tile) {
return new PacketPayload(new PacketPayload.StreamWriter() {
@Override
public void writeData(ByteBuf data) {
try {
SerializationContext context = new SerializationContext();
rootMappings[0].write(data, tile, context);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
});
}
public PacketPayload toPayload(Object obj) {
return toPayload(0, 0, 0, new Object[] { obj });
}
public PacketPayload toPayload(int x, int y, int z, Object obj) {
return toPayload(x, y, z, new Object[] { obj });
}
public PacketPayload toPayload(final int x, final int y, final int z, final Object[] obj) {
return new PacketPayload(new PacketPayload.StreamWriter() {
@Override
public void writeData(ByteBuf data) {
for (int i = 0; i < rootMappings.length; ++i) {
try {
SerializationContext context = new SerializationContext();
rootMappings[0].write(data, obj [i], context);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
});
}
public void fromPayload(TileEntity tile, PacketPayload packet) {
try {
ByteBuf data = packet.stream;
SerializationContext context = new SerializationContext();
rootMappings[0].read(data, tile, context);
} catch (Exception e) {
e.printStackTrace();
}
}
public void fromPayload(Object obj, PacketPayload packet) {
fromPayload(new Object[] { obj }, packet);
}
public void fromPayload(Object[] obj, PacketPayload packet) {
try {
ByteBuf data = packet.stream;
for (int i = 0; i < rootMappings.length; ++i) {
SerializationContext context = new SerializationContext();
rootMappings[i].read(data, obj[i], context);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -1,678 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.api.core.JavaTools;
import buildcraft.api.core.NetworkData;
import buildcraft.api.statements.IStatementParameter;
import buildcraft.core.network.INBTSerializable;
import buildcraft.core.network.NetworkIdRegistry;
/**
* This class implements custom class mapping. There are three advantages in
* using a custom serializer here:
*
* (1) the approach is constructive instead of destructive, that is to say,
* only marked fields will be taken. Granted, this is mostly coding style
* related, but this prevent introduction of useless serialized data by
* mistake.
*
* (2) we can introduce specific serialized types. For example (although not
* yet implemented?) we will be able to implement a tile as a reference to
* this tile through e.g. {x, y, z}, that is know what needs to be serialized,
* know what needs to be referenced, and how to reference it.
*
* (3) again, not yet implemented, but we can in theory have different set
* of serialization depending on the context.
*
* HISTORY NOTE
*
* This was initially developed because the initial network framework only
* allowed for byte, float and int, so more things were needed. To the light
* of current understanding, using only byte would have been good enough.
*
* It seems like the three points above indeed give more value and safety to
* the whole code and make this system still relevant. To be re-evaluated.
*
* QUESTION ON OBJECTS
*
* At the moment, we do not support object creation from this interface, so
* the objects are supposed to be already there and then updated. This may
* not always make sense, in particular in the context of RPC
*
* Non-null arrays of objects are forbidden as well, and they need to be set
* to the same null and non-null elements on both sides.
*
*/
public class ClassMapping extends ClassSerializer {
private static Map<String, ClassSerializer> classes = new TreeMap<String, ClassSerializer>();
private LinkedList<Field> floatFields = new LinkedList<Field>();
private LinkedList<Field> doubleFields = new LinkedList<Field>();
private LinkedList<Field> shortFields = new LinkedList<Field>();
private LinkedList<Field> intFields = new LinkedList<Field>();
private LinkedList<Field> booleanFields = new LinkedList<Field>();
private LinkedList<Field> enumFields = new LinkedList<Field>();
class FieldObject {
public Field field;
public ClassSerializer mapping;
}
private LinkedList<FieldObject> objectFields = new LinkedList<FieldObject>();
enum CptType {
Byte,
Float,
Double,
Short,
Int,
Char,
Boolean,
Enum,
Object
}
private CptType cptType;
private ClassSerializer cptMapping;
public ClassMapping() {
}
@SuppressWarnings({ "rawtypes" })
public void analyzeClass(final Class<? extends Object> c) {
try {
if (c.isArray()) {
Class cptClass = c.getComponentType();
if (byte.class.equals(cptClass)) {
cptType = CptType.Byte;
} else if (float.class.equals(cptClass)) {
cptType = CptType.Float;
} else if (double.class.equals(cptClass)) {
cptType = CptType.Double;
} else if (short.class.equals(cptClass)) {
cptType = CptType.Short;
} else if (int.class.equals(cptClass)) {
cptType = CptType.Int;
} else if (boolean.class.equals(cptClass)) {
cptType = CptType.Byte;
} else if (char.class.equals(cptClass)) {
cptType = CptType.Char;
} else if (Enum.class.isAssignableFrom(cptClass)) {
cptType = CptType.Enum;
} else {
cptType = CptType.Object;
cptMapping = get (cptClass);
}
} else {
List<Field> fields = JavaTools.getAllFields(c);
for (Field f : fields) {
if (!isSynchronizedField(f)) {
continue;
}
f.setAccessible(true);
Type t = f.getType();
if (t instanceof Class) {
Class fieldClass = (Class) t;
if (short.class.equals(fieldClass)) {
shortFields.add(f);
} else if (int.class.equals(fieldClass)) {
intFields.add(f);
} else if (boolean.class.equals(fieldClass)) {
booleanFields.add(f);
} else if (Enum.class.isAssignableFrom(fieldClass)) {
enumFields.add(f);
} else if (float.class.equals(fieldClass)) {
floatFields.add(f);
} else if (double.class.equals(fieldClass)) {
doubleFields.add(f);
} else if (char.class.equals(fieldClass)) {
doubleFields.add(f);
} else {
FieldObject obj = new FieldObject();
obj.mapping = get (fieldClass);
obj.field = f;
objectFields.add(obj);
}
}
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
private boolean isSynchronizedField(Field f) {
NetworkData updateAnnotation = f.getAnnotation(NetworkData.class);
return updateAnnotation != null;
}
/**
* This class will update data in an object from a stream. Public data
* market #NetworkData will get synchronized. The following rules will
* apply:
*
* In the following description, we consider strings as primitive objects.
*
* Market primitives data will be directly updated on the destination
* object after the value of the source object
*
* Market primitive arrays will be re-created in the destination object
* after the primitive array of the source object. This means that array
* references are not preserved by the proccess. If an array is null
* in the source array and not in the destination one, it will be turned to
* null.
*
* Market object will be synchronized - that it we do not create new
* instances in the destination object if they are already there but rather
* recursively synchronize values. If destination is null and not
* source, the destination will get the instance created. If destination is
* not null and source is, the destination will get truned to null.
*
* Market object arrays will be synchronized - not re-created. If
* destination is null and not source, the destination will get the instance
* created. If destination is not null and source is, the destination will
* get turned to null. The same behavior applies to the contents of the
* array. Trying to synchronize two arrays of different size is an error
* and will lead to an exception - so if the array needs to change on the
* destination it needs to be set to null first.
*
* WARNINGS
*
* - only public non-final fields can be serialized
* - non static nested classes are not supported
* - no reference analysis is done, e.g. an object referenced twice will
* be serialized twice
*/
@Override
public void write(ByteBuf data, Object o, SerializationContext context) throws IllegalArgumentException, IllegalAccessException {
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
if (mappedClass.isArray()) {
writeArray(o, data, context);
} else {
writeClass(o, data, context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
if (mappedClass.isArray()) {
return readArray(o, data, context);
} else {
return readClass(o, data, context);
}
}
}
@SuppressWarnings("rawtypes")
void writeClass(Object obj, ByteBuf data, SerializationContext context) throws IllegalArgumentException,
IllegalAccessException {
Class realClass = obj.getClass();
if (realClass.equals(this.mappedClass)) {
data.writeBoolean(true);
} else {
data.writeBoolean(false);
NetworkIdRegistry.write(data, realClass.getCanonicalName());
ClassMapping delegateMapping = (ClassMapping) get(realClass);
delegateMapping.writeClass(obj, data, context);
return;
}
for (Field f : shortFields) {
data.writeShort(f.getShort(obj));
}
for (Field f : intFields) {
data.writeInt(f.getInt(obj));
}
for (Field f : booleanFields) {
data.writeBoolean(f.getBoolean(obj));
}
for (Field f : enumFields) {
if (f.get(obj) == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeByte(((Enum) f.get(obj)).ordinal());
}
}
for (Field f : floatFields) {
data.writeFloat(f.getFloat(obj));
}
for (Field f : doubleFields) {
data.writeDouble(f.getDouble(obj));
}
for (FieldObject f : objectFields) {
Object cpt = f.field.get(obj);
f.mapping.write(data, cpt, context);
}
}
@SuppressWarnings("rawtypes")
Object readClass(Object objI, ByteBuf data, SerializationContext context) throws IllegalArgumentException,
IllegalAccessException, InstantiationException, ClassNotFoundException {
Object obj = objI;
// The data layout for an object is the following:
// [boolean] what is the object real class?
// {false} the same as the declared class
// {true} the network id of the class
// [bytes] the actual contents
if (!data.readBoolean()) {
String className = NetworkIdRegistry.read(data);
Class cls = Class.forName(className);
ClassMapping delegateMapping = (ClassMapping) get(cls);
return delegateMapping.readClass(obj, data, context);
}
if (obj == null) {
obj = mappedClass.newInstance();
}
for (Field f : shortFields) {
f.setShort(obj, data.readShort());
}
for (Field f : intFields) {
f.setInt(obj, data.readInt());
}
for (Field f : booleanFields) {
f.setBoolean(obj, data.readBoolean());
}
for (Field f : enumFields) {
if (data.readBoolean()) {
f.set(obj, ((Class) f.getGenericType()).getEnumConstants()[data.readByte()]);
}
}
for (Field f : floatFields) {
f.setFloat(obj, data.readFloat());
}
for (Field f : doubleFields) {
f.setDouble(obj, data.readDouble());
}
for (FieldObject f : objectFields) {
f.field.set(obj, f.mapping.read(data, f.field.get(obj), context));
}
return obj;
}
private void writeArray(Object obj, ByteBuf data, SerializationContext context) throws IllegalArgumentException,
IllegalAccessException {
switch (cptType) {
case Byte: {
byte[] arr = (byte[]) obj;
data.writeInt (arr.length);
data.writeBytes(arr);
break;
}
case Float: {
float[] arr = (float[]) obj;
data.writeInt (arr.length);
for (float element : arr) {
data.writeFloat(element);
}
break;
}
case Double: {
double[] arr = (double[]) obj;
data.writeInt (arr.length);
for (double element : arr) {
data.writeDouble(element);
}
break;
}
case Short: {
short[] arr = (short[]) obj;
data.writeInt (arr.length);
for (short element : arr) {
data.writeShort(element);
}
break;
}
case Int: {
int[] arr = (int[]) obj;
data.writeInt (arr.length);
for (int element : arr) {
data.writeInt(element);
}
break;
}
case Boolean: {
boolean[] arr = (boolean[]) obj;
data.writeInt (arr.length);
for (boolean element : arr) {
data.writeBoolean(element);
}
break;
}
case Char: {
char[] arr = (char[]) obj;
data.writeInt (arr.length);
for (char element : arr) {
data.writeChar(element);
}
break;
}
case Enum: {
Enum<?>[] arr = (Enum[]) obj;
data.writeInt (arr.length);
for (Enum<?> element : arr) {
data.writeBoolean(element != null);
if (element != null) {
data.writeByte(element.ordinal());
}
}
break;
}
case Object: {
Object[] arr = (Object[]) obj;
data.writeInt(arr.length);
for (Object element : arr) {
cptMapping.write(data, element, context);
}
break;
}
}
}
private Object readArray(Object objI, ByteBuf data, SerializationContext context) throws IllegalArgumentException,
IllegalAccessException, InstantiationException, ClassNotFoundException {
Object obj = objI;
Class<? extends Object> cpt = mappedClass.getComponentType();
int size = data.readInt();
switch (cptType) {
case Byte: {
byte[] arr;
if (obj == null) {
arr = new byte[size];
} else {
arr = (byte[]) obj;
}
data.readBytes (arr);
obj = arr;
break;
}
case Float: {
float[] arr;
if (obj == null) {
arr = new float[size];
} else {
arr = (float[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readFloat();
}
obj = arr;
break;
}
case Double: {
double[] arr;
if (obj == null) {
arr = new double[size];
} else {
arr = (double[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readDouble();
}
obj = arr;
break;
}
case Short: {
short[] arr;
if (obj == null) {
arr = new short[size];
} else {
arr = (short[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readShort();
}
obj = arr;
break;
}
case Int: {
int[] arr;
if (obj == null) {
arr = new int[size];
} else {
arr = (int[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readInt();
}
obj = arr;
break;
}
case Boolean: {
boolean[] arr;
if (obj == null) {
arr = new boolean[size];
} else {
arr = (boolean[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readBoolean();
}
obj = arr;
break;
}
case Char: {
char[] arr;
if (obj == null) {
arr = new char[size];
} else {
arr = (char[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = data.readChar();
}
obj = arr;
break;
}
case Enum: {
Enum<?>[] arr;
if (obj == null) {
arr = new Enum[size];
} else {
arr = (Enum[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
if (data.readBoolean()) {
arr[i] = (Enum<?>) cpt.getEnumConstants()[data.readByte()];
} else {
arr[i] = null;
}
}
obj = arr;
break;
}
case Object: {
Object[] arr;
if (obj == null) {
arr = (Object[]) Array.newInstance(cpt, size);
} else {
arr = (Object[]) obj;
}
for (int i = 0; i < arr.length; ++i) {
arr[i] = cptMapping.read(data, arr[i], context);
}
obj = arr;
break;
}
}
return obj;
}
private static void registerSerializer (Class<?> clas, ClassSerializer s) {
try {
s.mappedClass = clas;
classes.put(clas.getCanonicalName(), s);
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException("Can't register " + clas.getCanonicalName() + " in serializers");
}
}
public static ClassSerializer get (Class<?> clas) {
ClassSerializer mapping;
if (Block.class.isAssignableFrom(clas)) {
mapping = classes.get(Block.class.getCanonicalName());
} else if (Item.class.isAssignableFrom(clas)) {
mapping = classes.get(Item.class.getCanonicalName());
} else if (INBTSerializable.class.isAssignableFrom(clas)) {
mapping = classes.get(INBTSerializable.class.getCanonicalName());
} else if (!classes.containsKey(clas.getCanonicalName())) {
mapping = new ClassMapping ();
registerSerializer(clas, mapping);
((ClassMapping) mapping).analyzeClass(clas);
} else if (classes.containsKey(clas.getCanonicalName())) {
mapping = classes.get(clas.getCanonicalName());
} else {
mapping = null;
}
return mapping;
}
static {
registerSerializer(String.class, new SerializerString());
registerSerializer(HashMap.class, new SerializerHashMap());
registerSerializer(HashSet.class, new SerializerHashSet());
registerSerializer(LinkedList.class, new SerializerLinkedList());
registerSerializer(ArrayList.class, new SerializerArrayList());
registerSerializer(Block.class, new SerializerBlock());
registerSerializer(Item.class, new SerializerItem());
registerSerializer(NBTTagCompound.class, new SerializerNBT());
registerSerializer(ItemStack.class, new SerializerItemStack());
registerSerializer(FluidStack.class, new SerializerFluidStack());
registerSerializer(Integer.class, new SerializerInteger());
registerSerializer(Long.class, new SerializerLong());
registerSerializer(BitSet.class, new SerializerBitSet());
registerSerializer(INBTSerializable.class, new SerializerINBTSerializable());
registerSerializer(IStatementParameter.class, new SerializerIStatementParameter());
}
}

View file

@ -1,26 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
public abstract class ClassSerializer {
public Class<? extends Object> mappedClass;
public abstract void write(ByteBuf data, Object o,
SerializationContext context) throws IllegalArgumentException,
IllegalAccessException;
public abstract Object read(ByteBuf data, Object o,
SerializationContext context) throws IllegalArgumentException,
IllegalAccessException, InstantiationException,
ClassNotFoundException;
}

View file

@ -1,13 +0,0 @@
package buildcraft.core.network.serializers;
public class NetworkId {
private String str;
private String id;
public NetworkId(String str) {
id = str;
}
}

View file

@ -1,13 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
public class SerializationContext {
}

View file

@ -1,58 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import java.util.ArrayList;
import io.netty.buffer.ByteBuf;
public class SerializerArrayList extends ClassSerializer {
private static SerializerObject anonymousSerializer = new SerializerObject();
@Override
public void write(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException {
ArrayList<?> list = (ArrayList<?>) o;
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(list.size());
for (Object val : list) {
anonymousSerializer.write(data, val, context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
int size = data.readShort();
ArrayList<Object> list = new ArrayList<Object> ();
for (int i = 0; i < size; ++i) {
Object val = anonymousSerializer.read(data, null, context);
list.add(val);
}
return list;
}
}
}

View file

@ -1,46 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import java.util.BitSet;
import io.netty.buffer.ByteBuf;
import buildcraft.core.utils.BitSetUtils;
public class SerializerBitSet extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
BitSet set = (BitSet) o;
byte[] bytes = BitSetUtils.toByteArray(set);
data.writeInt(bytes.length);
data.writeBytes(bytes);
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
}
int actualSize = data.readInt();
byte[] bytes = new byte[actualSize];
data.readBytes(bytes);
BitSet set = BitSetUtils.fromByteArray(bytes);
return set;
}
}

View file

@ -1,36 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
public class SerializerBlock extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
Block b = (Block) o;
if (b == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(Block.getIdFromBlock(b));
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
return Block.getBlockById(data.readUnsignedShort());
}
}
}

View file

@ -1,56 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.core.utils.Utils;
public class SerializerFluidStack extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
FluidStack stack = (FluidStack) o;
if (stack == null) {
data.writeBoolean(false);
} else {
data.writeShort(stack.getFluid().getID());
data.writeInt(stack.amount);
if (stack.tag == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
Utils.writeNBT(data, stack.tag);
}
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
int id = data.readShort();
int amount = data.readerIndex();
NBTTagCompound nbt = null;
if (data.readBoolean()) {
nbt = Utils.readNBT(data);
return new FluidStack(id, amount, nbt);
} else {
return new FluidStack(id, amount);
}
}
}
}

View file

@ -1,62 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import io.netty.buffer.ByteBuf;
public class SerializerHashMap extends ClassSerializer {
private static SerializerObject anonymousSerializer = new SerializerObject();
@Override
public void write(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException {
HashMap map = (HashMap<?, ?>) o;
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(map.size());
Set<Map.Entry> s = map.entrySet();
for (Map.Entry e : s) {
anonymousSerializer.write(data, e.getKey(), context);
anonymousSerializer.write(data, e.getValue(), context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
int size = data.readShort();
HashMap<Object, Object> map = new HashMap<Object, Object> ();
for (int i = 0; i < size; ++i) {
Object key = anonymousSerializer.read(data, null, context);
Object value = anonymousSerializer.read(data, null, context);
map.put(key, value);
}
return map;
}
}
}

View file

@ -1,56 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import java.util.HashSet;
import io.netty.buffer.ByteBuf;
public class SerializerHashSet extends ClassSerializer {
private static SerializerObject anonymousSerializer = new SerializerObject();
@Override
public void write(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException {
HashSet<?> set = (HashSet<?>) o;
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(set.size());
for (Object item : set) {
anonymousSerializer.write(data, item, context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
int size = data.readShort();
HashSet<Object> set = new HashSet<Object>();
for (int i = 0; i < size; ++i) {
Object value = anonymousSerializer.read(data, null, context);
set.add(value);
}
return set;
}
}
}

View file

@ -1,28 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.core.network.INBTSerializable;
public class SerializerINBTSerializable extends SerializerNBT {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
super.write(data, ((INBTSerializable) o).serializeNBT(), context);
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
((INBTSerializable) o).serializeNBT((NBTTagCompound) super.read(data, o, context));
return o;
}
}

View file

@ -1,49 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.api.statements.IStatementParameter;
import buildcraft.api.statements.StatementManager;
import buildcraft.core.utils.Utils;
/**
* An NBT-based serializer for IStatementParameters.
*/
public class SerializerIStatementParameter extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
IStatementParameter parameter = (IStatementParameter) o;
if (parameter == null) {
data.writeBoolean(false);
} else {
NBTTagCompound cpt = new NBTTagCompound();
parameter.writeToNBT(cpt);
data.writeBoolean(true);
Utils.writeUTF(data, parameter.getUniqueTag());
Utils.writeNBT(data, cpt);
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
String kind = Utils.readUTF(data);
IStatementParameter parameter = StatementManager.createParameter(kind);
parameter.readFromNBT(Utils.readNBT(data));
return parameter;
}
}
}

View file

@ -1,26 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
public class SerializerInteger extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
Integer i = (Integer) o;
data.writeInt(i);
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
return new Integer(data.readInt());
}
}

View file

@ -1,36 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.Item;
public class SerializerItem extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
Item i = (Item) o;
if (i == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(Item.getIdFromItem(i));
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
return Item.getItemById(data.readUnsignedShort());
}
}
}

View file

@ -1,41 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.core.utils.Utils;
public class SerializerItemStack extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
ItemStack stack = (ItemStack) o;
if (stack == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
NBTTagCompound nbt = new NBTTagCompound();
stack.writeToNBT(nbt);
Utils.writeNBT(data, nbt);
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
return ItemStack.loadItemStackFromNBT(Utils.readNBT(data));
}
}
}

View file

@ -1,56 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import java.util.LinkedList;
import io.netty.buffer.ByteBuf;
public class SerializerLinkedList extends ClassSerializer {
private static SerializerObject anonymousSerializer = new SerializerObject();
@Override
public void write(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException {
LinkedList<?> list = (LinkedList<?>) o;
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(list.size());
for (Object val : list) {
anonymousSerializer.write(data, val, context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
int size = data.readShort();
LinkedList<Object> list = new LinkedList<Object>();
for (int i = 0; i < size; ++i) {
Object val = anonymousSerializer.read(data, null, context);
list.add(val);
}
return list;
}
}
}

View file

@ -1,26 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
public class SerializerLong extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
Long i = (Long) o;
data.writeLong(i);
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
return new Long(data.readLong());
}
}

View file

@ -1,37 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import buildcraft.core.utils.Utils;
public class SerializerNBT extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
NBTTagCompound nbt = (NBTTagCompound) o;
if (nbt == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
Utils.writeNBT(data, nbt);
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
return Utils.readNBT(data);
}
}
}

View file

@ -1,55 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import buildcraft.core.network.NetworkIdRegistry;
public class SerializerObject extends ClassSerializer {
@Override
public void write(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException {
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
Class<? extends Object> realClass = o.getClass();
NetworkIdRegistry.write(data, realClass.getCanonicalName());
ClassSerializer delegateMapping = ClassMapping.get(realClass);
if (delegateMapping instanceof ClassMapping) {
((ClassMapping) delegateMapping).writeClass(o, data, context);
} else {
delegateMapping.write(data, o, context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
String className = NetworkIdRegistry.read(data);
Class cls = Class.forName(className);
ClassSerializer delegateMapping = ClassMapping.get(cls);
if (delegateMapping instanceof ClassMapping) {
return ((ClassMapping) delegateMapping).readClass(o, data, context);
} else {
return delegateMapping.read(data, o, context);
}
}
}
}

View file

@ -1,37 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.network.serializers;
import io.netty.buffer.ByteBuf;
import buildcraft.core.utils.Utils;
public class SerializerString extends ClassSerializer {
@Override
public void write (ByteBuf data, Object o, SerializationContext context) {
String s = (String) o;
if (s == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
Utils.writeUTF(data, s);
}
}
@Override
public Object read (ByteBuf data, Object o, SerializationContext context) {
if (!data.readBoolean()) {
return null;
} else {
return Utils.readUTF(data);
}
}
}

View file

@ -37,6 +37,7 @@ import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftCore;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
@ -51,17 +52,16 @@ import buildcraft.api.robots.IDockingStation;
import buildcraft.core.DefaultProps;
import buildcraft.core.LaserData;
import buildcraft.core.RFBattery;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.NBTUtils;
import buildcraft.core.utils.Utils;
import buildcraft.silicon.statements.ActionRobotWorkInArea;
import buildcraft.transport.gates.ActionIterator;
import buildcraft.transport.gates.StatementSlot;
public class EntityRobot extends EntityRobotBase implements
IEntityAdditionalSpawnData, IInventory, IFluidHandler {
IEntityAdditionalSpawnData, IInventory, IFluidHandler, ICommandReceiver {
public static final ResourceLocation ROBOT_BASE = new ResourceLocation("buildcraft",
DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_base.png");
@ -201,7 +201,7 @@ public class EntityRobot extends EntityRobotBase implements
protected void init() {
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "requestInitialization");
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "requestInitialization"));
}
}
@ -608,7 +608,7 @@ public class EntityRobot extends EntityRobotBase implements
inv[var1] = null;
}
RPCHandler.rpcBroadcastAllPlayers(this, "rpcClientSetInventory", var1, inv[var1]);
updateClientSlot(var1);
return result;
}
@ -622,7 +622,7 @@ public class EntityRobot extends EntityRobotBase implements
public void setInventorySlotContents(int var1, ItemStack var2) {
inv[var1] = var2;
RPCHandler.rpcBroadcastAllPlayers(this, "rpcClientSetInventory", var1, inv[var1]);
updateClientSlot(var1);
}
@Override
@ -644,6 +644,17 @@ public class EntityRobot extends EntityRobotBase implements
public void markDirty() {
}
public void updateClientSlot(final int slot) {
BuildCraftCore.instance.sendToWorld(new PacketCommand(this, "clientSetInventory") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeShort(slot);
Utils.writeStack(data, inv[slot]);
}
}, worldObj);
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1) {
return false;
@ -672,41 +683,92 @@ public class EntityRobot extends EntityRobotBase implements
@Override
public void setItemInUse(ItemStack stack) {
itemInUse = stack;
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "clientSetItemInUse", stack);
BuildCraftCore.instance.sendToWorld(new PacketCommand(this, "clientSetItemInUse") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeStack(data, itemInUse);
}
}, worldObj);
}
@RPC(RPCSide.CLIENT)
private void clientSetItemInUse(ItemStack stack) {
itemInUse = stack;
}
@RPC(RPCSide.CLIENT)
private void rpcClientSetInventory(int i, ItemStack stack) {
inv[i] = stack;
}
@RPC(RPCSide.SERVER)
public void requestInitialization(RPCMessageInfo info) {
RPCHandler.rpcPlayer(info.sender, this, "rpcInitialize", itemInUse, itemActive);
for (int i = 0; i < inv.length; ++i) {
RPCHandler.rpcPlayer(info.sender, this, "rpcClientSetInventory", i, inv[i]);
}
if (currentDockingStation != null) {
setSteamDirection(
currentDockingStation.side.offsetX,
currentDockingStation.side.offsetY,
currentDockingStation.side.offsetZ);
private void setSteamDirection(final int x, final int y, final int z) {
if (!worldObj.isRemote) {
BuildCraftCore.instance.sendToWorld(new PacketCommand(this, "setSteamDirection") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeInt(x);
data.writeShort(y);
data.writeInt(z);
}
}, worldObj);
} else {
setSteamDirection(0, -1, 0);
Vec3 v = Vec3.createVectorHelper(x, y, z);
v.normalize();
steamDx = (int) v.xCoord;
steamDy = (int) v.yCoord;
steamDz = (int) v.zCoord;
}
}
@RPC(RPCSide.CLIENT)
private void rpcInitialize(ItemStack stack, boolean active) {
itemInUse = stack;
itemActive = active;
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isClient()) {
if (command.equals("clientSetItemInUse")) {
itemInUse = Utils.readStack(stream);
} else if (command.equals("clientSetInventory")) {
int slot = stream.readUnsignedShort();
inv[slot] = Utils.readStack(stream);
} else if (command.equals("initialize")) {
itemInUse = Utils.readStack(stream);
itemActive = stream.readBoolean();
} else if (command.equals("setItemActive")) {
itemActive = stream.readBoolean();
itemActiveStage = 0;
lastUpdateTime = new Date().getTime();
if (!itemActive) {
setSteamDirection(0, -1, 0);
}
} else if (command.equals("setSteamDirection")) {
setSteamDirection(stream.readInt(), stream.readShort(), stream.readInt());
}
} else if (side.isServer()) {
EntityPlayer p = (EntityPlayer) sender;
if (command.equals("requestInitialization")) {
BuildCraftCore.instance.sendToPlayer(p, new PacketCommand(this, "initialize") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeStack(data, itemInUse);
data.writeBoolean(itemActive);
}
});
for (int i = 0; i < inv.length; ++i) {
final int j = i;
BuildCraftCore.instance.sendToPlayer(p, new PacketCommand(this, "clientSetInventory") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeShort(j);
Utils.writeStack(data, inv[j]);
}
});
}
if (currentDockingStation != null) {
setSteamDirection(
currentDockingStation.side.offsetX,
currentDockingStation.side.offsetY,
currentDockingStation.side.offsetZ);
} else {
setSteamDirection(0, -1, 0);
}
}
}
}
@Override
@ -751,35 +813,16 @@ public class EntityRobot extends EntityRobotBase implements
}
@Override
public void setItemActive(boolean isActive) {
public void setItemActive(final boolean isActive) {
if (isActive != itemActive) {
itemActive = isActive;
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "rpcSetItemActive", isActive);
}
}
@RPC(RPCSide.CLIENT)
private void rpcSetItemActive(boolean isActive) {
itemActive = isActive;
itemActiveStage = 0;
lastUpdateTime = new Date().getTime();
if (!isActive) {
setSteamDirection(0, -1, 0);
}
}
@RPC(RPCSide.CLIENT)
private void setSteamDirection(int x, int y, int z) {
if (!worldObj.isRemote) {
RPCHandler.rpcBroadcastAllPlayers(this, "setSteamDirection", x, y, z);
} else {
Vec3 v = Vec3.createVectorHelper(x, y, z);
v.normalize();
steamDx = (int) v.xCoord;
steamDy = (int) v.yCoord;
steamDz = (int) v.zCoord;
BuildCraftCore.instance.sendToWorld(new PacketCommand(this, "setItemActive") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeBoolean(isActive);
}
}, worldObj);
}
}

View file

@ -22,6 +22,7 @@ import io.netty.buffer.Unpooled;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTSizeTracker;
@ -35,8 +36,6 @@ import cpw.mods.fml.common.network.internal.FMLProxyPacket;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.BlockIndex;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.core.Position;
import buildcraft.api.transport.IPipeTile;
@ -52,8 +51,6 @@ import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ISynchronizedTile;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.energy.TileEngine;
@ -333,24 +330,6 @@ public final class Utils {
return lasers;
}
public static void handleBufferedDescription(ISynchronizedTile tileSynch) {
TileEntity tile = (TileEntity) tileSynch;
BlockIndex index = new BlockIndex(tile.xCoord, tile.yCoord, tile.zCoord);
if (BuildCraftCore.bufferedDescriptions.containsKey(index)) {
PacketUpdate payload = BuildCraftCore.bufferedDescriptions.get(index);
BuildCraftCore.bufferedDescriptions.remove(index);
try {
tileSynch.handleDescriptionPacket(payload);
} catch (IOException ex) {
ex.printStackTrace();
}
tileSynch.postPacketHandling(payload);
}
}
public static void preDestroyBlock(World world, int i, int j, int k) {
TileEntity tile = world.getTileEntity(i, j, k);
@ -484,26 +463,48 @@ public final class Utils {
}
public static void writeStack (ByteBuf data, ItemStack stack) {
if (stack == null) {
data.writeBoolean(false);
if (stack == null || stack.getItem() == null || stack.stackSize < 0) {
data.writeByte(0);
} else {
data.writeBoolean(true);
NBTTagCompound nbt = new NBTTagCompound();
stack.writeToNBT(nbt);
Utils.writeNBT(data, nbt);
// ItemStacks generally shouldn't have a stackSize above 64,
// so we use this "trick" to save bandwidth by storing it in the first byte.
data.writeByte((MathUtils.clamp(stack.stackSize + 1, 0, 64) & 0x7F) | (stack.hasTagCompound() ? 128 : 0));
data.writeShort(Item.getIdFromItem(stack.getItem()));
data.writeShort(stack.getItemDamage());
if (stack.hasTagCompound()) {
Utils.writeNBT(data, stack.getTagCompound());
}
}
}
public static ItemStack readStack(ByteBuf data) {
if (!data.readBoolean()) {
int flags = data.readUnsignedByte();
if (flags == 0) {
return null;
} else {
NBTTagCompound nbt = readNBT(data);
return ItemStack.loadItemStackFromNBT(nbt);
boolean hasCompound = (flags & 0x80) != 0;
int stackSize = (flags & 0x7F) - 1;
int itemId = data.readUnsignedShort();
int itemDamage = data.readShort();
ItemStack stack = new ItemStack(Item.getItemById(itemId), stackSize, itemDamage);
if (hasCompound) {
stack.setTagCompound(Utils.readNBT(data));
}
return stack;
}
}
public static void writeByteArray(ByteBuf stream, byte[] data) {
stream.writeInt(data.length);
stream.writeBytes(data);
}
public static byte[] readByteArray(ByteBuf stream) {
byte[] data = new byte[stream.readInt()];
stream.readBytes(data, 0, data.length);
return data;
}
/**
* This subprogram transforms a packet into a FML packet to be send in the
* minecraft default packet mechanism. This always use BC-CORE as a

View file

@ -18,13 +18,9 @@ import buildcraft.api.core.SafeTimeTracker;
import buildcraft.core.LaserData;
import buildcraft.core.RFBattery;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
public class TileEnergyEmitter extends TileBuildCraft {
public Map<BlockIndex, Target> targets = new TreeMap<BlockIndex, Target>();
/* public Map<BlockIndex, Target> targets = new TreeMap<BlockIndex, Target>();
public int rfAcc = 0;
public int accumulated = 0;
@ -226,5 +222,5 @@ public class TileEnergyEmitter extends TileBuildCraft {
}
return AxisAlignedBB.getBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax);
}
}*/
}

View file

@ -8,6 +8,7 @@
*/
package buildcraft.energy;
import io.netty.buffer.ByteBuf;
import buildcraft.api.power.IEngine;
import buildcraft.api.tiles.IHeatable;
import buildcraft.core.utils.MathUtils;
@ -18,7 +19,6 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.ForgeDirection;
import cofh.api.energy.IEnergyHandler;
import buildcraft.api.core.NetworkData;
import buildcraft.api.transport.IPipeConnection;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.IPipeTile.PipeType;
@ -70,9 +70,7 @@ public abstract class TileEngine extends TileBuildCraft implements IPipeConnecti
public float progress;
public int energy;
public float heat = MIN_HEAT;
@NetworkData
public EnergyStage energyStage = EnergyStage.BLUE;
@NetworkData
public ForgeDirection orientation = ForgeDirection.UP;
protected int progressPart = 0;
@ -80,7 +78,6 @@ public abstract class TileEngine extends TileBuildCraft implements IPipeConnecti
private boolean checkOrientation = false;
@NetworkData
private boolean isPumping = false; // Used for SMP synch
public TileEngine() {
@ -395,6 +392,20 @@ public abstract class TileEngine extends TileBuildCraft implements IPipeConnecti
data.setFloat("heat", heat);
}
@Override
public void readData(ByteBuf stream) {
int flags = stream.readUnsignedByte();
energyStage = EnergyStage.values()[flags & 0x07];
isPumping = (flags & 0x08) != 0;
orientation = ForgeDirection.getOrientation(stream.readByte());
}
@Override
public void writeData(ByteBuf stream) {
stream.writeByte(energyStage.ordinal() | (isPumping ? 8 : 0));
stream.writeByte(orientation.ordinal());
}
public void getGUINetworkData(int id, int value) {
switch (id) {
case 0:

View file

@ -8,20 +8,18 @@
*/
package buildcraft.energy;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.NetworkData;
import buildcraft.api.tools.IToolWrench;
import buildcraft.core.PowerMode;
import buildcraft.core.utils.StringUtils;
public class TileEngineCreative extends TileEngine {
@NetworkData
private PowerMode powerMode = PowerMode.M2;
@Override
@ -79,6 +77,18 @@ public class TileEngineCreative extends TileEngine {
data.setByte("mode", (byte) powerMode.ordinal());
}
@Override
public void readData(ByteBuf stream) {
super.readData(stream);
powerMode = PowerMode.fromId(stream.readUnsignedByte());
}
@Override
public void writeData(ByteBuf stream) {
super.writeData(stream);
stream.writeByte(powerMode.ordinal());
}
@Override
public float getPistonSpeed() {
return 0.02F * (powerMode.ordinal() + 1);

View file

@ -23,7 +23,7 @@ import buildcraft.core.DefaultProps;
import buildcraft.core.EntityLaser;
import buildcraft.core.render.RenderLaser;
import buildcraft.energy.TileEnergyEmitter;
import buildcraft.energy.TileEnergyEmitter.Target;
//import buildcraft.energy.TileEnergyEmitter.Target;
public class RenderEnergyEmitter extends TileEntitySpecialRenderer {
@ -89,13 +89,13 @@ public class RenderEnergyEmitter extends TileEntitySpecialRenderer {
GL11.glTranslated(x, y, z);
for (Target t : emitter.targets.values()) {
/* for (Target t : emitter.targets.values()) {
GL11.glPushMatrix();
GL11.glTranslated(0.5F, 0.5F, 0.5F);
RenderLaser.doRenderLaserWave(TileEntityRendererDispatcher.instance.field_147553_e,
t.data, EntityLaser.LASER_TEXTURES[3]);
GL11.glPopMatrix();
}
} */
//GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopAttrib();

View file

@ -38,8 +38,6 @@ import buildcraft.core.TileBuffer;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.fluids.TankUtils;
import buildcraft.core.fluids.SingleUseTank;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.core.utils.BlockUtils;
import buildcraft.core.utils.Utils;
@ -372,35 +370,21 @@ public class TilePump extends TileBuildCraft implements IHasWork, IFluidHandler
}
@Override
public PacketPayload getPacketPayload() {
PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
@Override
public void writeData(ByteBuf buf) {
buf.writeInt(aimY);
buf.writeFloat((float) tubeY);
buf.writeBoolean(powered);
}
});
return payload;
public void writeData(ByteBuf buf) {
buf.writeShort(aimY);
buf.writeFloat((float) tubeY);
buf.writeBoolean(powered);
}
@Override
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
PacketPayload payload = packet.payload;
ByteBuf data = payload.stream;
aimY = data.readInt();
public void readData(ByteBuf data) {
aimY = data.readShort();
tubeY = data.readFloat();
powered = data.readBoolean();
setTubePosition();
}
@Override
public void handleDescriptionPacket(PacketUpdate packet) throws IOException {
handleUpdatePacket(packet);
}
private void setTubePosition() {
if (tube != null) {
tube.iSize = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;

View file

@ -15,6 +15,7 @@ import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
@ -35,7 +36,6 @@ import buildcraft.BuildCraftCore;
import buildcraft.BuildCraftFactory;
import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.core.IAreaProvider;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.filler.FillerManager;
import buildcraft.api.tiles.IHasWork;
@ -65,23 +65,14 @@ public class TileQuarry extends TileAbstractBuilder implements IHasWork, ISidedI
public EntityMechanicalArm arm;
public EntityPlayer placedBy;
@NetworkData
protected Box box = new Box();
@NetworkData
private int targetX, targetY, targetZ;
@NetworkData
private double headPosX, headPosY, headPosZ;
@NetworkData
private double speed = 0.03;
@NetworkData
private Stage stage = Stage.BUILDING;
@NetworkData
private boolean isAlive;
@NetworkData
private boolean movingHorizontally;
@NetworkData
private boolean movingVertically;
@NetworkData
private double headTrajectory;
private SafeTimeTracker updateTracker = new SafeTimeTracker(10);
@ -632,8 +623,41 @@ public class TileQuarry extends TileAbstractBuilder implements IHasWork, ISidedI
}
@Override
public void postPacketHandling(PacketUpdate packet) {
super.postPacketHandling(packet);
public void writeData(ByteBuf stream) {
super.writeData(stream);
box.writeData(stream);
stream.writeInt(targetX);
stream.writeShort(targetY);
stream.writeInt(targetZ);
stream.writeDouble(headPosX);
stream.writeDouble(headPosY);
stream.writeDouble(headPosZ);
stream.writeFloat((float) speed);
stream.writeFloat((float) headTrajectory);
int flags = stage.ordinal();
flags |= (isAlive ? 0x08 : 0);
flags |= (movingHorizontally ? 0x10 : 0);
flags |= (movingVertically ? 0x20 : 0);
stream.writeByte(flags);
}
@Override
public void readData(ByteBuf stream) {
super.readData(stream);
box.readData(stream);
targetX = stream.readInt();
targetY = stream.readUnsignedShort();
targetZ = stream.readInt();
headPosX = stream.readDouble();
headPosY = stream.readDouble();
headPosZ = stream.readDouble();
speed = stream.readFloat();
headTrajectory = stream.readFloat();
int flags = stream.readUnsignedByte();
stage = Stage.values()[flags & 0x07];
isAlive = (flags & 0x08) != 0;
movingHorizontally = (flags & 0x10) != 0;
movingVertically = (flags & 0x20) != 0;
if (isAlive) {
createUtilsIfNeeded();

View file

@ -25,7 +25,6 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IFlexibleCrafter;
@ -35,9 +34,9 @@ import buildcraft.core.RFBattery;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.fluids.SingleUseTank;
import buildcraft.core.fluids.TankManager;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.recipes.RefineryRecipeManager;
import buildcraft.core.utils.Utils;
public class TileRefinery extends TileBuildCraft implements IFluidHandler, IInventory, IHasWork, IFlexibleCrafter {
@ -58,7 +57,6 @@ public class TileRefinery extends TileBuildCraft implements IFluidHandler, IInve
private SafeTimeTracker updateNetworkTime = new SafeTimeTracker(BuildCraftCore.updateFactor);
private boolean isActive;
@NetworkData
private String currentRecipeId = "";
public TileRefinery() {
@ -350,23 +348,23 @@ public class TileRefinery extends TileBuildCraft implements IFluidHandler, IInve
}
// Network
@Override
public PacketPayload getPacketPayload() {
PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
@Override
public void writeData(ByteBuf data) {
data.writeFloat(animationSpeed);
tankManager.writeData(data);
}
});
return payload;
public void writeData(ByteBuf stream) {
stream.writeFloat(animationSpeed);
Utils.writeUTF(stream, currentRecipeId);
tankManager.writeData(stream);
}
@Override
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
ByteBuf stream = packet.payload.stream;
public void readData(ByteBuf stream) {
animationSpeed = stream.readFloat();
currentRecipeId = Utils.readUTF(stream);
tankManager.readData(stream);
currentRecipe = RefineryRecipeManager.INSTANCE.getRecipe(currentRecipeId);
if (currentRecipe != null) {
craftingResult = currentRecipe.craft(this, true);
}
}
@Override
@ -384,17 +382,6 @@ public class TileRefinery extends TileBuildCraft implements IFluidHandler, IInve
return false;
}
@Override
public void postPacketHandling(PacketUpdate packet) {
super.postPacketHandling(packet);
currentRecipe = RefineryRecipeManager.INSTANCE.getRecipe(currentRecipeId);
if (currentRecipe != null) {
craftingResult = currentRecipe.craft(this, true);
}
}
@Override
public int getCraftingItemStackSize() {
return 0;

View file

@ -29,8 +29,6 @@ import buildcraft.api.core.SafeTimeTracker;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.fluids.Tank;
import buildcraft.core.fluids.TankManager;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
public class TileTank extends TileBuildCraft implements IFluidHandler {
@ -65,19 +63,12 @@ public class TileTank extends TileBuildCraft implements IFluidHandler {
/* NETWORK */
@Override
public PacketPayload getPacketPayload() {
PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
@Override
public void writeData(ByteBuf data) {
public void writeData(ByteBuf data) {
tankManager.writeData(data);
}
});
return payload;
}
@Override
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
ByteBuf stream = packet.payload.stream;
public void readData(ByteBuf stream) {
tankManager.readData(stream);
}

View file

@ -18,14 +18,14 @@ import net.minecraft.inventory.Slot;
import net.minecraftforge.fluids.Fluid;
import buildcraft.BuildCraftFactory;
import buildcraft.api.core.ISerializable;
import buildcraft.core.gui.BuildCraftContainer;
import buildcraft.core.network.PacketIds;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.Serializable;
import buildcraft.factory.TileRefinery;
public class ContainerRefinery extends BuildCraftContainer {
public TileRefinery refinery;
public ContainerRefinery(InventoryPlayer inventory, TileRefinery refinery) {
@ -55,13 +55,13 @@ public class ContainerRefinery extends BuildCraftContainer {
refinery.setFilter(slot, filter);
if (refinery.getWorldObj().isRemote) {
PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
ISerializable payload = new Serializable() {
@Override
public void writeData(ByteBuf data) {
data.writeByte(slot);
data.writeShort(filter != null ? filter.getID() : -1);
}
});
};
BuildCraftFactory.instance.sendToServer(new PacketUpdate(PacketIds.REFINERY_FILTER_SET, refinery.xCoord, refinery.yCoord, refinery.zCoord, payload));
}
}

View file

@ -75,7 +75,7 @@ public class PacketHandlerFactory extends SimpleChannelInboundHandler<BuildCraft
return;
}
ByteBuf stream = packet.payload.stream;
ByteBuf stream = packet.stream;
tile.setFilter(stream.readByte(), FluidRegistry.getFluid(stream.readShort()));
}

View file

@ -12,6 +12,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@ -19,18 +20,17 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.api.core.NetworkData;
import buildcraft.BuildCraftCore;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IFlexibleCrafter;
import buildcraft.api.recipes.IFlexibleRecipe;
import buildcraft.api.tiles.IControllable;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.recipes.AssemblyRecipeManager;
import buildcraft.core.robots.EntityRobot;
import buildcraft.core.robots.ResourceIdAssemblyTable;
@ -38,14 +38,9 @@ import buildcraft.core.robots.RobotRegistry;
import buildcraft.core.utils.StringUtils;
import buildcraft.core.utils.Utils;
public class TileAssemblyTable extends TileLaserTableBase implements IInventory, IFlexibleCrafter {
@NetworkData
public class TileAssemblyTable extends TileLaserTableBase implements IInventory, IFlexibleCrafter, ICommandReceiver {
public String currentRecipeId = "";
public IFlexibleRecipe<ItemStack> currentRecipe;
@NetworkData
private HashSet<String> plannedOutput = new HashSet<String>();
public List<CraftingResult<ItemStack>> getPotentialOutputs() {
@ -138,6 +133,28 @@ public class TileAssemblyTable extends TileLaserTableBase implements IInventory,
return StringUtils.localize("tile.assemblyTableBlock.name");
}
@Override
public void readData(ByteBuf stream) {
super.readData(stream);
currentRecipeId = Utils.readUTF(stream);
plannedOutput.clear();
int size = stream.readUnsignedByte();
for (int i = 0; i < size; i++) {
plannedOutput.add(Utils.readUTF(stream));
}
}
@Override
public void writeData(ByteBuf stream) {
super.writeData(stream);
Utils.writeUTF(stream, currentRecipeId);
stream.writeByte(plannedOutput.size());
for (String s: plannedOutput) {
Utils.writeUTF(stream, s);
}
currentRecipe = AssemblyRecipeManager.INSTANCE.getRecipe(currentRecipeId);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
@ -267,23 +284,35 @@ public class TileAssemblyTable extends TileLaserTableBase implements IInventory,
setCurrentRecipe(null);
}
public void rpcSelectRecipe(String id, boolean select) {
RPCHandler.rpcServer(this, "selectRecipe", id, select);
public void rpcSelectRecipe(final String id, final boolean select) {
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "select") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
Utils.writeUTF(data, id);
data.writeBoolean(select);
}
});
}
@RPC(RPCSide.SERVER)
private void selectRecipe(String id, boolean select) {
IFlexibleRecipe<ItemStack> recipe = AssemblyRecipeManager.INSTANCE.getRecipe(id);
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer() && command.equals("select")) {
String id = Utils.readUTF(stream);
boolean select = stream.readBoolean();
if (recipe != null) {
if (select) {
planOutput(recipe);
} else {
cancelPlanOutput(recipe);
IFlexibleRecipe<ItemStack> recipe = AssemblyRecipeManager.INSTANCE.getRecipe(id);
if (recipe != null) {
if (select) {
planOutput(recipe);
} else {
cancelPlanOutput(recipe);
}
}
}
sendNetworkUpdate();
sendNetworkUpdate();
}
}
@Override
@ -306,11 +335,6 @@ public class TileAssemblyTable extends TileLaserTableBase implements IInventory,
return false;
}
@Override
public void postPacketHandling(PacketUpdate packet) {
currentRecipe = AssemblyRecipeManager.INSTANCE.getRecipe(currentRecipeId);
}
@Override
public int getCraftingItemStackSize() {
return getSizeInventory();

View file

@ -11,12 +11,12 @@ package buildcraft.silicon;
import java.util.LinkedList;
import java.util.List;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.NetworkData;
import buildcraft.api.core.Position;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.power.ILaserTarget;
@ -34,7 +34,6 @@ public class TileLaser extends TileBuildCraft implements IHasWork, IControllable
private static final float LASER_OFFSET = 2.0F / 16.0F;
private static final short POWER_AVERAGING = 100;
@NetworkData
public LaserData laser = new LaserData();
private final SafeTimeTracker laserTickTracker = new SafeTimeTracker(10);
@ -44,7 +43,6 @@ public class TileLaser extends TileBuildCraft implements IHasWork, IControllable
private IControllable.Mode lastMode = IControllable.Mode.Unknown;
private int powerIndex = 0;
@NetworkData
private short powerAverage = 0;
private final short[] power = new short[POWER_AVERAGING];
@ -270,6 +268,19 @@ public class TileLaser extends TileBuildCraft implements IHasWork, IControllable
super.writeToNBT(nbttagcompound);
}
@Override
public void readData(ByteBuf stream) {
laser = new LaserData();
laser.readData(stream);
powerAverage = stream.readShort();
}
@Override
public void writeData(ByteBuf stream) {
laser.writeData(stream);
stream.writeShort(powerAverage);
}
@Override
public void invalidate() {
super.invalidate();

View file

@ -38,7 +38,6 @@ import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.PipeWire;
import buildcraft.core.IDropControlInventory;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.network.TilePacketWrapper;
import buildcraft.core.utils.Utils;
import buildcraft.transport.gates.GateFactory;
import buildcraft.transport.gates.StatementSlot;
@ -46,9 +45,6 @@ import buildcraft.transport.pipes.events.PipeEvent;
import buildcraft.transport.statements.ActionValve.ValveState;
public abstract class Pipe<T extends PipeTransport> implements IDropControlInventory, IPipe {
@SuppressWarnings("rawtypes")
private static Map<Class, TilePacketWrapper> networkWrappers = new HashMap<Class, TilePacketWrapper>();
private static Map<Class<? extends Pipe>, Map<Class<? extends PipeEvent>, EventHandler>> eventHandlers = new HashMap<Class<? extends Pipe>, Map<Class<? extends PipeEvent>, EventHandler>>();
public int[] signalStrength = new int[]{0, 0, 0, 0};
@ -66,11 +62,6 @@ public abstract class Pipe<T extends PipeTransport> implements IDropControlInven
public Pipe(T transport, Item item) {
this.transport = transport;
this.item = item;
if (!networkWrappers.containsKey(this.getClass())) {
networkWrappers
.put(this.getClass(), new TilePacketWrapper(new Class[]{TileGenericPipe.class, this.transport.getClass()}));
}
}
public void setTile(TileEntity tile) {

View file

@ -14,25 +14,29 @@ import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import cpw.mods.fml.relauncher.Side;
import buildcraft.BuildCraftCore;
import buildcraft.api.statements.IStatement;
import buildcraft.api.statements.IStatementParameter;
import buildcraft.api.statements.StatementManager;
import buildcraft.core.gui.BuildCraftContainer;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.ICommandReceiver;
import buildcraft.core.network.PacketCommand;
import buildcraft.core.utils.Utils;
import buildcraft.transport.ActionActiveState;
import buildcraft.transport.Gate;
import buildcraft.transport.Pipe;
import buildcraft.transport.gates.GateDefinition;
public class ContainerGateInterface extends BuildCraftContainer {
public class ContainerGateInterface extends BuildCraftContainer implements ICommandReceiver {
public ActionActiveState[] actionsState = new ActionActiveState[8];
public GuiGateInterface gateCallback;
@ -165,12 +169,12 @@ public class ContainerGateInterface extends BuildCraftContainer {
public void synchronize() {
if (!isNetInitialized && pipe.container.getWorldObj().isRemote) {
isNetInitialized = true;
RPCHandler.rpcServer(this, "initRequest");
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "initRequest"));
}
if (!isSynchronized && pipe.container.getWorldObj().isRemote && gate != null) {
isSynchronized = true;
RPCHandler.rpcServer(this, "selectionRequest");
BuildCraftCore.instance.sendToServer(new PacketCommand(this, "selectionRequest"));
}
}
@ -220,47 +224,6 @@ public class ContainerGateInterface extends BuildCraftContainer {
}
/**
* Sends gate info to the client
*/
@RPC(RPCSide.SERVER)
public void initRequest(RPCMessageInfo info) {
EntityPlayer player = info.sender;
RPCHandler.rpcPlayer(player, this, "setGate", gate.getDirection().ordinal());
RPCHandler.rpcPlayer(player, this, "setPotential", statementsToStrings(potentialActions), statementsToStrings(potentialTriggers));
}
@RPC(RPCSide.CLIENT)
public void setPotential(String[] potentialActions, String[] potentialTriggers) {
stringsToStatements(this.potentialActions, potentialActions);
stringsToStatements(this.potentialTriggers, potentialTriggers);
}
@RPC(RPCSide.CLIENT)
public void setGate(int direction) {
this.gate = pipe.gates[direction];
init();
}
@RPC(RPCSide.SERVER)
public void selectionRequest(RPCMessageInfo info) {
EntityPlayer player = info.sender;
for (int position = 0; position < gate.material.numSlots; position++) {
IStatement action = gate.getAction(position);
IStatement trigger = gate.getTrigger(position);
RPCHandler.rpcPlayer(player, this, "setAction", position, action != null ? action.getUniqueTag() : null, false);
RPCHandler.rpcPlayer(player, this, "setTrigger", position, trigger != null ? trigger.getUniqueTag() : null, false);
for (int p = 0; p < gate.material.numActionParameters; ++p) {
RPCHandler.rpcPlayer(player, this, "setActionParameter", position, p,
gate.getActionParameter(position, p), false);
}
for (int q = 0; q < gate.material.numTriggerParameters; ++q) {
RPCHandler.rpcPlayer(player, this, "setTriggerParameter", position, q,
gate.getTriggerParameter(position, q), false);
}
}
}
/**
* TRIGGERS *
*/
@ -296,24 +259,22 @@ public class ContainerGateInterface extends BuildCraftContainer {
}
}
@RPC(RPCSide.BOTH)
public void setTrigger(int trigger, String tag, boolean notifyServer) {
if (gate == null) {
return;
}
IStatement statement = null;
if (tag != null) {
gate.setTrigger(trigger, (IStatement) StatementManager.statements.get(tag));
} else {
gate.setTrigger(trigger, null);
}
gate.setTrigger(trigger, statement);
if (pipe.container.getWorldObj().isRemote && notifyServer) {
RPCHandler.rpcServer(this, "setTrigger", trigger, tag, false);
BuildCraftCore.instance.sendToServer(getStatementPacket("setTrigger", trigger, statement));
}
}
@RPC(RPCSide.BOTH)
public void setTriggerParameter(int trigger, int param, IStatementParameter parameter, boolean notifyServer) {
if (gate == null) {
return;
@ -322,7 +283,7 @@ public class ContainerGateInterface extends BuildCraftContainer {
gate.setTriggerParameter(trigger, param, parameter);
if (pipe.container.getWorldObj().isRemote && notifyServer) {
RPCHandler.rpcServer(this, "setTriggerParameter", trigger, param, parameter, false);
BuildCraftCore.instance.sendToServer(getStatementParameterPacket("setTriggerParameter", trigger, param, parameter));
}
}
@ -361,24 +322,138 @@ public class ContainerGateInterface extends BuildCraftContainer {
return descending ? potentialActions.descendingIterator() : potentialActions.iterator();
}
@RPC(RPCSide.BOTH)
// PACKET GENERATION
public BuildCraftPacket getStatementPacket(final String name, final int slot, final IStatement statement) {
final String statementKind = statement != null ? statement.getUniqueTag() : null;
return new PacketCommand(this, name) {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(slot);
Utils.writeUTF(data, statementKind);
}
};
}
public BuildCraftPacket getStatementParameterPacket(final String name, final int slot,
final int paramSlot, final IStatementParameter parameter) {
final String parameterName = parameter != null ? parameter.getUniqueTag() : null;
final NBTTagCompound parameterNBT = new NBTTagCompound();
if (parameter != null) {
parameter.writeToNBT(parameterNBT);
}
return new PacketCommand(this, name) {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(slot);
data.writeByte(paramSlot);
Utils.writeUTF(data, parameterName);
Utils.writeNBT(data, parameterNBT);
}
};
}
public void setGate(int direction) {
this.gate = pipe.gates[direction];
}
@Override
public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
if (side.isServer()) {
EntityPlayer player = (EntityPlayer) sender;
if (command.equals("initRequest")) {
BuildCraftCore.instance.sendToPlayer(player, new PacketCommand(this, "init") {
@Override
public void writeData(ByteBuf data) {
super.writeData(data);
data.writeByte(gate.getDirection().ordinal());
String[] triggerStrings = statementsToStrings(potentialTriggers);
String[] actionStrings = statementsToStrings(potentialActions);
data.writeShort(triggerStrings.length);
data.writeShort(actionStrings.length);
for (String trigger : triggerStrings) {
Utils.writeUTF(data, trigger);
}
for (String action : actionStrings) {
Utils.writeUTF(data, action);
}
}
});
} else if (command.equals("selectionRequest")) {
for (int position = 0; position < gate.material.numSlots; position++) {
IStatement action = gate.getAction(position);
IStatement trigger = gate.getTrigger(position);
BuildCraftCore.instance.sendToPlayer(player, getStatementPacket("setAction", position, action));
BuildCraftCore.instance.sendToPlayer(player, getStatementPacket("setTrigger", position, trigger));
for (int p = 0; p < gate.material.numActionParameters; ++p) {
BuildCraftCore.instance.sendToPlayer(player, getStatementParameterPacket(
"setActionParameter", position, p, gate.getActionParameter(position, p)));
}
for (int q = 0; q < gate.material.numTriggerParameters; ++q) {
BuildCraftCore.instance.sendToPlayer(player, getStatementParameterPacket(
"setTriggerParameter", position, q, gate.getTriggerParameter(position, q)));
}
}
}
} else if (side.isClient()) {
if (command.equals("init")) {
setGate(stream.readUnsignedByte());
String[] triggerStrings = new String[stream.readUnsignedShort()];
String[] actionStrings = new String[stream.readUnsignedShort()];
for (int i = 0; i < triggerStrings.length; i++) {
triggerStrings[i] = Utils.readUTF(stream);
}
for (int i = 0; i < actionStrings.length; i++) {
actionStrings[i] = Utils.readUTF(stream);
}
stringsToStatements(this.potentialTriggers, triggerStrings);
stringsToStatements(this.potentialActions, actionStrings);
}
}
if (command.equals("setAction")) {
setAction(stream.readUnsignedByte(), Utils.readUTF(stream), false);
} else if (command.equals("setTrigger")) {
setTrigger(stream.readUnsignedByte(), Utils.readUTF(stream), false);
} else if (command.equals("setActionParameter") || command.equals("setTriggerParameter")) {
int slot = stream.readUnsignedByte();
int param = stream.readUnsignedByte();
String parameterName = Utils.readUTF(stream);
NBTTagCompound parameterData = Utils.readNBT(stream);
IStatementParameter parameter = StatementManager.createParameter(parameterName);
if (parameter != null) {
parameter.readFromNBT(parameterData);
if (command.equals("setActionParameter")) {
setActionParameter(slot, param, parameter, false);
} else {
setTriggerParameter(slot, param, parameter, false);
}
}
}
}
public void setAction(int action, String tag, boolean notifyServer) {
if (gate == null) {
return;
}
IStatement statement = null;
if (tag != null) {
gate.setAction(action, (IStatement) StatementManager.statements.get(tag));
} else {
gate.setAction(action, null);
statement = (IStatement) StatementManager.statements.get(tag);
}
gate.setAction(action, statement);
if (pipe.container.getWorldObj().isRemote && notifyServer) {
RPCHandler.rpcServer(this, "setAction", action, tag, false);
BuildCraftCore.instance.sendToServer(getStatementPacket("setAction", action, statement));
}
}
@RPC(RPCSide.BOTH)
public void setActionParameter(int action, int param, IStatementParameter parameter, boolean notifyServer) {
if (gate == null) {
return;
@ -387,7 +462,7 @@ public class ContainerGateInterface extends BuildCraftContainer {
gate.setActionParameter(action, param, parameter);
if (pipe.container.getWorldObj().isRemote && notifyServer) {
RPCHandler.rpcServer(this, "setActionParameter", action, param, parameter, false);
BuildCraftCore.instance.sendToServer(getStatementParameterPacket("setActionParameter", action, param, parameter));
}
}

View file

@ -8,6 +8,7 @@
*/
package buildcraft.transport.pipes;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.tileentity.TileEntity;
@ -25,16 +26,15 @@ import cofh.api.energy.IEnergyHandler;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.NetworkData;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.PipeManager;
import buildcraft.core.RFBattery;
import buildcraft.core.network.IClientState;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeTransportFluids;
public class PipeFluidsWood extends Pipe<PipeTransportFluids> implements IEnergyHandler {
@NetworkData
public class PipeFluidsWood extends Pipe<PipeTransportFluids> implements IEnergyHandler, IClientState {
public int liquidToExtract;
protected int standardIconIndex = PipeIconProvider.TYPE.PipeFluidsWood_Standard.ordinal();
@ -186,4 +186,14 @@ public class PipeFluidsWood extends Pipe<PipeTransportFluids> implements IEnergy
public int getMaxEnergyStored(ForgeDirection from) {
return battery.getMaxEnergyStored();
}
@Override
public void writeData(ByteBuf data) {
data.writeInt(liquidToExtract);
}
@Override
public void readData(ByteBuf data) {
liquidToExtract = data.readInt();
}
}

View file

@ -12,6 +12,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
@ -23,9 +24,9 @@ import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.EnumColor;
import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.NetworkData;
import buildcraft.api.statements.IActionInternal;
import buildcraft.api.tools.IToolWrench;
import buildcraft.core.network.IClientState;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeTransportItems;
@ -37,11 +38,10 @@ import buildcraft.transport.pipes.events.PipeEventItem;
import buildcraft.transport.statements.ActionPipeColor;
import buildcraft.transport.statements.ActionPipeDirection;
public class PipeItemsDaizuli extends Pipe<PipeTransportItems> {
public class PipeItemsDaizuli extends Pipe<PipeTransportItems> implements IClientState {
private int standardIconIndex = PipeIconProvider.TYPE.PipeItemsDaizuli_Black.ordinal();
private int solidIconIndex = PipeIconProvider.TYPE.PipeAllDaizuli_Solid.ordinal();
@NetworkData
private int color = EnumColor.BLACK.ordinal();
private PipeLogicIron logic = new PipeLogicIron(this) {
@Override
@ -191,4 +191,14 @@ public class PipeItemsDaizuli extends Pipe<PipeTransportItems> {
super.readFromNBT(data);
color = data.getByte("color");
}
@Override
public void writeData(ByteBuf data) {
data.writeByte(color);
}
@Override
public void readData(ByteBuf data) {
color = data.readByte();
}
}

View file

@ -11,18 +11,13 @@ package buildcraft.transport.utils;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.ISerializable;
import buildcraft.api.core.NetworkData;
import buildcraft.core.network.serializers.ClassMapping;
import buildcraft.core.network.serializers.SerializationContext;
public class RobotStationMatrix {
public class RobotStationMatrix implements ISerializable {
// TODO: All these matrixes should be passed by RPC, instead of having a
// single state carrying everything
@NetworkData
private RobotStationState[] states = new RobotStationState[6];
private boolean dirty = false;
@ -56,22 +51,17 @@ public class RobotStationMatrix {
dirty = false;
}
@Override
public void writeData(ByteBuf data) {
try {
SerializationContext context = new SerializationContext();
ClassMapping.get(this.getClass()).write(data, this, context);
} catch (Exception e) {
e.printStackTrace();
for (int i = 0; i < states.length; i++) {
data.writeByte(states[i].ordinal());
}
}
@Override
public void readData(ByteBuf data) {
try {
SerializationContext context = new SerializationContext();
ClassMapping.get(this.getClass()).read(data, this, context);
dirty = true;
} catch (Exception e) {
e.printStackTrace();
for (int i = 0; i < states.length; i++) {
states[i] = RobotStationState.values()[data.readUnsignedByte()];
}
}
}