CVE-2023-38689 (Java, published 2023-08-04T17:15Z)
Description: value: Logistics Pipes is a modification (a.k.a. mod) for the computer game Minecraft Java Edition. The mod used Java's `ObjectInputStream#readObject` on untrusted data coming from clients or servers over the network resulting in possible remote code execution when sending specifically crafted network packets after connecting. The affected versions were released between 2013 and 2016 and the issue (back then unknown) was fixed in 2016 by a refactoring of the network IO code.  
The issue is present in all Logistics Pipes versions ranged from 0.7.0.91 prior to 0.10.0.71, which were downloaded from different platforms summing up to multi-million downloads. For Minecraft version 1.7.10 the issue was fixed in build 0.10.0.71. Everybody on Minecraft 1.7.10 should check their version number of Logistics Pipes in their modlist and update, if the version number is smaller than 0.10.0.71. Any newer supported Minecraft version (like 1.12.2) never had a Logistics Pipes version with vulnerable code. The best available workaround for vulnerable versions is to play in singleplayer only or update to newer Minecraft versions and modpacks.
Severity: nan (CVSS v3 base score: 9.8)
Weakness: CWE-502 \u2014 Deserialization of Untrusted Data
The product deserializes untrusted data without sufficiently verifying that the resulting data will be valid.
Repository: https://github.com/RS485/LogisticsPipes
Files changed:
common/logisticspipes/blocks/stats/TrackingTask.java
common/logisticspipes/config/PlayerConfig.java
common/logisticspipes/interfaces/IClientState.java
common/logisticspipes/network/IReadListObject.java
common/logisticspipes/network/IWriteListObject.java
common/logisticspipes/network/NewGuiHandler.java
common/logisticspipes/network/PacketHandler.java
common/logisticspipes/network/abstractguis/BooleanModuleCoordinatesGuiProvider.java
common/logisticspipes/network/abstractguis/CoordinatesGuiProvider.java
common/logisticspipes/network/abstractguis/CoordinatesPopupGuiProvider.java
common/logisticspipes/network/abstractguis/GuiProvider.java
common/logisticspipes/network/abstractguis/ModuleCoordinatesGuiProvider.java
common/logisticspipes/network/abstractguis/ModuleInHandGuiProvider.java
common/logisticspipes/network/abstractguis/NBTModuleCoordinatesGuiProvider.java
common/logisticspipes/network/abstractguis/UpgradeCoordinatesGuiProvider.java
common/logisticspipes/network/abstractpackets/BitSetCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/BooleanModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/CoordinatesPacket.java
common/logisticspipes/network/abstractpackets/DirectionModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/Integer2CoordinatesPacket.java
common/logisticspipes/network/abstractpackets/Integer2ModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/IntegerCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/IntegerModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/IntegerPacket.java
common/logisticspipes/network/abstractpackets/InventoryModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/ItemPacket.java
common/logisticspipes/network/abstractpackets/ListSyncPacket.java
common/logisticspipes/network/abstractpackets/ModernPacket.java
common/logisticspipes/network/abstractpackets/ModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/NBTCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/NBTModuleCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/RequestPacket.java
common/logisticspipes/network/abstractpackets/SlotPacket.java
common/logisticspipes/network/abstractpackets/StringCoordinatesPacket.java
common/logisticspipes/network/abstractpackets/StringListPacket.java
common/logisticspipes/network/guis/block/AutoCraftingGui.java
common/logisticspipes/network/guis/block/StatisticsGui.java
common/logisticspipes/network/guis/item/ItemAmountSignGui.java
common/logisticspipes/network/guis/module/inhand/CraftingModuleInHand.java
common/logisticspipes/network/guis/module/inpipe/ActiveSupplierSlot.java
common/logisticspipes/network/guis/module/inpipe/AdvancedExtractorModuleSlot.java
common/logisticspipes/network/guis/module/inpipe/ApiaristAnalyzerModuleSlot.java
common/logisticspipes/network/guis/module/inpipe/CCBasedQuickSortSlot.java
common/logisticspipes/network/guis/module/inpipe/CraftingModuleSlot.java
common/logisticspipes/network/guis/module/inpipe/ExtractorModuleSlot.java
common/logisticspipes/network/guis/module/inpipe/ItemSinkSlot.java
common/logisticspipes/network/guis/module/inpipe/ProviderModuleGuiProvider.java
common/logisticspipes/network/packets/ActivateNBTDebug.java
common/logisticspipes/network/packets/BufferTransfer.java
common/logisticspipes/network/packets/CraftingPermissionPacket.java
common/logisticspipes/network/packets/DummyPacket.java
common/logisticspipes/network/packets/NEISetCraftingRecipe.java
common/logisticspipes/network/packets/PlayerConfigToClientPacket.java
common/logisticspipes/network/packets/PlayerConfigToServerPacket.java
common/logisticspipes/network/packets/PlayerListRequest.java
common/logisticspipes/network/packets/RequestUpdateNamesPacket.java
common/logisticspipes/network/packets/UpdateName.java
common/logisticspipes/network/packets/block/AddItemToTrackPacket.java
common/logisticspipes/network/packets/block/CraftingCycleRecipe.java
common/logisticspipes/network/packets/block/CraftingSetType.java
common/logisticspipes/network/packets/block/PowerPacketLaser.java
common/logisticspipes/network/packets/block/PowerProviderLevel.java
common/logisticspipes/network/packets/block/RemoveAmoundTask.java
common/logisticspipes/network/packets/block/RunningCraftingTasks.java
common/logisticspipes/network/packets/block/SecurityStationId.java
common/logisticspipes/network/packets/chassis/ChassisGUI.java
common/logisticspipes/network/packets/chassis/ChestGuiClosed.java
common/logisticspipes/network/packets/chassis/ChestGuiOpened.java
common/logisticspipes/network/packets/chassis/EnableQuickSortMarker.java
common/logisticspipes/network/packets/cpipe/CPipeCleanupStatus.java
common/logisticspipes/network/packets/cpipe/CPipeSatelliteId.java
common/logisticspipes/network/packets/debug/PipeDebugLogAskForTarget.java
common/logisticspipes/network/packets/debug/SendNewLogLine.java
common/logisticspipes/network/packets/debug/SendNewLogWindow.java
common/logisticspipes/network/packets/debug/UpdateStatusEntries.java
common/logisticspipes/network/packets/debuggui/DebugAskForTarget.java
common/logisticspipes/network/packets/debuggui/DebugDataPacket.java
common/logisticspipes/network/packets/debuggui/DebugPanelOpen.java
common/logisticspipes/network/packets/debuggui/DebugTargetResponse.java
common/logisticspipes/network/packets/gui/DummyContainerSlotClick.java
common/logisticspipes/network/packets/gui/FuzzySlotSettingsPacket.java
common/logisticspipes/network/packets/gui/GUIPacket.java
common/logisticspipes/network/packets/gui/GuiReopenPacket.java
common/logisticspipes/network/packets/gui/OpenChatGui.java
common/logisticspipes/network/packets/hud/HUDSettingsPacket.java
common/logisticspipes/network/packets/module/ApiaristAnalyserMode.java
common/logisticspipes/network/packets/module/BeeModuleSetBeePacket.java
common/logisticspipes/network/packets/module/ItemSinkDefaultPacket.java
common/logisticspipes/network/packets/module/ModuleBasedItemSinkList.java
common/logisticspipes/network/packets/module/SupplierPipeLimitedPacket.java
common/logisticspipes/network/packets/modules/CCBasedQuickSortMode.java
common/logisticspipes/network/packets/modules/CCBasedQuickSortSinkSize.java
common/logisticspipes/network/packets/modules/ItemSinkFuzzy.java
common/logisticspipes/network/packets/modules/ProviderModuleMode.java
common/logisticspipes/network/packets/modules/SupplierPipeMode.java
common/logisticspipes/network/packets/multiblock/MultiBlockCoordinatesPacket.java
common/logisticspipes/network/packets/orderer/ComponentList.java
common/logisticspipes/network/packets/orderer/MissingItems.java
common/logisticspipes/network/packets/orderer/OrdererWatchPacket.java
common/logisticspipes/network/packets/pipe/AskForOpenTarget.java
common/logisticspipes/network/packets/pipe/CraftingPipeUpdatePacket.java
common/logisticspipes/network/packets/pipe/FindMostLikelyRecipeComponents.java
common/logisticspipes/network/packets/pipe/ItemAmountSignUpdatePacket.java
common/logisticspipes/network/packets/pipe/ItemBufferSyncPacket.java
common/logisticspipes/network/packets/pipe/MostLikelyRecipeComponentsResponse.java
common/logisticspipes/network/packets/pipe/ParticleFX.java
common/logisticspipes/network/packets/pipe/PipeContentPacket.java
common/logisticspipes/network/packets/pipe/PipeDebugAskForTarget.java
common/logisticspipes/network/packets/pipe/PipeFluidUpdate.java
common/logisticspipes/network/packets/pipe/PipeManagerContentPacket.java
common/logisticspipes/network/packets/pipe/PipeManagerWatchingPacket.java
common/logisticspipes/network/packets/pipe/PipePositionPacket.java
common/logisticspipes/network/packets/pipe/PipeSignTypes.java
common/logisticspipes/network/packets/pipe/PipeTileStatePacket.java
common/logisticspipes/network/packets/pipe/RoutingLaserPacket.java
common/logisticspipes/network/packets/pipe/SlotFinderActivatePacket.java
common/logisticspipes/network/packets/pipe/SlotFinderNumberPacket.java
common/logisticspipes/network/packets/pipe/SlotFinderOpenGuiPacket.java
common/logisticspipes/network/packets/pipe/StatUpdate.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateAskForTarget.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateCanidatePipe.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateClearClient.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateDebugCanidateList.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateDebugClosedSet.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateDebugFilters.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateDoneDebug.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateInitDebug.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateSourcePipe.java
common/logisticspipes/network/packets/routingdebug/RoutingUpdateTargetResponse.java
common/logisticspipes/network/packets/satpipe/SatPipeSetID.java
common/logisticspipes/network/packets/upgrade/SneakyUpgradeSidePacket.java
common/logisticspipes/network/packets/upgrade/ToogleDisconnectionUpgradeSidePacket.java
common/logisticspipes/pipes/basic/CoreRoutedPipe.java
common/logisticspipes/pipes/basic/LogisticsTileGenericPipe.java
common/logisticspipes/pipes/tubes/HSTubeCurve.java
common/logisticspipes/pipes/tubes/HSTubeGain.java
common/logisticspipes/pipes/tubes/HSTubeLine.java
common/logisticspipes/pipes/tubes/HSTubeSCurve.java
common/logisticspipes/pipes/tubes/HSTubeSpeedup.java
common/logisticspipes/pipes/unrouted/PipeItemsBasicTransport.java
common/logisticspipes/proxy/ProxyManager.java
common/logisticspipes/proxy/buildcraft/subproxies/IBCPluggableState.java
common/logisticspipes/proxy/buildcraft/subproxies/IBCRenderState.java
common/logisticspipes/proxy/buildcraft/subproxies/LPBCPipeRenderState.java
common/logisticspipes/proxy/buildcraft/subproxies/LPBCPluggableState.java
common/logisticspipes/renderer/state/ConnectionMatrix.java
common/logisticspipes/renderer/state/PipeRenderState.java
common/logisticspipes/renderer/state/TextureMatrix.java
common/logisticspipes/request/resources/DictResource.java
common/logisticspipes/request/resources/FluidResource.java
common/logisticspipes/request/resources/IResource.java
common/logisticspipes/request/resources/ItemResource.java
common/logisticspipes/request/resources/ResourceNetwork.java
common/logisticspipes/routing/LaserData.java
common/logisticspipes/ticks/ClientPacketBufferHandlerThread.java
common/logisticspipes/ticks/ServerPacketBufferHandlerThread.java
common/network/rs485/logisticspipes/util/LPDataIOWrapper.java
common/network/rs485/logisticspipes/util/LPDataInput.java
common/network/rs485/logisticspipes/util/LPDataOutput.java
test/network/rs485/logisticspipes/util/LPDataIOWrapperTest.java
Commit message: Remove IOException escalation



Vulnerable code:
import java.io.IOException;

	public void writeToLPData(LPDataOutput output) throws IOException {
	public void readFromLPData(LPDataInput input) throws IOException {
	public void setUseNewRenderer(boolean flag) {
		useNewRenderer = flag;
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	void writeData(LPDataOutput output) throws IOException;
	void readData(LPDataInput input) throws IOException;
import java.io.IOException;

	T readObject(LPDataInput input) throws IOException;
import java.io.IOException;

	void writeObject(LPDataOutput output, T object) throws IOException;
	@SneakyThrows(IOException.class)
	@SneakyThrows(IOException.class)

	public static final Map<Integer, StackTraceElement[]> debugMap = new HashMap<>();
	//horrible hack to carry the proper player for the side along...
	static class InboundModernPacketWrapper {

		final ModernPacket packet;
		final EntityPlayer player;

		InboundModernPacketWrapper(ModernPacket p, EntityPlayer e) {
			packet = p;
			player = e;
		}
	}

	//TODO correct to work with WeakReference (See FML original)
	protected static final AttributeKey<ThreadLocal<FMLProxyPacket>> INBOUNDPACKETTRACKER = new AttributeKey<>("lp:inboundpacket");

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		super.handlerAdded(ctx);
		ctx.attr(PacketHandler.INBOUNDPACKETTRACKER).set(new ThreadLocal<>());
	}

	//hacky callback to process packets coming from by the packetbufferhandler decompressors
	//TODO replace with proper netty implementation
	public static void onPacketData(final LPDataInput data, final EntityPlayer player) throws IOException {
		if (player == null) {
			return;
		}
		final int packetID = data.readShort();
		final ModernPacket packet = PacketHandler.packetlist.get(packetID).template();
		packet.setDebugId(data.readInt());
		packet.readData(data);
		PacketHandler.onPacketData(packet, player);
	}
	private static void onPacketData(ModernPacket packet, final EntityPlayer player) {
		try {
			packet.processPacket(player);
			if (LPConstants.DEBUG) {
				PacketHandler.debugMap.remove(packet.getDebugId());
			}
		} catch (DelayPacketException e) {
			if (packet.retry() && MainProxy.isClient(player.getEntityWorld())) {
				SimpleServiceLocator.clientBufferHandler.queueFailedPacket(packet, player);
			} else if (LPConstants.DEBUG) {
				LogisticsPipes.log.error(packet.getClass().getName());
				LogisticsPipes.log.error(packet.toString());
				e.printStackTrace();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
import java.io.IOException;

	public BooleanModuleCoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public CoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public CoordinatesPopupGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {}
	public void readData(LPDataInput input) throws IOException {}
import java.io.IOException;

	public ModuleCoordinatesGuiProvider(int id) {
		super(id);
	}


	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public ModuleInHandGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public UpgradeCoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public enum LTGPCompletionCheck {
		NONE,
		PIPE,
		TRANSPORT
	}

	public CoordinatesPacket(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
package logisticspipes.network.abstractpackets;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

import lombok.Getter;

import network.rs485.logisticspipes.util.LPDataInput;
import network.rs485.logisticspipes.util.LPDataOutput;

public abstract class GenericPacket extends ModernPacket {

	@Getter
	private Object[] args;

	public GenericPacket(int id) {
		super(id);
	}

	@Override
	public void readData(LPDataInput input) throws IOException {
		int size = input.readInt();
		args = new Object[size];
		for (int i = 0; i < size; i++) {
			byte[] bytes = input.readByteArray();
			ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
			ObjectInput in = new ObjectInputStream(bis);
			try {
				Object o = in.readObject();
				args[i] = o;
			} catch (ClassNotFoundException e) {
				throw new UnsupportedOperationException(e);
			}
		}
	}

	@Override
	public void writeData(LPDataOutput output) throws IOException {
		output.writeInt(args.length);
		for (Object arg : args) {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutput out = new ObjectOutputStream(bos);
			out.writeObject(arg);
			output.writeByteArray(bos.toByteArray());
		}
	}

	public GenericPacket setArgs(Object... input) {
		args = input;
		return this;
	}
}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	@Getter
	@Setter
	private boolean isChunkDataPacket;

	@Getter
	@Setter
	private boolean compressable;


	protected int leftRetries = 5;

	public abstract void readData(LPDataInput input) throws IOException;
	public abstract void writeData(LPDataOutput output) throws IOException;
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
	private boolean moduleBased = false;

import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public CraftingCycleRecipe(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public CraftingSetType(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public PowerPacketLaser(int id) {
		super(id);
	}






	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
			public StatusEntry readObject(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
			public void writeObject(LPDataOutput output, StatusEntry entry) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
					.setAdditions(new Object[] { box.blockX, box.blockY, box.blockZ }));
					.setAdditions(new Object[] { box.entityHit.getEntityId() }));
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

	public DebugTargetResponse(int id) {
		super(id);
	}

	public enum TargetMode {
		Block,
		Entity,
		None
	}


	private Object[] additions = new Object[0];
	public void readData(LPDataInput input) throws IOException {
		int size = input.readInt();
		additions = new Object[size];
		for (int i = 0; i < size; i++) {
			byte[] bytes = input.readByteArray();
			ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
			ObjectInput in = new ObjectInputStream(bis);
			try {
				Object o = in.readObject();
				additions[i] = o;
			} catch (ClassNotFoundException e) {
				throw new UnsupportedOperationException(e);
			}
		}
			int x = (Integer) additions[0];
			int y = (Integer) additions[1];
			int z = (Integer) additions[2];
			int entityId = (Integer) additions[0];
	public void writeData(LPDataOutput output) throws IOException {
		output.writeInt(additions.length);
		for (Object addition : additions) {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutput out = null;
			out = new ObjectOutputStream(bos);
			out.writeObject(addition);
			output.writeByteArray(bos.toByteArray());
		}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
	public GuiReopenPacket(int id) {
		super(id);
	}

import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
	public MultiBlockCoordinatesPacket(int id) {
		super(id);
	}

import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

			Triplet<ItemIdentifierStack, Pair<Integer /* Time */, Integer /* BufferCounter */>, LPTravelingItemServer> object) throws IOException {
	public Triplet<ItemIdentifierStack, Pair<Integer /* Time */, Integer /* BufferCounter */>, LPTravelingItemServer> readObject(LPDataInput input)
			throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public ParticleFX(int id) {
		super(id);
	}

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public PipeContentPacket(int id) {
		super(id);
	}

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public PipeFluidUpdate(int id) {
		super(id);
	}


	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public PipeSignTypes(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

		try {
			LPDataIOWrapper.provideData(bytesRenderState, pipe.renderState::readData);
			LPDataIOWrapper.provideData(bytesCoreState, pipe.coreState::readData);
			LPDataIOWrapper.provideData(bytesBCPluggableState, pipe.bcPlugableState::readData);
			pipe.afterStateUpdated();
			LPDataIOWrapper.provideData(bytesPipe, pipe.pipe::readData);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
					.setAdditions(new Object[] { box.blockX, box.blockY, box.blockZ }));
					.setAdditions(new Object[] { box.entityHit.getEntityId() }));
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;
	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {}
	public void writeData(LPDataOutput output) throws IOException {}
import java.io.IOException;

	public void readData(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

	public RoutingUpdateTargetResponse(int id) {
		super(id);
	}

	public enum TargetMode {
		Block,
		Entity,
		None
	}


	private Object[] additions = new Object[0];
	public void readData(LPDataInput input) throws IOException {
		int size = input.readInt();
		additions = new Object[size];
		for (int i = 0; i < size; i++) {
			byte[] bytes = input.readByteArray();
			ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
			ObjectInput in = new ObjectInputStream(bis);
			try {
				Object o = in.readObject();
				additions[i] = o;
			} catch (ClassNotFoundException e) {
				throw new UnsupportedOperationException(e);
			}
		}
			int x = (Integer) additions[0];
			int y = (Integer) additions[1];
			int z = (Integer) additions[2];
	public void writeData(LPDataOutput output) throws IOException {
		output.writeInt(additions.length);
		for (Object addition : additions) {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutput out = new ObjectOutputStream(bos);
			out.writeObject(addition);
			output.writeByteArray(bos.toByteArray());
		}
import java.io.IOException;

	@Getter
	@Setter
	private int satID;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public enum ItemSendMode {
		Normal,
		Fast
	}

	protected boolean stillNeedReplace = true;
	private boolean recheckConnections = false;

	protected IRouter router;
	protected String routerId;
	protected Object routerIdLock = new Object();
	protected int _delayOffset = 0;


	protected boolean _initialInit = true;

	private boolean enabled = true;
	private boolean preventRemove = false;
	private boolean destroyByPlayer = false;
	private PowerSupplierHandler powerHandler = new PowerSupplierHandler(this);


	protected RouteLayer _routeLayer;
	protected TransportLayer _transportLayer;
	protected final PriorityBlockingQueue<ItemRoutingInformation> _inTransitToMe = new PriorityBlockingQueue<>(10,
			new ItemRoutingInformation.DelayComparator());

	protected UpgradeManager upgradeManager = new UpgradeManager(this);
	protected LogisticsItemOrderManager _orderItemManager = null;

	@Getter
	private List<IOrderInfoProvider> clientSideOrderManager = new ArrayList<>();




	protected final LinkedList<Triplet<IRoutedItem, ForgeDirection, ItemSendMode>> _sendQueue = new LinkedList<>();

	protected final Map<ItemIdentifier, Queue<Pair<Integer, ItemRoutingInformation>>> queuedDataForUnroutedItems = Collections.synchronizedMap(new TreeMap<>());

	public final PlayerCollectionList watchers = new PlayerCollectionList();




	protected IPipeSign[] signItem = new IPipeSign[6];
	public boolean globalIgnoreConnectionDisconnection = false;

	/* Power System */

	@CCCommand(description = "Sets the TurtleConnect flag for this Turtle on this LogisticsPipe")
	public void setTurtleConnect(Boolean flag) {
			container.setTurtleConnect(flag);
	@CCCommand(description = "Returns the TurtleConnect flag for this Turtle on this LogisticsPipe")
	public boolean getTurtleConnect() {
			return container.getTurtleConnect();
		return false;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;



	private LogisticsTileRenderController renderController;





	public LogicController logicController = new LogicController();

	public final PipeRenderState renderState;
	public final CoreState coreState = new CoreState();
	public final IBCTilePart tilePart;
	public final IBCPluggableState bcPlugableState;
	public final ITDPart tdPart;
	public void setTurtleConnect(boolean flag) {
		SimpleServiceLocator.ccProxy.setTurtleConnect(flag, this);
	}

	/* IPipeInformationProvider */

	@Getter
	private boolean initialized = false;

	public boolean[] pipeConnectionsBuffer = new boolean[6];
	public boolean[] pipeBCConnectionsBuffer = new boolean[6];
	public boolean[] pipeTDConnectionsBuffer = new boolean[6];

	public CoreUnroutedPipe pipe;
	//public int redstoneInput = 0;
	//public int[] redstoneInputSide = new int[ForgeDirection.VALID_DIRECTIONS.length];

	private boolean deletePipe = false;
	private TileBuffer[] tileBuffer;
	private boolean sendClientUpdate = false;
	private boolean blockNeighborChange = false;
	private boolean refreshRenderState = false;
	private boolean pipeBound = false;

	public class CoreState implements IClientState {

		public int pipeId = -1;

		@Override
		public void writeData(LPDataOutput output) throws IOException {
			output.writeInt(pipeId);

		}

		@Override
		public void readData(LPDataInput input) throws IOException {
			pipeId = input.readInt();

		}
	}

	@SideOnly(Side.CLIENT)
	private AxisAlignedBB renderBox;

import java.io.IOException;
	@AllArgsConstructor
	public enum CurveOrientation implements ITubeOrientation {
		//@formatter:off
		// Name: Placement from  _ TurnDirection
		NORTH_NORTH_EAST(TurnDirection.NORTH_EAST, new DoubleCoordinates(2, 0, 2), ForgeDirection.NORTH, ForgeDirection.EAST),
		NORTH_WEST_NORTH(TurnDirection.WEST_NORTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH, ForgeDirection.WEST),
		WEST_WEST_NORTH(TurnDirection.WEST_NORTH, new DoubleCoordinates(2, 0, -2), ForgeDirection.WEST, ForgeDirection.NORTH),
		WEST_SOUTH_WEST(TurnDirection.SOUTH_WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.WEST, ForgeDirection.SOUTH),
		SOUTH_SOUTH_WEST(TurnDirection.SOUTH_WEST, new DoubleCoordinates(-2, 0, -2), ForgeDirection.SOUTH, ForgeDirection.WEST),
		SOUTH_EAST_SOUTH(TurnDirection.EAST_SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.SOUTH, ForgeDirection.EAST),
		EAST_EAST_SOUTH(TurnDirection.EAST_SOUTH, new DoubleCoordinates(-2, 0, 2), ForgeDirection.EAST, ForgeDirection.SOUTH),
		EAST_NORTH_EAST(TurnDirection.NORTH_EAST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST, ForgeDirection.NORTH);
		//@formatter:on
		@Getter
		TurnDirection renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection from;
		@Getter
		ForgeDirection looking;

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotatePositions(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeCurve) pipe).orientation = this;
		}
	}

	@AllArgsConstructor
	public enum TurnDirection implements ITubeRenderOrientation {
		//@formatter:off
		NORTH_EAST(ForgeDirection.NORTH, ForgeDirection.EAST),
		EAST_SOUTH(ForgeDirection.EAST, ForgeDirection.SOUTH),
		SOUTH_WEST(ForgeDirection.SOUTH, ForgeDirection.WEST),
		WEST_NORTH(ForgeDirection.WEST, ForgeDirection.NORTH);
		//@formatter:on
		@Getter
		ForgeDirection dir1;
		ForgeDirection dir2;

		public void rotatePositions(IPositionRotateble set) {
			if (this == WEST_NORTH) {
				return;
			} else if (this == NORTH_EAST) {
				set.rotateRight();
			} else if (this == EAST_SOUTH) {
				set.rotateLeft();
				set.rotateLeft();
			} else if (this == SOUTH_WEST) {
				set.rotateLeft();
			}
		}
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public enum TubeGainOrientation implements ITubeOrientation {
		NORTH(TubeGainRenderOrientation.NORTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH),
		SOUTH(TubeGainRenderOrientation.SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.SOUTH),
		EAST(TubeGainRenderOrientation.EAST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST),
		WEST(TubeGainRenderOrientation.WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.WEST);

		@Getter
		TubeGainRenderOrientation renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection dir;

		TubeGainOrientation(TubeGainRenderOrientation render, DoubleCoordinates off, ForgeDirection dir) {
			renderOrientation = render;
			offset = off;
			this.dir = dir;
		}

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotateOrientation(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeGain) pipe).orientation = this;
		}
	}

	public enum TubeGainRenderOrientation implements ITubeRenderOrientation {
		NORTH(ForgeDirection.NORTH),
		SOUTH(ForgeDirection.SOUTH),
		WEST(ForgeDirection.WEST),
		EAST(ForgeDirection.EAST);

		@Getter
		private ForgeDirection dir;

		TubeGainRenderOrientation(ForgeDirection dir) {
			this.dir = dir;
		}

		public void rotateOrientation(IPositionRotateble set) {
			if (this == EAST) {
				set.rotateRight();
			} else if (this == WEST) {
				set.rotateLeft();
			} else if (this == SOUTH) {
				set.rotateLeft();
				set.rotateLeft();
			}
		}
	}


	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public enum TubeLineOrientation implements ITubeOrientation {
		NORTH(TubeLineRenderOrientation.NORTH_SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH),
		SOUTH(TubeLineRenderOrientation.NORTH_SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.SOUTH),
		EAST(TubeLineRenderOrientation.EAST_WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST),
		WEST(TubeLineRenderOrientation.EAST_WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.WEST);

		@Getter
		TubeLineRenderOrientation renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection dir;

		TubeLineOrientation(TubeLineRenderOrientation render, DoubleCoordinates off, ForgeDirection dir) {
			renderOrientation = render;
			offset = off;
			this.dir = dir;
		}

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotateOrientation(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeLine) pipe).orientation = this;
		}
	}

	public enum TubeLineRenderOrientation implements ITubeRenderOrientation {
		NORTH_SOUTH(ForgeDirection.NORTH),
		EAST_WEST(ForgeDirection.EAST);

		@Getter
		private ForgeDirection dir;

		TubeLineRenderOrientation(ForgeDirection dir) {
			this.dir = dir;
		}

		public void rotateOrientation(IPositionRotateble set) {
			if (this == EAST_WEST) {
				set.rotateLeft();
			}
		}
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	@AllArgsConstructor
	public enum CurveSOrientation implements ITubeOrientation {
		//@formatter:off
		// Name: Placement from  _ TurnDirection
		NORTH_EAST(TurnSDirection.NORTH_INV, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH, ForgeDirection.EAST),
		NORTH_WEST(TurnSDirection.NORTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH, ForgeDirection.WEST),
		EAST_SOUTH(TurnSDirection.EAST_INV, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST, ForgeDirection.SOUTH),
		EAST_NORTH(TurnSDirection.EAST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST, ForgeDirection.NORTH),
		SOUTH_WEST(TurnSDirection.NORTH_INV, new DoubleCoordinates(-1, 0, 3), ForgeDirection.SOUTH, ForgeDirection.WEST),
		SOUTH_EAST(TurnSDirection.NORTH, new DoubleCoordinates(1, 0, 3), ForgeDirection.SOUTH, ForgeDirection.EAST),
		WEST_NORTH(TurnSDirection.EAST_INV, new DoubleCoordinates(-3, 0, -1), ForgeDirection.WEST, ForgeDirection.NORTH),
		WEST_SOUTH(TurnSDirection.EAST, new DoubleCoordinates(-3, 0, 1), ForgeDirection.WEST, ForgeDirection.SOUTH);
		//@formatter:on

		@Getter
		TurnSDirection renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection dir;
		@Getter
		ForgeDirection looking;

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotatePositions(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeSCurve) pipe).orientation = this;
		}
	}

	@AllArgsConstructor
	public enum TurnSDirection implements ITubeRenderOrientation {
		//@formatter:off
		NORTH(ForgeDirection.NORTH),
		EAST(ForgeDirection.EAST),
		NORTH_INV(ForgeDirection.SOUTH),
		EAST_INV(ForgeDirection.WEST);
		//@formatter:on

		@Getter
		private ForgeDirection dir1;

		public void rotatePositions(IPositionRotateble set) {
			if (this == NORTH) {
				set.mirrorX();
			} else if (this == EAST) {
				set.mirrorX();
				set.rotateRight();
			} else if (this == EAST_INV) {
				set.rotateRight();
			}
		}
	}


	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	@AllArgsConstructor
	public enum SpeedupDirection implements ITubeRenderOrientation, ITubeOrientation {
		//@formatter:off
		NORTH(ForgeDirection.NORTH),
		SOUTH(ForgeDirection.SOUTH),
		EAST(ForgeDirection.EAST),
		WEST(ForgeDirection.WEST);
		//@formatter:on
		@Getter
		ForgeDirection dir1;

		@Override
		public void rotatePositions(IPositionRotateble set) {
			if (this == SOUTH) {
				set.rotateLeft();
				set.rotateLeft();
			} else if (this == EAST) {
				set.rotateRight();
			} else if (this == WEST) {
				set.rotateLeft();
			}
		}

		@Override
		public ITubeRenderOrientation getRenderOrientation() {
			return this;
		}

		@Override
		public DoubleCoordinates getOffset() {
			return new DoubleCoordinates(0, 0, 0);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeSpeedup) pipe).orientation = this;
		}
	}

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {}
	public void readData(LPDataInput input) throws IOException {}
import java.io.IOException;
							@Override public void writeData_LP(LPDataOutput output) throws IOException {
							@Override public void writeData(LPDataOutput output) throws IOException {}
							@Override public void readData(LPDataInput input) throws IOException {}
import java.io.IOException;

	void writeData(LPDataOutput output) throws IOException;
	void readData(LPDataInput input) throws IOException;
import java.io.IOException;

	void writeData_LP(LPDataOutput output) throws IOException;
	void readData_LP(LPDataInput input) throws IOException;
import java.io.IOException;

	public void writeData_LP(LPDataOutput output) throws IOException {
	public void readData_LP(LPDataInput input) throws IOException {
import java.io.IOException;
import lombok.SneakyThrows;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
	@SneakyThrows({ IOException.class })
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;

	public void writeData(LPDataOutput output) throws IOException {
	public void readData(LPDataInput input) throws IOException {
import java.io.IOException;
	public ItemIdentifierStack stack;

	public DictResource(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
	private Object ccObject;

	public void setCCType(Object type) {
		ccObject = type;
	public Object getCCType() {
		return ccObject;
import java.io.IOException;

	private int amount;
	public FluidResource(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
	private Object ccObject;

	public void setCCType(Object type) {
		ccObject = type;
	public Object getCCType() {
		return ccObject;
import java.io.IOException;

	/**
	 * Settings only apply for the normal Item Implementation.
	 */
	enum MatchSettings {
		NORMAL,
		WITHOUT_NBT
	}

	void writeData(LPDataOutput output) throws IOException;
import java.io.IOException;

	public ItemResource(LPDataInput input) throws IOException {
	public void writeData(LPDataOutput output) throws IOException {
	private Object ccObject;

	public void setCCType(Object type) {
		ccObject = type;
	public Object getCCType() {
		return ccObject;
import java.io.IOException;

		protected IResource readData(LPDataInput input) throws IOException {
		protected IResource readData(LPDataInput input) throws IOException {
		protected IResource readData(LPDataInput input) throws IOException {
	public static void writeResource(LPDataOutput output, IResource resource) throws IOException {
	public static IResource readResource(LPDataInput input) throws IOException {
	protected abstract IResource readData(LPDataInput input) throws IOException;
import java.io.IOException;
	public void writeData(LPDataOutput output) throws IOException {
	public LaserData readData(LPDataInput input) throws IOException {
				try {
					synchronized (clientList) {
						if (!pause && clientList.size() > 0) {
							clientBuffer = LPDataIOWrapper.collectData(output -> {
								output.writeBytes(clientBuffer);
								clearLock.lock();
								try {
									for (ModernPacket packet : clientList) {
										output.writeShort(packet.getId());
										output.writeInt(packet.getDebugId());
										packet.writeData(output);
									}
								} finally {
									clientList.clear();
									clearLock.unlock();
							});
						}
					//Send Content
					if (clientBuffer.length > 0) {
						while (clientBuffer.length > 1024 * 32) {
							byte[] sendbuffer = Arrays.copyOf(clientBuffer, 1024 * 32);
							clientBuffer = Arrays.copyOfRange(clientBuffer, 1024 * 32, clientBuffer.length);
							byte[] compressed = ClientPacketBufferHandlerThread.compress(sendbuffer);
							MainProxy.sendPacketToServer(PacketHandler.getPacket(BufferTransfer.class).setContent(compressed));
						}
						byte[] sendbuffer = clientBuffer;
						clientBuffer = new byte[] {};
				} catch (IOException e) {
					e.printStackTrace();
						} catch (InterruptedException e) {}
	private final ClientCompressorThread clientCompressorThread = new ClientCompressorThread();

		//decompressed serialized S->C data
		private byte[] ByteBuffer = new byte[] {};
			try {
				LPDataIOWrapper.provideData(playerDataPair.getValue2(), input -> {
					PacketHandler.onPacketData(input, playerDataPair.getValue1());
				});
			} catch (IOException e) {
				System.err.println("IO Error in handlePacketData for player " + playerDataPair.getValue1().getCommandSenderName());
				e.printStackTrace();
			}
						} catch (InterruptedException e) { }

	private final ClientDecompressorThread clientDecompressorThread = new ClientDecompressorThread();

	public ClientPacketBufferHandlerThread() {}

	public void clientTick(ClientTickEvent event) {
		if (event.phase != Phase.END) {
			return;
		}
		clientDecompressorThread.clientTickEnd();
	}

	public void setPause(boolean flag) {
		clientCompressorThread.setPause(flag);
	}

	public void addPacketToCompressor(ModernPacket packet) {
		clientCompressorThread.addPacketToCompressor(packet);
	}

	public void handlePacket(byte[] content) {
		clientDecompressorThread.handlePacket(content);
	}

	private static byte[] compress(byte[] content) {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try {
			GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
			gzipOutputStream.write(content);
			gzipOutputStream.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return byteArrayOutputStream.toByteArray();
	}

	private static byte[] decompress(byte[] contentBytes) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(contentBytes));
			int buffer = 0;
			while ((buffer = gzip.read()) != -1) {
				out.write(buffer);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return out.toByteArray();
	}

	public void clear() {
		clientCompressorThread.clear();
		clientDecompressorThread.clear();
	}

	public void queueFailedPacket(ModernPacket packet, EntityPlayer player) {
		clientDecompressorThread.queueFailedPacket(packet, player);
	}
				try {
					synchronized (serverList) {
						if (!pause) {
							for (Entry<EntityPlayer, LinkedList<ModernPacket>> playerPacketEntry : serverList.entrySet()) {
								EntityPlayer player = playerPacketEntry.getKey();
								serverBuffer.put(player, LPDataIOWrapper.collectData(output -> {
									if (serverBuffer.containsKey(player)) {
										output.writeBytes(serverBuffer.get(player));
									}
									LinkedList<ModernPacket> packets = playerPacketEntry.getValue();
									try {
										for (ModernPacket packet : packets) {
											output.writeShort(packet.getId());
											output.writeInt(packet.getDebugId());
											packet.writeData(output);
										}
									} finally {
										packets.clear();
								}));
							}
							serverList.clear();
					//Send Content
					for (Entry<EntityPlayer, byte[]> player : serverBuffer.entrySet()) {
						while (player.getValue().length > 32 * 1024) {
							byte[] sendbuffer = Arrays.copyOf(player.getValue(), 1024 * 32);
							byte[] newbuffer = Arrays.copyOfRange(player.getValue(), 1024 * 32, player.getValue().length);
							player.setValue(newbuffer);
							byte[] compressed = ServerPacketBufferHandlerThread.compress(sendbuffer);
							MainProxy.sendPacketToPlayer(PacketHandler.getPacket(BufferTransfer.class).setContent(compressed), player.getKey());
						}
						byte[] sendbuffer = player.getValue();
				} catch (IOException e) {
					e.printStackTrace();
						} catch (InterruptedException e) {}
	private final ServerCompressorThread serverCompressorThread = new ServerCompressorThread();

			try {
				LPDataIOWrapper.provideData(playerDataPair.getValue2(), input -> {
					PacketHandler.onPacketData(input, playerDataPair.getValue1());
				});
			} catch (IOException e) {
				System.err.println("IO Error in handlePacketData for player " + playerDataPair.getValue1().getCommandSenderName());
				e.printStackTrace();
			}
						} catch (InterruptedException e) {}

	private final ServerDecompressorThread serverDecompressorThread = new ServerDecompressorThread();

	public ServerPacketBufferHandlerThread() {}

	public void serverTick(ServerTickEvent event) {
		if (event.phase != Phase.END) {
			return;
		}
		serverDecompressorThread.serverTickEnd();
	}

	public void setPause(boolean flag) {
		serverCompressorThread.setPause(flag);
	}

	public void addPacketToCompressor(ModernPacket packet, EntityPlayer player) {
		serverCompressorThread.addPacketToCompressor(packet, player);
	}

	public void handlePacket(byte[] content, EntityPlayer player) {
		serverDecompressorThread.handlePacket(content, player);
	}

	private static byte[] compress(byte[] content) {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try {
			GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
			gzipOutputStream.write(content);
			gzipOutputStream.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return byteArrayOutputStream.toByteArray();
	}

	private static byte[] decompress(byte[] contentBytes) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(contentBytes));
			int buffer = 0;
			while ((buffer = gzip.read()) != -1) {
				out.write(buffer);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return out.toByteArray();
	}

	public void clear(final EntityPlayer player) {
		new Thread() {

			@Override
			public void run() {
				serverCompressorThread.clear(player);
				serverDecompressorThread.clear(player);
			}
		}.start();
	}
	private void unsetBuffer() {
		if (localBuffer.hasMemoryAddress()) {
			if (--reference < 1) {
				BUFFER_WRAPPER_MAP.remove(localBuffer.memoryAddress());
			}
		}
		localBuffer = null;
	}

	public static void provideData(byte[] data, LPDataInputConsumer dataInputConsumer) throws IOException {
	public static byte[] collectData(LPDataOutputConsumer dataOutputConsumer) throws IOException {
	public static void provideData(ByteBuf dataBuffer, LPDataInputConsumer dataInputConsumer) throws IOException {
	public static void writeData(ByteBuf dataBuffer, LPDataOutputConsumer dataOutputConsumer) throws IOException {
	public void writeByteArray(byte[] arr) throws IOException {
	public byte[] readByteArray() throws IOException {
	public void writeUTF(String s) throws IOException {
	public void writeExitRoute(ExitRoute route) throws IOException {
	public <T extends Enum<T>> void writeEnumSet(EnumSet<T> types, Class<T> clazz) throws IOException {
	public void writeBitSet(BitSet bits) throws IOException {
	public void writeNBTTagCompound(NBTTagCompound tag) throws IOException {
			CompressedStreamTools.write(tag, new ByteBufOutputStream(localBuffer));
	public void writeBooleanArray(boolean[] arr) throws IOException {
	public void writeItemStack(ItemStack itemstack) throws IOException {
	public void writeItemIdentifier(ItemIdentifier item) throws IOException {
	public void writeItemIdentifierStack(ItemIdentifierStack stack) throws IOException {
	public <T> void writeCollection(Collection<T> collection, IWriteListObject<T> handler) throws IOException {
	public void writeOrderInfo(IOrderInfoProvider order) throws IOException {
	public void writeLinkedLogisticsOrderList(LinkedLogisticsOrderList orderList) throws IOException {
	public void writeResource(IResource res) throws IOException {
	public void writeBytes(byte[] arr) throws IOException {
	public String readUTF() throws IOException {
	public ExitRoute readExitRoute(World world) throws IOException {
	public <T extends Enum<T>> EnumSet<T> readEnumSet(Class<T> clazz) throws IOException {
	public BitSet readBitSet() throws IOException {
	public NBTTagCompound readNBTTagCompound() throws IOException {
		return CompressedStreamTools.func_152456_a(new ByteBufInputStream(localBuffer), NBTSizeTracker.field_152451_a);
	public boolean[] readBooleanArray() throws IOException {
	public byte[] readBytes(int length) throws IOException {
	public ItemStack readItemStack() throws IOException {
	public ItemIdentifier readItemIdentifier() throws IOException {
	public ItemIdentifierStack readItemIdentifierStack() throws IOException {
	public <T> ArrayList<T> readArrayList(IReadListObject<T> reader) throws IOException {
	public <T> LinkedList<T> readLinkedList(IReadListObject<T> reader) throws IOException {
	public <T> Set<T> readSet(IReadListObject<T> handler) throws IOException {
	public IOrderInfoProvider readOrderInfo() throws IOException {
	public LinkedLogisticsOrderList readLinkedLogisticsOrderList() throws IOException {
			throw new IOException("Expected order info provider list");
			throw new IOException("Expected logistics order list");
	public ByteBuf readByteBuf() throws IOException {
	public IResource readResource() throws IOException {
import java.io.IOException;
	byte[] readByteArray() throws IOException;
	byte readByte() throws IOException;
	short readShort() throws IOException;
	int readInt() throws IOException;
	long readLong() throws IOException;
	float readFloat() throws IOException;
	double readDouble() throws IOException;
	boolean readBoolean() throws IOException;
	String readUTF() throws IOException;
	ForgeDirection readForgeDirection() throws IOException;
	ExitRoute readExitRoute(World world) throws IOException;
	IRouter readIRouter(World world) throws IOException;
	DoubleCoordinates readLPPosition() throws IOException;
	<T extends Enum<T>> EnumSet<T> readEnumSet(Class<T> clazz) throws IOException;
	BitSet readBitSet() throws IOException;
	NBTTagCompound readNBTTagCompound() throws IOException;
	boolean[] readBooleanArray() throws IOException;
	int[] readIntArray() throws IOException;
	byte[] readBytes(int length) throws IOException;
	ItemIdentifier readItemIdentifier() throws IOException;
	ItemIdentifierStack readItemIdentifierStack() throws IOException;
	ItemStack readItemStack() throws IOException;
	<T> ArrayList<T> readArrayList(IReadListObject<T> reader) throws IOException;
	<T> LinkedList<T> readLinkedList(IReadListObject<T> reader) throws IOException;
	<T> Set<T> readSet(IReadListObject<T> handler) throws IOException;
	IOrderInfoProvider readOrderInfo() throws IOException;
	<T extends Enum<T>> T readEnum(Class<T> clazz) throws IOException;
	LinkedLogisticsOrderList readLinkedLogisticsOrderList() throws IOException;
	ByteBuf readByteBuf() throws IOException;
	long[] readLongArray() throws IOException;
	IResource readResource() throws IOException;
		void accept(LPDataInput dataInput) throws IOException;
import java.io.IOException;
	void writeByte(int b) throws IOException;
	void writeByte(byte b) throws IOException;
	void writeShort(int s) throws IOException;
	void writeShort(short s) throws IOException;
	void writeInt(int i) throws IOException;
	void writeLong(long l) throws IOException;
	void writeFloat(float f) throws IOException;
	void writeDouble(double d) throws IOException;
	void writeBoolean(boolean b) throws IOException;
	void writeUTF(String s) throws IOException;
	void writeByteArray(byte[] arr) throws IOException;
	void writeByteBuf(ByteBuf buffer) throws IOException;
	void writeIntArray(int[] arr) throws IOException;
	void writeLongArray(long[] arr) throws IOException;
	void writeBooleanArray(boolean[] arr) throws IOException;
	void writeForgeDirection(ForgeDirection direction) throws IOException;
	void writeExitRoute(ExitRoute route) throws IOException;
	void writeIRouter(IRouter router) throws IOException;
	void writeLPPosition(DoubleCoordinates pos) throws IOException;
	<T extends Enum<T>> void writeEnumSet(EnumSet<T> types, Class<T> clazz) throws IOException;
	void writeBitSet(BitSet bits) throws IOException;
	void writeNBTTagCompound(NBTTagCompound tag) throws IOException;
	void writeItemStack(ItemStack itemstack) throws IOException;
	void writeItemIdentifier(ItemIdentifier item) throws IOException;
	void writeItemIdentifierStack(ItemIdentifierStack stack) throws IOException;
	<T> void writeCollection(Collection<T> collection, IWriteListObject<T> handler) throws IOException;
	void writeOrderInfo(IOrderInfoProvider order) throws IOException;
	<T extends Enum<T>> void writeEnum(T obj) throws IOException;
	void writeLinkedLogisticsOrderList(LinkedLogisticsOrderList orderList) throws IOException;
	void writeResource(IResource res) throws IOException;
	void writeBytes(byte[] arr) throws IOException;
		void accept(LPDataOutput dataOutput) throws IOException;
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(arrayList, LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(null, LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(linkedList, LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(null, LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(set, LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(null, LPDataOutput::writeUTF));

Fixed code:
	public void writeToLPData(LPDataOutput output) {
	public void readFromLPData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	public void setUseNewRenderer(boolean flag) {
		useNewRenderer = flag;
	}
	void writeData(LPDataOutput output);
	void readData(LPDataInput input);
	T readObject(LPDataInput input);
	void writeObject(LPDataOutput output, T object);
	private NewGuiHandler() { }

	public static final Map<Integer, StackTraceElement[]> debugMap = new HashMap<>();
	//TODO correct to work with WeakReference (See FML original)
	protected static final AttributeKey<ThreadLocal<FMLProxyPacket>> INBOUNDPACKETTRACKER = new AttributeKey<>("lp:inboundpacket");
	//hacky callback to process packets coming from by the packetbufferhandler decompressors
	//TODO replace with proper netty implementation
	public static void onPacketData(final LPDataInput data, final EntityPlayer player) {
		if (player == null) {
			return;
		}
		final int packetID = data.readShort();
		final ModernPacket packet = PacketHandler.packetlist.get(packetID).template();
		packet.setDebugId(data.readInt());
		packet.readData(data);
		PacketHandler.onPacketData(packet, player);
	}

	private static void onPacketData(ModernPacket packet, final EntityPlayer player) {
		try {
			packet.processPacket(player);
			if (LPConstants.DEBUG) {
				PacketHandler.debugMap.remove(packet.getDebugId());
			}
		} catch (DelayPacketException e) {
			if (packet.retry() && MainProxy.isClient(player.getEntityWorld())) {
				SimpleServiceLocator.clientBufferHandler.queueFailedPacket(packet, player);
			} else if (LPConstants.DEBUG) {
				LogisticsPipes.log.error(packet.getClass().getName());
				LogisticsPipes.log.error(packet.toString());
				e.printStackTrace();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		super.handlerAdded(ctx);
		ctx.attr(PacketHandler.INBOUNDPACKETTRACKER).set(new ThreadLocal<>());
	}

	//horrible hack to carry the proper player for the side along...
	static class InboundModernPacketWrapper {
		final ModernPacket packet;
		final EntityPlayer player;

		InboundModernPacketWrapper(ModernPacket p, EntityPlayer e) {
			packet = p;
			player = e;
	public BooleanModuleCoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public CoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public CoordinatesPopupGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {}
	public ModuleCoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public ModuleInHandGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public UpgradeCoordinatesGuiProvider(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public CoordinatesPacket(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	public enum LTGPCompletionCheck {
		NONE,
		PIPE,
		TRANSPORT
	}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	protected int leftRetries = 5;
	@Getter
	@Setter
	private boolean isChunkDataPacket;
	@Getter
	@Setter
	private boolean compressable;
	public abstract void readData(LPDataInput input);
	public abstract void writeData(LPDataOutput output);
	private boolean moduleBased = false;
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public CraftingCycleRecipe(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public CraftingSetType(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public PowerPacketLaser(int id) {
		super(id);
	}

	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
			public StatusEntry readObject(LPDataInput input) {
	public void writeData(LPDataOutput output) {
			public void writeObject(LPDataOutput output, StatusEntry entry) {
	public void readData(LPDataInput input) {}
					.setAdditions(new int[] { box.blockX, box.blockY, box.blockZ }));
					.setAdditions(new int[] { box.entityHit.getEntityId() }));
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	private int[] additions = new int[0];

	public DebugTargetResponse(int id) {
		super(id);
	}
	public void readData(LPDataInput input) {
		additions = input.readIntArray();
			int x = additions[0];
			int y = additions[1];
			int z = additions[2];
			int entityId = additions[0];
	public void writeData(LPDataOutput output) {
		output.writeIntArray(additions);

	public enum TargetMode {
		Block,
		Entity,
		None
	}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public GuiReopenPacket(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public MultiBlockCoordinatesPacket(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
			Triplet<ItemIdentifierStack, Pair<Integer /* Time */, Integer /* BufferCounter */>, LPTravelingItemServer> object) {
	public Triplet<ItemIdentifierStack, Pair<Integer /* Time */, Integer /* BufferCounter */>, LPTravelingItemServer> readObject(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public ParticleFX(int id) {
		super(id);
	}

	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public PipeContentPacket(int id) {
		super(id);
	}

	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public PipeFluidUpdate(int id) {
		super(id);
	}

	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public PipeSignTypes(int id) {
		super(id);
	}

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
		LPDataIOWrapper.provideData(bytesRenderState, pipe.renderState::readData);
		LPDataIOWrapper.provideData(bytesCoreState, pipe.coreState::readData);
		LPDataIOWrapper.provideData(bytesBCPluggableState, pipe.bcPlugableState::readData);
		pipe.afterStateUpdated();
		LPDataIOWrapper.provideData(bytesPipe, pipe.pipe::readData);
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void readData(LPDataInput input) {}
					.setAdditions(new int[] { box.blockX, box.blockY, box.blockZ }));
					.setAdditions(new int[] { box.entityHit.getEntityId() }));
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	private int[] additions = new int[0];

	public RoutingUpdateTargetResponse(int id) {
		super(id);
	}
	public void readData(LPDataInput input) {
		additions = input.readIntArray();
			int x = additions[0];
			int y = additions[1];
			int z = additions[2];
	public void writeData(LPDataOutput output) {
		output.writeIntArray(additions);

	public enum TargetMode {
		Block,
		Entity,
		None
	}
	@Getter
	@Setter
	private int satID;

	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public final PlayerCollectionList watchers = new PlayerCollectionList();
	protected final PriorityBlockingQueue<ItemRoutingInformation> _inTransitToMe = new PriorityBlockingQueue<>(10,
			new ItemRoutingInformation.DelayComparator());
	protected final LinkedList<Triplet<IRoutedItem, ForgeDirection, ItemSendMode>> _sendQueue = new LinkedList<>();
	protected final Map<ItemIdentifier, Queue<Pair<Integer, ItemRoutingInformation>>> queuedDataForUnroutedItems = Collections.synchronizedMap(new TreeMap<>());
	public boolean globalIgnoreConnectionDisconnection = false;
	protected boolean stillNeedReplace = true;
	protected IRouter router;
	protected String routerId;
	protected Object routerIdLock = new Object();
	protected int _delayOffset = 0;
	protected boolean _initialInit = true;
	protected RouteLayer _routeLayer;
	protected TransportLayer _transportLayer;
	protected UpgradeManager upgradeManager = new UpgradeManager(this);
	protected LogisticsItemOrderManager _orderItemManager = null;
	protected IPipeSign[] signItem = new IPipeSign[6];
	private boolean recheckConnections = false;
	private boolean enabled = true;
	private boolean preventRemove = false;
	private boolean destroyByPlayer = false;
	private PowerSupplierHandler powerHandler = new PowerSupplierHandler(this);
	@Getter
	private List<IOrderInfoProvider> clientSideOrderManager = new ArrayList<>();
	/* Power System */

	@CCCommand(description = "Returns the TurtleConnect flag for this Turtle on this LogisticsPipe")
	public boolean getTurtleConnect() {
			return container.getTurtleConnect();
		return false;
	@CCCommand(description = "Sets the TurtleConnect flag for this Turtle on this LogisticsPipe")
	public void setTurtleConnect(Boolean flag) {
			container.setTurtleConnect(flag);
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	public enum ItemSendMode {
		Normal,
		Fast
	}
	public final PipeRenderState renderState;
	public final CoreState coreState = new CoreState();
	public final IBCTilePart tilePart;
	public final IBCPluggableState bcPlugableState;
	public final ITDPart tdPart;
	public LogicController logicController = new LogicController();
	public boolean[] pipeConnectionsBuffer = new boolean[6];
	public boolean[] pipeBCConnectionsBuffer = new boolean[6];
	public boolean[] pipeTDConnectionsBuffer = new boolean[6];
	public CoreUnroutedPipe pipe;
	private LogisticsTileRenderController renderController;
	@Getter
	private boolean initialized = false;
	private boolean deletePipe = false;
	private TileBuffer[] tileBuffer;
	private boolean sendClientUpdate = false;
	private boolean blockNeighborChange = false;
	private boolean refreshRenderState = false;
	private boolean pipeBound = false;
	@SideOnly(Side.CLIENT)
	private AxisAlignedBB renderBox;
	/* IPipeInformationProvider */

	public void setTurtleConnect(boolean flag) {
		SimpleServiceLocator.ccProxy.setTurtleConnect(flag, this);
	}

	//public int redstoneInput = 0;
	//public int[] redstoneInputSide = new int[ForgeDirection.VALID_DIRECTIONS.length];

	public class CoreState implements IClientState {

		public int pipeId = -1;

		@Override
		public void writeData(LPDataOutput output) {
			output.writeInt(pipeId);

		}

		@Override
		public void readData(LPDataInput input) {
			pipeId = input.readInt();

		}
	}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	@AllArgsConstructor
	public enum CurveOrientation implements ITubeOrientation {
		//@formatter:off
		// Name: Placement from  _ TurnDirection
		NORTH_NORTH_EAST(TurnDirection.NORTH_EAST, new DoubleCoordinates(2, 0, 2), ForgeDirection.NORTH, ForgeDirection.EAST),
		NORTH_WEST_NORTH(TurnDirection.WEST_NORTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH, ForgeDirection.WEST),
		WEST_WEST_NORTH(TurnDirection.WEST_NORTH, new DoubleCoordinates(2, 0, -2), ForgeDirection.WEST, ForgeDirection.NORTH),
		WEST_SOUTH_WEST(TurnDirection.SOUTH_WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.WEST, ForgeDirection.SOUTH),
		SOUTH_SOUTH_WEST(TurnDirection.SOUTH_WEST, new DoubleCoordinates(-2, 0, -2), ForgeDirection.SOUTH, ForgeDirection.WEST),
		SOUTH_EAST_SOUTH(TurnDirection.EAST_SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.SOUTH, ForgeDirection.EAST),
		EAST_EAST_SOUTH(TurnDirection.EAST_SOUTH, new DoubleCoordinates(-2, 0, 2), ForgeDirection.EAST, ForgeDirection.SOUTH),
		EAST_NORTH_EAST(TurnDirection.NORTH_EAST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST, ForgeDirection.NORTH);
		//@formatter:on
		@Getter
		TurnDirection renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection from;
		@Getter
		ForgeDirection looking;

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotatePositions(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeCurve) pipe).orientation = this;
		}
	}

	@AllArgsConstructor
	public enum TurnDirection implements ITubeRenderOrientation {
		//@formatter:off
		NORTH_EAST(ForgeDirection.NORTH, ForgeDirection.EAST),
		EAST_SOUTH(ForgeDirection.EAST, ForgeDirection.SOUTH),
		SOUTH_WEST(ForgeDirection.SOUTH, ForgeDirection.WEST),
		WEST_NORTH(ForgeDirection.WEST, ForgeDirection.NORTH);
		//@formatter:on
		@Getter
		ForgeDirection dir1;
		ForgeDirection dir2;

		public void rotatePositions(IPositionRotateble set) {
			if (this == WEST_NORTH) {
				return;
			} else if (this == NORTH_EAST) {
				set.rotateRight();
			} else if (this == EAST_SOUTH) {
				set.rotateLeft();
				set.rotateLeft();
			} else if (this == SOUTH_WEST) {
				set.rotateLeft();
			}
		}
	}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	public enum TubeGainOrientation implements ITubeOrientation {
		NORTH(TubeGainRenderOrientation.NORTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH),
		SOUTH(TubeGainRenderOrientation.SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.SOUTH),
		EAST(TubeGainRenderOrientation.EAST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST),
		WEST(TubeGainRenderOrientation.WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.WEST);

		@Getter
		TubeGainRenderOrientation renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection dir;

		TubeGainOrientation(TubeGainRenderOrientation render, DoubleCoordinates off, ForgeDirection dir) {
			renderOrientation = render;
			offset = off;
			this.dir = dir;
		}

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotateOrientation(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeGain) pipe).orientation = this;
		}
	}

	public enum TubeGainRenderOrientation implements ITubeRenderOrientation {
		NORTH(ForgeDirection.NORTH),
		SOUTH(ForgeDirection.SOUTH),
		WEST(ForgeDirection.WEST),
		EAST(ForgeDirection.EAST);

		@Getter
		private ForgeDirection dir;

		TubeGainRenderOrientation(ForgeDirection dir) {
			this.dir = dir;
		}

		public void rotateOrientation(IPositionRotateble set) {
			if (this == EAST) {
				set.rotateRight();
			} else if (this == WEST) {
				set.rotateLeft();
			} else if (this == SOUTH) {
				set.rotateLeft();
				set.rotateLeft();
			}
		}
	}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	public enum TubeLineOrientation implements ITubeOrientation {
		NORTH(TubeLineRenderOrientation.NORTH_SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH),
		SOUTH(TubeLineRenderOrientation.NORTH_SOUTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.SOUTH),
		EAST(TubeLineRenderOrientation.EAST_WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST),
		WEST(TubeLineRenderOrientation.EAST_WEST, new DoubleCoordinates(0, 0, 0), ForgeDirection.WEST);

		@Getter
		TubeLineRenderOrientation renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection dir;

		TubeLineOrientation(TubeLineRenderOrientation render, DoubleCoordinates off, ForgeDirection dir) {
			renderOrientation = render;
			offset = off;
			this.dir = dir;
		}

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotateOrientation(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeLine) pipe).orientation = this;
		}
	}

	public enum TubeLineRenderOrientation implements ITubeRenderOrientation {
		NORTH_SOUTH(ForgeDirection.NORTH),
		EAST_WEST(ForgeDirection.EAST);

		@Getter
		private ForgeDirection dir;

		TubeLineRenderOrientation(ForgeDirection dir) {
			this.dir = dir;
		}

		public void rotateOrientation(IPositionRotateble set) {
			if (this == EAST_WEST) {
				set.rotateLeft();
			}
		}
	}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	@AllArgsConstructor
	public enum CurveSOrientation implements ITubeOrientation {
		//@formatter:off
		// Name: Placement from  _ TurnDirection
		NORTH_EAST(TurnSDirection.NORTH_INV, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH, ForgeDirection.EAST),
		NORTH_WEST(TurnSDirection.NORTH, new DoubleCoordinates(0, 0, 0), ForgeDirection.NORTH, ForgeDirection.WEST),
		EAST_SOUTH(TurnSDirection.EAST_INV, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST, ForgeDirection.SOUTH),
		EAST_NORTH(TurnSDirection.EAST, new DoubleCoordinates(0, 0, 0), ForgeDirection.EAST, ForgeDirection.NORTH),
		SOUTH_WEST(TurnSDirection.NORTH_INV, new DoubleCoordinates(-1, 0, 3), ForgeDirection.SOUTH, ForgeDirection.WEST),
		SOUTH_EAST(TurnSDirection.NORTH, new DoubleCoordinates(1, 0, 3), ForgeDirection.SOUTH, ForgeDirection.EAST),
		WEST_NORTH(TurnSDirection.EAST_INV, new DoubleCoordinates(-3, 0, -1), ForgeDirection.WEST, ForgeDirection.NORTH),
		WEST_SOUTH(TurnSDirection.EAST, new DoubleCoordinates(-3, 0, 1), ForgeDirection.WEST, ForgeDirection.SOUTH);
		//@formatter:on

		@Getter
		TurnSDirection renderOrientation;
		@Getter
		DoubleCoordinates offset;
		@Getter
		ForgeDirection dir;
		@Getter
		ForgeDirection looking;

		@Override
		public void rotatePositions(IPositionRotateble set) {
			renderOrientation.rotatePositions(set);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeSCurve) pipe).orientation = this;
		}
	}

	@AllArgsConstructor
	public enum TurnSDirection implements ITubeRenderOrientation {
		//@formatter:off
		NORTH(ForgeDirection.NORTH),
		EAST(ForgeDirection.EAST),
		NORTH_INV(ForgeDirection.SOUTH),
		EAST_INV(ForgeDirection.WEST);
		//@formatter:on

		@Getter
		private ForgeDirection dir1;

		public void rotatePositions(IPositionRotateble set) {
			if (this == NORTH) {
				set.mirrorX();
			} else if (this == EAST) {
				set.mirrorX();
				set.rotateRight();
			} else if (this == EAST_INV) {
				set.rotateRight();
			}
		}
	}
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {

	@AllArgsConstructor
	public enum SpeedupDirection implements ITubeRenderOrientation, ITubeOrientation {
		//@formatter:off
		NORTH(ForgeDirection.NORTH),
		SOUTH(ForgeDirection.SOUTH),
		EAST(ForgeDirection.EAST),
		WEST(ForgeDirection.WEST);
		//@formatter:on
		@Getter
		ForgeDirection dir1;

		@Override
		public void rotatePositions(IPositionRotateble set) {
			if (this == SOUTH) {
				set.rotateLeft();
				set.rotateLeft();
			} else if (this == EAST) {
				set.rotateRight();
			} else if (this == WEST) {
				set.rotateLeft();
			}
		}

		@Override
		public ITubeRenderOrientation getRenderOrientation() {
			return this;
		}

		@Override
		public DoubleCoordinates getOffset() {
			return new DoubleCoordinates(0, 0, 0);
		}

		@Override
		public void setOnPipe(CoreMultiBlockPipe pipe) {
			((HSTubeSpeedup) pipe).orientation = this;
		}
	}
	public void writeData(LPDataOutput output) {}
	public void readData(LPDataInput input) {}
							@Override public void writeData_LP(LPDataOutput output)  {
							@Override public void writeData(LPDataOutput output)  {}
							@Override public void readData(LPDataInput input)  {}
	void writeData(LPDataOutput output);
	void readData(LPDataInput input);
	void writeData_LP(LPDataOutput output);
	void readData_LP(LPDataInput input);
	public void writeData_LP(LPDataOutput output) {
	public void readData_LP(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public void readData(LPDataInput input) {
	public ItemIdentifierStack stack;
	private Object ccObject;
	public DictResource(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public Object getCCType() {
		return ccObject;
	public void setCCType(Object type) {
		ccObject = type;
	private int amount;
	private Object ccObject;
	public FluidResource(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public Object getCCType() {
		return ccObject;
	public void setCCType(Object type) {
		ccObject = type;
	void writeData(LPDataOutput output);
	/**
	 * Settings only apply for the normal Item Implementation.
	 */
	enum MatchSettings {
		NORMAL,
		WITHOUT_NBT
	}

	private Object ccObject;
	public ItemResource(LPDataInput input) {
	public void writeData(LPDataOutput output) {
	public Object getCCType() {
		return ccObject;
	public void setCCType(Object type) {
		ccObject = type;
		protected IResource readData(LPDataInput input) {
		protected IResource readData(LPDataInput input) {
		protected IResource readData(LPDataInput input) {
	public static void writeResource(LPDataOutput output, IResource resource) {
	public static IResource readResource(LPDataInput input) {
	protected abstract IResource readData(LPDataInput input);
	public void writeData(LPDataOutput output) {
	public LaserData readData(LPDataInput input) {
	private final ClientCompressorThread clientCompressorThread = new ClientCompressorThread();
	private final ClientDecompressorThread clientDecompressorThread = new ClientDecompressorThread();

	public ClientPacketBufferHandlerThread() {}

	private static byte[] compress(byte[] content) {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try {
			GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
			gzipOutputStream.write(content);
			gzipOutputStream.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return byteArrayOutputStream.toByteArray();
	}

	private static byte[] decompress(byte[] contentBytes) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(contentBytes));
			int buffer = 0;
			while ((buffer = gzip.read()) != -1) {
				out.write(buffer);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return out.toByteArray();
	}

	public void clientTick(ClientTickEvent event) {
		if (event.phase != Phase.END) {
			return;
		}
		clientDecompressorThread.clientTickEnd();
	}

	public void setPause(boolean flag) {
		clientCompressorThread.setPause(flag);
	}

	public void addPacketToCompressor(ModernPacket packet) {
		clientCompressorThread.addPacketToCompressor(packet);
	}

	public void handlePacket(byte[] content) {
		clientDecompressorThread.handlePacket(content);
	}

	public void clear() {
		clientCompressorThread.clear();
		clientDecompressorThread.clear();
	}

	public void queueFailedPacket(ModernPacket packet, EntityPlayer player) {
		clientDecompressorThread.queueFailedPacket(packet, player);
	}

				synchronized (clientList) {
					if (!pause && clientList.size() > 0) {
						clientBuffer = LPDataIOWrapper.collectData(output -> {
							output.writeBytes(clientBuffer);
							clearLock.lock();
							try {
								for (ModernPacket packet : clientList) {
									output.writeShort(packet.getId());
									output.writeInt(packet.getDebugId());
									packet.writeData(output);
							} finally {
								clientList.clear();
								clearLock.unlock();
							}
						});
				}
				//Send Content
				if (clientBuffer.length > 0) {
					while (clientBuffer.length > 1024 * 32) {
						byte[] sendbuffer = Arrays.copyOf(clientBuffer, 1024 * 32);
						clientBuffer = Arrays.copyOfRange(clientBuffer, 1024 * 32, clientBuffer.length);
					byte[] sendbuffer = clientBuffer;
					clientBuffer = new byte[] {};
					byte[] compressed = ClientPacketBufferHandlerThread.compress(sendbuffer);
					MainProxy.sendPacketToServer(PacketHandler.getPacket(BufferTransfer.class).setContent(compressed));
						} catch (InterruptedException ignored) { }
		//decompressed serialized S->C data
		private byte[] ByteBuffer = new byte[] {};
			LPDataIOWrapper.provideData(playerDataPair.getValue2(), input -> {
				PacketHandler.onPacketData(input, playerDataPair.getValue1());
			});
						} catch (InterruptedException ignored) { }
	private final ServerCompressorThread serverCompressorThread = new ServerCompressorThread();
	private final ServerDecompressorThread serverDecompressorThread = new ServerDecompressorThread();

	public ServerPacketBufferHandlerThread() {}

	private static byte[] compress(byte[] content) {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try {
			GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
			gzipOutputStream.write(content);
			gzipOutputStream.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return byteArrayOutputStream.toByteArray();
	}

	private static byte[] decompress(byte[] contentBytes) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(contentBytes));
			int buffer = 0;
			while ((buffer = gzip.read()) != -1) {
				out.write(buffer);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return out.toByteArray();
	}

	public void serverTick(ServerTickEvent event) {
		if (event.phase != Phase.END) {
			return;
		}
		serverDecompressorThread.serverTickEnd();
	}

	public void setPause(boolean flag) {
		serverCompressorThread.setPause(flag);
	}

	public void addPacketToCompressor(ModernPacket packet, EntityPlayer player) {
		serverCompressorThread.addPacketToCompressor(packet, player);
	}

	public void handlePacket(byte[] content, EntityPlayer player) {
		serverDecompressorThread.handlePacket(content, player);
	}

	public void clear(final EntityPlayer player) {
		new Thread() {

			@Override
			public void run() {
				serverCompressorThread.clear(player);
				serverDecompressorThread.clear(player);
			}
		}.start();
	}

				synchronized (serverList) {
					if (!pause) {
						for (Entry<EntityPlayer, LinkedList<ModernPacket>> playerPacketEntry : serverList.entrySet()) {
							EntityPlayer player = playerPacketEntry.getKey();
							serverBuffer.put(player, LPDataIOWrapper.collectData(output -> {
								if (serverBuffer.containsKey(player)) {
									output.writeBytes(serverBuffer.get(player));
								}
								LinkedList<ModernPacket> packets = playerPacketEntry.getValue();
								try {
									for (ModernPacket packet : packets) {
										output.writeShort(packet.getId());
										output.writeInt(packet.getDebugId());
										packet.writeData(output);
								} finally {
									packets.clear();
								}
							}));
						serverList.clear();
				}
				//Send Content
				for (Entry<EntityPlayer, byte[]> player : serverBuffer.entrySet()) {
					while (player.getValue().length > 32 * 1024) {
						byte[] sendbuffer = Arrays.copyOf(player.getValue(), 1024 * 32);
						byte[] newbuffer = Arrays.copyOfRange(player.getValue(), 1024 * 32, player.getValue().length);
						player.setValue(newbuffer);
					byte[] sendbuffer = player.getValue();
					byte[] compressed = ServerPacketBufferHandlerThread.compress(sendbuffer);
					MainProxy.sendPacketToPlayer(PacketHandler.getPacket(BufferTransfer.class).setContent(compressed), player.getKey());
						} catch (InterruptedException ignored) { }
			LPDataIOWrapper.provideData(playerDataPair.getValue2(), input -> {
				PacketHandler.onPacketData(input, playerDataPair.getValue1());
			});
						} catch (InterruptedException ignored) { }
	public static void provideData(byte[] data, LPDataInputConsumer dataInputConsumer) {
	public static byte[] collectData(LPDataOutputConsumer dataOutputConsumer) {
	public static void provideData(ByteBuf dataBuffer, LPDataInputConsumer dataInputConsumer) {
	public static void writeData(ByteBuf dataBuffer, LPDataOutputConsumer dataOutputConsumer) {
	private void unsetBuffer() {
		if (localBuffer.hasMemoryAddress()) {
			if (--reference < 1) {
				BUFFER_WRAPPER_MAP.remove(localBuffer.memoryAddress());
			}
		}
		localBuffer = null;
	}

	public void writeByteArray(byte[] arr) {
	public byte[] readByteArray() {
	public void writeUTF(String s) {
	public void writeExitRoute(ExitRoute route) {
	public <T extends Enum<T>> void writeEnumSet(EnumSet<T> types, Class<T> clazz) {
	public void writeBitSet(BitSet bits) {
	public void writeNBTTagCompound(NBTTagCompound tag) {
			try {
				CompressedStreamTools.write(tag, new ByteBufOutputStream(localBuffer));
			} catch (IOException e) {

				e.printStackTrace();
			}
	public void writeBooleanArray(boolean[] arr) {
	public void writeItemStack(ItemStack itemstack) {
	public void writeItemIdentifier(ItemIdentifier item) {
	public void writeItemIdentifierStack(ItemIdentifierStack stack) {
	public <T> void writeCollection(Collection<T> collection, IWriteListObject<T> handler) {
	public void writeOrderInfo(IOrderInfoProvider order) {
	public void writeLinkedLogisticsOrderList(LinkedLogisticsOrderList orderList) {
	public void writeResource(IResource res) {
	public void writeBytes(byte[] arr) {
	public String readUTF() {
	public ExitRoute readExitRoute(World world) {
	public <T extends Enum<T>> EnumSet<T> readEnumSet(Class<T> clazz) {
	public BitSet readBitSet() {
	public NBTTagCompound readNBTTagCompound() {
		try {
			return CompressedStreamTools.func_152456_a(new ByteBufInputStream(localBuffer), NBTSizeTracker.field_152451_a);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	public boolean[] readBooleanArray() {
	public byte[] readBytes(int length) {
	public ItemStack readItemStack() {
	public ItemIdentifier readItemIdentifier() {
	public ItemIdentifierStack readItemIdentifierStack() {
	public <T> ArrayList<T> readArrayList(IReadListObject<T> reader) {
	public <T> LinkedList<T> readLinkedList(IReadListObject<T> reader) {
	public <T> Set<T> readSet(IReadListObject<T> handler) {
	public IOrderInfoProvider readOrderInfo() {
	public LinkedLogisticsOrderList readLinkedLogisticsOrderList() {
			throw new NullPointerException("Expected order info provider list");
			throw new NullPointerException("Expected logistics order list");
	public ByteBuf readByteBuf() {
	public IResource readResource() {
	byte[] readByteArray();
	byte readByte();
	short readShort();
	int readInt();
	long readLong();
	float readFloat();
	double readDouble();
	boolean readBoolean();
	String readUTF();
	ForgeDirection readForgeDirection();
	ExitRoute readExitRoute(World world);
	IRouter readIRouter(World world);
	DoubleCoordinates readLPPosition();
	<T extends Enum<T>> EnumSet<T> readEnumSet(Class<T> clazz);
	BitSet readBitSet();
	NBTTagCompound readNBTTagCompound();
	boolean[] readBooleanArray();
	int[] readIntArray();
	byte[] readBytes(int length);
	ItemIdentifier readItemIdentifier();
	ItemIdentifierStack readItemIdentifierStack();
	ItemStack readItemStack();
	<T> ArrayList<T> readArrayList(IReadListObject<T> reader);
	<T> LinkedList<T> readLinkedList(IReadListObject<T> reader);
	<T> Set<T> readSet(IReadListObject<T> handler);
	IOrderInfoProvider readOrderInfo();
	<T extends Enum<T>> T readEnum(Class<T> clazz);
	LinkedLogisticsOrderList readLinkedLogisticsOrderList();
	ByteBuf readByteBuf();
	long[] readLongArray();
	IResource readResource();
		void accept(LPDataInput dataInput);
	void writeByte(int b);
	void writeByte(byte b);
	void writeShort(int s);
	void writeShort(short s);
	void writeInt(int i);
	void writeLong(long l);
	void writeFloat(float f);
	void writeDouble(double d);
	void writeBoolean(boolean b);
	void writeUTF(String s);
	void writeByteArray(byte[] arr);
	void writeByteBuf(ByteBuf buffer);
	void writeIntArray(int[] arr);
	void writeLongArray(long[] arr);
	void writeBooleanArray(boolean[] arr);
	void writeForgeDirection(ForgeDirection direction);
	void writeExitRoute(ExitRoute route);
	void writeIRouter(IRouter router);
	void writeLPPosition(DoubleCoordinates pos);
	<T extends Enum<T>> void writeEnumSet(EnumSet<T> types, Class<T> clazz);
	void writeBitSet(BitSet bits);
	void writeNBTTagCompound(NBTTagCompound tag);
	void writeItemStack(ItemStack itemstack);
	void writeItemIdentifier(ItemIdentifier item);
	void writeItemIdentifierStack(ItemIdentifierStack stack);
	<T> void writeCollection(Collection<T> collection, IWriteListObject<T> handler);
	void writeOrderInfo(IOrderInfoProvider order);
	<T extends Enum<T>> void writeEnum(T obj);
	void writeLinkedLogisticsOrderList(LinkedLogisticsOrderList orderList);
	void writeResource(IResource res);
	void writeBytes(byte[] arr);
		void accept(LPDataOutput dataOutput);
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(arrayList,
				(logisticspipes.network.IWriteListObject<String>) LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(null,
				(logisticspipes.network.IWriteListObject<String>) LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(linkedList,
				(logisticspipes.network.IWriteListObject<String>) LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(null,
				(logisticspipes.network.IWriteListObject<String>) LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(set,
				(logisticspipes.network.IWriteListObject<String>) LPDataOutput::writeUTF));
		byte[] data = LPDataIOWrapper.collectData(output -> output.writeCollection(null,
				(logisticspipes.network.IWriteListObject<String>) LPDataOutput::writeUTF));