Repository: RS485/LogisticsPipes Branch: dev Commit: 122ea1c99f12 Files: 1401 Total size: 4.8 MB Directory structure: gitextract_3aq3x4ml/ ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .idea/ │ ├── .name │ ├── codeInsightSettings.xml │ ├── codeStyles/ │ │ ├── Project.xml │ │ └── codeStyleConfig.xml │ ├── copyright/ │ │ ├── RS485_Dual_MIT_MMPL.xml │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── externalAnnotations/ │ │ └── net/ │ │ └── minecraft/ │ │ ├── block/ │ │ │ └── state/ │ │ │ └── annotations.xml │ │ ├── client/ │ │ │ └── gui/ │ │ │ └── inventory/ │ │ │ └── annotations.xml │ │ ├── item/ │ │ │ └── annotations.xml │ │ └── world/ │ │ └── annotations.xml │ ├── inspectionProfiles/ │ │ └── Project_Default.xml │ ├── kotlinc.xml │ ├── libraries-with-intellij-classes.xml │ └── scopes/ │ └── network_rs485_package.xml ├── .travis.yml ├── BUILDING.md ├── LICENSE.md ├── README.md ├── build.gradle ├── common/ │ └── logisticspipes/ │ ├── LPBlocks.java │ ├── LPConstants.java │ ├── LPItems.java │ ├── LogisticsEventListener.java │ ├── LogisticsPipes.java │ ├── api/ │ │ ├── IHUDArmor.java │ │ ├── ILPPipe.java │ │ ├── ILPPipeConfigTool.java │ │ ├── ILPPipeTile.java │ │ ├── ILogisticsPowerProvider.java │ │ ├── IProgressProvider.java │ │ └── IRoutedPowerProvider.java │ ├── asm/ │ │ ├── ClientSideOnlyMethodContent.java │ │ ├── IgnoreDisabledProxy.java │ │ ├── LogisticsASMHookClass.java │ │ ├── LogisticsClassTransformer.java │ │ ├── LogisticsPipesClassInjector.java │ │ ├── LogisticsPipesCoreLoader.java │ │ ├── ModAccessTransformerRemapper.java │ │ ├── ModDependentField.java │ │ ├── ModDependentInterface.java │ │ ├── ModDependentMethod.java │ │ ├── ModDependentMethodName.java │ │ ├── ModVersionedClass.java │ │ ├── ParamProfiler.java │ │ ├── addinfo/ │ │ │ ├── IAddInfo.java │ │ │ └── IAddInfoProvider.java │ │ ├── mcmp/ │ │ │ ├── ClassBlockMultipartContainerHandler.java │ │ │ └── MCMPHooks.java │ │ ├── td/ │ │ │ ├── ClassRenderDuctItemsHandler.java │ │ │ ├── ClassTravelingItemHandler.java │ │ │ ├── ILPTravelingItemInfo.java │ │ │ └── ThermalDynamicsHooks.java │ │ ├── te/ │ │ │ ├── ILPTEInformation.java │ │ │ ├── ITileEntityChangeListener.java │ │ │ └── LPTileEntityObject.java │ │ ├── util/ │ │ │ └── ASMHelper.java │ │ └── wrapper/ │ │ ├── AbstractSubWrapper.java │ │ ├── AbstractWrapper.java │ │ ├── CraftingRecipeProviderWrapper.java │ │ ├── GenericLPPipeConfigToolWrapper.java │ │ ├── GenericProgressProviderWrapper.java │ │ ├── LogisticsWrapperHandler.java │ │ └── WrapperState.java │ ├── blocks/ │ │ ├── BlockDummy.java │ │ ├── LogisticsProgramCompilerTileEntity.java │ │ ├── LogisticsSecurityTileEntity.java │ │ ├── LogisticsSolidBlock.java │ │ ├── LogisticsSolidTileEntity.java │ │ ├── crafting/ │ │ │ ├── AutoCraftingInventory.java │ │ │ └── LogisticsCraftingTableTileEntity.java │ │ ├── powertile/ │ │ │ ├── LogisticsIC2PowerProviderTileEntity.java │ │ │ ├── LogisticsPowerJunctionTileEntity.java │ │ │ ├── LogisticsPowerProviderTileEntity.java │ │ │ └── LogisticsRFPowerProviderTileEntity.java │ │ └── stats/ │ │ ├── LogisticsStatisticsTileEntity.java │ │ └── TrackingTask.java │ ├── commands/ │ │ ├── LogisticsPipesCommand.java │ │ ├── MainCommandHandler.java │ │ ├── abstracts/ │ │ │ ├── ICommandHandler.java │ │ │ └── SubCommandHandler.java │ │ ├── chathelper/ │ │ │ ├── LPChatListener.java │ │ │ └── MorePageDisplay.java │ │ ├── commands/ │ │ │ ├── BypassCommand.java │ │ │ ├── ChangelogCommand.java │ │ │ ├── ClearCommand.java │ │ │ ├── DebugCommand.java │ │ │ ├── DummyCommand.java │ │ │ ├── DumpCommand.java │ │ │ ├── NBTDebugCommand.java │ │ │ ├── NameLookupCommand.java │ │ │ ├── RoutingThreadCommand.java │ │ │ ├── TestCommand.java │ │ │ ├── TransferNamesCommand.java │ │ │ ├── VersionCommand.java │ │ │ ├── WrapperCommand.java │ │ │ ├── debug/ │ │ │ │ ├── DebugGuiController.java │ │ │ │ ├── HandCommand.java │ │ │ │ ├── MeCommand.java │ │ │ │ ├── PipeCommand.java │ │ │ │ ├── RoutingTableCommand.java │ │ │ │ └── TargetCommand.java │ │ │ └── wrapper/ │ │ │ ├── EnableCommand.java │ │ │ ├── ListCommand.java │ │ │ └── ShowCommand.java │ │ └── exception/ │ │ ├── CommandNotFoundException.java │ │ ├── DuplicatedCommandException.java │ │ ├── LPCommandException.java │ │ ├── MissingArgumentException.java │ │ └── PermissionDeniedException.java │ ├── config/ │ │ └── Configs.java │ ├── datafixer/ │ │ ├── DataFixerSolidBlockItems.java │ │ ├── DataFixerTE.java │ │ ├── LPDataFixer.java │ │ └── MissingMappingHandler.java │ ├── entity/ │ │ ├── FakeNetServerHandler.java │ │ └── FakePlayerLP.java │ ├── gui/ │ │ ├── GuiCardManager.java │ │ ├── GuiChassisPipe.java │ │ ├── GuiCraftingPipe.java │ │ ├── GuiFirewall.java │ │ ├── GuiFluidBasic.java │ │ ├── GuiFluidSupplierMk2Pipe.java │ │ ├── GuiFluidSupplierPipe.java │ │ ├── GuiFluidTerminus.java │ │ ├── GuiFreqCardContent.java │ │ ├── GuiInvSysConnector.java │ │ ├── GuiLogisticsCraftingTable.java │ │ ├── GuiLogisticsSettings.java │ │ ├── GuiPipeController.java │ │ ├── GuiPowerJunction.java │ │ ├── GuiPowerProvider.java │ │ ├── GuiProgramCompiler.java │ │ ├── GuiSatellitePipe.java │ │ ├── GuiSecurityStation.java │ │ ├── GuiStatistics.java │ │ ├── GuiSupplierPipe.java │ │ ├── ItemAmountSignCreationGui.java │ │ ├── hud/ │ │ │ ├── BasicHUDGui.java │ │ │ ├── GuiHUDSettings.java │ │ │ ├── HUDCrafting.java │ │ │ ├── HUDInvSysConnector.java │ │ │ ├── HUDPowerLevel.java │ │ │ ├── HUDProvider.java │ │ │ ├── HUDSatellite.java │ │ │ ├── HudChassisPipe.java │ │ │ └── modules/ │ │ │ ├── HUDAdvancedExtractor.java │ │ │ ├── HUDItemSink.java │ │ │ ├── HUDOreDictItemSink.java │ │ │ ├── HUDProviderModule.java │ │ │ ├── HUDSimpleFilterModule.java │ │ │ └── HUDStringBasedItemSink.java │ │ ├── modules/ │ │ │ ├── GuiAdvancedExtractor.java │ │ │ ├── GuiFluidSupplier.java │ │ │ ├── GuiOreDictItemSink.java │ │ │ ├── GuiSimpleFilter.java │ │ │ ├── GuiSneakyConfigurator.java │ │ │ ├── GuiStringBasedItemSink.java │ │ │ └── ModuleBaseGui.java │ │ ├── orderer/ │ │ │ ├── FluidGuiOrderer.java │ │ │ ├── GuiOrderer.java │ │ │ ├── GuiRequestTable.java │ │ │ ├── NormalGuiOrderer.java │ │ │ └── NormalMk2GuiOrderer.java │ │ └── popup/ │ │ ├── ActionChoicePopup.java │ │ ├── DisconnectionConfigurationPopup.java │ │ ├── GuiAddChannelPopup.java │ │ ├── GuiAddMacro.java │ │ ├── GuiAddTracking.java │ │ ├── GuiDiskPopup.java │ │ ├── GuiEditCCAccessTable.java │ │ ├── GuiEditChannelPopup.java │ │ ├── GuiManageChannelPopup.java │ │ ├── GuiMessagePopup.java │ │ ├── GuiRecipeImport.java │ │ ├── GuiRequestPopup.java │ │ ├── GuiSecurityStationPopup.java │ │ ├── GuiSelectChannelPopup.java │ │ ├── GuiSelectSatellitePopup.java │ │ ├── RequestMonitorPopup.java │ │ ├── SelectItemOutOfList.java │ │ └── SneakyConfigurationPopup.java │ ├── hud/ │ │ └── HUDConfig.java │ ├── interfaces/ │ │ ├── IBlockWatchingHandler.java │ │ ├── IBufferItems.java │ │ ├── IChainAddList.java │ │ ├── IChangeListener.java │ │ ├── IChestContentReceiver.java │ │ ├── IClientInformationProvider.java │ │ ├── IClientState.java │ │ ├── IDebugHUDProvider.java │ │ ├── IDiskProvider.java │ │ ├── IFuzzySlot.java │ │ ├── IGUIChannelInformationReceiver.java │ │ ├── IGuiOpenControler.java │ │ ├── IGuiTileEntity.java │ │ ├── IHUDButton.java │ │ ├── IHUDConfig.java │ │ ├── IHUDModuleHandler.java │ │ ├── IHUDModuleRenderer.java │ │ ├── IHeadUpDisplayBlockRendererProvider.java │ │ ├── IHeadUpDisplayRenderer.java │ │ ├── IHeadUpDisplayRendererProvider.java │ │ ├── IInventoryUtil.java │ │ ├── IItemAdvancedExistance.java │ │ ├── ILPItemAcceptor.java │ │ ├── ILPPositionProvider.java │ │ ├── ILegacyActiveModule.java │ │ ├── ILogisticsItem.java │ │ ├── IModuleInventoryReceive.java │ │ ├── IModuleWatchReciver.java │ │ ├── IOrderManagerContentReceiver.java │ │ ├── IPipeServiceProvider.java │ │ ├── IPipeUpgradeManager.java │ │ ├── IPowerLevelDisplay.java │ │ ├── IQueueCCEvent.java │ │ ├── IRequestWatcher.java │ │ ├── IRotationProvider.java │ │ ├── IRoutingDebugAdapter.java │ │ ├── ISecurityProvider.java │ │ ├── ISecurityStationManager.java │ │ ├── ISendQueueContentRecieiver.java │ │ ├── ISendRoutedItem.java │ │ ├── ISlotCheck.java │ │ ├── ISlotClick.java │ │ ├── ISlotUpgradeManager.java │ │ ├── ISpawnParticles.java │ │ ├── ISpecialInsertion.java │ │ ├── ISpecialItemRenderer.java │ │ ├── ISpecialTankAccessHandler.java │ │ ├── ISpecialTankHandler.java │ │ ├── ISpecialTankUtil.java │ │ ├── IStringBasedModule.java │ │ ├── ISubSystemPowerProvider.java │ │ ├── ITankUtil.java │ │ ├── ITileEntityPart.java │ │ ├── ITubeOrientation.java │ │ ├── ITubeRenderOrientation.java │ │ ├── IWatchingHandler.java │ │ ├── IWorldProvider.java │ │ ├── PlayerListReciver.java │ │ └── routing/ │ │ ├── IAdditionalTargetInformation.java │ │ ├── IChannelConnectionManager.java │ │ ├── IChannelManager.java │ │ ├── IChannelManagerProvider.java │ │ ├── IChannelRoutingConnection.java │ │ ├── ICraft.java │ │ ├── ICraftItems.java │ │ ├── IFilter.java │ │ ├── IFilteringPipe.java │ │ ├── IFluidSink.java │ │ ├── IItemSpaceControl.java │ │ ├── IProvide.java │ │ ├── IProvideFluids.java │ │ ├── IProvideItems.java │ │ ├── IRequest.java │ │ ├── IRequestFluid.java │ │ ├── IRequestItems.java │ │ ├── IRequireReliableFluidTransport.java │ │ ├── IRequireReliableTransport.java │ │ ├── ISpecialPipedConnection.java │ │ ├── ISpecialTileConnection.java │ │ └── ITargetSlotInformation.java │ ├── items/ │ │ ├── ItemBlankModule.java │ │ ├── ItemDisk.java │ │ ├── ItemHUDArmor.java │ │ ├── ItemLogisticsChips.java │ │ ├── ItemLogisticsPipe.java │ │ ├── ItemLogisticsProgrammer.java │ │ ├── ItemModule.java │ │ ├── ItemParts.java │ │ ├── ItemPipeController.java │ │ ├── ItemPipeManager.java │ │ ├── ItemPipeSignCreator.java │ │ ├── ItemUpgrade.java │ │ ├── LogisticsBrokenItem.java │ │ ├── LogisticsFluidContainer.java │ │ ├── LogisticsItem.java │ │ ├── LogisticsItemCard.java │ │ ├── LogisticsSolidBlockItem.java │ │ └── RemoteOrderer.java │ ├── logic/ │ │ ├── BaseLogicConnection.java │ │ ├── BaseLogicTask.java │ │ ├── LogicController.java │ │ ├── LogicParameterType.java │ │ ├── gui/ │ │ │ └── LogicLayoutGui.java │ │ └── interfaces/ │ │ └── ILogicControllerTile.java │ ├── logistics/ │ │ ├── ILogisticsFluidManager.java │ │ ├── ILogisticsManager.java │ │ ├── LogisticsFluidManager.java │ │ └── LogisticsManager.java │ ├── logisticspipes/ │ │ ├── ChassisTransportLayer.java │ │ ├── IRoutedItem.java │ │ ├── ITrackStatistics.java │ │ ├── ItemModuleInformationManager.java │ │ ├── PipeTransportLayer.java │ │ ├── RouteLayer.java │ │ └── TransportLayer.java │ ├── modplugins/ │ │ ├── jei/ │ │ │ ├── AdvancedGuiHandler.java │ │ │ ├── GhostIngredientHandler.java │ │ │ ├── JEIPluginLoader.java │ │ │ └── RecipeTransferHandler.java │ │ ├── mcmp/ │ │ │ ├── LPMCMPAddon.java │ │ │ ├── LPMultipartTile.java │ │ │ └── LPPipeMultipart.java │ │ └── nei/ │ │ ├── DebugHelper.java │ │ ├── DrawHandler.java │ │ ├── LoadingHelper.java │ │ ├── LogisticsCraftingOverlayHandler.java │ │ ├── NEILogisticsPipesConfig.java │ │ └── NEISolderingStationRecipeManager.java │ ├── modules/ │ │ ├── ChassisModule.java │ │ ├── LogisticsModule.java │ │ ├── ModuleActiveSupplier.java │ │ ├── ModuleCrafter.java │ │ ├── ModuleCreativeTabBasedItemSink.java │ │ ├── ModuleEnchantmentSink.java │ │ ├── ModuleEnchantmentSinkMK2.java │ │ ├── ModuleFluidSupplier.java │ │ ├── ModuleItemSink.java │ │ ├── ModuleModBasedItemSink.java │ │ ├── ModuleOreDictItemSink.java │ │ ├── ModulePassiveSupplier.java │ │ ├── ModulePolymorphicItemSink.java │ │ ├── ModuleProvider.java │ │ ├── ModuleSatellite.java │ │ └── ModuleTerminus.java │ ├── network/ │ │ ├── GuiHandler.java │ │ ├── GuiIDs.java │ │ ├── IReadListObject.java │ │ ├── IWriteListObject.java │ │ ├── NewGuiHandler.java │ │ ├── PacketHandler.java │ │ ├── PacketInboundHandler.java │ │ ├── abstractguis/ │ │ │ ├── BooleanModuleCoordinatesGuiProvider.java │ │ │ ├── CoordinatesGuiProvider.java │ │ │ ├── CoordinatesPopupGuiProvider.java │ │ │ ├── GuiProvider.java │ │ │ ├── ModuleCoordinatesGuiProvider.java │ │ │ ├── ModuleInHandGuiProvider.java │ │ │ ├── NBTModuleCoordinatesGuiProvider.java │ │ │ ├── PopupGuiProvider.java │ │ │ └── UpgradeCoordinatesGuiProvider.java │ │ ├── abstractpackets/ │ │ │ ├── BitSetCoordinatesPacket.java │ │ │ ├── BooleanCoordinatesPacket.java │ │ │ ├── BooleanModuleCoordinatesPacket.java │ │ │ ├── ChannelInformationListCoordinatesPopupGuiProvider.java │ │ │ ├── CoordinatesPacket.java │ │ │ ├── DirectionModuleCoordinatesPacket.java │ │ │ ├── GuiPacket.java │ │ │ ├── Integer2CoordinatesPacket.java │ │ │ ├── Integer2ModuleCoordinatesPacket.java │ │ │ ├── IntegerCoordinatesPacket.java │ │ │ ├── IntegerModuleCoordinatesPacket.java │ │ │ ├── IntegerPacket.java │ │ │ ├── InventoryModuleCoordinatesPacket.java │ │ │ ├── ItemPacket.java │ │ │ ├── ListSyncPacket.java │ │ │ ├── ModernPacket.java │ │ │ ├── ModuleCoordinatesPacket.java │ │ │ ├── NBTCoordinatesPacket.java │ │ │ ├── NBTModuleCoordinatesPacket.java │ │ │ ├── RequestPacket.java │ │ │ ├── SlotPacket.java │ │ │ ├── StringCoordinatesPacket.java │ │ │ └── StringListPacket.java │ │ ├── exception/ │ │ │ ├── DelayPacketException.java │ │ │ └── TargetNotFoundException.java │ │ ├── guis/ │ │ │ ├── AddChannelGuiProvider.java │ │ │ ├── EditChannelGuiProvider.java │ │ │ ├── LogisticsPlayerSettingsGuiProvider.java │ │ │ ├── OpenGuideBook.java │ │ │ ├── block/ │ │ │ │ ├── AutoCraftingGui.java │ │ │ │ ├── PowerJunctionGui.java │ │ │ │ ├── PowerProviderGui.java │ │ │ │ ├── ProgramCompilerGui.java │ │ │ │ ├── SecurityChannelManagerGui.java │ │ │ │ ├── SecurityStationGui.java │ │ │ │ └── StatisticsGui.java │ │ │ ├── item/ │ │ │ │ ├── ItemAmountSignGui.java │ │ │ │ └── ItemMangerGui.java │ │ │ ├── logic/ │ │ │ │ └── LogicControllerGuiProvider.java │ │ │ ├── module/ │ │ │ │ ├── inhand/ │ │ │ │ │ ├── ActiveSupplierInHand.java │ │ │ │ │ ├── AdvancedExtractorModuleInHand.java │ │ │ │ │ ├── CraftingModuleInHand.java │ │ │ │ │ ├── ItemSinkInHand.java │ │ │ │ │ ├── OreDictItemSinkModuleInHand.java │ │ │ │ │ ├── ProviderModuleInHand.java │ │ │ │ │ ├── SimpleFilterInventoryInHand.java │ │ │ │ │ ├── SneakyModuleInHandGuiProvider.java │ │ │ │ │ └── StringBasedItemSinkModuleGuiInHand.java │ │ │ │ └── inpipe/ │ │ │ │ ├── ActiveSupplierSlot.java │ │ │ │ ├── AdvancedExtractorModuleSlot.java │ │ │ │ ├── CraftingModuleSlot.java │ │ │ │ ├── FluidSupplierSlot.java │ │ │ │ ├── ItemSinkSlot.java │ │ │ │ ├── OreDictItemSinkModuleSlot.java │ │ │ │ ├── ProviderModuleGuiProvider.java │ │ │ │ ├── SimpleFilterInventorySlot.java │ │ │ │ ├── SneakyModuleInSlotGuiProvider.java │ │ │ │ └── StringBasedItemSinkModuleGuiSlot.java │ │ │ ├── pipe/ │ │ │ │ ├── ChassisGuiProvider.java │ │ │ │ ├── InvSysConGuiProvider.java │ │ │ │ ├── InvSysConSelectChannelPopupGUIProvider.java │ │ │ │ └── PipeController.java │ │ │ └── upgrade/ │ │ │ ├── DisconnectionUpgradeConfigGuiProvider.java │ │ │ └── SneakyUpgradeConfigGuiProvider.java │ │ ├── packetcontent/ │ │ │ ├── IPacketContent.java │ │ │ ├── IntegerContent.java │ │ │ ├── ItemStackContent.java │ │ │ └── PacketContentBuilder.java │ │ └── packets/ │ │ ├── ActivateNBTDebug.java │ │ ├── AddNewChannelPacket.java │ │ ├── BufferTransfer.java │ │ ├── DeleteChannelPacket.java │ │ ├── DummyPacket.java │ │ ├── EditChannelPacket.java │ │ ├── NEISetCraftingRecipe.java │ │ ├── PlayerConfigToClientPacket.java │ │ ├── PlayerConfigToServerPacket.java │ │ ├── PlayerList.java │ │ ├── PlayerListRequest.java │ │ ├── RequestUpdateNamesPacket.java │ │ ├── SetGhostItemPacket.java │ │ ├── UpdateName.java │ │ ├── block/ │ │ │ ├── AddItemToTrackPacket.java │ │ │ ├── AmountTaskSubGui.java │ │ │ ├── ClearCraftingGridPacket.java │ │ │ ├── CompilerStatusPacket.java │ │ │ ├── CompilerTriggerTaskPacket.java │ │ │ ├── CraftingCycleRecipe.java │ │ │ ├── CraftingSetType.java │ │ │ ├── LogicControllerPacket.java │ │ │ ├── PipeSolidSideCheck.java │ │ │ ├── PowerJunctionCheatPacket.java │ │ │ ├── PowerJunctionLevel.java │ │ │ ├── PowerPacketLaser.java │ │ │ ├── PowerProviderLevel.java │ │ │ ├── RemoveAmoundTask.java │ │ │ ├── RequestAmountTaskSubGui.java │ │ │ ├── RequestRotationPacket.java │ │ │ ├── RequestRunningCraftingTasks.java │ │ │ ├── Rotation.java │ │ │ ├── RunningCraftingTasks.java │ │ │ ├── SaveSecurityPlayerPacket.java │ │ │ ├── SecurityAddCCIdPacket.java │ │ │ ├── SecurityAuthorizationPacket.java │ │ │ ├── SecurityCardPacket.java │ │ │ ├── SecurityRemoveCCIdPacket.java │ │ │ ├── SecurityRequestCCIdsPacket.java │ │ │ ├── SecurityStationAuthorizedList.java │ │ │ ├── SecurityStationAutoDestroy.java │ │ │ ├── SecurityStationCC.java │ │ │ ├── SecurityStationCCIDs.java │ │ │ ├── SecurityStationId.java │ │ │ ├── SecurityStationOpenPlayer.java │ │ │ └── SecurityStationOpenPlayerRequest.java │ │ ├── chassis/ │ │ │ ├── ChassisGUI.java │ │ │ ├── ChestGuiClosed.java │ │ │ ├── ChestGuiOpened.java │ │ │ └── EnableQuickSortMarker.java │ │ ├── cpipe/ │ │ │ ├── CPipeCleanupImport.java │ │ │ ├── CPipeSatelliteImport.java │ │ │ ├── CPipeSatelliteImportBack.java │ │ │ └── CraftingPipeOpenConnectedGuiPacket.java │ │ ├── debug/ │ │ │ ├── PipeDebugLogAskForTarget.java │ │ │ ├── PipeDebugLogResponse.java │ │ │ ├── SendNewLogLine.java │ │ │ ├── SendNewLogWindow.java │ │ │ └── UpdateStatusEntries.java │ │ ├── debuggui/ │ │ │ ├── DebugAskForTarget.java │ │ │ ├── DebugDataPacket.java │ │ │ ├── DebugPanelOpen.java │ │ │ └── DebugTargetResponse.java │ │ ├── gui/ │ │ │ ├── ChannelInformationPacket.java │ │ │ ├── DummyContainerSlotClick.java │ │ │ ├── FuzzySlotSettingsPacket.java │ │ │ ├── GuiClosePacket.java │ │ │ ├── GuiOpenChassis.java │ │ │ ├── GuiReopenPacket.java │ │ │ ├── OpenAddChannelGUIPacket.java │ │ │ ├── OpenChatGui.java │ │ │ ├── OpenEditChannelGUIPacket.java │ │ │ ├── OpenGUIPacket.java │ │ │ ├── OpenSecurityChannelManagerPacket.java │ │ │ ├── OpenUpgradePacket.java │ │ │ ├── ProvideSatellitePipeListPacket.java │ │ │ └── RequestSatellitePipeListPacket.java │ │ ├── hud/ │ │ │ ├── ChestContent.java │ │ │ ├── HUDSettingsPacket.java │ │ │ ├── HUDStartBlockWatchingPacket.java │ │ │ ├── HUDStartModuleWatchingPacket.java │ │ │ ├── HUDStartWatchingPacket.java │ │ │ ├── HUDStopBlockWatchingPacket.java │ │ │ ├── HUDStopModuleWatchingPacket.java │ │ │ └── HUDStopWatchingPacket.java │ │ ├── module/ │ │ │ ├── AdvancedExtractorSneakyGuiPacket.java │ │ │ ├── ItemSinkImportPacket.java │ │ │ ├── ModuleBasedItemSinkList.java │ │ │ ├── ModuleInventory.java │ │ │ ├── ModulePropertiesUpdate.java │ │ │ └── OreDictItemSinkList.java │ │ ├── modules/ │ │ │ ├── AdvancedExtractorInclude.java │ │ │ ├── ItemSinkDefault.java │ │ │ ├── ProviderModuleInclude.java │ │ │ ├── ProviderModuleMode.java │ │ │ ├── QuickSortState.java │ │ │ ├── SneakyModuleDirectionUpdate.java │ │ │ └── SupplierPipeMode.java │ │ ├── multiblock/ │ │ │ └── MultiBlockCoordinatesPacket.java │ │ ├── orderer/ │ │ │ ├── ComponentList.java │ │ │ ├── DiscContent.java │ │ │ ├── DiskDropPacket.java │ │ │ ├── DiskMacroRequestPacket.java │ │ │ ├── DiskRequestConectPacket.java │ │ │ ├── DiskSetNamePacket.java │ │ │ ├── MissingItems.java │ │ │ ├── OrderWatchRemovePacket.java │ │ │ ├── OrdererContent.java │ │ │ ├── OrdererManagerContent.java │ │ │ ├── OrdererRefreshRequestPacket.java │ │ │ ├── OrdererWatchPacket.java │ │ │ ├── RequestComponentPacket.java │ │ │ ├── RequestFluidOrdererRefreshPacket.java │ │ │ ├── RequestSubmitListPacket.java │ │ │ ├── RequestSubmitPacket.java │ │ │ └── SubmitFluidRequestPacket.java │ │ ├── pipe/ │ │ │ ├── AskForOpenTarget.java │ │ │ ├── ChassisOrientationPacket.java │ │ │ ├── ChassisPipeModuleContent.java │ │ │ ├── CraftingPipeSetSatellitePacket.java │ │ │ ├── CraftingPipeUpdatePacket.java │ │ │ ├── CraftingPriority.java │ │ │ ├── FindMostLikelyRecipeComponents.java │ │ │ ├── FireWallFlag.java │ │ │ ├── FluidCraftingAmount.java │ │ │ ├── FluidSupplierAmount.java │ │ │ ├── FluidSupplierMinMode.java │ │ │ ├── FluidSupplierMode.java │ │ │ ├── InvSysConContent.java │ │ │ ├── InvSysConContentRequest.java │ │ │ ├── InvSysConOpenSelectChannelPopupPacket.java │ │ │ ├── InvSysConResistance.java │ │ │ ├── InvSysConSetChannelOnPipePacket.java │ │ │ ├── ItemAmountSignUpdatePacket.java │ │ │ ├── ItemBufferSyncPacket.java │ │ │ ├── MostLikelyRecipeComponentsResponse.java │ │ │ ├── ParticleFX.java │ │ │ ├── PipeContentPacket.java │ │ │ ├── PipeContentRequest.java │ │ │ ├── PipeDebugAskForTarget.java │ │ │ ├── PipeDebugResponse.java │ │ │ ├── PipeFluidUpdate.java │ │ │ ├── PipeManagerContentPacket.java │ │ │ ├── PipeManagerWatchingPacket.java │ │ │ ├── PipePositionPacket.java │ │ │ ├── PipePropertiesUpdate.java │ │ │ ├── PipeSignTypes.java │ │ │ ├── PipeTileStatePacket.java │ │ │ ├── RequestChassisOrientationPacket.java │ │ │ ├── RequestPipeDimension.java │ │ │ ├── RequestRoutingLasersPacket.java │ │ │ ├── RequestSignPacket.java │ │ │ ├── RoutingLaserPacket.java │ │ │ ├── SendQueueContent.java │ │ │ ├── SlotFinderActivatePacket.java │ │ │ ├── SlotFinderNumberPacket.java │ │ │ ├── SlotFinderOpenGuiPacket.java │ │ │ └── StatUpdate.java │ │ ├── routingdebug/ │ │ │ ├── RoutingUpdateAskForTarget.java │ │ │ ├── RoutingUpdateCanidatePipe.java │ │ │ ├── RoutingUpdateClearClient.java │ │ │ ├── RoutingUpdateDebugCanidateList.java │ │ │ ├── RoutingUpdateDebugClosedSet.java │ │ │ ├── RoutingUpdateDebugFilters.java │ │ │ ├── RoutingUpdateDoneDebug.java │ │ │ ├── RoutingUpdateInitDebug.java │ │ │ ├── RoutingUpdateSourcePipe.java │ │ │ ├── RoutingUpdateTargetResponse.java │ │ │ └── RoutingUpdateUntrace.java │ │ ├── satpipe/ │ │ │ ├── SatelliteSetNamePacket.java │ │ │ ├── SetNameResult.java │ │ │ └── SyncSatelliteNamePacket.java │ │ └── upgrade/ │ │ ├── SneakyUpgradeSidePacket.java │ │ └── ToogleDisconnectionUpgradeSidePacket.java │ ├── pipefxhandlers/ │ │ ├── EntityModelFX.java │ │ ├── EntitySparkleFX.java │ │ ├── GenericSparkleFactory.java │ │ ├── ParticleProvider.java │ │ ├── Particles.java │ │ ├── PipeFXLaserPowerBall.java │ │ ├── PipeFXLaserPowerBeam.java │ │ ├── PipeFXRenderHandler.java │ │ └── providers/ │ │ ├── EntityBlueSparkleFXProvider.java │ │ ├── EntityGoldSparkleFXProvider.java │ │ ├── EntityGreenSparkleFXProvider.java │ │ ├── EntityLightGreenSparkleFXProvider.java │ │ ├── EntityLightRedSparkleFXProvider.java │ │ ├── EntityOrangeSparkleFXProvider.java │ │ ├── EntityRedSparkleFXProvider.java │ │ ├── EntityVioletSparkleFXProvider.java │ │ └── EntityWhiteSparkleFXProvider.java │ ├── pipes/ │ │ ├── PipeBlockRequestTable.java │ │ ├── PipeFluidExtractor.java │ │ ├── PipeFluidInsertion.java │ │ ├── PipeFluidProvider.java │ │ ├── PipeFluidRequestLogistics.java │ │ ├── PipeFluidSatellite.java │ │ ├── PipeFluidSupplierMk2.java │ │ ├── PipeItemsBasicLogistics.java │ │ ├── PipeItemsCraftingLogistics.java │ │ ├── PipeItemsFirewall.java │ │ ├── PipeItemsFluidSupplier.java │ │ ├── PipeItemsInvSysConnector.java │ │ ├── PipeItemsProviderLogistics.java │ │ ├── PipeItemsRemoteOrdererLogistics.java │ │ ├── PipeItemsRequestLogistics.java │ │ ├── PipeItemsRequestLogisticsMk2.java │ │ ├── PipeItemsSatelliteLogistics.java │ │ ├── PipeItemsSupplierLogistics.java │ │ ├── PipeItemsSystemDestinationLogistics.java │ │ ├── PipeItemsSystemEntranceLogistics.java │ │ ├── PipeLogisticsChassis.java │ │ ├── PipeLogisticsChassisMk1.java │ │ ├── PipeLogisticsChassisMk2.java │ │ ├── PipeLogisticsChassisMk3.java │ │ ├── PipeLogisticsChassisMk4.java │ │ ├── PipeLogisticsChassisMk5.java │ │ ├── SatelliteNamingResult.java │ │ ├── basic/ │ │ │ ├── CoreMultiBlockPipe.java │ │ │ ├── CoreRoutedPipe.java │ │ │ ├── CoreUnroutedPipe.java │ │ │ ├── ItemInsertionHandler.java │ │ │ ├── LogisticsBlockGenericPipe.java │ │ │ ├── LogisticsBlockGenericSubMultiBlock.java │ │ │ ├── LogisticsTileGenericPipe.java │ │ │ ├── LogisticsTileGenericSubMultiBlock.java │ │ │ ├── PowerSupplierHandler.java │ │ │ ├── debug/ │ │ │ │ ├── DebugLogController.java │ │ │ │ ├── LogWindow.java │ │ │ │ └── StatusEntry.java │ │ │ ├── fluid/ │ │ │ │ └── FluidRoutedPipe.java │ │ │ └── ltgpmodcompat/ │ │ │ ├── LPDuctHolderTileEntity.java │ │ │ ├── LPMicroblockBlock.java │ │ │ └── LPMicroblockTileEntity.java │ │ ├── signs/ │ │ │ ├── CraftingPipeSign.java │ │ │ ├── IPipeSign.java │ │ │ └── ItemAmountPipeSign.java │ │ ├── tubes/ │ │ │ ├── HSTubeCurve.java │ │ │ ├── HSTubeGain.java │ │ │ ├── HSTubeLine.java │ │ │ ├── HSTubeSCurve.java │ │ │ └── HSTubeSpeedup.java │ │ ├── unrouted/ │ │ │ └── PipeItemsBasicTransport.java │ │ └── upgrades/ │ │ ├── ActionSpeedUpgrade.java │ │ ├── AdvancedSatelliteUpgrade.java │ │ ├── CCRemoteControlUpgrade.java │ │ ├── CombinedSneakyUpgrade.java │ │ ├── ConnectionUpgradeConfig.java │ │ ├── CraftingByproductUpgrade.java │ │ ├── CraftingCleanupUpgrade.java │ │ ├── CraftingMonitoringUpgrade.java │ │ ├── FluidCraftingUpgrade.java │ │ ├── FuzzyUpgrade.java │ │ ├── IConfigPipeUpgrade.java │ │ ├── IPipeUpgrade.java │ │ ├── ItemExtractionUpgrade.java │ │ ├── ItemStackExtractionUpgrade.java │ │ ├── LogicControllerUpgrade.java │ │ ├── ModuleUpgradeManager.java │ │ ├── OpaqueUpgrade.java │ │ ├── PatternUpgrade.java │ │ ├── PowerTransportationUpgrade.java │ │ ├── SneakyUpgradeConfig.java │ │ ├── SpeedUpgrade.java │ │ ├── UpgradeManager.java │ │ ├── UpgradeModuleUpgrade.java │ │ └── power/ │ │ ├── BCPowerSupplierUpgrade.java │ │ ├── IC2EVPowerSupplierUpgrade.java │ │ ├── IC2HVPowerSupplierUpgrade.java │ │ ├── IC2LVPowerSupplierUpgrade.java │ │ ├── IC2MVPowerSupplierUpgrade.java │ │ ├── IC2PowerSupplierUpgrade.java │ │ └── RFPowerSupplierUpgrade.java │ ├── proxy/ │ │ ├── ConfigToolHandler.java │ │ ├── DontLoadProxy.java │ │ ├── MainProxy.java │ │ ├── PowerProxy.java │ │ ├── ProxyManager.java │ │ ├── SimpleServiceLocator.java │ │ ├── SpecialInventoryHandlerManager.java │ │ ├── SpecialTankHandlerManager.java │ │ ├── VersionNotSupportedException.java │ │ ├── buildcraft/ │ │ │ ├── BCPipeInformationProvider.java │ │ │ ├── BuildCraftProxy.java │ │ │ ├── BuildCraftToolWrench.java │ │ │ ├── recipeprovider/ │ │ │ │ └── AssemblyTable.java │ │ │ └── subproxies/ │ │ │ ├── BCPipeCapabilityProvider.java │ │ │ └── IBCPipeCapabilityProvider.java │ │ ├── cc/ │ │ │ ├── CCConstants.java │ │ │ ├── CCProxy.java │ │ │ ├── LPASMHookCC.java │ │ │ ├── LPPeripheralProvider.java │ │ │ └── wrapper/ │ │ │ ├── CCCommandWrapper.java │ │ │ ├── LPPeripheralTilePipeWrapper.java │ │ │ └── LPPeripheralTileSolidWrapper.java │ │ ├── ccl/ │ │ │ ├── CCLProxy.java │ │ │ ├── Model3D.java │ │ │ └── TransformationProxy.java │ │ ├── cofh/ │ │ │ ├── CoFHToolHammer.java │ │ │ └── subproxies/ │ │ │ ├── ICoFHEnergyReceiver.java │ │ │ └── ICoFHEnergyStorage.java │ │ ├── computers/ │ │ │ ├── interfaces/ │ │ │ │ ├── CCCommand.java │ │ │ │ ├── CCDirectCall.java │ │ │ │ ├── CCQueued.java │ │ │ │ ├── CCSecurtiyCheck.java │ │ │ │ ├── CCType.java │ │ │ │ ├── ICCTypeWrapped.java │ │ │ │ ├── ILPCCTypeDefinition.java │ │ │ │ └── ILPCCTypeHolder.java │ │ │ ├── objects/ │ │ │ │ ├── CCFilterInventory.java │ │ │ │ ├── CCFluidIdentifier.java │ │ │ │ ├── CCItemIdentifier.java │ │ │ │ ├── CCItemIdentifierBuilder.java │ │ │ │ ├── CCItemIdentifierInventory.java │ │ │ │ ├── CCItemIdentifierStack.java │ │ │ │ ├── CCPair.java │ │ │ │ ├── CCQuartet.java │ │ │ │ ├── CCResource.java │ │ │ │ ├── CCSinkResponder.java │ │ │ │ ├── CCTriplet.java │ │ │ │ └── LPGlobalCCAccess.java │ │ │ └── wrapper/ │ │ │ ├── CCObjectWrapper.java │ │ │ ├── CCWrapperInformation.java │ │ │ └── ICommandWrapper.java │ │ ├── enderchest/ │ │ │ └── EnderStorageProxy.java │ │ ├── endercore/ │ │ │ └── EnderCoreProgressProvider.java │ │ ├── ic/ │ │ │ └── IronChestProxy.java │ │ ├── ic2/ │ │ │ ├── IC2ProgressProvider.java │ │ │ └── IC2Proxy.java │ │ ├── interfaces/ │ │ │ ├── IBCProxy.java │ │ │ ├── ICCLProxy.java │ │ │ ├── ICCProxy.java │ │ │ ├── ICraftingRecipeProvider.java │ │ │ ├── IEnderStorageProxy.java │ │ │ ├── IFuzzyRecipeProvider.java │ │ │ ├── IGenericProgressProvider.java │ │ │ ├── IIC2Proxy.java │ │ │ ├── IIronChestProxy.java │ │ │ ├── ILPPipeConfigToolWrapper.java │ │ │ ├── INEIProxy.java │ │ │ ├── IOpenComputersProxy.java │ │ │ ├── IPowerProxy.java │ │ │ ├── IProxy.java │ │ │ ├── ITDProxy.java │ │ │ └── IThermalExpansionProxy.java │ │ ├── nei/ │ │ │ └── NEIProxy.java │ │ ├── object3d/ │ │ │ ├── interfaces/ │ │ │ │ ├── I3DOperation.java │ │ │ │ ├── IBounds.java │ │ │ │ ├── IModel3D.java │ │ │ │ ├── IRenderState.java │ │ │ │ ├── ITranslation.java │ │ │ │ ├── IVec3.java │ │ │ │ └── TextureTransformation.java │ │ │ └── operation/ │ │ │ ├── LPColourMultiplier.java │ │ │ ├── LPRotation.java │ │ │ ├── LPScale.java │ │ │ ├── LPTranslation.java │ │ │ ├── LPUVScale.java │ │ │ ├── LPUVTransformationList.java │ │ │ └── LPUVTranslation.java │ │ ├── opencomputers/ │ │ │ ├── IOCTile.java │ │ │ ├── OpenComputersProxy.java │ │ │ └── asm/ │ │ │ ├── BaseWrapperClass.java │ │ │ ├── ClassCreator.java │ │ │ └── DummyWrapperClass.java │ │ ├── progressprovider/ │ │ │ └── MachineProgressProvider.java │ │ ├── recipeproviders/ │ │ │ ├── AssemblyAdvancedWorkbench.java │ │ │ ├── AutoWorkbench.java │ │ │ └── LogisticsCraftingTable.java │ │ ├── side/ │ │ │ ├── ClientProxy.java │ │ │ └── ServerProxy.java │ │ ├── specialconnection/ │ │ │ ├── SpecialPipeConnection.java │ │ │ ├── SpecialTileConnection.java │ │ │ └── TeleportPipes.java │ │ ├── specialinventoryhandler/ │ │ │ ├── AEInterfaceInventoryHandler.java │ │ │ ├── BuildCraftTransactorHandler.java │ │ │ └── SpecialInventoryHandler.java │ │ ├── specialtankhandler/ │ │ │ ├── AETankHandler.java │ │ │ ├── BuildCraftTankHandler.java │ │ │ └── SpecialTankHandler.java │ │ ├── td/ │ │ │ ├── LPDuctUnitItem.java │ │ │ ├── TDDuctInformationProvider.java │ │ │ ├── ThermalDynamicsProxy.java │ │ │ └── subproxies/ │ │ │ ├── ITDPart.java │ │ │ └── TDPart.java │ │ └── te/ │ │ ├── ThermalExpansionProgressProvider.java │ │ └── ThermalExpansionProxy.java │ ├── recipes/ │ │ ├── CraftingPartRecipes.java │ │ ├── CraftingParts.java │ │ ├── CraftingRecipes.java │ │ ├── IRecipeProvider.java │ │ ├── LPChipRecipes.java │ │ ├── ModuleChippedCraftingRecipes.java │ │ ├── NBTIngredient.java │ │ ├── PipeChippedCraftingRecipes.java │ │ ├── RecipeManager.java │ │ ├── ShapelessResetRecipe.java │ │ ├── UpgradeChippedCraftingRecipes.java │ │ ├── conditions/ │ │ │ └── ConditionOreExists.java │ │ └── ingredients/ │ │ └── IngredientPart.java │ ├── renderer/ │ │ ├── CustomBlockRenderer.java │ │ ├── FluidContainerRenderer.java │ │ ├── FluidRenderer.java │ │ ├── GuiOverlay.java │ │ ├── IIconProvider.java │ │ ├── LogisticsHUDRenderer.java │ │ ├── LogisticsPipeItemRenderer.java │ │ ├── LogisticsPipeWorldRenderer.java │ │ ├── LogisticsRenderPipe.java │ │ ├── LogisticsSolidBlockWorldRenderer.java │ │ ├── LogisticsTileRenderController.java │ │ ├── newpipe/ │ │ │ ├── GLRenderList.java │ │ │ ├── GLRenderListHandler.java │ │ │ ├── IHighlightPlacementRenderer.java │ │ │ ├── ISpecialPipeRenderer.java │ │ │ ├── LogisticsBlockModel.java │ │ │ ├── LogisticsNewPipeItemBoxRenderer.java │ │ │ ├── LogisticsNewPipeItemRenderer.java │ │ │ ├── LogisticsNewPipeModel.java │ │ │ ├── LogisticsNewPipeWorldRenderer.java │ │ │ ├── LogisticsNewRenderPipe.java │ │ │ ├── LogisticsNewSolidBlockWorldRenderer.java │ │ │ ├── PropertyCache.java │ │ │ ├── PropertyRenderList.java │ │ │ ├── RenderEntry.java │ │ │ └── tube/ │ │ │ ├── CurveTubeRenderer.java │ │ │ ├── GainTubeRenderer.java │ │ │ ├── LineTubeRenderer.java │ │ │ ├── SCurveTubeRenderer.java │ │ │ └── SpeedupTubeRenderer.java │ │ └── state/ │ │ ├── ConnectionMatrix.java │ │ ├── PipeRenderState.java │ │ ├── PipeSubRenderState.java │ │ └── TextureMatrix.java │ ├── request/ │ │ ├── DictCraftingTemplate.java │ │ ├── ICraftingTemplate.java │ │ ├── IExtraPromise.java │ │ ├── IPromise.java │ │ ├── IReqCraftingTemplate.java │ │ ├── ItemCraftingTemplate.java │ │ ├── RequestHandler.java │ │ ├── RequestLog.java │ │ ├── RequestTree.java │ │ ├── RequestTreeNode.java │ │ └── resources/ │ │ ├── DictResource.java │ │ ├── FluidResource.java │ │ ├── IResource.java │ │ ├── ItemResource.java │ │ └── ResourceNetwork.java │ ├── routing/ │ │ ├── ClientRouter.java │ │ ├── DummyRoutingDebugAdapter.java │ │ ├── ExitRoute.java │ │ ├── FluidLogisticsPromise.java │ │ ├── IPaintPath.java │ │ ├── IRouter.java │ │ ├── IRouterQueuedTask.java │ │ ├── ItemRoutingInformation.java │ │ ├── LaserData.java │ │ ├── LogisticsDictPromise.java │ │ ├── LogisticsExtraDictPromise.java │ │ ├── LogisticsExtraPromise.java │ │ ├── LogisticsPromise.java │ │ ├── PipeRoutingConnectionType.java │ │ ├── RouterCost.java │ │ ├── RouterManager.java │ │ ├── ServerRouter.java │ │ ├── channels/ │ │ │ ├── ChannelConnection.java │ │ │ ├── ChannelInformation.java │ │ │ ├── ChannelManager.java │ │ │ └── ChannelManagerProvider.java │ │ ├── debug/ │ │ │ ├── ClientViewController.java │ │ │ ├── DebugController.java │ │ │ ├── DebugWindow.java │ │ │ ├── ExitRouteDebug.java │ │ │ ├── HUDRoutingTableDebugProvider.java │ │ │ ├── HUDRoutingTableGeneralInfo.java │ │ │ └── RoutingTableDebugUpdateThread.java │ │ ├── order/ │ │ │ ├── ClientSideOrderInfo.java │ │ │ ├── DistanceTracker.java │ │ │ ├── IDistanceTracker.java │ │ │ ├── IOrderInfoProvider.java │ │ │ ├── LinkedLogisticsOrderList.java │ │ │ ├── LogisticsFluidOrder.java │ │ │ ├── LogisticsFluidOrderManager.java │ │ │ ├── LogisticsItemOrder.java │ │ │ ├── LogisticsItemOrderManager.java │ │ │ ├── LogisticsOrder.java │ │ │ ├── LogisticsOrderLinkedList.java │ │ │ └── LogisticsOrderManager.java │ │ └── pathfinder/ │ │ ├── IPipeInformationProvider.java │ │ ├── IRouteProvider.java │ │ ├── ISubMultiBlockPipeInformationProvider.java │ │ ├── PathFinder.java │ │ ├── PipeInformationManager.java │ │ └── changedetection/ │ │ └── TEControl.java │ ├── security/ │ │ ├── PermissionException.java │ │ └── SecuritySettings.java │ ├── textures/ │ │ ├── Textures.java │ │ └── provider/ │ │ ├── LPActionTriggerIconProvider.java │ │ ├── LPPipeIconProvider.java │ │ └── LPPipeIconTransformerProvider.java │ ├── ticks/ │ │ ├── ClientPacketBufferHandlerThread.java │ │ ├── HudUpdateTick.java │ │ ├── LPTickHandler.java │ │ ├── QueuedTasks.java │ │ ├── RenderTickHandler.java │ │ ├── RoutingTableUpdateThread.java │ │ ├── ServerPacketBufferHandlerThread.java │ │ └── VersionChecker.java │ ├── transport/ │ │ ├── EntrencsTransport.java │ │ ├── LPItemList.java │ │ ├── LPTravelingItem.java │ │ ├── PipeFluidTransportLogistics.java │ │ ├── PipeMultiBlockTransportLogistics.java │ │ ├── PipeTransportLogistics.java │ │ └── TransportInvConnection.java │ └── utils/ │ ├── CacheHolder.java │ ├── CardManagementInventory.java │ ├── ChainAddArrayList.java │ ├── Color.java │ ├── CraftingUtil.java │ ├── DelayedGeneric.java │ ├── DummyWorldProvider.java │ ├── EnumFacingUtil.java │ ├── EqualWeakReference.java │ ├── FinalNBTTagCompound.java │ ├── FinalPair.java │ ├── FluidIdentifier.java │ ├── FluidIdentifierStack.java │ ├── FluidSinkReply.java │ ├── IHavePriority.java │ ├── IPositionRotateble.java │ ├── ISimpleInventoryEventHandler.java │ ├── InventoryHelper.java │ ├── InventoryUtil.java │ ├── InventoryUtilFactory.java │ ├── LPPositionSet.java │ ├── MinecraftColor.java │ ├── ModStatusHelper.java │ ├── OneList.java │ ├── OrientationsUtil.java │ ├── PlayerCollectionList.java │ ├── PlayerIdentifier.java │ ├── QuickSortChestMarkerStorage.java │ ├── ReflectionHelper.java │ ├── RoutedItemHelper.java │ ├── SafeTimeTracker.java │ ├── SinkReply.java │ ├── SlidingWindowBitSet.java │ ├── SpecialTankUtil.java │ ├── StackTraceUtil.java │ ├── StaticResolve.java │ ├── StaticResolverUtil.java │ ├── StreamHelper.java │ ├── SyncList.java │ ├── TankUtil.java │ ├── TileBuffer.java │ ├── gui/ │ │ ├── ColorSlot.java │ │ ├── DummyContainer.java │ │ ├── DummyModuleContainer.java │ │ ├── DummySlot.java │ │ ├── FluidSlot.java │ │ ├── FuzzyDummySlot.java │ │ ├── FuzzyUnmodifiableSlot.java │ │ ├── GuiCheckBox.java │ │ ├── GuiGraphics.java │ │ ├── GuiStringHandlerButton.java │ │ ├── HandelableSlot.java │ │ ├── HudGraphics.java │ │ ├── IGuiAccess.java │ │ ├── IItemSearch.java │ │ ├── IItemTextureRenderSlot.java │ │ ├── IRenderSlot.java │ │ ├── ISmallColorRenderSlot.java │ │ ├── ISubGuiControler.java │ │ ├── InputBar.java │ │ ├── ItemDisplay.java │ │ ├── LogisticsBaseGuiScreen.java │ │ ├── LogisticsBaseTabGuiScreen.java │ │ ├── ModuleSlot.java │ │ ├── RestrictedSlot.java │ │ ├── SimpleGraphics.java │ │ ├── SmallGuiButton.java │ │ ├── SneakyUpgradeSlot.java │ │ ├── StaticRestrictedSlot.java │ │ ├── SubGuiScreen.java │ │ ├── TextListDisplay.java │ │ ├── UnmodifiableSlot.java │ │ ├── UpgradeSlot.java │ │ ├── extension/ │ │ │ ├── GuiExtension.java │ │ │ └── GuiExtensionController.java │ │ ├── hud/ │ │ │ └── BasicHUDButton.java │ │ └── sideconfig/ │ │ └── SideConfigDisplay.java │ ├── item/ │ │ ├── DictIdentifier.java │ │ ├── DictItemIdentifier.java │ │ ├── ItemIdentifier.java │ │ ├── ItemIdentifierInventory.java │ │ ├── ItemIdentifierStack.java │ │ ├── ItemStackRenderer.java │ │ └── SimpleStackInventory.java │ ├── math/ │ │ ├── BoundingBox.java │ │ ├── Camera.java │ │ ├── Matrix4d.java │ │ ├── MatrixTranformations.java │ │ ├── Vec2.java │ │ ├── VecmathUtil.java │ │ ├── Vector2d.java │ │ ├── Vector2f.java │ │ ├── Vector3d.java │ │ ├── Vector3f.java │ │ ├── Vector4d.java │ │ └── Vertex.java │ ├── string/ │ │ ├── ChatColor.java │ │ └── StringUtils.java │ ├── transactor/ │ │ ├── IInvSlot.java │ │ ├── ITransactor.java │ │ ├── InventoryIterator.java │ │ ├── InventoryIteratorSimple.java │ │ ├── Transactor.java │ │ └── TransactorSimple.java │ └── tuples/ │ ├── Pair.java │ ├── Quartet.java │ └── Triplet.java ├── dummy/ │ └── src/ │ └── main/ │ └── java/ │ ├── com/ │ │ └── enderio/ │ │ └── core/ │ │ ├── api/ │ │ │ └── common/ │ │ │ └── util/ │ │ │ └── IProgressTile.java │ │ └── common/ │ │ └── util/ │ │ ├── BlockCoord.java │ │ ├── InventoryWrapper.java │ │ └── RoundRobinIterator.java │ ├── cpw/ │ │ └── mods/ │ │ └── ironchest/ │ │ ├── client/ │ │ │ └── gui/ │ │ │ └── chest/ │ │ │ └── GUIChest.java │ │ └── common/ │ │ └── tileentity/ │ │ └── chest/ │ │ └── TileEntityIronChest.java │ ├── crazypants/ │ │ └── enderio/ │ │ ├── conduit/ │ │ │ ├── AbstractConduit.java │ │ │ ├── ConnectionMode.java │ │ │ ├── IConduit.java │ │ │ ├── IConduitBundle.java │ │ │ ├── item/ │ │ │ │ ├── IItemConduit.java │ │ │ │ └── ItemConduit.java │ │ │ └── liquid/ │ │ │ └── ILiquidConduit.java │ │ └── machine/ │ │ └── transceiver/ │ │ ├── Channel.java │ │ ├── ChannelType.java │ │ ├── ServerChannelRegister.java │ │ └── TileTransceiver.java │ ├── ic2/ │ │ ├── api/ │ │ │ └── classic/ │ │ │ └── tile/ │ │ │ └── machine/ │ │ │ └── IProgressMachine.java │ │ └── core/ │ │ └── block/ │ │ └── machine/ │ │ └── tileentity/ │ │ └── TileEntityStandardMachine.java │ └── org/ │ └── luaj/ │ └── vm2/ │ ├── LuaNil.java │ ├── LuaTable.java │ ├── LuaValue.java │ └── Varargs.java ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── lib/ │ └── appliedenergistics2-rv6-stable-7-api.jar ├── lombok.config ├── resources/ │ ├── META-INF/ │ │ └── lp_at.cfg │ ├── assets/ │ │ └── logisticspipes/ │ │ ├── blockstates/ │ │ │ ├── pipe.json │ │ │ ├── solid_block.json │ │ │ └── sub_multiblock.json │ │ ├── book/ │ │ │ └── en_us/ │ │ │ ├── dev_zero_guides/ │ │ │ │ ├── active_routing.md │ │ │ │ ├── consolidating_pipes.md │ │ │ │ ├── crafting.md │ │ │ │ ├── index.md │ │ │ │ ├── managing_items_with_pipes.md │ │ │ │ └── passive_routing.md │ │ │ └── main_menu.md │ │ ├── fonts/ │ │ │ ├── OFL.TXT │ │ │ ├── minecraft-bold.bdf │ │ │ ├── minecraft-plain.bdf │ │ │ └── ter-u12n.bdf │ │ ├── lang/ │ │ │ └── en_us.lang │ │ ├── models/ │ │ │ ├── block/ │ │ │ │ ├── pipe.json │ │ │ │ ├── solid_block.json │ │ │ │ └── sub_multiblock.json │ │ │ └── item/ │ │ │ ├── broken_item.json │ │ │ ├── chip/ │ │ │ │ ├── advanced.json │ │ │ │ ├── advanced_raw.json │ │ │ │ ├── basic.json │ │ │ │ ├── basic_raw.json │ │ │ │ ├── fpga.json │ │ │ │ └── fpga_raw.json │ │ │ ├── disk.json │ │ │ ├── fluid_container.json │ │ │ ├── guide_book.json │ │ │ ├── hud_glasses.json │ │ │ ├── item_card.json │ │ │ ├── logistics_programmer.json │ │ │ ├── module/ │ │ │ │ ├── active_supplier.json │ │ │ │ ├── blank.json │ │ │ │ ├── crafter.json │ │ │ │ ├── crafter_mk2.json │ │ │ │ ├── crafter_mk3.json │ │ │ │ ├── enchantment_sink.json │ │ │ │ ├── enchantment_sink_mk2.json │ │ │ │ ├── extractor.json │ │ │ │ ├── extractor_advanced.json │ │ │ │ ├── extractor_advanced_mk2.json │ │ │ │ ├── extractor_advanced_mk3.json │ │ │ │ ├── extractor_mk2.json │ │ │ │ ├── extractor_mk3.json │ │ │ │ ├── item_sink.json │ │ │ │ ├── item_sink_cc.json │ │ │ │ ├── item_sink_creativetab.json │ │ │ │ ├── item_sink_mod.json │ │ │ │ ├── item_sink_oredict.json │ │ │ │ ├── item_sink_polymorphic.json │ │ │ │ ├── passive_supplier.json │ │ │ │ ├── provider.json │ │ │ │ ├── provider_mk2.json │ │ │ │ ├── quick_sort.json │ │ │ │ ├── quick_sort_cc.json │ │ │ │ ├── terminus.json │ │ │ │ └── thaumic_aspect_sink.json │ │ │ ├── parts/ │ │ │ │ ├── 0.json │ │ │ │ ├── 1.json │ │ │ │ ├── 2.json │ │ │ │ └── 3.json │ │ │ ├── pipe.json │ │ │ ├── pipe_controller.json │ │ │ ├── pipe_manager.json │ │ │ ├── remote_orderer/ │ │ │ │ ├── 0.json │ │ │ │ ├── 1.json │ │ │ │ ├── 10.json │ │ │ │ ├── 11.json │ │ │ │ ├── 12.json │ │ │ │ ├── 13.json │ │ │ │ ├── 14.json │ │ │ │ ├── 15.json │ │ │ │ ├── 16.json │ │ │ │ ├── 2.json │ │ │ │ ├── 3.json │ │ │ │ ├── 4.json │ │ │ │ ├── 5.json │ │ │ │ ├── 6.json │ │ │ │ ├── 7.json │ │ │ │ ├── 8.json │ │ │ │ └── 9.json │ │ │ ├── sign_creator.0.json │ │ │ ├── sign_creator.1.json │ │ │ ├── solid_block.json │ │ │ ├── sub_multiblock.json │ │ │ └── upgrade/ │ │ │ ├── action_speed.json │ │ │ ├── cc_remote_control.json │ │ │ ├── crafting_byproduct.json │ │ │ ├── crafting_cleanup.json │ │ │ ├── crafting_monitoring.json │ │ │ ├── disconnection.json │ │ │ ├── fluid_crafting.json │ │ │ ├── fuzzy.json │ │ │ ├── item_extraction.json │ │ │ ├── item_stack_extraction.json │ │ │ ├── logic_controller.json │ │ │ ├── module_upgrade.json │ │ │ ├── opaque.json │ │ │ ├── pattern.json │ │ │ ├── power_supplier_eu.json │ │ │ ├── power_supplier_eu_ev.json │ │ │ ├── power_supplier_eu_hv.json │ │ │ ├── power_supplier_eu_lv.json │ │ │ ├── power_supplier_eu_mv.json │ │ │ ├── power_supplier_mj.json │ │ │ ├── power_supplier_rf.json │ │ │ ├── power_transportation.json │ │ │ ├── satellite_advanced.json │ │ │ ├── sneaky.json │ │ │ ├── sneaky_combination.json │ │ │ └── speed.json │ │ ├── recipes/ │ │ │ ├── _factories.json │ │ │ ├── block_frame.json │ │ │ ├── chip/ │ │ │ │ ├── chip_advanced_raw.json │ │ │ │ ├── chip_basic_raw.json │ │ │ │ ├── chip_basic_raw_nocopper.json │ │ │ │ └── chip_fpga_raw.json │ │ │ ├── crafting_table.json │ │ │ ├── crafting_table_fuzzy.json │ │ │ ├── disk.json │ │ │ ├── guide_book.json │ │ │ ├── logistics_programmer.json │ │ │ ├── module_blank.json │ │ │ ├── pipe/ │ │ │ │ ├── pipe_basic.json │ │ │ │ ├── pipe_hs_curve.json │ │ │ │ ├── pipe_hs_gain.json │ │ │ │ ├── pipe_hs_line.json │ │ │ │ ├── pipe_hs_s_curve.json │ │ │ │ ├── pipe_hs_speedup.json │ │ │ │ ├── pipe_request_table.json │ │ │ │ └── pipe_transport_basic.json │ │ │ ├── pipe_controller.json │ │ │ ├── pipe_manager.json │ │ │ ├── power_junction.json │ │ │ ├── program_compiler.json │ │ │ ├── remote_orderer.json │ │ │ ├── security_station.json │ │ │ ├── sign_creator.json │ │ │ └── statistics_table.json │ │ └── textures/ │ │ └── particles/ │ │ └── laserball.psd │ ├── logisticspipes/ │ │ └── models/ │ │ ├── BlockModel_result.obj │ │ ├── HSTube-Gain_result.obj │ │ ├── HSTube-Line_result.obj │ │ ├── HSTube-Speedup_result.obj │ │ ├── HSTube-Turn_result.obj │ │ ├── PipeModel_Transport_Box.obj │ │ └── PipeModel_moved.obj │ └── pack.mcmeta ├── resources_raw/ │ ├── chips/ │ │ └── chip.xcf │ ├── logistics3.blend │ ├── logistics4-v2.blend │ ├── logistics4.blend │ ├── logistics4.blend1 │ └── mcmod.info ├── run/ │ └── .gitkeep ├── run-server/ │ └── .gitkeep ├── settings.gradle ├── src/ │ ├── api/ │ │ ├── java/ │ │ │ └── network/ │ │ │ └── rs485/ │ │ │ └── debug/ │ │ │ └── api/ │ │ │ ├── IDataConnection.java │ │ │ ├── IDebugGuiEntry.java │ │ │ └── IObjectIdentification.java │ │ └── kotlin/ │ │ └── network/ │ │ └── rs485/ │ │ └── logisticspipes/ │ │ ├── IStore.kt │ │ ├── connection/ │ │ │ ├── Adjacent.kt │ │ │ ├── ConnectionType.kt │ │ │ └── NeighborTileEntity.kt │ │ ├── gui/ │ │ │ ├── Constraints.kt │ │ │ ├── Dsl.kt │ │ │ └── SwingStuff.kt │ │ ├── pipes/ │ │ │ └── IChassisPipe.kt │ │ ├── property/ │ │ │ ├── BitSetProperty.kt │ │ │ ├── BooleanProperty.kt │ │ │ ├── EnumProperty.kt │ │ │ ├── IntegerProperty.kt │ │ │ ├── InventoryProperty.kt │ │ │ ├── ListProperty.kt │ │ │ ├── NullableEnumProperty.kt │ │ │ ├── Property.kt │ │ │ ├── PropertyHolder.kt │ │ │ ├── UUIDProperty.kt │ │ │ ├── Util.kt │ │ │ ├── ValueProperty.kt │ │ │ └── layer/ │ │ │ ├── PropertyLayer.kt │ │ │ ├── PropertyLayerInventoryAdapter.kt │ │ │ ├── PropertyOverlay.kt │ │ │ ├── SimplePropertyOverlay.kt │ │ │ └── ValuePropertyOverlay.kt │ │ └── util/ │ │ └── Rectangle.kt │ ├── main/ │ │ ├── java/ │ │ │ └── network/ │ │ │ └── rs485/ │ │ │ └── logisticspipes/ │ │ │ ├── network/ │ │ │ │ └── packets/ │ │ │ │ └── SetCurrentPagePacket.java │ │ │ ├── proxy/ │ │ │ │ └── mcmp/ │ │ │ │ ├── BlockAccessDelegate.java │ │ │ │ ├── IMCMPProxy.java │ │ │ │ ├── MCMPProxy.java │ │ │ │ └── subproxy/ │ │ │ │ ├── IMCMPBlockAccess.java │ │ │ │ ├── IMCMPLTGPCompanion.java │ │ │ │ ├── LPTileMultipartContainer.java │ │ │ │ ├── MCMPBlockAccess.java │ │ │ │ ├── MCMPLTGPCompanion.java │ │ │ │ └── MCMPMultipartContainerProvider.java │ │ │ ├── util/ │ │ │ │ ├── LPDataIOWrapper.java │ │ │ │ ├── LPDataInput.java │ │ │ │ ├── LPDataOutput.java │ │ │ │ ├── LPFinalSerializable.java │ │ │ │ ├── LPSerializable.java │ │ │ │ └── items/ │ │ │ │ └── ItemStackLoader.java │ │ │ └── world/ │ │ │ ├── CoordinateUtils.java │ │ │ ├── DoubleCoordinates.java │ │ │ ├── DoubleCoordinatesType.java │ │ │ └── ICoordinates.java │ │ └── kotlin/ │ │ ├── logisticspipes/ │ │ │ ├── pipes/ │ │ │ │ ├── PipeFluidBasic.kt │ │ │ │ ├── PipeFluidTerminus.kt │ │ │ │ └── PipeFluidUtil.kt │ │ │ └── routing/ │ │ │ └── AsyncRouting.kt │ │ └── network/ │ │ └── rs485/ │ │ ├── debug/ │ │ │ ├── OpenGLDebugger.kt │ │ │ └── PerformanceMeter.kt │ │ ├── grow/ │ │ │ ├── ChunkedChannel.kt │ │ │ ├── Coroutines.kt │ │ │ └── ServerTickDispatcher.kt │ │ ├── logisticspipes/ │ │ │ ├── FluidSinkPipe.kt │ │ │ ├── SatellitePipe.kt │ │ │ ├── compat/ │ │ │ │ ├── BarrelInventoryHandler.kt │ │ │ │ ├── JEIAdvancedGuiHandler.kt │ │ │ │ ├── JEIGhostIngredientHandler.kt │ │ │ │ └── TheOneProbeIntegration.kt │ │ │ ├── config/ │ │ │ │ ├── ClientConfiguration.kt │ │ │ │ ├── PlayerConfiguration.kt │ │ │ │ ├── ServerConfiguration.kt │ │ │ │ └── ServerConfigurationManager.kt │ │ │ ├── connection/ │ │ │ │ ├── AdjacentFactory.kt │ │ │ │ ├── AdjacentUtil.kt │ │ │ │ ├── DynamicAdjacent.kt │ │ │ │ ├── LPNeighborTileEntity.kt │ │ │ │ ├── LPNeighborTileEntitySneakyInsertion.kt │ │ │ │ ├── NoAdjacent.kt │ │ │ │ ├── PipeInventoryConnectionChecker.kt │ │ │ │ └── SingleAdjacent.kt │ │ │ ├── gui/ │ │ │ │ ├── BaseGuiContainer.kt │ │ │ │ ├── BaseGuiScreen.kt │ │ │ │ ├── DslExtension.kt │ │ │ │ ├── GuiDrawer.kt │ │ │ │ ├── GuiRenderer.kt │ │ │ │ ├── WidgetContainer.kt │ │ │ │ ├── WidgetScreen.kt │ │ │ │ ├── font/ │ │ │ │ │ ├── BDF.kt │ │ │ │ │ ├── FontParser.kt │ │ │ │ │ ├── FontWrapper.kt │ │ │ │ │ ├── IFont.kt │ │ │ │ │ └── LPFontRenderer.kt │ │ │ │ ├── guidebook/ │ │ │ │ │ ├── BookmarkManagingButton.kt │ │ │ │ │ ├── Drawable.kt │ │ │ │ │ ├── DrawableHeaderParagraph.kt │ │ │ │ │ ├── DrawableHorizontalLine.kt │ │ │ │ │ ├── DrawableImageParagraph.kt │ │ │ │ │ ├── DrawableMenuParagraph.kt │ │ │ │ │ ├── DrawablePage.kt │ │ │ │ │ ├── DrawablePageFactory.kt │ │ │ │ │ ├── DrawableParagraph.kt │ │ │ │ │ ├── DrawableRegularParagraph.kt │ │ │ │ │ ├── DrawableWord.kt │ │ │ │ │ ├── GuiGuideBook.kt │ │ │ │ │ ├── HomeButton.kt │ │ │ │ │ ├── LPGuiButton.kt │ │ │ │ │ ├── LinkGroup.kt │ │ │ │ │ ├── Page.kt │ │ │ │ │ ├── SliderButton.kt │ │ │ │ │ └── TabButton.kt │ │ │ │ ├── module/ │ │ │ │ │ ├── ItemSinkGui.kt │ │ │ │ │ └── ProviderGui.kt │ │ │ │ └── widget/ │ │ │ │ ├── FuzzySelectionWidget.kt │ │ │ │ ├── GhostSlots.kt │ │ │ │ ├── LPGuiButton.kt │ │ │ │ ├── LPGuiWidget.kt │ │ │ │ ├── Label.kt │ │ │ │ ├── LabelWidget.kt │ │ │ │ ├── LockedSlot.kt │ │ │ │ ├── PlayerInventorySlotGroup.kt │ │ │ │ ├── SlotGroup.kt │ │ │ │ ├── TextButton.kt │ │ │ │ └── VerticalLabel.kt │ │ │ ├── guidebook/ │ │ │ │ ├── BookContents.kt │ │ │ │ ├── DebugPage.kt │ │ │ │ └── ItemGuideBook.kt │ │ │ ├── inventory/ │ │ │ │ ├── FuzzySlotAccess.kt │ │ │ │ ├── IItemIdentifierInventory.kt │ │ │ │ ├── ProviderMode.kt │ │ │ │ ├── SlotAccess.kt │ │ │ │ └── container/ │ │ │ │ ├── ItemSinkContainer.kt │ │ │ │ ├── LPBaseContainer.kt │ │ │ │ └── ProviderContainer.kt │ │ │ ├── logistics/ │ │ │ │ └── LogisticsManager.kt │ │ │ ├── module/ │ │ │ │ ├── AsyncAdvancedExtractor.kt │ │ │ │ ├── AsyncComputerQuicksort.kt │ │ │ │ ├── AsyncExtractorModule.kt │ │ │ │ ├── AsyncModule.kt │ │ │ │ ├── AsyncQuicksortModule.kt │ │ │ │ ├── Gui.kt │ │ │ │ ├── PipeServiceProviderUtil.kt │ │ │ │ ├── SimpleFilter.kt │ │ │ │ ├── SneakyDirection.kt │ │ │ │ └── Util.kt │ │ │ ├── property/ │ │ │ │ ├── AdjacentProperty.kt │ │ │ │ ├── ItemIdentifierInventoryProperty.kt │ │ │ │ ├── PropertyUpdater.kt │ │ │ │ ├── PropertyUpdaterEventListener.kt │ │ │ │ ├── SimpleInventoryProperty.kt │ │ │ │ ├── SlottedModule.kt │ │ │ │ ├── SlottedModuleListProperty.kt │ │ │ │ └── UpgradeManagerListProperty.kt │ │ │ ├── proxy/ │ │ │ │ ├── StorageDrawersProxy.kt │ │ │ │ └── StorageDrawersProxyImpl.kt │ │ │ ├── util/ │ │ │ │ ├── ColorUtil.kt │ │ │ │ ├── FuzzyUtil.kt │ │ │ │ ├── Item.kt │ │ │ │ ├── TextUtil.kt │ │ │ │ └── math/ │ │ │ │ ├── BorderedRectangle.kt │ │ │ │ └── MutableRectangle.kt │ │ │ └── world/ │ │ │ └── WorldCoordinatesWrapper.kt │ │ ├── markdown/ │ │ │ ├── Element.kt │ │ │ ├── MarkdownParser.kt │ │ │ └── Paragraph.kt │ │ └── util/ │ │ ├── ByteBufUtils.kt │ │ └── SystemUtil.kt │ └── test/ │ └── kotlin/ │ └── network/ │ └── rs485/ │ ├── logisticspipes/ │ │ ├── integration/ │ │ │ ├── CraftingTest.kt │ │ │ ├── LPTestBuilder.kt │ │ │ ├── MinecraftTest.kt │ │ │ ├── PipePlacer.kt │ │ │ ├── TestWorldBuilder.kt │ │ │ └── UnroutedPipePlacer.kt │ │ └── util/ │ │ ├── LPDataIOWrapperTest.kt │ │ └── TestUtil.kt │ ├── markdown/ │ │ └── MarkdownParserTest.kt │ └── minecraft/ │ ├── BlockPlacer.kt │ ├── BlockPosSelector.kt │ └── WorldBuilder.kt └── style/ └── LP_Format_IntelliJ.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] end_of_line = lf insert_final_newline = true [*.gradle] indent_size = 4 indent_style = space [*.yml] indent_size = 2 indent_style = space [common/**.java] indent_size = 4 indent_style = tab ij_java_imports_layout = java.**,javax.**,|,net.minecraft.**,|,net.minecraftforge.**,|,*,|,logisticspipes.**,network.rs485.** [src/**.java] indent_size = 4 indent_style = space ij_java_imports_layout = java.**,javax.**,|,net.minecraft.**,|,net.minecraftforge.**,|,*,|,logisticspipes.**,network.rs485.** [*.{kt,kts}] indent_size = 4 indent_style = space max_line_length = 120 ktlint_code_style = official ktlint_disabled_rules = no-wildcard-imports ij_kotlin_name_count_to_use_star_import = 5 ij_kotlin_name_count_to_use_star_import_for_members = 3 ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** ij_kotlin_imports_layout = network.rs485.**,logisticspipes.**,*,net.minecraftforge.**,net.minecraft.**,java.**,javax.**,kotlin.**,kotlinx.**,^ ij_kotlin_allow_trailing_comma = true ij_kotlin_allow_trailing_comma_on_call_site = true ================================================ FILE: .gitattributes ================================================ *.bat text eol=crlf *.bdf binary *.jar filter=lfs diff=lfs merge=lfs -text ================================================ FILE: .gitignore ================================================ # IDEA project output path /classes /logs # IDEA run configurations .idea/runConfigurations # Created by https://www.gitignore.io/api/java,gradle,kotlin,forgegradle,intellij+iml # Edit at https://www.gitignore.io/?templates=java,gradle,kotlin,forgegradle,intellij+iml ### ForgeGradle ### # Minecraft client/server files run/* run-server/* run-server-test/* !run/.gitkeep !run-server/.gitkeep ### Intellij+iml ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf .idea/**/vcs.xml # Generated files .idea/**/contentModel.xml # Sensitive or high-churn files .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/dbnavigator.xml # Gradle .idea/**/gradle.xml .idea/**/libraries # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. # .idea/artifacts .idea/compiler.xml .idea/jarRepositories.xml # .idea/modules.xml # .idea/*.iml # .idea/modules # *.iml # *.ipr # File-based project format *.iws # IntelliJ out/ ### Intellij+iml Patch ### # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 *.iml modules.xml .idea/misc.xml *.ipr ### Java ### # Compiled class file *.class # Log file *.log # BlueJ files *.ctxt # Mobile Tools for Java (J2ME) .mtj.tmp/ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* replay_pid* ### Gradle ### .gradle **/build/ !src/**/build/ # Ignore Gradle GUI config gradle-app.setting # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar # Avoid ignore Gradle wrappper properties !gradle-wrapper.properties # Cache of project .gradletasknamecache # Eclipse Gradle plugin generated files # Eclipse Core .project # JDT-specific (Eclipse Java Development Tools) .classpath ### Gradle Patch ### # Java heap dump *.hprof # End of https://www.gitignore.io/api/java,gradle,kotlin,forgegradle,intellij+iml ================================================ FILE: .idea/.name ================================================ LogisticsPipes ================================================ FILE: .idea/codeInsightSettings.xml ================================================ scala ================================================ FILE: .idea/codeStyles/Project.xml ================================================ ================================================ FILE: .idea/codeStyles/codeStyleConfig.xml ================================================ ================================================ FILE: .idea/copyright/RS485_Dual_MIT_MMPL.xml ================================================ ================================================ FILE: .idea/copyright/profiles_settings.xml ================================================ ================================================ FILE: .idea/encodings.xml ================================================ ================================================ FILE: .idea/externalAnnotations/net/minecraft/block/state/annotations.xml ================================================ ================================================ FILE: .idea/externalAnnotations/net/minecraft/client/gui/inventory/annotations.xml ================================================ ================================================ FILE: .idea/externalAnnotations/net/minecraft/item/annotations.xml ================================================ ================================================ FILE: .idea/externalAnnotations/net/minecraft/world/annotations.xml ================================================ ================================================ FILE: .idea/inspectionProfiles/Project_Default.xml ================================================ ================================================ FILE: .idea/kotlinc.xml ================================================ ================================================ FILE: .idea/libraries-with-intellij-classes.xml ================================================ ================================================ FILE: .idea/scopes/network_rs485_package.xml ================================================ ================================================ FILE: .travis.yml ================================================ language: java jobs: include: - stage: build name: "Build and install" script: ./gradlew install -xtest - stage: test name: "Unit tests" script: ./gradlew check - stage: test name: "Integration tests" script: ./gradlew -P acceptMinecraftServerEula=true integrationTests jdk: - openjdk8 before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ cache: directories: - build/fg_cache - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ ================================================ FILE: BUILDING.md ================================================ # Building Logistics Pipes If you are familiar with Minecraft Forge and Gradle or you are a Java developer you should not have many problems starting with Logistics Pipes and your IDE. But we have some required steps that you need to follow to make things work. ## Prerequisites 1. Having [git](http://git-scm.com/) and git-lfs installed 2. Having an IDE (we do use [IntelliJ IDEA](https://www.jetbrains.com/idea/)) 3. Having Java Development Kit 8; newer versions are not supported by this Minecraft or Minecraft Forge version. 4. Matrix/Discord wouldn't be bad if you want to communicate with other contributors and us. ## Matrix [Logistics Pipes Space](https://matrix.to/#/#logisticspipes+space:rs485.network) - [Dev Channel](https://matrix.to/#/#logisticspipes+dev:rs485.network) The channels are all linked to Discord and some even to IRC. ## How to set up a local development environment ### git First off you need to clone Logistics Pipes from GitHub of course. If you only want to browse the source, you can clone the official repository. But it is best practice to actually fork the repository and clone your own copy. The git command line is `git clone https://github.com/RS485/LogisticsPipes.git` where you can replace *RS485* by your own user name, **if** you forked the repository. ### git-lfs If you didn't have git-lfs installed at the time of cloning the git repository, jar files are "broken", because lfs did not download and replace them. You can manually run the following commands to fix the situation peacefully: ```shell $ git lfs install $ git lfs fetch $ git lfs checkout ``` ### Gradle Make sure you are running Gradle with Java 8: You can check the default java version with `java -version` and control the version Gradle uses with the `JAVA_HOME` environment variable. LP can be built with `./gradlew build` and the output found in the directory `build/libs`. If the task fails there may be something wrong with maven repositories or [a Java update broke ForgeGradle 2](https://github.com/MinecraftForge/ForgeGradle/issues/652) or something may be wrong with your setup. You may definitely ask for help on the mentioned communication channels above, but please be sure to state your issue as good as possible and be nice to others. ### IDEA Quirks For IDEA to use the correct Java SDK, you might have to select the correct JDK (Java JDK 8, OpenJDK build preferred) in `File > Project Structure` in the project part of the project settings under SDK. ### Running Minecraft from your dev environment After you successfully built LP you can probably run Minecraft directly from your IDE after running the correct ForgeGradle generate run configuration task. Please look at ForgeGradle documentation for more information. If you are not using IntelliJ IDEA, there may be a ton of missing texture errors and missing language files. The cause is newer ForgeGradle versions. Our ForgeGradle version and our build script contain fixes for IntelliJ IDEA only; sorry if you are not using IDEA. The solution is to remove `build/classes/*/*` and `build/resources/*` from the run configuration classpath and add the custom `build/run_classes` path to the classpath. We are open for any contributions for a better solution or wider support. The workaround is to copy your `build/resources/main/*` into `build/classes/java/main` before launching the game, or you may link those two together (Linux or WSL): ```shell $ rm -r build/resources/main && ln -s ../classes/java/main build/resources/main ``` Windows `cmd`: ``` rd /s /q "build\\resources\\main" && mklink /D "build\\resources\\main" "..\\classes\\java\\main" ``` ================================================ FILE: LICENSE.md ================================================ Minecraft Mod Public License ============================ Version 1.0.1 0. Definitions -------------- Minecraft: Denotes a copy of the Minecraft game licensed by Mojang AB User: Anybody that interacts with the software in one of the following ways: - play - decompile - recompile or compile - modify - distribute Mod: The mod code designated by the present license, in source form, binary form, as obtained standalone, as part of a wider distribution or resulting from the compilation of the original or modified sources. Dependency: Code required for the mod to work properly. This includes dependencies required to compile the code as well as any file or modification that is explicitely or implicitely required for the mod to be working. 1. Scope -------- The present license is granted to any user of the mod. As a prerequisite, a user must own a legally acquired copy of Minecraft 2. Liability ------------ This mod is provided 'as is' with no warranties, implied or otherwise. The owner of this mod takes no responsibility for any damages incurred from the use of this mod. This mod alters fundamental parts of the Minecraft game, parts of Minecraft may not work with this mod installed. All damages caused from the use or misuse of this mad fall on the user. 3. Play rights -------------- The user is allowed to install this mod on a client or a server and to play without restriction. 4. Modification rights ---------------------- The user has the right to decompile the source code, look at either the decompiled version or the original source code, and to modify it. 5. Derivation rights -------------------- The user has the rights to derive code from this mod, that is to say to write code that extends or instanciate the mod classes or interfaces, refer to its objects, or calls its functions. This code is known as "derived" code, and can be licensed under a license different from this mod. 6. Distribution of original or modified copy rights --------------------------------------------------- Is subject to distribution rights this entire mod in its various forms. This include: - original binary or source forms of this mod files - modified versions of these binaries or source files, as well as binaries resulting from source modifications - patch to its source or binary files - any copy of a portion of its binary source files The user is allowed to redistribute this mod partially, in totality, or included in a distribution. When distributing binary files, the user must provide means to obtain its entire set of sources or modified sources at no costs. All distributions of this mod must remain licensed under the MMPL. All dependencies that this mod have on other mods or classes must be licensed under conditions comparable to this version of MMPL, with the exception of the Minecraft code and the mod loading framework (e.g. ModLoader, ModLoaderMP or Bukkit). Modified version of binaries and sources, as well as files containing sections copied from this mod, should be distributed under the terms of the present license. ================================================ FILE: README.md ================================================ # LogisticsPipes [![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.rs485.network%2Fview%2Fall%2Fjob%2FLogisticsPipes-0.10-mc112)](https://ci.rs485.network/) ![Lines of Code](https://tokei.rs/b1/github/RS485/LogisticsPipes?category=code) Logistics Pipes is an extensive overhaul of the Buildcraft pipe system. It allows for better distribution of items via pipes, more organised stockkeeping and easier automated crafting. Go to the [CurseForge Page](https://www.curseforge.com/minecraft/mc-mods/logistics-pipes) for more information and recent downloads. We advise anyone who is not a developer to go there. You are free to use this mod in your modpack without asking or noticing us. If you want to understand the sheer amount of changes we have made to the source, you can use [Gource](http://gource.io/) Credits for the code goes to all [contributors](https://github.com/RS485/LogisticsPipes/contributors). Credits for the idea and basic code goes to Krapht. ## Translate See [this repo](https://github.com/RS485/LogisticsPipes-Language) for translations. ## Builds See our [Jenkins](https://ci.rs485.network/). Our jar certificate fingerprint is `e0c86912b2f7cc0cc646ad57799574aea43dbd45`. Our GPG key id is `C4E5 0DBF CE49 AC33 E052 B591 2669 A04F D19F 2F7A` and we sign our jars with the subkey `386B 2790 B001 3BF8 1ED2 2D81 0119 F8E9 56C4 E048`. ## Contact Get in touch with us on [Matrix](https://matrix.to/#/#lp:rs485.network) or the [RS485 Discord](https://discord.gg/6vPP3A8) ================================================ FILE: build.gradle ================================================ buildscript { repositories { mavenCentral() maven { url = "https://maven.removeco.de/" } } dependencies { classpath group: 'network.rs485.forge', name: 'ForgeGradle', version: forgegradle_version } } plugins { id 'java' id 'maven-publish' id 'org.jetbrains.kotlin.jvm' version "$kotlin_version" id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version" id 'org.jetbrains.kotlin.plugin.lombok' version "$kotlin_version" id 'io.freefair.lombok' version "$lombok_plugin_version" id 'signing' id 'com.matthewprenger.cursegradle' version "$cursegradle_version" id 'com.github.johnrengelman.shadow' version "$shadow_version" } apply plugin: 'network.rs485.forge' archivesBaseName = "logisticspipes" group = "network.rs485" version = "0.10.4" ext.vendor = "unknown" ext.target = "Forge $forge_version" java.toolchain.languageVersion = JavaLanguageVersion.of(8) println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" def ENV = System.getenv() if (ENV.BUILD_NUMBER) { version = "$version.${ENV.BUILD_NUMBER}" } else if (ENV.VERSION) { version = "$version.${ENV.VERSION}" } else { version = "$version-SNAPSHOT" } if (ENV.JENKINS_URL) { ext.vendor = ENV.JENKINS_URL } else if (ENV.JITPACK) { ext.vendor = "JitPack.io" group = ENV.GROUP } ext.sharedManifest = manifest { attributes( 'FMLCorePlugin': 'logisticspipes.asm.LogisticsPipesCoreLoader', 'FMLCorePluginContainsFMLMod': 'true', 'FMLAT': 'lp_at.cfg', 'Specification-Title': 'LogisticsPipes', 'Specification-Vendor': 'RS485', 'Specification-Version': '1', 'Implementation-Vendor': "$vendor", 'Implementation-Title': "${project.name}", 'Implementation-Version': "$version", 'Implementation-Target': "$target", 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")) } sourceSets { api { java { srcDirs = ['src/api/java'] } } dummy { java { srcDirs = ['dummy/src/main/java'] } } main { compileClasspath += dummy.output compileClasspath += api.output runtimeClasspath += api.output java { srcDirs += 'common' } resources { srcDirs += 'resources' } } test { compileClasspath += dummy.output compileClasspath += api.output runtimeClasspath += api.output } } configurations { testCompileOnly.extendsFrom compileOnly ktlint } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { languageVersion = "1.7" jvmTarget = JavaVersion.VERSION_1_8 freeCompilerArgs += "-Xjvm-default=all" } } kotlinLombok { lombokConfigurationFile file("lombok.config") } project.afterEvaluate { tasks.register('copyRunClasses', Copy.class) { dependsOn ['classes'] from sourceSets.main.output.classesDirs, sourceSets.main.output.resourcesDir, sourceSets.api.output.classesDirs into "${project.buildDir}/run_classes/" duplicatesStrategy = DuplicatesStrategy.EXCLUDE includeEmptyDirs false } tasks['prepareRuns'].dependsOn('copyRunClasses') } minecraft { mappings channel: 'snapshot', version: "$mappings_version" accessTransformer = file("$rootDir/resources/META-INF/lp_at.cfg") runs { client { workingDirectory project.file('run') // Recommended logging data for a userdev environment property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' // Recommended logging level for the console property 'forge.logging.console.level', 'debug' // load LP core mod from classpath property 'fml.coreMods.load', 'logisticspipes.asm.LogisticsPipesCoreLoader' jvmArgs '-ea' environment 'MC_VERSION', mcversion lazyToken 'classpathExclude', { def paths = [ sourceSets.main.output.resourcesDir.toPath().toString(), sourceSets.api.output.resourcesDir.toPath().toString(), ] for (final def file in sourceSets.main.output.classesDirs.getFiles()) { paths.add(file.toPath().toString()) } for (final def file in sourceSets.api.output.classesDirs.getFiles()) { paths.add(file.toPath().toString()) } String.join(File.pathSeparator, paths) } lazyToken 'classpathInclude', { def paths = [project.buildDir.toPath().resolve("run_classes").toString()] String.join(File.pathSeparator, paths) } mods { logisticspipes { sources = [sourceSets.api, sourceSets.main] } } } server { workingDirectory project.file('run-server') // Recommended logging data for a userdev environment property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' // Recommended logging level for the console property 'forge.logging.console.level', 'debug' // load LP core mod from classpath property 'fml.coreMods.load', 'logisticspipes.asm.LogisticsPipesCoreLoader' jvmArgs '-ea' environment 'MC_VERSION', mcversion lazyToken 'classpathExclude', { def paths = [ sourceSets.main.output.classesDirs.asPath, sourceSets.api.output.classesDirs.asPath, sourceSets.main.output.resourcesDir.path, sourceSets.api.output.resourcesDir.path, ] String.join(File.pathSeparator, paths) } lazyToken 'classpathInclude', { def paths = ["${project.buildDir}/run_classes/"] String.join(File.pathSeparator, paths) } mods { logisticspipes { sources = [sourceSets.api, sourceSets.main] } } } serverTest { environment 'target', 'server' // mimic the runServer task environment 'mainClass', 'net.minecraft.launchwrapper.Launch' environment 'MCP_TO_SRG', "$buildDir/createSrgToMcp/output.srg" environment 'MC_VERSION', mcversion main 'net.minecraftforge.legacydev.MainServer' args '--tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker' arg 'nogui' // without GUI jvmArg '-ea' workingDirectory project.file('run-server-test') // load LP core mod from classpath property 'fml.coreMods.load', 'logisticspipes.asm.LogisticsPipesCoreLoader' // put LP in test mode property 'logisticspipes.test', 'true' property 'logisticspipes.test.debug', 'false' // set this to true in the generated run configuration lazyToken 'classpathExclude', { def paths = [ sourceSets.main.output.classesDirs.asPath, sourceSets.api.output.classesDirs.asPath, sourceSets.main.output.resourcesDir.path, sourceSets.api.output.resourcesDir.path, ] String.join(File.pathSeparator, paths) } lazyToken 'classpathInclude', { def paths = [ "${project.buildDir}/run_classes/", sourceSets.test.output.classesDirs.asPath, sourceSets.test.output.resourcesDir.path, ] // sorry for the mess in the run configuration's classpath, // but using the test classpath included the dependencies from the provided scope for (final def file in configurations.testRuntimeClasspath.resolvedConfiguration.files) { paths.add(file.toPath().toString()) } String.join(File.pathSeparator, paths) } mods { logisticspipes { sources = [sourceSets.api, sourceSets.main, sourceSets.test] } } } } } jar { from sourceSets.api.output finalizedBy 'shadowJar' duplicatesStrategy = DuplicatesStrategy.WARN manifest = project.manifest { from sharedManifest } } shadowJar { from sourceSets.api.output finalizedBy 'reobfJar' archiveClassifier.set('') dependencies { include(dependency(group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: kotlin_version)) include(dependency(group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version)) include(dependency(group: 'org.jetbrains', name: 'annotations', version: kannotations_version)) include(dependency(group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core-jvm', version: kcoroutines_version)) include(dependency(group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-jdk8', version: kcoroutines_version)) include(dependency(group: 'org.jetbrains.kotlinx', name: 'kotlinx-serialization-json-jvm', version: kserialization_version)) include(dependency(group: 'org.jetbrains.kotlinx', name: 'kotlinx-serialization-core-jvm', version: kserialization_version)) include(dependency(group: 'com.charleskorn.kaml', name: 'kaml-jvm', version: kaml_version)) include(dependency(group: 'org.snakeyaml', name: 'snakeyaml-engine', version: '2.3')) } relocate 'kotlin', 'logisticspipes.kotlin' relocate 'kotlinx', 'logisticspipes.kotlinx' relocate 'org.intellij', 'logisticspipes.intellij' relocate 'org.jetbrains', 'logisticspipes.jetbrains' relocate 'org.snakeyaml', 'logisticspipes.snakeyaml' relocate 'com.charleskorn.kaml', 'logisticspipes.kaml' exclude 'META-INF/versions/9/*' exclude 'DebugProbesKt.bin' manifest { inheritFrom sharedManifest } } task sourceJar(type: Jar) { from sourceSets.api.allSource from sourceSets.main.allSource archiveClassifier.set('sources') } test { reports { html.required.set(true) } } processResources { // this will ensure that this task is redone when the versions change. inputs.property "version", project.version duplicatesStrategy = DuplicatesStrategy.FAIL // replace stuff in mcmod.info, nothing else from(project.file('resources_raw')) { include 'mcmod.info' // replace version and mcversion expand 'version': project.version, 'mcversion': mcversion } } repositories { mavenCentral() maven { url = "https://maven.removeco.de/" } } dependencies { minecraft group: 'net.minecraftforge', name: 'forge', version: forge_version apiImplementation group: 'net.minecraftforge', name: 'forge', version: forge_version dummyImplementation group: 'net.minecraftforge', name: 'forge', version: forge_version implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: kotlin_version implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version implementation group: 'org.jetbrains', name: 'annotations', version: kannotations_version implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: kcoroutines_version implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-jdk8', version: kcoroutines_version implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-serialization-json', version: kserialization_version implementation group: 'com.charleskorn.kaml', name: 'kaml', version: kaml_version implementation group: 'network.rs485', name: 'CodeChickenLib', version: '3.3.0.9', classifier: 'deobf' compileOnly group: 'mcjty.theoneprobe', name: 'TheOneProbe-1.12', version: '1.12-1.4.28-17', classifier: 'api' compileOnly group: 'mezz.jei', name: 'jei_1.12.2', version: '4.15.0.293' compileOnly group: 'MCMultiPart2', name: 'MCMultiPart', version: '2.5.4', classifier: 'deobf' compileOnly group: 'com.mod-buildcraft', name: 'buildcraft-all', version: '7.99.24.6', transitive: false compileOnly group: 'net.industrial-craft', name: 'industrialcraft-2', version: '2.8.170-ex112', classifier: 'api' compileOnly group: 'codechicken', name: 'NotEnoughItems', version: '1.12.2-2.4.3.245', classifier: 'deobf', transitive: false compileOnly group: 'codechicken', name: 'EnderStorage', version: '1.12.2-2.4.6.137', classifier: 'deobf', transitive: false compileOnly group: 'li.cil.oc', name: 'OpenComputers', version: 'MC1.12.2-1.7.5.205', classifier: 'api' compileOnly files('lib/appliedenergistics2-rv6-stable-7-api.jar') compileOnly group: 'cofh', name: 'CoFHCore', version: '1.12.2-4.6.3.27', classifier: 'deobf', transitive: false compileOnly group: 'cofh', name: 'RedstoneFlux', version: '1.12-2.1.0.7', classifier: 'deobf', transitive: false compileOnly group: 'cofh', name: 'CoFHWorld', version: '1.12.2-1.2.0.5', classifier: 'deobf', transitive: false compileOnly group: 'cofh', name: 'ThermalDynamics', version: '1.12.2-2.5.5.21', classifier: 'deobf', transitive: false compileOnly group: 'cofh', name: 'ThermalFoundation', version: '1.12.2-2.6.3.27', classifier: 'deobf', transitive: false compileOnly group: 'cofh', name: 'ThermalExpansion', version: '1.12.2-5.5.4.43', classifier: 'deobf', transitive: false compileOnly group: 'org.squiddev', name: 'cc-tweaked-1.12.2', version: '1.89.2', transitive: false compileOnly group: 'com.jaquadro.minecraft.storagedrawers', name: 'StorageDrawers', version: '1.12.2-5.4.2', transitive: false compileOnly group: 'pl.asie.charset', name: 'Charset', version: '0.5.6.6', classifier: 'api', transitive: false ktlint("com.pinterest:ktlint:0.47.1") { attributes { attribute(Bundling.BUNDLING_ATTRIBUTE, getObjects().named(Bundling, Bundling.EXTERNAL)) } } testImplementation 'org.jetbrains.kotlin:kotlin-test' testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5' testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' } import net.minecraftforge.gradle.userdev.MinecraftUserRepo import java.nio.file.Files final nonMinecraftConfigurations = configurations.findAll { conf -> conf != configurations.minecraft } if (!nonMinecraftConfigurations.empty) { final fgextension = project.getExtensions().findByName("minecraft") final mcrepo = new MinecraftUserRepo( /* project = */ project, /* group = */ 'net.minecraftforge', /* name = */ 'forge', /* version = */ "$forge_version", /* ats = */ fgextension.getAccessTransformers().getFrom().toList(), /* mapping = */ fgextension.getMappings().get(), ) nonMinecraftConfigurations.each { it.resolutionStrategy.dependencySubstitution { substitute module('net.minecraftforge:forge') using module(mcrepo.getDependencyString()) } } } task ktlint(type: JavaExec, group: "verification") { description = "Check Kotlin code style." classpath = configurations.ktlint mainClass.set("com.pinterest.ktlint.Main") args "**/*.kt" } //check.dependsOn ktlint // not enforced, ktlint is in trial mode clean { // this folder is created by dependency resolution and will be created before 'clean' runs, // resulting in missing minecraft sources etc. Set here: https://fckaf.de/voZ setDelete(project.fileTree("$buildDir") { exclude 'fg_cache' }) } tasks.withType(Test) { useJUnitPlatform() testLogging { events("passed", "skipped", "failed") } } task deobfJar(type: Jar) { from sourceSets.main.output from sourceSets.api.output archiveClassifier.set('deobf') duplicatesStrategy = DuplicatesStrategy.WARN manifest = project.manifest { from sharedManifest } } task apiJar(type: Jar, dependsOn: apiClasses) { from sourceSets.api.output from sourceSets.api.allSource archiveClassifier.set('api') duplicatesStrategy = DuplicatesStrategy.WARN } curseforge { apiKey = project.hasProperty('LogisticsPipes.curseForgeApiKey') ? project.findProperty("LogisticsPipes.curseForgeApiKey") : '0' project { id = "232838" changelog = project.hasProperty('changelog') ? project.findProperty('changelog') : '' releaseType = 'beta' relations { requiredDependency 'codechicken-lib-1-8' } mainArtifact(shadowJar) { displayName = "Logistics Pipes $project.version" } } } artifacts { archives apiJar archives shadowJar archives deobfJar archives sourceJar } task enableSigningTasks { doFirst { tasks.withType(Sign) { enabled = true } } } signing { useGpgCmd() sign apiJar sign shadowJar sign deobfJar sign sourceJar } task sign { dependsOn enableSigningTasks dependsOn(tasks.withType(Sign)) } tasks.withType(Sign) { // disable signing by default enabled = false mustRunAfter enableSigningTasks // sign all jars, except the source jar – it doesn't have classes ext.useJarsigner = (name.toLowerCase().endsWith("jar") && name != "signSourceJar") } gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph -> taskGraph.allTasks.each { Task task -> if (task instanceof Sign && task.useJarsigner) { task.doFirst { task.filesToSign.each { File file -> // see https://ant.apache.org/manual/Tasks/signjar.html for arguments // ForgeGradle also uses ant.signjar: https://fckaf.de/DCw println "$task – signing $file with ant.signjar" task.ant.signjar( jar: file, alias: "1", storetype: findProperty("LogisticsPipes.storetype"), keystore: findProperty("LogisticsPipes.keystore"), storepass: findProperty("LogisticsPipes.storepass"), verbose: "true", preservelastmodified: "true" ) } } } else if (task.name.startsWith('prepareRunServerTest')) { task.doFirst { final def serverTestHome = projectDir.toPath().resolve('run-server-test') if (findProperty("acceptMinecraftServerEula") == 'true') { def eulaFile = serverTestHome.resolve('eula.txt') Files.deleteIfExists(eulaFile) eulaFile.write('eula=true') } final serverProperties = serverTestHome.resolve('server.properties') def properties = new Properties() try { serverProperties.withReader {reader -> properties.load(reader) } } catch (IOException e) { println "Error reading $serverProperties" e.printStackTrace() } properties.setProperty('spawn-monsters', 'false') properties.setProperty('spawn-npcs', 'false') properties.setProperty('spawn-animals', 'false') properties.setProperty('generate-structures', 'false') properties.setProperty('online-mode', 'false') properties.setProperty('gamemode', '1') properties.setProperty('level-type', 'FLAT') properties.setProperty('generator-settings', '3;minecraft:bedrock,3*minecraft:stone,96*minecraft:sandstone;2;') properties.setProperty('motd', 'Logistics Pipes Test Server') //properties.setProperty('max-tick-time', '0') // for debugging the server try { serverProperties.withWriter {writer -> properties.store(writer, null) } } catch (IOException e) { println "Error reading $serverProperties" e.printStackTrace() } } } } } abstract class DownloadTask extends DefaultTask { @Input String url @OutputFile final RegularFileProperty outputFile = project.objects.fileProperty() @TaskAction void download() { ant.get(src: url, dest: outputFile.get().asFile) } } task downloadLanguage(type: DownloadTask) { url = "https://github.com/RS485/LogisticsPipes-Language/archive/master.zip" outputFile.set(layout.buildDirectory.file("language.zip")) } task languageMain(dependsOn: downloadLanguage, type: Copy) { from zipTree(downloadLanguage.outputFile) into "${sourceSets.main.getOutput().resourcesDir}/assets/logisticspipes/lang/" include "*/*.lang" includeEmptyDirs false eachFile { FileCopyDetails fcd -> fcd.relativePath = new RelativePath(!fcd.isDirectory(), fcd.relativePath.segments.drop(1)) } } task languageBook(dependsOn: downloadLanguage, type: Copy) { from zipTree(downloadLanguage.outputFile) into "${sourceSets.main.getOutput().resourcesDir}/assets/logisticspipes/book/" include "*/book/" includeEmptyDirs false eachFile { FileCopyDetails fcd -> fcd.relativePath = new RelativePath(!fcd.isDirectory(), fcd.relativePath.segments.drop(2)) } } task language(dependsOn: [languageMain, languageBook], type: Copy) { processResources.dependsOn language } tasks.named('wrapper') { gradleVersion = '7.5' distributionType = Wrapper.DistributionType.ALL } tasks.withType(AbstractArchiveTask) { preserveFileTimestamps = false reproducibleFileOrder = true } task integrationTests(dependsOn: ['prepareRunServerTest'], type: Exec) { workingDir projectDir commandLine "$projectDir/gradlew" args '--no-daemon', '--stacktrace', 'runServerTest' ignoreExitValue = true standardOutput = new ByteArrayOutputStream() errorOutput = standardOutput // redirect stderr to stdout doFirst { if (System.properties['os.name'].toLowerCase().contains('windows')) { commandLine = ["cmd", "/c", "$projectDir/gradlew.bat"] + args } } doLast { final output = standardOutput.toString() final start = output.indexOf('[STARTING LOGISTICSPIPES TESTS]') if (start == -1) throw new GradleException("Cannot find LP test start:\n${output}") final logStart = output.substring(0, start).lastIndexOf('\n') + 1 def testOutput = output.substring(logStart) final end = testOutput.indexOf('Attempting to read last messages from the daemon log') if (end != -1) { // remove double output from daemon log testOutput = testOutput.substring(0, end) } if (testOutput.contains('[FAILED]')) { throw new GradleException("Error in LP Tests:\n${testOutput}") } else { testOutput.eachLine { if (it.contains('[STARTING LOGISTICSPIPES TESTS]') || it.contains('[PASSED]') || it.contains('[SKIPPED]')) { println(it) } } } } } publishing { publications { mavenJava(MavenPublication) { artifact jar } } repositories { maven { url "file://${project.projectDir}/mcmodsrepo" } } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation } ================================================ FILE: common/logisticspipes/LPBlocks.java ================================================ package logisticspipes; import net.minecraftforge.fml.common.registry.GameRegistry; import logisticspipes.blocks.BlockDummy; import logisticspipes.blocks.LogisticsSolidBlock; import logisticspipes.pipes.basic.LogisticsBlockGenericPipe; import logisticspipes.pipes.basic.LogisticsBlockGenericSubMultiBlock; public class LPBlocks { // Logistics Blocks @GameRegistry.ObjectHolder("logisticspipes:solid_block") public static BlockDummy dummy; @GameRegistry.ObjectHolder("logisticspipes:frame") public static LogisticsSolidBlock frame; @GameRegistry.ObjectHolder("logisticspipes:power_junction") public static LogisticsSolidBlock powerJunction; @GameRegistry.ObjectHolder("logisticspipes:security_station") public static LogisticsSolidBlock securityStation; @GameRegistry.ObjectHolder("logisticspipes:crafting_table") public static LogisticsSolidBlock crafter; @GameRegistry.ObjectHolder("logisticspipes:crafting_table_fuzzy") public static LogisticsSolidBlock crafterFuzzy; @GameRegistry.ObjectHolder("logisticspipes:statistics_table") public static LogisticsSolidBlock statisticsTable; @GameRegistry.ObjectHolder("logisticspipes:power_provider_rf") public static LogisticsSolidBlock powerProviderRF; @GameRegistry.ObjectHolder("logisticspipes:power_provider_eu") public static LogisticsSolidBlock powerProviderEU; @GameRegistry.ObjectHolder("logisticspipes:power_provider_mj") public static LogisticsSolidBlock powerProviderMJ; @GameRegistry.ObjectHolder("logisticspipes:program_compiler") public static LogisticsSolidBlock programCompiler; @GameRegistry.ObjectHolder("logisticspipes:pipe") public static LogisticsBlockGenericPipe pipe; @GameRegistry.ObjectHolder("logisticspipes:sub_multiblock") public static LogisticsBlockGenericSubMultiBlock subMultiblock; } ================================================ FILE: common/logisticspipes/LPConstants.java ================================================ package logisticspipes; public class LPConstants { private LPConstants() {} public static final String LP_MOD_ID = "logisticspipes"; public static final float FACADE_THICKNESS = 2F / 16F; public static final float PIPE_NORMAL_SPEED = 0.01F; public static final float PIPE_MIN_POS = 0.1875F; public static final float PIPE_MAX_POS = 0.8125F; public static final float BC_PIPE_MIN_POS = 0.25F; public static final float BC_PIPE_MAX_POS = 0.75F; public static final String computerCraftModID = "computercraft"; public static final String openComputersModID = "opencomputers"; public static final String ic2ModID = "ic2"; public static final String bcSiliconModID = "buildcraftsilicon"; public static final String bcTransportModID = "buildcrafttransport"; public static final String thermalExpansionModID = "thermalexpansion"; public static final String enderCoreModID = "endercore"; public static final String neiModID = "notenoughitems"; public static final String thermalDynamicsModID = "thermaldynamics"; public static final String cclrenderModID = "cclrender"; public static final String ironChestModID = "ironchest"; public static final String cofhCoreModID = "cofhcore"; public static final String mcmpModID = "mcmultipart"; public static final String appliedenergisticsModID = "appliedenergistics2"; public static final String storagedrawersModID = "storagedrawers"; public static final String theOneProbeModID = "theoneprobe"; } ================================================ FILE: common/logisticspipes/LPItems.java ================================================ package logisticspipes; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import logisticspipes.items.ItemBlankModule; import logisticspipes.items.ItemDisk; import logisticspipes.items.ItemHUDArmor; import logisticspipes.items.ItemLogisticsChips; import logisticspipes.items.ItemLogisticsProgrammer; import logisticspipes.items.ItemPipeController; import logisticspipes.items.LogisticsBrokenItem; import logisticspipes.items.LogisticsFluidContainer; import logisticspipes.items.LogisticsItemCard; import logisticspipes.items.RemoteOrderer; import network.rs485.logisticspipes.guidebook.ItemGuideBook; public class LPItems { // Logistics Pipes @ObjectHolder("logisticspipes:pipe_transport_basic") public static Item pipeUnrouted; @ObjectHolder("logisticspipes:pipe_basic") public static Item pipeBasic; @ObjectHolder("logisticspipes:pipe_request") public static Item pipeRequest; @ObjectHolder("logisticspipes:pipe_request_mk2") public static Item pipeRequestMk2; @ObjectHolder("logisticspipes:pipe_provider") public static Item pipeProvider; @ObjectHolder("logisticspipes:pipe_crafting") public static Item pipeCrafting; @ObjectHolder("logisticspipes:pipe_satellite") public static Item pipeSatellite; @ObjectHolder("logisticspipes:pipe_supplier") public static Item pipeSupplier; @ObjectHolder("logisticspipes:pipe_chassis_mk1") public static Item pipeChassisMk1; @ObjectHolder("logisticspipes:pipe_chassis_mk2") public static Item pipeChassisMk2; @ObjectHolder("logisticspipes:pipe_chassis_mk3") public static Item pipeChassisMk3; @ObjectHolder("logisticspipes:pipe_chassis_mk4") public static Item pipeChassisMk4; @ObjectHolder("logisticspipes:pipe_chassis_mk5") public static Item pipeChassisMk5; @ObjectHolder("logisticspipes:pipe_inventory_system_connector") public static Item pipeInvSystemConnector; @ObjectHolder("logisticspipes:pipe_system_entrance") public static Item pipeSystemEntrance; @ObjectHolder("logisticspipes:pipe_system_destination") public static Item pipeSystemDestination; @ObjectHolder("logisticspipes:pipe_firewall") public static Item pipeFirewall; @ObjectHolder("logisticspipes:pipe_remote_orderer") public static Item pipeRemoteOrderer; @ObjectHolder("logisticspipes:pipe_request_table") public static Item requestTable; // Logistics Fluid Pipes @ObjectHolder("logisticspipes:pipe_fluid_basic") public static Item pipeFluidBasic; @ObjectHolder("logisticspipes:pipe_fluid_request") public static Item pipeFluidRequest; @ObjectHolder("logisticspipes:pipe_fluid_provider") public static Item pipeFluidProvider; @ObjectHolder("logisticspipes:pipe_fluid_satellite") public static Item pipeFluidSatellite; @ObjectHolder("logisticspipes:pipe_fluid_supplier") public static Item pipeFluidSupplier; @ObjectHolder("logisticspipes:pipe_fluid_supplier_mk2") public static Item pipeFluidSupplierMk2; @ObjectHolder("logisticspipes:pipe_fluid_insertion") public static Item pipeFluidInsertion; @ObjectHolder("logisticspipes:pipe_fluid_extractor") public static Item pipeFluidExtractor; @ObjectHolder("logisticspipes:pipe_fluid_terminus") public static Item pipeFluidTerminus; // Logistics Modules/Upgrades @ObjectHolder("logisticspipes:module_blank") public static ItemBlankModule blankModule; public static BiMap modules = HashBiMap.create(); public static BiMap upgrades = HashBiMap.create(); // Miscellaneous Items @ObjectHolder("logisticspipes:guide_book") public static ItemGuideBook itemGuideBook; @ObjectHolder("logisticspipes:remote_orderer") public static RemoteOrderer remoteOrderer; @ObjectHolder("logisticspipes:disk") public static ItemDisk disk; @ObjectHolder("logisticspipes:item_card") public static LogisticsItemCard itemCard; @ObjectHolder("logisticspipes:hud_glasses") public static ItemHUDArmor hudGlasses; @ObjectHolder("logisticspipes:fluid_container") public static LogisticsFluidContainer fluidContainer; @ObjectHolder("logisticspipes:pipe_controller") public static ItemPipeController pipeController; @ObjectHolder("logisticspipes:logistics_programmer") public static ItemLogisticsProgrammer logisticsProgrammer; @ObjectHolder("logisticspipes:chip_basic") public static ItemLogisticsChips chipBasic; @ObjectHolder("logisticspipes:chip_basic_raw") public static ItemLogisticsChips chipBasicRaw; @ObjectHolder("logisticspipes:chip_advanced") public static ItemLogisticsChips chipAdvanced; @ObjectHolder("logisticspipes:chip_advanced_raw") public static ItemLogisticsChips chipAdvancedRaw; @ObjectHolder("logisticspipes:chip_fpga") public static ItemLogisticsChips chipFPGA; @ObjectHolder("logisticspipes:chip_fpga_raw") public static ItemLogisticsChips chipFPGARaw; @ObjectHolder("logisticspipes:broken_item") public static LogisticsBrokenItem brokenItem; } ================================================ FILE: common/logisticspipes/LogisticsEventListener.java ================================================ package logisticspipes; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Queue; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityChest; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.ChunkWatchEvent.UnWatch; import net.minecraftforge.event.world.ChunkWatchEvent.Watch; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent; import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import logisticspipes.config.Configs; import logisticspipes.interfaces.IItemAdvancedExistance; import logisticspipes.network.PacketHandler; import logisticspipes.network.packets.PlayerConfigToClientPacket; import logisticspipes.network.packets.chassis.ChestGuiClosed; import logisticspipes.network.packets.chassis.ChestGuiOpened; import logisticspipes.network.packets.gui.GuiReopenPacket; import logisticspipes.pipes.PipeLogisticsChassis; import logisticspipes.pipes.basic.CoreRoutedPipe; import logisticspipes.pipes.basic.LogisticsTileGenericPipe; import logisticspipes.proxy.MainProxy; import logisticspipes.proxy.SimpleServiceLocator; import logisticspipes.renderer.GuiOverlay; import logisticspipes.renderer.LogisticsHUDRenderer; import logisticspipes.routing.ItemRoutingInformation; import logisticspipes.ticks.VersionChecker; import logisticspipes.utils.PlayerCollectionList; import logisticspipes.utils.PlayerIdentifier; import logisticspipes.utils.QuickSortChestMarkerStorage; import logisticspipes.utils.string.ChatColor; import network.rs485.logisticspipes.config.ClientConfiguration; import network.rs485.logisticspipes.config.PlayerConfiguration; import network.rs485.logisticspipes.connection.NeighborTileEntity; import network.rs485.logisticspipes.module.AsyncQuicksortModule; import network.rs485.logisticspipes.util.TextUtil; import network.rs485.logisticspipes.world.WorldCoordinatesWrapper; public class LogisticsEventListener { public static final WeakHashMap>> chestQuickSortConnection = new WeakHashMap<>(); public static Map watcherList = new ConcurrentHashMap<>(); @SubscribeEvent public void onEntitySpawn(EntityJoinWorldEvent event) { if (event != null && event.getEntity() instanceof EntityItem && event.getEntity().world != null && !event.getEntity().world.isRemote) { ItemStack stack = ((EntityItem) event.getEntity()).getItem(); //Get ItemStack if (!stack.isEmpty() && stack.getItem() instanceof IItemAdvancedExistance && !((IItemAdvancedExistance) stack.getItem()).canExistInWorld(stack)) { event.setCanceled(true); } if (stack.hasTagCompound()) { for (String key : Objects.requireNonNull(stack.getTagCompound(), "nbt for stack must be non-null").getKeySet()) { if (key.startsWith("logisticspipes:routingdata")) { ItemRoutingInformation info = ItemRoutingInformation.restoreFromNBT(stack.getTagCompound().getCompoundTag(key)); info.setItemTimedout(); ((EntityItem) event.getEntity()).setItem(info.getItem().getItem().makeNormalStack(stack.getCount())); break; } } } } } @SubscribeEvent public void onPlayerLeftClickBlock(final PlayerInteractEvent.LeftClickBlock event) { if (MainProxy.isServer(event.getEntityPlayer().world)) { final TileEntity tile = event.getEntityPlayer().world.getTileEntity(event.getPos()); if (tile instanceof LogisticsTileGenericPipe) { if (((LogisticsTileGenericPipe) tile).pipe instanceof CoreRoutedPipe) { if (!((CoreRoutedPipe) ((LogisticsTileGenericPipe) tile).pipe).canBeDestroyedByPlayer(event.getEntityPlayer())) { event.setCanceled(true); event.getEntityPlayer().sendMessage(new TextComponentTranslation("lp.chat.permissiondenied")); ((LogisticsTileGenericPipe) tile).scheduleNeighborChange(); World world = event.getEntityPlayer().world; BlockPos pos = tile.getPos(); IBlockState state = world.getBlockState(pos); world.markAndNotifyBlock(tile.getPos(), world.getChunk(pos), state, state, 2); ((CoreRoutedPipe) ((LogisticsTileGenericPipe) tile).pipe).delayTo = System.currentTimeMillis() + 200; ((CoreRoutedPipe) ((LogisticsTileGenericPipe) tile).pipe).repeatFor = 10; } else { ((CoreRoutedPipe) ((LogisticsTileGenericPipe) tile).pipe).setDestroyByPlayer(); } } } } } @SubscribeEvent public void onPlayerLeftClickBlock(final PlayerInteractEvent.RightClickBlock event) { if (MainProxy.isServer(event.getEntityPlayer().world)) { WorldCoordinatesWrapper worldCoordinates = new WorldCoordinatesWrapper(event.getEntityPlayer().world, event.getPos()); TileEntity tileEntity = worldCoordinates.getTileEntity(); if (tileEntity instanceof TileEntityChest || SimpleServiceLocator.ironChestProxy.isIronChest(tileEntity)) { List> list = worldCoordinates.allNeighborTileEntities().stream() .filter(NeighborTileEntity::isLogisticsPipe) .filter(adjacent -> ((LogisticsTileGenericPipe) adjacent.getTileEntity()).pipe instanceof PipeLogisticsChassis) .filter(adjacent -> ((PipeLogisticsChassis) ((LogisticsTileGenericPipe) adjacent.getTileEntity()).pipe).getPointedOrientation() == adjacent.getOurDirection()) .map(adjacent -> (PipeLogisticsChassis) ((LogisticsTileGenericPipe) adjacent.getTileEntity()).pipe) .flatMap(chassis -> chassis.getModules().getModules()) .filter(logisticsModule -> logisticsModule instanceof AsyncQuicksortModule) .map(logisticsModule -> new WeakReference<>((AsyncQuicksortModule) logisticsModule)) .collect(Collectors.toList()); if (!list.isEmpty()) { LogisticsEventListener.chestQuickSortConnection.put(event.getEntityPlayer(), list); } } } } public static HashMap WorldLoadTime = new HashMap<>(); @SubscribeEvent public void WorldLoad(WorldEvent.Load event) { if (MainProxy.isServer(event.getWorld())) { int dim = event.getWorld().provider.getDimension(); if (!LogisticsEventListener.WorldLoadTime.containsKey(dim)) { LogisticsEventListener.WorldLoadTime.put(dim, System.currentTimeMillis()); } } if (MainProxy.isClient(event.getWorld())) { SimpleServiceLocator.routerManager.clearClientRouters(); LogisticsHUDRenderer.instance().clear(); } } @SubscribeEvent public void WorldUnload(WorldEvent.Unload event) { if (MainProxy.isServer(event.getWorld())) { int dim = event.getWorld().provider.getDimension(); SimpleServiceLocator.routerManager.dimensionUnloaded(dim); } } @SubscribeEvent public void watchChunk(Watch event) { ChunkPos pos = event.getChunkInstance().getPos(); if (!LogisticsEventListener.watcherList.containsKey(pos)) { LogisticsEventListener.watcherList.put(pos, new PlayerCollectionList()); } LogisticsEventListener.watcherList.get(pos).add(event.getPlayer()); } @SubscribeEvent public void unWatchChunk(UnWatch event) { ChunkPos pos = event.getChunkInstance().getPos(); if (LogisticsEventListener.watcherList.containsKey(pos)) { LogisticsEventListener.watcherList.get(pos).remove(event.getPlayer()); } } @SubscribeEvent public void onPlayerLogin(PlayerLoggedInEvent event) { if (MainProxy.isServer(event.player.world)) { SimpleServiceLocator.securityStationManager.sendClientAuthorizationList(event.player); } SimpleServiceLocator.serverBufferHandler.clear(event.player); ClientConfiguration config = LogisticsPipes.getServerConfigManager().getPlayerConfiguration(PlayerIdentifier.get(event.player)); MainProxy.sendPacketToPlayer(PacketHandler.getPacket(PlayerConfigToClientPacket.class).setConfig(config), event.player); } @SubscribeEvent public void onPlayerLogout(PlayerLoggedOutEvent event) { SimpleServiceLocator.serverBufferHandler.clear(event.player); } @AllArgsConstructor private static class GuiEntry { @Getter private final int xCoord; @Getter private final int yCoord; @Getter private final int zCoord; @Getter private final int guiID; @Getter @Setter private boolean isActive; } @Getter(lazy = true) private static final Queue guiPos = new LinkedList<>(); //Handle GuiRepoen @SubscribeEvent @SideOnly(Side.CLIENT) public void onGuiOpen(GuiOpenEvent event) { if (!LogisticsEventListener.getGuiPos().isEmpty()) { if (event.getGui() == null) { GuiEntry part = LogisticsEventListener.getGuiPos().peek(); if (part.isActive()) { part = LogisticsEventListener.getGuiPos().poll(); MainProxy.sendPacketToServer(PacketHandler.getPacket(GuiReopenPacket.class).setGuiID(part.getGuiID()).setPosX(part.getXCoord()).setPosY(part.getYCoord()).setPosZ(part.getZCoord())); GuiOverlay.getInstance().setOverlaySlotActive(false); } } else { GuiEntry part = LogisticsEventListener.getGuiPos().peek(); part.setActive(true); } } if (event.getGui() == null) { GuiOverlay.getInstance().setOverlaySlotActive(false); } if (event.getGui() instanceof GuiChest || (SimpleServiceLocator.ironChestProxy != null && SimpleServiceLocator.ironChestProxy.isChestGui(event.getGui()))) { MainProxy.sendPacketToServer(PacketHandler.getPacket(ChestGuiOpened.class)); } else { QuickSortChestMarkerStorage.getInstance().disable(); MainProxy.sendPacketToServer(PacketHandler.getPacket(ChestGuiClosed.class)); } } @SideOnly(Side.CLIENT) public static void addGuiToReopen(int xCoord, int yCoord, int zCoord, int guiID) { LogisticsEventListener.getGuiPos().add(new GuiEntry(xCoord, yCoord, zCoord, guiID, false)); } @SubscribeEvent public void clientLoggedIn(ClientConnectedToServerEvent event) { SimpleServiceLocator.clientBufferHandler.clear(); if (Configs.CHECK_FOR_UPDATES) { LogisticsPipes.singleThreadExecutor.execute(() -> { // try to get player entity ten times, once a second int times = 0; EntityPlayerSP playerEntity; do { try { Thread.sleep(1000); } catch (InterruptedException e) { return; } playerEntity = FMLClientHandler.instance().getClientPlayerEntity(); ++times; } while (playerEntity == null && times <= 10); if (times > 10) { return; } VersionChecker checker = LogisticsPipes.versionChecker; // send player message String versionMessage = checker.getVersionCheckerStatus(); if (checker.isVersionCheckDone() && checker.getVersionInfo().isNewVersionAvailable() && !checker.getVersionInfo().isImcMessageSent()) { playerEntity.sendMessage(new TextComponentString(versionMessage)); playerEntity.sendMessage(new TextComponentString("Use \"/logisticspipes changelog\" to see a changelog.")); } else if (!checker.isVersionCheckDone()) { playerEntity.sendMessage(new TextComponentString(versionMessage)); } }); } } @SubscribeEvent @SideOnly(Side.CLIENT) public void onItemStackToolTip(ItemTooltipEvent event) { if (event.getItemStack().hasTagCompound()) { for (String key : event.getItemStack().getTagCompound().getKeySet()) { if (key.startsWith("logisticspipes:routingdata")) { ItemRoutingInformation info = ItemRoutingInformation.restoreFromNBT(event.getItemStack().getTagCompound().getCompoundTag(key)); List list = event.getToolTip(); list.set(0, ChatColor.RED + "!!! " + ChatColor.WHITE + list.get(0) + ChatColor.RED + " !!!" + ChatColor.WHITE); list.add(1, TextUtil.translate("itemstackinfo.lprouteditem")); list.add(2, TextUtil.translate("itemstackinfo.lproutediteminfo")); list.add(3, TextUtil.translate("itemstackinfo.lprouteditemtype") + ": " + info.getItem().toString()); } } } } @SubscribeEvent public void onItemCrafting(PlayerEvent.ItemCraftedEvent event) { if (event.player.isServerWorld() && !event.crafting.isEmpty()) { if (event.crafting.getItem().getRegistryName().getNamespace().equals(LPConstants.LP_MOD_ID)) { PlayerIdentifier identifier = PlayerIdentifier.get(event.player); PlayerConfiguration config = LogisticsPipes.getServerConfigManager().getPlayerConfiguration(identifier); if (!config.getHasCraftedLPItem() && !LogisticsPipes.isDEBUG()) { ItemStack book = new ItemStack(LPItems.itemGuideBook, 1); event.player.addItemStackToInventory(book); config.setHasCraftedLPItem(true); LogisticsPipes.getServerConfigManager().setPlayerConfiguration(identifier, config); } } } } } ================================================ FILE: common/logisticspipes/LogisticsPipes.java ================================================ /* * Copyright (c) Krapht, 2011 * "LogisticsPipes" is distributed under the terms of the Minecraft Mod Public * License 1.0, or MMPL. Please check the contents of the license located in * http://www.mod-buildcraft.com/MMPL-1.0.txt */ package logisticspipes; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Queue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nonnull; import net.minecraft.block.Block; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; import net.minecraft.launchwrapper.LaunchClassLoader; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLFingerprintViolationEvent; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLInterModComms; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.IForgeRegistry; import lombok.Getter; import lombok.SneakyThrows; import org.apache.logging.log4j.Logger; import logisticspipes.asm.LogisticsPipesClassInjector; import logisticspipes.asm.LogisticsPipesCoreLoader; import logisticspipes.asm.wrapper.LogisticsWrapperHandler; import logisticspipes.blocks.BlockDummy; import logisticspipes.blocks.LogisticsProgramCompilerTileEntity; import logisticspipes.blocks.LogisticsSecurityTileEntity; import logisticspipes.blocks.LogisticsSolidBlock; import logisticspipes.blocks.crafting.LogisticsCraftingTableTileEntity; import logisticspipes.blocks.powertile.LogisticsIC2PowerProviderTileEntity; import logisticspipes.blocks.powertile.LogisticsPowerJunctionTileEntity; import logisticspipes.blocks.powertile.LogisticsRFPowerProviderTileEntity; import logisticspipes.blocks.stats.LogisticsStatisticsTileEntity; import logisticspipes.commands.LogisticsPipesCommand; import logisticspipes.commands.chathelper.LPChatListener; import logisticspipes.config.Configs; import logisticspipes.datafixer.LPDataFixer; import logisticspipes.items.ItemBlankModule; import logisticspipes.items.ItemDisk; import logisticspipes.items.ItemHUDArmor; import logisticspipes.items.ItemLogisticsChips; import logisticspipes.items.ItemLogisticsPipe; import logisticspipes.items.ItemLogisticsProgrammer; import logisticspipes.items.ItemModule; import logisticspipes.items.ItemParts; import logisticspipes.items.ItemPipeController; import logisticspipes.items.ItemPipeManager; import logisticspipes.items.ItemPipeSignCreator; import logisticspipes.items.ItemUpgrade; import logisticspipes.items.LogisticsBrokenItem; import logisticspipes.items.LogisticsFluidContainer; import logisticspipes.items.LogisticsItemCard; import logisticspipes.items.LogisticsSolidBlockItem; import logisticspipes.items.RemoteOrderer; import logisticspipes.logistics.LogisticsFluidManager; import logisticspipes.logistics.LogisticsManager; import logisticspipes.network.GuiHandler; import logisticspipes.network.NewGuiHandler; import logisticspipes.network.PacketHandler; import logisticspipes.pipes.PipeBlockRequestTable; import logisticspipes.pipes.PipeFluidBasic; import logisticspipes.pipes.PipeFluidExtractor; import logisticspipes.pipes.PipeFluidInsertion; import logisticspipes.pipes.PipeFluidProvider; import logisticspipes.pipes.PipeFluidRequestLogistics; import logisticspipes.pipes.PipeFluidSatellite; import logisticspipes.pipes.PipeFluidSupplierMk2; import logisticspipes.pipes.PipeFluidTerminus; import logisticspipes.pipes.PipeItemsBasicLogistics; import logisticspipes.pipes.PipeItemsCraftingLogistics; import logisticspipes.pipes.PipeItemsFirewall; import logisticspipes.pipes.PipeItemsFluidSupplier; import logisticspipes.pipes.PipeItemsInvSysConnector; import logisticspipes.pipes.PipeItemsProviderLogistics; import logisticspipes.pipes.PipeItemsRemoteOrdererLogistics; import logisticspipes.pipes.PipeItemsRequestLogistics; import logisticspipes.pipes.PipeItemsRequestLogisticsMk2; import logisticspipes.pipes.PipeItemsSatelliteLogistics; import logisticspipes.pipes.PipeItemsSupplierLogistics; import logisticspipes.pipes.PipeItemsSystemDestinationLogistics; import logisticspipes.pipes.PipeItemsSystemEntranceLogistics; import logisticspipes.pipes.PipeLogisticsChassisMk1; import logisticspipes.pipes.PipeLogisticsChassisMk2; import logisticspipes.pipes.PipeLogisticsChassisMk3; import logisticspipes.pipes.PipeLogisticsChassisMk4; import logisticspipes.pipes.PipeLogisticsChassisMk5; import logisticspipes.pipes.basic.CoreRoutedPipe; import logisticspipes.pipes.basic.CoreUnroutedPipe; import logisticspipes.pipes.basic.LogisticsBlockGenericPipe; import logisticspipes.pipes.basic.LogisticsBlockGenericSubMultiBlock; import logisticspipes.pipes.basic.LogisticsTileGenericPipe; import logisticspipes.pipes.basic.LogisticsTileGenericSubMultiBlock; import logisticspipes.pipes.basic.fluid.FluidRoutedPipe; import logisticspipes.pipes.tubes.HSTubeCurve; import logisticspipes.pipes.tubes.HSTubeGain; import logisticspipes.pipes.tubes.HSTubeLine; import logisticspipes.pipes.tubes.HSTubeSCurve; import logisticspipes.pipes.tubes.HSTubeSpeedup; import logisticspipes.pipes.unrouted.PipeItemsBasicTransport; import logisticspipes.proxy.MainProxy; import logisticspipes.proxy.ProxyManager; import logisticspipes.proxy.SimpleServiceLocator; import logisticspipes.proxy.SpecialInventoryHandlerManager; import logisticspipes.proxy.SpecialTankHandlerManager; import logisticspipes.proxy.computers.objects.LPGlobalCCAccess; import logisticspipes.proxy.endercore.EnderCoreProgressProvider; import logisticspipes.proxy.ic2.IC2ProgressProvider; import logisticspipes.proxy.progressprovider.MachineProgressProvider; import logisticspipes.proxy.recipeproviders.LogisticsCraftingTable; import logisticspipes.proxy.specialconnection.SpecialPipeConnection; import logisticspipes.proxy.specialconnection.SpecialTileConnection; import logisticspipes.proxy.specialtankhandler.SpecialTankHandler; import logisticspipes.proxy.te.ThermalExpansionProgressProvider; import logisticspipes.recipes.CraftingRecipes; import logisticspipes.recipes.LPChipRecipes; import logisticspipes.recipes.ModuleChippedCraftingRecipes; import logisticspipes.recipes.PipeChippedCraftingRecipes; import logisticspipes.recipes.RecipeManager; import logisticspipes.recipes.UpgradeChippedCraftingRecipes; import logisticspipes.renderer.LogisticsHUDRenderer; import logisticspipes.renderer.newpipe.LogisticsNewRenderPipe; import logisticspipes.renderer.newpipe.LogisticsNewSolidBlockWorldRenderer; import logisticspipes.renderer.newpipe.tube.CurveTubeRenderer; import logisticspipes.renderer.newpipe.tube.GainTubeRenderer; import logisticspipes.renderer.newpipe.tube.LineTubeRenderer; import logisticspipes.renderer.newpipe.tube.SCurveTubeRenderer; import logisticspipes.renderer.newpipe.tube.SpeedupTubeRenderer; import logisticspipes.routing.RouterManager; import logisticspipes.routing.ServerRouter; import logisticspipes.routing.channels.ChannelManagerProvider; import logisticspipes.routing.pathfinder.PipeInformationManager; import logisticspipes.textures.Textures; import logisticspipes.ticks.ClientPacketBufferHandlerThread; import logisticspipes.ticks.HudUpdateTick; import logisticspipes.ticks.LPTickHandler; import logisticspipes.ticks.QueuedTasks; import logisticspipes.ticks.RenderTickHandler; import logisticspipes.ticks.RoutingTableUpdateThread; import logisticspipes.ticks.ServerPacketBufferHandlerThread; import logisticspipes.ticks.VersionChecker; import logisticspipes.utils.FluidIdentifier; import logisticspipes.utils.InventoryUtilFactory; import logisticspipes.utils.RoutedItemHelper; import logisticspipes.utils.StaticResolverUtil; import logisticspipes.utils.tuples.Pair; import network.rs485.grow.ServerTickDispatcher; import network.rs485.logisticspipes.compat.TheOneProbeIntegration; import network.rs485.logisticspipes.config.ClientConfiguration; import network.rs485.logisticspipes.config.ServerConfigurationManager; import network.rs485.logisticspipes.gui.font.LPFontRenderer; import network.rs485.logisticspipes.guidebook.ItemGuideBook; import network.rs485.logisticspipes.property.PropertyUpdaterEventListener; import network.rs485.util.SystemUtilKt; //@formatter:off //CHECKSTYLE:OFF @Mod( name = "Logistics Pipes", modid = LPConstants.LP_MOD_ID, certificateFingerprint = "e0c86912b2f7cc0cc646ad57799574aea43dbd45", useMetadata = true) public class LogisticsPipes { //@formatter:on //CHECKSTYLE:ON public static final String UNKNOWN = "unknown"; private static boolean DEBUG = true; private Consumer minecraftTestStartMethod = null; public static boolean isDEBUG() { return DEBUG; } @Getter private static String VERSION = UNKNOWN; @Getter private static String VENDOR = UNKNOWN; @Getter private static String TARGET = UNKNOWN; public LogisticsPipes() { //TODO: remove throws final LaunchClassLoader loader = Launch.classLoader; loadManifestValues(loader); if (!LogisticsPipesCoreLoader.isCoremodLoaded()) { if (LogisticsPipes.DEBUG) { throw new RuntimeException("LogisticsPipes FMLLoadingPlugin wasn't loaded. If you are running MC from an IDE make sure to add '-Dfml.coreMods.load=logisticspipes.asm.LogisticsPipesCoreLoader' to the VM arguments. If you are running MC normal please report this as a bug at 'https://github.com/RS485/LogisticsPipes/issues'."); } else { throw new RuntimeException("LogisticsPipes FMLLoadingPlugin wasn't loaded. Your download seems to be corrupt/modified. Please redownload LP from our Jenkins [http://ci.rs485.network] and move it into your mods folder."); } } try { Field fTransformers = LaunchClassLoader.class.getDeclaredField("transformers"); fTransformers.setAccessible(true); @SuppressWarnings("unchecked") List transformers = (List) fTransformers.get(loader); IClassTransformer lpClassInjector = new LogisticsPipesClassInjector(); transformers.add(lpClassInjector); // Avoid NPE caused by wrong ClassTransformers for (int i = transformers.size() - 1; i > 0; i--) { // Move everything one up transformers.set(i, transformers.get(i - 1)); } transformers.set(0, lpClassInjector); // So that our injector can be first } catch (NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException e) { loader.registerTransformer("logisticspipes.asm.LogisticsPipesClassInjector"); e.printStackTrace(); } MinecraftForge.EVENT_BUS.register(this); } private static void loadManifestValues(ClassLoader loader) { try { final Enumeration resources = loader.getResources(JarFile.MANIFEST_NAME); boolean foundLp; do { final Manifest manifest = new Manifest(resources.nextElement().openStream()); foundLp = "LogisticsPipes".equals(manifest.getMainAttributes().getValue("Specification-Title")); if (foundLp) { LogisticsPipes.DEBUG = false; LogisticsPipes.VERSION = manifest.getMainAttributes().getValue("Implementation-Version"); LogisticsPipes.VENDOR = manifest.getMainAttributes().getValue("Implementation-Vendor"); LogisticsPipes.TARGET = manifest.getMainAttributes().getValue("Implementation-Target"); } } while (resources.hasMoreElements() && !foundLp); } catch (IOException e) { LogisticsPipes.log.error("There was a problem loading our MANIFEST file, Logistics Pipes will not know about its origin"); } } @Mod.Instance("logisticspipes") public static LogisticsPipes instance; private static boolean certificateError = false; public static String getVersionString() { return Stream.of( "Logistics Pipes " + LogisticsPipes.VERSION, LogisticsPipes.certificateError ? "certificate error" : "", LogisticsPipes.DEBUG ? "debug mode" : "", "target " + LogisticsPipes.TARGET, "vendor " + LogisticsPipes.VENDOR) .filter(str -> !str.isEmpty()) .collect(Collectors.joining(", ")); } // other statics public static Textures textures = new Textures(); public static Logger log; public static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); public static VersionChecker versionChecker; // initializes the creative tab public static final CreativeTabs CREATIVE_TAB_LP = new CreativeTabs("Logistics_Pipes") { @SideOnly(Side.CLIENT) @Nonnull public ItemStack createIcon() { return new ItemStack(LPItems.pipeBasic); } }; private Queue postInitRun = new LinkedList<>(); private static LPGlobalCCAccess generalAccess; private static ClientConfiguration playerConfig; private static ServerConfigurationManager serverConfigManager; private List>> resetRecipeList = new ArrayList<>(); @CapabilityInject(IItemHandler.class) public static Capability ITEM_HANDLER_CAPABILITY = null; @CapabilityInject(IFluidHandler.class) public static Capability FLUID_HANDLER_CAPABILITY = null; public static boolean isDevelopmentEnvironment() { if (!isDEBUG()) { return false; } else { boolean eclipseCheck = (new File(".classpath")).exists(); boolean ideaCheck = System.getProperty("java.class.path").contains("idea_rt.jar"); return eclipseCheck || ideaCheck; } } @Mod.EventHandler public void init(FMLInitializationEvent event) { registerRecipes(); // TODO data fileS!!!!! //Register Network channels MainProxy.createChannels(); RouterManager manager = new RouterManager(); SimpleServiceLocator.setRouterManager(manager); SimpleServiceLocator.setChannelConnectionManager(manager); SimpleServiceLocator.setSecurityStationManager(manager); SimpleServiceLocator.setLogisticsManager(new LogisticsManager()); SimpleServiceLocator.setInventoryUtilFactory(new InventoryUtilFactory()); SimpleServiceLocator.setSpecialConnectionHandler(new SpecialPipeConnection()); SimpleServiceLocator.setSpecialConnectionHandler(new SpecialTileConnection()); SimpleServiceLocator.setSpecialTankHandler(new SpecialTankHandler()); SimpleServiceLocator.setMachineProgressProvider(new MachineProgressProvider()); SimpleServiceLocator.setRoutedItemHelper(new RoutedItemHelper()); SimpleServiceLocator.setChannelManagerProvider(new ChannelManagerProvider()); NetworkRegistry.INSTANCE.registerGuiHandler(LogisticsPipes.instance, new GuiHandler()); MinecraftForge.EVENT_BUS.register(new LPTickHandler()); if (event.getSide().equals(Side.CLIENT)) { RenderTickHandler sub = new RenderTickHandler(); MinecraftForge.EVENT_BUS.register(sub); } MinecraftForge.EVENT_BUS.register(new QueuedTasks()); if (event.getSide() == Side.CLIENT) { SimpleServiceLocator.setClientPacketBufferHandlerThread(new ClientPacketBufferHandlerThread()); } SimpleServiceLocator.setServerPacketBufferHandlerThread(new ServerPacketBufferHandlerThread()); for (int i = 0; i < Configs.MULTI_THREAD_NUMBER; i++) { new RoutingTableUpdateThread(i); } MinecraftForge.EVENT_BUS.register(new LogisticsEventListener()); MinecraftForge.EVENT_BUS.register(new LPChatListener()); MinecraftForge.EVENT_BUS.register(PropertyUpdaterEventListener.INSTANCE); LPDataFixer.INSTANCE.init(); if (event.getSide() == Side.SERVER) { LogisticsPipes.textures.registerBlockIcons(null); } else if (event.getSide() == Side.CLIENT) { LPFontRenderer.Factory.asyncPreload(); } // load all the models so they don't get loaded and crash on concurrent class loading // the OBJParser is a non-sharable static thing LogisticsNewRenderPipe.loadModels(); LogisticsNewSolidBlockWorldRenderer.loadModels(); CurveTubeRenderer.loadModels(); GainTubeRenderer.loadModels(); LineTubeRenderer.loadModels(); SpeedupTubeRenderer.loadModels(); SCurveTubeRenderer.loadModels(); if (isTesting()) { final Class testClass; try { testClass = Class.forName("network.rs485.logisticspipes.integration.MinecraftTest"); } catch (ReflectiveOperationException e) { throw new RuntimeException("Error loading minecraft test class", e); } final Object minecraftTestInstance; try { minecraftTestInstance = testClass.getDeclaredField("INSTANCE").get(null); final Method serverStartMethod = testClass .getDeclaredMethod("serverStart", FMLServerStartedEvent.class); minecraftTestStartMethod = (FMLServerStartedEvent serverStartedEvent) -> { try { serverStartMethod.invoke(minecraftTestInstance, serverStartedEvent); } catch (ReflectiveOperationException e) { throw new RuntimeException("Could not run server started hook in " + minecraftTestInstance, e); } }; } catch (ReflectiveOperationException e) { throw new RuntimeException("Error accessing minecraft test instance", e); } MinecraftForge.EVENT_BUS.register(minecraftTestInstance); } } public static boolean isTesting() { return SystemUtilKt.checkBooleanProperty("logisticspipes.test"); } @Mod.EventHandler public void preInit(FMLPreInitializationEvent evt) { StaticResolverUtil.useASMDataTable(evt.getAsmData()); PacketHandler.initialize(); NewGuiHandler.initialize(); LogisticsPipes.log = evt.getModLog(); log.info("===================================================="); log.info(" LogisticsPipes Logger initialized, enabled levels: "); log.info("----------------------------------------------------"); log.info(" Fatal: " + log.isFatalEnabled()); log.info(" Error: " + log.isErrorEnabled()); log.info(" Warn: " + log.isWarnEnabled()); log.info(" Info: " + log.isInfoEnabled()); log.info(" Trace: " + log.isTraceEnabled()); log.info(" Debug: " + log.isDebugEnabled()); log.info("===================================================="); loadClasses(); ProxyManager.load(); Configs.load(); if (LogisticsPipes.certificateError) { LogisticsPipes.log.fatal("Certificate not correct"); LogisticsPipes.log.fatal("This in not a LogisticsPipes version from RS485."); } if (LogisticsPipes.UNKNOWN.equals(LogisticsPipes.VERSION)) { LogisticsPipes.log.warn("Could not determine Logistics Pipes version, we do need that " + JarFile.MANIFEST_NAME + ", don't you know?"); } LogisticsPipes.log.info("Running " + getVersionString()); SimpleServiceLocator.setPipeInformationManager(new PipeInformationManager()); SimpleServiceLocator.setLogisticsFluidManager(new LogisticsFluidManager()); if (Loader.isModLoaded(LPConstants.theOneProbeModID)) { FMLInterModComms.sendFunctionMessage(LPConstants.theOneProbeModID, "getTheOneProbe", TheOneProbeIntegration.class.getName()); } MainProxy.proxy.initModelLoader(); } @Mod.EventHandler public void postInit(FMLPostInitializationEvent event) { postInitRun.forEach(Runnable::run); postInitRun = null; SpecialInventoryHandlerManager.load(); SpecialTankHandlerManager.load(); SimpleServiceLocator.buildCraftProxy.registerPipeInformationProvider(); SimpleServiceLocator.buildCraftProxy.initProxy(); SimpleServiceLocator.thermalDynamicsProxy.registerPipeInformationProvider(); //SimpleServiceLocator.specialpipeconnection.registerHandler(new TeleportPipes()); //SimpleServiceLocator.specialtileconnection.registerHandler(new TesseractConnection()); //SimpleServiceLocator.addCraftingRecipeProvider(LogisticsWrapperHandler.getWrappedRecipeProvider("BuildCraft|Factory", "AutoWorkbench", AutoWorkbench.class)); //SimpleServiceLocator.addCraftingRecipeProvider(LogisticsWrapperHandler.getWrappedRecipeProvider("BuildCraft|Silicon", "AssemblyAdvancedWorkbench", AssemblyAdvancedWorkbench.class)); if (SimpleServiceLocator.buildCraftProxy.getAssemblyTableProviderClass() != null) { SimpleServiceLocator.addCraftingRecipeProvider(LogisticsWrapperHandler.getWrappedRecipeProvider(LPConstants.bcSiliconModID, "AssemblyTable", SimpleServiceLocator.buildCraftProxy.getAssemblyTableProviderClass())); } SimpleServiceLocator.addCraftingRecipeProvider(new LogisticsCraftingTable()); SimpleServiceLocator.machineProgressProvider.registerProgressProvider(LogisticsWrapperHandler.getWrappedProgressProvider(LPConstants.thermalExpansionModID, "Generic", ThermalExpansionProgressProvider.class)); SimpleServiceLocator.machineProgressProvider.registerProgressProvider(LogisticsWrapperHandler.getWrappedProgressProvider(LPConstants.ic2ModID, "Generic", IC2ProgressProvider.class)); //SimpleServiceLocator.machineProgressProvider.registerProgressProvider(LogisticsWrapperHandler.getWrappedProgressProvider("EnderIO", "Generic", EnderIOProgressProvider.class)); SimpleServiceLocator.machineProgressProvider.registerProgressProvider(LogisticsWrapperHandler.getWrappedProgressProvider(LPConstants.enderCoreModID, "Generic", EnderCoreProgressProvider.class)); GameRegistry.registerTileEntity(LogisticsPowerJunctionTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "power_junction")); GameRegistry.registerTileEntity(LogisticsRFPowerProviderTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "power_provider_rf")); GameRegistry.registerTileEntity(LogisticsIC2PowerProviderTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "power_provider_ic2")); GameRegistry.registerTileEntity(LogisticsSecurityTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "security_station")); GameRegistry.registerTileEntity(LogisticsCraftingTableTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "logistics_crafting_table")); GameRegistry.registerTileEntity(LogisticsTileGenericPipe.class, new ResourceLocation(LPConstants.LP_MOD_ID, "pipe")); GameRegistry.registerTileEntity(LogisticsStatisticsTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "statistics_table")); GameRegistry.registerTileEntity(LogisticsProgramCompilerTileEntity.class, new ResourceLocation(LPConstants.LP_MOD_ID, "program_compiler")); GameRegistry.registerTileEntity(LogisticsTileGenericSubMultiBlock.class, new ResourceLocation(LPConstants.LP_MOD_ID, "submultiblock")); MainProxy.proxy.registerTileEntities(); SimpleServiceLocator.mcmpProxy.registerTileEntities(); //Registering special particles MainProxy.proxy.registerParticles(); //init Fluids FluidIdentifier.initFromForge(false); versionChecker = VersionChecker.runVersionCheck(); } @SubscribeEvent @SideOnly(Side.CLIENT) public void textureLoad(TextureStitchEvent.Pre event) { if (!event.getMap().getBasePath().equals("textures")) { return; } MainProxy.proxy.registerTextures(); } @SubscribeEvent public void initItems(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); ItemPipeSignCreator.registerPipeSignTypes(); ItemModule.loadModules(registry); ItemUpgrade.loadUpgrades(registry); registerPipes(registry); registry.register(setName(new LogisticsItemCard(), "item_card")); registry.register(setName(new RemoteOrderer(), "remote_orderer")); registry.register(setName(new ItemPipeSignCreator(), "sign_creator")); registry.register(setName(new ItemHUDArmor(), "hud_glasses")); registry.register(setName(new ItemParts(), "parts")); registry.register(setName(new ItemBlankModule(), "module_blank")); registry.register(setName(new ItemDisk(), "disk")); registry.register(setName(new LogisticsFluidContainer(), "fluid_container")); registry.register(setName(new LogisticsBrokenItem(), "broken_item")); registry.register(setName(new ItemGuideBook(), "guide_book")); registry.register(setName(new ItemPipeController(), "pipe_controller")); registry.register(setName(new ItemPipeManager(), "pipe_manager")); registry.register(setName(new ItemLogisticsProgrammer(), "logistics_programmer")); registry.register(setName(new ItemLogisticsChips(ItemLogisticsChips.ITEM_CHIP_BASIC), "chip_basic")); registry.register(setName(new ItemLogisticsChips(ItemLogisticsChips.ITEM_CHIP_BASIC_RAW), "chip_basic_raw")); registry.register(setName(new ItemLogisticsChips(ItemLogisticsChips.ITEM_CHIP_ADVANCED), "chip_advanced")); registry.register(setName(new ItemLogisticsChips(ItemLogisticsChips.ITEM_CHIP_ADVANCED_RAW), "chip_advanced_raw")); registry.register(setName(new ItemLogisticsChips(ItemLogisticsChips.ITEM_CHIP_FPGA), "chip_fpga")); registry.register(setName(new ItemLogisticsChips(ItemLogisticsChips.ITEM_CHIP_FPGA_RAW), "chip_fpga_raw")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.frame), "frame")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.powerJunction), "power_junction")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.securityStation), "security_station")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.crafter), "crafting_table")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.crafterFuzzy), "crafting_table_fuzzy")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.statisticsTable), "statistics_table")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.powerProviderRF), "power_provider_rf")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.powerProviderEU), "power_provider_eu")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.powerProviderMJ), "power_provider_mj")); registry.register(setName(new LogisticsSolidBlockItem(LPBlocks.programCompiler), "program_compiler")); } // TODO move somewhere public static T setName(T item, String name) { return setName(item, name, LPConstants.LP_MOD_ID); } public static T setName(T item, String name, String modID) { item.setRegistryName(modID, name); item.setTranslationKey(String.format("%s.%s", modID, name)); return item; } // TODO move somewhere public static T setName(T block, String name) { block.setRegistryName(LPConstants.LP_MOD_ID, name); block.setTranslationKey(String.format("%s.%s", LPConstants.LP_MOD_ID, name)); return block; } @SubscribeEvent public void initBlocks(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_BLOCK_FRAME), "frame")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_POWER_JUNCTION), "power_junction")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_SECURITY_STATION), "security_station")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_AUTOCRAFTING_TABLE), "crafting_table")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_FUZZYCRAFTING_TABLE), "crafting_table_fuzzy")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_STATISTICS_TABLE), "statistics_table")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_RF_POWERPROVIDER), "power_provider_rf")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_IC2_POWERPROVIDER), "power_provider_eu")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_BC_POWERPROVIDER), "power_provider_mj")); registry.register(setName(new LogisticsSolidBlock(LogisticsSolidBlock.Type.LOGISTICS_PROGRAM_COMPILER), "program_compiler")); registry.register(setName(new BlockDummy(), "solid_block")); registry.register(setName(new LogisticsBlockGenericPipe(), "pipe")); registry.register(setName(new LogisticsBlockGenericSubMultiBlock(), "sub_multiblock")); } @SubscribeEvent public void onModelLoad(ModelRegistryEvent e) { MainProxy.proxy.registerModels(); } private void registerRecipes() { RecipeManager.recipeProvider.add(new LPChipRecipes()); RecipeManager.recipeProvider.add(new UpgradeChippedCraftingRecipes()); RecipeManager.recipeProvider.add(new ModuleChippedCraftingRecipes()); RecipeManager.recipeProvider.add(new PipeChippedCraftingRecipes()); RecipeManager.recipeProvider.add(new CraftingRecipes()); RecipeManager.loadRecipes(); resetRecipeList.stream() .map(Supplier::get) .forEach(itemItemPair -> registerShapelessResetRecipe(itemItemPair.getValue1(), itemItemPair.getValue2())); } @SneakyThrows private void loadClasses() { //Try to load all classes to let our checksums get generated forName("net.minecraft.tileentity.TileEntity"); forName("net.minecraft.world.World"); forName("net.minecraft.item.ItemStack"); forName("net.minecraftforge.fluids.FluidStack"); forName("net.minecraftforge.fluids.Fluid"); forName("cofh.thermaldynamics.block.TileTDBase"); forName("cofh.thermaldynamics.duct.item.TravelingItem"); forName("crazypants.enderio.conduit.item.ItemConduit"); forName("crazypants.enderio.conduit.item.NetworkedInventory"); forName("crazypants.enderio.conduit.liquid.AbstractLiquidConduit"); forName("mcmultipart.block.BlockMultipartContainer"); } private void forName(String string) { try { Class.forName(string); } catch (Exception ignore) {} } @Mod.EventHandler public void beforeStart(FMLServerAboutToStartEvent event) { ServerTickDispatcher.INSTANCE.serverStart(); } @Mod.EventHandler public void cleanup(FMLServerStoppingEvent event) { SimpleServiceLocator.routerManager.serverStopClean(); QueuedTasks.clearAllTasks(); HudUpdateTick.clearUpdateFlags(); PipeItemsSatelliteLogistics.cleanup(); PipeFluidSatellite.cleanup(); ServerRouter.cleanup(); if (event.getSide().equals(Side.CLIENT)) { LogisticsHUDRenderer.instance().clear(); } ServerTickDispatcher.INSTANCE.cleanup(); LogisticsPipes.serverConfigManager = null; } @Mod.EventHandler public void registerCommands(FMLServerStartingEvent event) { event.registerServerCommand(new LogisticsPipesCommand()); } @Mod.EventHandler public void serverStarted(FMLServerStartedEvent event) { if (minecraftTestStartMethod != null) minecraftTestStartMethod.accept(event); } @Mod.EventHandler public void certificateWarning(FMLFingerprintViolationEvent warning) { LogisticsPipes.certificateError = true; if (!LogisticsPipes.isDEBUG()) { System.out.println("[LogisticsPipes|Certificate] Certificate not correct"); System.out.println("[LogisticsPipes|Certificate] Expected: " + warning.getExpectedFingerprint()); System.out.println("[LogisticsPipes|Certificate] File: " + warning.getSource().getAbsolutePath()); System.out.println("[LogisticsPipes|Certificate] This in not a LogisticsPipes version from RS485."); } } public static Object getComputerLP() { if (LogisticsPipes.generalAccess == null) { LogisticsPipes.generalAccess = new LPGlobalCCAccess(); } return LogisticsPipes.generalAccess; } public void registerPipes(IForgeRegistry registry) { registerPipe(registry, "basic", PipeItemsBasicLogistics::new); registerPipe(registry, "request", PipeItemsRequestLogistics::new); registerPipe(registry, "provider", PipeItemsProviderLogistics::new); registerPipe(registry, "crafting", PipeItemsCraftingLogistics::new); registerPipe(registry, "satellite", PipeItemsSatelliteLogistics::new); registerPipe(registry, "supplier", PipeItemsSupplierLogistics::new); registerPipe(registry, "chassis_mk1", PipeLogisticsChassisMk1::new); registerPipe(registry, "chassis_mk2", PipeLogisticsChassisMk2::new); registerPipe(registry, "chassis_mk3", PipeLogisticsChassisMk3::new); registerPipe(registry, "chassis_mk4", PipeLogisticsChassisMk4::new); registerPipe(registry, "chassis_mk5", PipeLogisticsChassisMk5::new); registerPipe(registry, "request_mk2", PipeItemsRequestLogisticsMk2::new); registerPipe(registry, "remote_orderer", PipeItemsRemoteOrdererLogistics::new); registerPipe(registry, "inventory_system_connector", PipeItemsInvSysConnector::new); registerPipe(registry, "system_entrance", PipeItemsSystemEntranceLogistics::new); registerPipe(registry, "system_destination", PipeItemsSystemDestinationLogistics::new); registerPipe(registry, "firewall", PipeItemsFirewall::new); registerPipe(registry, "fluid_basic", PipeFluidBasic::new); registerPipe(registry, "fluid_supplier", PipeItemsFluidSupplier::new); registerPipe(registry, "fluid_insertion", PipeFluidInsertion::new); registerPipe(registry, "fluid_provider", PipeFluidProvider::new); registerPipe(registry, "fluid_request", PipeFluidRequestLogistics::new); registerPipe(registry, "fluid_extractor", PipeFluidExtractor::new); registerPipe(registry, "fluid_satellite", PipeFluidSatellite::new); registerPipe(registry, "fluid_supplier_mk2", PipeFluidSupplierMk2::new); registerPipe(registry, "fluid_terminus", PipeFluidTerminus::new); registerPipe(registry, "request_table", PipeBlockRequestTable::new); registerPipe(registry, "transport_basic", PipeItemsBasicTransport::new); registerPipe(registry, "hs_curve", HSTubeCurve::new); registerPipe(registry, "hs_speedup", HSTubeSpeedup::new); registerPipe(registry, "hs_s_curve", HSTubeSCurve::new); registerPipe(registry, "hs_line", HSTubeLine::new); registerPipe(registry, "hs_gain", HSTubeGain::new); } protected void registerPipe(IForgeRegistry registry, String name, Function constructor) { final ItemLogisticsPipe res = LogisticsBlockGenericPipe.registerPipe(registry, name, constructor); final CoreUnroutedPipe pipe = Objects.requireNonNull(LogisticsBlockGenericPipe.createPipe(res), "created a null pipe from " + res); if (pipe instanceof CoreRoutedPipe) { postInitRun.add(() -> res.setPipeIconIndex(((CoreRoutedPipe) pipe).getTextureType(null).normal, ((CoreRoutedPipe) pipe).getTextureType(null).newTexture)); } if (pipe.getClass() != PipeItemsBasicLogistics.class && CoreRoutedPipe.class.isAssignableFrom(pipe.getClass())) { if (pipe.getClass() != PipeFluidBasic.class && FluidRoutedPipe.class.isAssignableFrom(pipe.getClass())) { resetRecipeList.add(() -> new Pair<>(res, LPItems.pipeFluidBasic)); } else if (!pipe.isPipeBlock()) { resetRecipeList.add(() -> new Pair<>(res, LPItems.pipeBasic)); } } } protected void registerShapelessResetRecipe(Item fromItem, Item toItem) { NonNullList list = NonNullList.create(); list.add(CraftingHelper.getIngredient(new ItemStack(fromItem, 1, 0))); ItemStack output = new ItemStack(toItem, 1, 0); ResourceLocation baseLoc = new ResourceLocation(LPConstants.LP_MOD_ID, fromItem.getRegistryName().getPath() + ".resetrecipe"); ResourceLocation recipeLoc = baseLoc; int index = 0; while (CraftingManager.REGISTRY.containsKey(recipeLoc)) { index++; recipeLoc = new ResourceLocation(LPConstants.LP_MOD_ID, baseLoc.getPath() + "_" + index); } ShapelessRecipes recipe = new ShapelessRecipes("logisticspipes.resetrecipe.pipe", output, list); recipe.setRegistryName(recipeLoc); GameData.register_impl(recipe); } public static ClientConfiguration getClientPlayerConfig() { if (LogisticsPipes.playerConfig == null) { LogisticsPipes.playerConfig = new ClientConfiguration(); } return LogisticsPipes.playerConfig; } public static ServerConfigurationManager getServerConfigManager() { if (LogisticsPipes.serverConfigManager == null) { LogisticsPipes.serverConfigManager = new ServerConfigurationManager(); } return LogisticsPipes.serverConfigManager; } } ================================================ FILE: common/logisticspipes/api/IHUDArmor.java ================================================ package logisticspipes.api; import javax.annotation.Nonnull; import net.minecraft.item.ItemStack; public interface IHUDArmor { boolean isEnabled(@Nonnull ItemStack item); } ================================================ FILE: common/logisticspipes/api/ILPPipe.java ================================================ package logisticspipes.api; /** * Public interface implemented by LP's internal Pipe logic */ public interface ILPPipe { /** * @return true if the pipe can route items inside the network */ boolean isRoutedPipe(); } ================================================ FILE: common/logisticspipes/api/ILPPipeConfigTool.java ================================================ package logisticspipes.api; import javax.annotation.Nonnull; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; /** * public interface to be implemented by an item which can open the config GUI for a logistics pipe. * Some mod compatibility is already implemented inside LP. */ public interface ILPPipeConfigTool { boolean canWrench(EntityPlayer player, @Nonnull ItemStack wrench, ILPPipeTile pipe); void wrenchUsed(EntityPlayer player, @Nonnull ItemStack wrench, ILPPipeTile pipe); } ================================================ FILE: common/logisticspipes/api/ILPPipeTile.java ================================================ package logisticspipes.api; import net.minecraft.util.math.BlockPos; /** * Public interface implemented by LP's Pipe tile */ public interface ILPPipeTile { /** * Used to access the internal pipe logic This also can return the * IRequestAPI or IRoutedPowerProvider * * @return the pipe */ ILPPipe getLPPipe(); BlockPos getBlockPos(); } ================================================ FILE: common/logisticspipes/api/ILogisticsPowerProvider.java ================================================ package logisticspipes.api; /** * things which directly provide power to the logsitics network implement this. * lists of these objects available to a network will be cached, and the closest * one with power preferentially pulled from. * * @author Andrew */ public interface ILogisticsPowerProvider extends IRoutedPowerProvider { int getPowerLevel(); } ================================================ FILE: common/logisticspipes/api/IProgressProvider.java ================================================ package logisticspipes.api; /** * Implemented by an TileEntity this will allow LP to access the current * progress of an TileEntity connected to a crafting pipe and display the * progress inside it's crafting tree view. */ public interface IProgressProvider { /** * @return a value between 0 and 100 that indicates the current progress of * this TileEntity machine */ byte getMachineProgressForLP(); } ================================================ FILE: common/logisticspipes/api/IRoutedPowerProvider.java ================================================ package logisticspipes.api; import java.util.List; /** * things implementing this interface are capable of providing power, but they * draw from another sources Implement ILogisticsPowerProvider if you wish to * provide power to the LP network. Losses of energy based on distance may be * involved. * * @author Andrew */ public interface IRoutedPowerProvider { // typically calls useEnergy(amount,null); boolean useEnergy(int amount); // typically calls canUseEnergy(amount,null); boolean canUseEnergy(int amount); // for the case where 1 IRoutedPowerProvider has to check another // each IRoutedPowerProvider that can recurse should: // a) check that it is not already on the list // b) add itself to the list (creating it if the list is null), boolean useEnergy(int amount, List providersToIgnore); boolean canUseEnergy(int amount, List providersToIgnore); int getX(); // the coordinates of the associated tile (typically "this.xCoords"). needed for sending packets. int getY(); int getZ(); } ================================================ FILE: common/logisticspipes/asm/ClientSideOnlyMethodContent.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ClientSideOnlyMethodContent { } ================================================ FILE: common/logisticspipes/asm/IgnoreDisabledProxy.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface IgnoreDisabledProxy { } ================================================ FILE: common/logisticspipes/asm/LogisticsASMHookClass.java ================================================ package logisticspipes.asm; import net.minecraft.tileentity.TileEntity; import lombok.SneakyThrows; import logisticspipes.LogisticsPipes; import logisticspipes.routing.pathfinder.changedetection.TEControl; public class LogisticsASMHookClass { public static void callingClearedMethod() { throw new RuntimeException("This Method should never be called"); } @SneakyThrows(Exception.class) public static void validate(TileEntity tile) { try { TEControl.validate(tile); } catch (Exception e) { if (LogisticsPipes.isDEBUG()) { throw e; } e.printStackTrace(); } } @SneakyThrows(Exception.class) public static void invalidate(TileEntity tile) { try { TEControl.invalidate(tile); } catch (Exception e) { if (LogisticsPipes.isDEBUG()) { throw e; } e.printStackTrace(); } } } ================================================ FILE: common/logisticspipes/asm/LogisticsClassTransformer.java ================================================ package logisticspipes.asm; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.function.Consumer; import java.util.jar.Manifest; import java.util.stream.Collectors; import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; import net.minecraft.launchwrapper.LaunchClassLoader; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.asm.transformers.AccessTransformer; import net.minecraftforge.fml.common.asm.transformers.ModAccessTransformer; import net.minecraftforge.fml.common.versioning.ArtifactVersion; import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; import net.minecraftforge.fml.common.versioning.VersionParser; import net.minecraftforge.fml.common.versioning.VersionRange; import net.minecraftforge.fml.relauncher.Side; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; import logisticspipes.LogisticsPipes; import logisticspipes.asm.mcmp.ClassBlockMultipartContainerHandler; import logisticspipes.asm.td.ClassRenderDuctItemsHandler; import logisticspipes.asm.td.ClassTravelingItemHandler; import logisticspipes.utils.ModStatusHelper; public class LogisticsClassTransformer implements IClassTransformer { public List interfacesToClearA = new ArrayList<>(); public List interfacesToClearB = new ArrayList<>(); private LaunchClassLoader cl = (LaunchClassLoader) LogisticsClassTransformer.class.getClassLoader(); private Field negativeResourceCache; private Field invalidClasses; public static LogisticsClassTransformer instance; public LogisticsClassTransformer() { LogisticsClassTransformer.instance = this; try { negativeResourceCache = LaunchClassLoader.class.getDeclaredField("negativeResourceCache"); negativeResourceCache.setAccessible(true); } catch (Exception e) { //e.printStackTrace(); } try { invalidClasses = LaunchClassLoader.class.getDeclaredField("invalidClasses"); invalidClasses.setAccessible(true); } catch (Exception e) { e.printStackTrace(); } } @Override public byte[] transform(String name, String transformedName, byte[] bytes) { // if dev environment and transform on first class is launched, boot the AT remapper if (LogisticsPipesCoreLoader.isDevelopmentEnvironment() && name.equals("net.minecraftforge.fml.common.Loader")) bootATRemapper(); Thread thread = Thread.currentThread(); if (thread.getName().equals("Minecraft main thread") || thread.getName().equals("main") || thread.getName().equals("Server thread")) { //Only clear when called from the main thread to avoid ConcurrentModificationException on start clearNegativeInterfaceCache(); } if (bytes == null) { return null; } if (transformedName.startsWith("logisticspipes.") || transformedName.startsWith("net.minecraft")) { return ParamProfiler.handleClass(applyLPTransforms(transformedName, bytes)); } byte[] tmp = bytes.clone(); bytes = applyLPTransforms(transformedName, bytes); if (!Arrays.equals(bytes, tmp)) { final ClassReader reader = new ClassReader(bytes); final ClassNode node = new ClassNode(); reader.accept(node, 0); node.sourceFile = "[LP|ASM] " + node.sourceFile; ClassWriter writer = new ClassWriter(0); node.accept(writer); bytes = writer.toByteArray(); } return ParamProfiler.handleClass(bytes); } private void bootATRemapper() { System.err.println("Fetching ModAccessTransformers"); final List modATs = Launch.classLoader.getTransformers().stream().filter(transformer -> transformer instanceof ModAccessTransformer).collect(Collectors.toList()); System.err.println("Found " + modATs); if (modATs.size() == 0) return; System.err.println("Inserting missing ATs from classpath"); try { readClasspathATs(modATs); } catch (IllegalStateException e) { System.err.println("Could not inject classpath FMLATs"); e.printStackTrace(); } System.err.println("Booting Logistics Pipes ModAccessTransformerRemapper"); final ModAccessTransformerRemapper remapper; try { remapper = new ModAccessTransformerRemapper(); } catch (IllegalStateException e) { System.err.println("Could not initialize ModAccessTransformerRemapper:"); e.printStackTrace(); return; } modATs.forEach(remapper::apply); } private void readClasspathATs(List modATs) { final Method readMapFile; try { readMapFile = AccessTransformer.class.getDeclaredMethod("readMapFile", String.class); } catch (NoSuchMethodException e) { throw new IllegalStateException("Could not find method readMapFile on AccessTransformer class", e); } final boolean wasAccessible = readMapFile.isAccessible(); if (!wasAccessible) readMapFile.setAccessible(true); try { readClasspathATsInner(path -> { final IClassTransformer classTransformer = modATs.get(0); try { readMapFile.invoke(classTransformer, path); } catch (IllegalAccessException | InvocationTargetException e) { throw new IllegalStateException("Could not access readMapFile method of " + classTransformer); } }); } catch (IOException e) { throw new IllegalArgumentException("IO Error when fetching FMLATs", e); } finally { if (!wasAccessible) readMapFile.setAccessible(false); } } private void readClasspathATsInner(Consumer readMapFile) throws IOException { final Enumeration manifestEntries = Launch.classLoader.findResources("META-INF/MANIFEST.MF"); while (manifestEntries.hasMoreElements()) { final String accessTransformer; try (InputStream manifestInputStream = manifestEntries.nextElement().openStream()) { final Manifest manifest = new Manifest(manifestInputStream); accessTransformer = manifest.getMainAttributes().getValue(ModAccessTransformer.FMLAT); } final Enumeration atEntries = Launch.classLoader.findResources("META-INF/" + accessTransformer); while (atEntries.hasMoreElements()) { readMapFile.accept(atEntries.nextElement().toString()); } } } private byte[] applyLPTransforms(String name, byte[] bytes) { try { if (name.equals("net.minecraft.tileentity.TileEntity")) { return handleTileEntityClass(bytes); } if (name.equals("net.minecraft.item.ItemStack")) { return handleItemStackClass(bytes); } if (name.equals("net.minecraftforge.fluids.FluidStack")) { return handleFluidStackClass(bytes); } if (name.equals("net.minecraftforge.fluids.Fluid")) { return handleFluidClass(bytes); } if (name.equals("mcmultipart.block.BlockMultipartContainer")) { return ClassBlockMultipartContainerHandler.handleClass(bytes); } if (name.equals("dan200.computercraft.core.lua.LuaJLuaMachine")) { return handleCCLuaJLuaMachine(bytes); } if (name.equals("dan200.computercraft.core.lua.CobaltLuaMachine")) { return handleCCLuaJLuaMachine(bytes); } if (name.equals("cofh.thermaldynamics.duct.item.TravelingItem")) { return ClassTravelingItemHandler.handleTravelingItemClass(bytes); } if (name.equals("cofh.thermaldynamics.render.RenderDuctItems")) { return ClassRenderDuctItemsHandler.handleRenderDuctItemsClass(bytes); } if (!name.startsWith("logisticspipes.")) { return bytes; } return handleLPTransformation(bytes); } catch (Exception e) { if (LogisticsPipes.isDEBUG()) { //For better Debugging e.printStackTrace(); return bytes; } throw new RuntimeException(e); } } public void clearNegativeInterfaceCache() { //Remove previously not found Classes to Fix ClassNotFound Exceptions for Interfaces. //TODO remove in future version when everybody starts using a ClassTransformer system for Interfaces. if (negativeResourceCache != null) { if (!interfacesToClearA.isEmpty()) { handleField(negativeResourceCache, interfacesToClearA); } } if (invalidClasses != null) { if (!interfacesToClearB.isEmpty()) { handleField(invalidClasses, interfacesToClearB); } } } @SuppressWarnings("unchecked") private void handleField(Field field, List toClear) { try { Set set = (Set) field.get(cl); Iterator it = toClear.iterator(); while (it.hasNext()) { String content = it.next(); if (set.contains(content)) { set.remove(content); it.remove(); } } } catch (Exception e) { if (LogisticsPipes.isDEBUG()) { //For better Debugging e.printStackTrace(); } } } @SuppressWarnings("unchecked") private byte[] handleLPTransformation(byte[] bytes) { final ClassNode node = new ClassNode(); ClassReader reader = new ClassReader(bytes); reader.accept(node, 0); boolean changed = false; if (node.visibleAnnotations != null) { for (AnnotationNode a : node.visibleAnnotations) { if (a.desc.equals("Llogisticspipes/asm/ModDependentInterface;")) { if (a.values.size() == 4 && a.values.get(0).equals("modId") && a.values.get(2).equals("interfacePath")) { List modId = (List) a.values.get(1); List interfacePath = (List) a.values.get(3); if (modId.size() != interfacePath.size()) { throw new RuntimeException("The Arrays have to be of the same size."); } for (int i = 0; i < modId.size(); i++) { if (!ModStatusHelper.isModLoaded(modId.get(i))) { interfacesToClearA.add(interfacePath.get(i)); interfacesToClearB.add(interfacePath.get(i)); for (String inter : node.interfaces) { if (inter.replace("/", ".").equals(interfacePath.get(i))) { node.interfaces.remove(inter); changed = true; break; } } } } } else { throw new UnsupportedOperationException("Can't parse the annotations correctly"); } } } } List methodsToRemove = new ArrayList<>(); for (MethodNode m : node.methods) { if (m.visibleAnnotations != null) { for (AnnotationNode a : m.visibleAnnotations) { if (a.desc.equals("Llogisticspipes/asm/ModDependentMethod;")) { if (a.values.size() == 2 && a.values.get(0).equals("modId")) { String modId = a.values.get(1).toString(); if (!ModStatusHelper.isModLoaded(modId)) { methodsToRemove.add(m); break; } } else { throw new UnsupportedOperationException("Can't parse the annotation correctly"); } } else if (a.desc.equals("Llogisticspipes/asm/ClientSideOnlyMethodContent;")) { if (FMLCommonHandler.instance().getSide().equals(Side.SERVER)) { m.instructions.clear(); m.localVariables.clear(); m.tryCatchBlocks.clear(); m.visitCode(); Label l0 = new Label(); m.visitLabel(l0); m.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/LogisticsASMHookClass", "callingClearedMethod", "()V"); Label l1 = new Label(); m.visitLabel(l1); m.visitInsn(Opcodes.RETURN); Label l2 = new Label(); m.visitLabel(l2); m.visitLocalVariable("this", "Llogisticspipes/network/packets/DummyPacket;", null, l0, l2, 0); m.visitLocalVariable("player", "Lnet/minecraft/entity/player/EntityPlayer;", null, l0, l2, 1); m.visitMaxs(0, 2); m.visitEnd(); changed = true; break; } } else if (a.desc.equals("Llogisticspipes/asm/ModDependentMethodName;")) { if (a.values.size() == 6 && a.values.get(0).equals("modId") && a.values.get(2).equals("newName") && a.values.get(4).equals("version")) { String modId = a.values.get(1).toString(); final String newName = a.values.get(3).toString(); final String version = a.values.get(5).toString(); boolean loaded = ModStatusHelper.isModLoaded(modId); if (loaded && !version.equals("")) { ModContainer mod = Loader.instance().getIndexedModList().get(modId); if (mod != null) { VersionRange range = VersionParser.parseRange(version); ArtifactVersion artifactVersion = new DefaultArtifactVersion("Version", mod.getVersion()); loaded = range.containsVersion(artifactVersion); } else { loaded = false; } } if (loaded) { final String oldName = m.name; m.name = newName; MethodNode newM = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { if (name.equals(oldName) && owner.equals(node.superName)) { super.visitMethodInsn(opcode, owner, newName, desc); } else { super.visitMethodInsn(opcode, owner, name, desc); } } }; m.accept(newM); node.methods.set(node.methods.indexOf(m), newM); changed = true; break; } } else { throw new UnsupportedOperationException("Can't parse the annotation correctly"); } } } } } for (MethodNode m : methodsToRemove) { node.methods.remove(m); } List fieldsToRemove = new ArrayList<>(); for (FieldNode f : node.fields) { if (f.visibleAnnotations != null) { for (AnnotationNode a : f.visibleAnnotations) { if (a.desc.equals("Llogisticspipes/asm/ModDependentField;")) { if (a.values.size() == 2 && a.values.get(0).equals("modId")) { String modId = a.values.get(1).toString(); if (!ModStatusHelper.isModLoaded(modId)) { fieldsToRemove.add(f); break; } } else { throw new UnsupportedOperationException("Can't parse the annotation correctly"); } } } } } for (FieldNode f : fieldsToRemove) { node.fields.remove(f); } if (!changed && methodsToRemove.isEmpty() && fieldsToRemove.isEmpty()) { return bytes; } ClassWriter writer = new ClassWriter(0); node.accept(writer); return writer.toByteArray(); } private byte[] handleCCLuaJLuaMachine(byte[] bytes) { final ClassReader reader = new ClassReader(bytes); final ClassNode node = new ClassNode(); reader.accept(node, 0); for (MethodNode m : node.methods) { if (m.name.equals("wrapLuaObject") && m.desc.equals("(Ldan200/computercraft/api/lua/ILuaObject;)Lorg/luaj/vm2/LuaTable;")) { MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) { @Override public void visitInsn(int opcode) { if (opcode == Opcodes.ARETURN) { super.visitVarInsn(Opcodes.ALOAD, 1); super.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/proxy/cc/LPASMHookCC", "onCCWrappedILuaObject", "(Lorg/luaj/vm2/LuaTable;Ldan200/computercraft/api/lua/ILuaObject;)Lorg/luaj/vm2/LuaTable;"); } super.visitInsn(opcode); } @Override public void visitCode() { super.visitCode(); Label l0 = new Label(); super.visitLabel(l0); super.visitVarInsn(Opcodes.ALOAD, 1); super.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/proxy/cc/LPASMHookCC", "handleCCWrappedILuaObject", "(Ldan200/computercraft/api/lua/ILuaObject;)Z"); Label l1 = new Label(); super.visitJumpInsn(Opcodes.IFEQ, l1); Label l2 = new Label(); super.visitLabel(l2); super.visitVarInsn(Opcodes.ALOAD, 1); super.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/proxy/cc/LPASMHookCC", "returnCCWrappedILuaObject", "(Ldan200/computercraft/api/lua/ILuaObject;)Lorg/luaj/vm2/LuaTable;"); super.visitInsn(Opcodes.ARETURN); super.visitLabel(l1); } }; m.accept(mv); node.methods.set(node.methods.indexOf(m), mv); } if (m.name.equals("toObject") && (m.desc.equals("(Lorg/luaj/vm2/LuaValue;)Ljava/lang/Object;") || m.desc.equals("(Lorg/luaj/vm2/LuaValue;Ljava/util/Map;)Ljava/lang/Object;"))) { MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) { boolean added = false; @Override public void visitLineNumber(int line, Label start) { if (!added) { added = true; super.visitVarInsn(Opcodes.ALOAD, 1); super.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/proxy/cc/LPASMHookCC", "handleCCToObject", "(Lorg/luaj/vm2/LuaValue;)Z"); start = new Label(); super.visitJumpInsn(Opcodes.IFEQ, start); Label l5 = new Label(); super.visitLabel(l5); super.visitVarInsn(Opcodes.ALOAD, 1); super.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/proxy/cc/LPASMHookCC", "returnCCToObject", "(Lorg/luaj/vm2/LuaValue;)Ljava/lang/Object;"); super.visitInsn(Opcodes.ARETURN); super.visitLabel(start); } super.visitLineNumber(line, start); } }; m.accept(mv); node.methods.set(node.methods.indexOf(m), mv); } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { protected String getCommonSuperClass(final String type1, final String type2) { Class c, d; ClassLoader classLoader = Launch.classLoader; // Change Classloader to the MC one try { c = Class.forName(type1.replace('/', '.'), false, classLoader); d = Class.forName(type2.replace('/', '.'), false, classLoader); } catch (Exception e) { throw new RuntimeException(e.toString()); } if (c.isAssignableFrom(d)) { return type1; } if (d.isAssignableFrom(c)) { return type2; } if (c.isInterface() || d.isInterface()) { return "java/lang/Object"; } else { do { c = c.getSuperclass(); } while (!c.isAssignableFrom(d)); return c.getName().replace('.', '/'); } } }; node.accept(writer); return writer.toByteArray(); } private byte[] handleTileEntityClass(byte[] bytes) { final ClassReader reader = new ClassReader(bytes); final ClassNode node = new ClassNode(); reader.accept(node, 0); node.interfaces.add("logisticspipes/asm/te/ILPTEInformation"); node.visitField(Opcodes.ACC_PRIVATE, "informationObjectLogisticsPipes", "Llogisticspipes/asm/te/LPTileEntityObject;", null, null); for (MethodNode m : node.methods) { if (m.name.equals("validate") || m.name.equals("func_145829_t") || (m.name.equals("A") && m.desc.equals("()V"))) { MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) { @Override public void visitCode() { super.visitCode(); Label l0 = new Label(); visitLabel(l0); visitVarInsn(Opcodes.ALOAD, 0); this.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/LogisticsASMHookClass", "validate", "(Lnet/minecraft/tileentity/TileEntity;)V"); } }; m.accept(mv); node.methods.set(node.methods.indexOf(m), mv); } if (m.name.equals("invalidate") || m.name.equals("func_145843_s") || (m.name.equals("z") && m.desc.equals("()V"))) { MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) { @Override public void visitCode() { super.visitCode(); Label l0 = new Label(); visitLabel(l0); visitVarInsn(Opcodes.ALOAD, 0); this.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/LogisticsASMHookClass", "invalidate", "(Lnet/minecraft/tileentity/TileEntity;)V"); } }; m.accept(mv); node.methods.set(node.methods.indexOf(m), mv); } } MethodVisitor mv; { mv = node.visitMethod(Opcodes.ACC_PUBLIC, "getLPTileEntityObject", "()Llogisticspipes/asm/te/LPTileEntityObject;", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/tileentity/TileEntity", "informationObjectLogisticsPipes", "Llogisticspipes/asm/te/LPTileEntityObject;"); mv.visitInsn(Opcodes.ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = node.visitMethod(Opcodes.ACC_PUBLIC, "setLPTileEntityObject", "(Llogisticspipes/asm/te/LPTileEntityObject;)V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/tileentity/TileEntity", "informationObjectLogisticsPipes", "Llogisticspipes/asm/te/LPTileEntityObject;"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(Opcodes.RETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitMaxs(2, 2); mv.visitEnd(); } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); node.accept(writer); return writer.toByteArray(); } private byte[] handleItemStackClass(byte[] bytes) { return addAddInfoPart(bytes, "net/minecraft/item/ItemStack"); } private byte[] handleFluidStackClass(byte[] bytes) { return addAddInfoPart(bytes, "net/minecraftforge/fluids/FluidStack"); } private byte[] handleFluidClass(byte[] bytes) { return addAddInfoPart(bytes, "net/minecraftforge/fluids/Fluid"); } private byte[] addAddInfoPart(byte[] bytes, String className) { final ClassReader reader = new ClassReader(bytes); final ClassNode node = new ClassNode(); reader.accept(node, 0); node.interfaces.add("logisticspipes/asm/addinfo/IAddInfoProvider"); { FieldVisitor fv = node.visitField(Opcodes.ACC_PRIVATE, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;", "Ljava/util/ArrayList;", null); fv.visitEnd(); } MethodVisitor mv; { mv = node.visitMethod(Opcodes.ACC_PUBLIC, "getLogisticsPipesAddInfo", "(Ljava/lang/Class;)Llogisticspipes/asm/addinfo/IAddInfo;", "(Ljava/lang/Class;)TT;", null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(11, l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); Label l1 = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, l1); Label l2 = new Label(); mv.visitLabel(l2); mv.visitLineNumber(12, l2); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitInsn(Opcodes.ARETURN); mv.visitLabel(l1); mv.visitLineNumber(14, l1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "iterator", "()Ljava/util/Iterator;", false); mv.visitVarInsn(Opcodes.ASTORE, 2); Label l3 = new Label(); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/util/Iterator" }, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 2); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); Label l4 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, l4); mv.visitVarInsn(Opcodes.ALOAD, 2); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); mv.visitTypeInsn(Opcodes.CHECKCAST, "logisticspipes/asm/addinfo/IAddInfo"); mv.visitVarInsn(Opcodes.ASTORE, 3); Label l5 = new Label(); mv.visitLabel(l5); mv.visitLineNumber(15, l5); mv.visitVarInsn(Opcodes.ALOAD, 3); Label l6 = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, l6); mv.visitJumpInsn(Opcodes.GOTO, l3); mv.visitLabel(l6); mv.visitLineNumber(16, l6); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "logisticspipes/asm/addinfo/IAddInfo" }, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 3); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitVarInsn(Opcodes.ALOAD, 1); Label l7 = new Label(); mv.visitJumpInsn(Opcodes.IF_ACMPNE, l7); Label l8 = new Label(); mv.visitLabel(l8); mv.visitLineNumber(17, l8); mv.visitVarInsn(Opcodes.ALOAD, 3); mv.visitInsn(Opcodes.ARETURN); mv.visitLabel(l7); mv.visitLineNumber(19, l7); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitJumpInsn(Opcodes.GOTO, l3); mv.visitLabel(l4); mv.visitLineNumber(20, l4); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitInsn(Opcodes.ARETURN); Label l9 = new Label(); mv.visitLabel(l9); mv.visitLocalVariable("info", "Llogisticspipes/asm/addinfo/IAddInfo;", null, l5, l7, 3); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l9, 0); mv.visitLocalVariable("clazz", "Ljava/lang/Class;", "Ljava/lang/Class;", l0, l9, 1); mv.visitMaxs(2, 4); mv.visitEnd(); } { mv = node.visitMethod(Opcodes.ACC_PUBLIC, "setLogisticsPipesAddInfo", "(Llogisticspipes/asm/addinfo/IAddInfo;)V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(25, l0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); Label l1 = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, l1); Label l2 = new Label(); mv.visitLabel(l2); mv.visitLineNumber(26, l2); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "", "()V", false); mv.visitFieldInsn(Opcodes.PUTFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitLabel(l1); mv.visitLineNumber(28, l1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(Opcodes.ICONST_0); mv.visitVarInsn(Opcodes.ISTORE, 2); Label l3 = new Label(); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null); mv.visitVarInsn(Opcodes.ILOAD, 2); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "size", "()I", false); Label l4 = new Label(); mv.visitJumpInsn(Opcodes.IF_ICMPGE, l4); Label l5 = new Label(); mv.visitLabel(l5); mv.visitLineNumber(29, l5); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitVarInsn(Opcodes.ILOAD, 2); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); Label l6 = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, l6); Label l7 = new Label(); mv.visitJumpInsn(Opcodes.GOTO, l7); mv.visitLabel(l6); mv.visitLineNumber(30, l6); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitVarInsn(Opcodes.ILOAD, 2); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); mv.visitTypeInsn(Opcodes.CHECKCAST, "logisticspipes/asm/addinfo/IAddInfo"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitJumpInsn(Opcodes.IF_ACMPNE, l7); Label l8 = new Label(); mv.visitLabel(l8); mv.visitLineNumber(31, l8); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitVarInsn(Opcodes.ILOAD, 2); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "set", "(ILjava/lang/Object;)Ljava/lang/Object;", false); mv.visitInsn(Opcodes.POP); Label l9 = new Label(); mv.visitLabel(l9); mv.visitLineNumber(32, l9); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(l7); mv.visitLineNumber(28, l7); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitIincInsn(2, 1); mv.visitJumpInsn(Opcodes.GOTO, l3); mv.visitLabel(l4); mv.visitLineNumber(35, l4); mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, className, "logisticsPipesAdditionalInformation", "Ljava/util/ArrayList;"); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "add", "(Ljava/lang/Object;)Z", false); mv.visitInsn(Opcodes.POP); Label l10 = new Label(); mv.visitLabel(l10); mv.visitLineNumber(36, l10); mv.visitInsn(Opcodes.RETURN); Label l11 = new Label(); mv.visitLabel(l11); mv.visitLocalVariable("i", "I", null, l3, l4, 2); mv.visitLocalVariable("this", "L" + className + ";", null, l0, l11, 0); mv.visitLocalVariable("info", "Llogisticspipes/asm/addinfo/IAddInfo;", null, l0, l11, 1); mv.visitMaxs(3, 3); mv.visitEnd(); } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); node.accept(writer); return writer.toByteArray(); } } ================================================ FILE: common/logisticspipes/asm/LogisticsPipesClassInjector.java ================================================ package logisticspipes.asm; import java.lang.reflect.Field; import java.util.Map; import java.util.Set; import java.util.TreeSet; import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; import net.minecraft.launchwrapper.LaunchClassLoader; import com.google.common.io.BaseEncoding; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; import logisticspipes.LogisticsPipes; import logisticspipes.proxy.computers.wrapper.CCObjectWrapper; import logisticspipes.proxy.opencomputers.asm.ClassCreator; import logisticspipes.utils.ModStatusHelper; public class LogisticsPipesClassInjector implements IClassTransformer { private Field fResourceCache; private Boolean isObfEnv = null; public LogisticsPipesClassInjector() throws NoSuchFieldException, SecurityException { fResourceCache = LaunchClassLoader.class.getDeclaredField("resourceCache"); fResourceCache.setAccessible(true); } @Override @SuppressWarnings("unchecked") public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes != null) { if (name.startsWith("logisticspipes.")) { final ClassReader reader = new ClassReader(bytes); final ClassNode node = new ClassNode(); reader.accept(node, 0); if (node.visibleAnnotations != null) { for (AnnotationNode a : node.visibleAnnotations) { if (a.desc.equals("Llogisticspipes/asm/ModVersionedClass;")) { if (a.values.size() == 8 && a.values.get(0).equals("modId") && a.values.get(2).equals("version") && a.values.get(4).equals("classData") && a.values.get(6).equals("classDataDev")) { String modId = a.values.get(1).toString(); String version = a.values.get(3).toString(); String classData = a.values.get(5).toString(); String classDataDev = a.values.get(7).toString(); if (ModStatusHelper.isModLoaded(modId) && !ModStatusHelper.isModVersionEqualsOrHigher(modId, version)) { if (isObfEnv == null) { try { isObfEnv = (Class.forName("net.minecraft.world.World").getDeclaredField("chunkProvider") == null); } catch (Throwable e) { isObfEnv = true; } } bytes = transform(name, transformedName, BaseEncoding.base64().decode(isObfEnv ? classData : classDataDev)); } } else { throw new UnsupportedOperationException("Can't parse the annotations correctly"); } } } } } return bytes; } try { if (name.startsWith("logisticspipes.proxy.opencomputers.asm.BaseWrapperClass$") && name.endsWith("$OpenComputersWrapper")) { String correctName = name.substring(56, name.length() - 21); Class clazz = Launch.classLoader.findClass(correctName); bytes = ClassCreator.getWrappedClassAsBytes(CCObjectWrapper.getWrapperInformation(clazz), clazz.getName()); Set set = new TreeSet<>(); set.add(name); Launch.classLoader.clearNegativeEntries(set); Map map = (Map) fResourceCache.get(Launch.classLoader); map.put(name, bytes); return bytes; } } catch (Exception e) { if (LogisticsPipes.isDEBUG()) { // For better Debugging e.printStackTrace(); return bytes; } throw new RuntimeException(e); } return bytes; } } ================================================ FILE: common/logisticspipes/asm/LogisticsPipesCoreLoader.java ================================================ package logisticspipes.asm; import java.util.Map; import net.minecraft.launchwrapper.Launch; import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; import lombok.Getter; @IFMLLoadingPlugin.MCVersion("1.12.2") //@IFMLLoadingPlugin.SortingIndex(1001) TODO: For next MC update. Changing this now, will change ASM check sums as well. public class LogisticsPipesCoreLoader implements IFMLLoadingPlugin { @Getter private static boolean coremodLoaded = false; private static boolean developmentEnvironment = false; public LogisticsPipesCoreLoader() throws Exception { Launch.classLoader.addTransformerExclusion("logisticspipes.asm."); coremodLoaded = true; } @Override public String[] getASMTransformerClass() { return new String[] { "logisticspipes.asm.LogisticsClassTransformer" }; } @Override public String getModContainerClass() { return null; } @Override public String getSetupClass() { return null; } @Override public void injectData(Map data) { if (data.containsKey("runtimeDeobfuscationEnabled")) { developmentEnvironment = !((Boolean) data.get("runtimeDeobfuscationEnabled")); } } @Override public String getAccessTransformerClass() { return null; } public static boolean isDevelopmentEnvironment() { return developmentEnvironment; } } ================================================ FILE: common/logisticspipes/asm/ModAccessTransformerRemapper.java ================================================ package logisticspipes.asm; import java.lang.reflect.Field; import java.util.Map; import java.util.Objects; import javax.annotation.Nonnull; import net.minecraft.launchwrapper.IClassTransformer; import net.minecraftforge.fml.common.asm.transformers.AccessTransformer; import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; import com.google.common.collect.Multimap; public class ModAccessTransformerRemapper { private final Map> fieldMappings; private final Map> methodMappings; private final Field modifiersField; private Field modifierDesc; private Field modifierName; @SuppressWarnings("unchecked") public ModAccessTransformerRemapper() { try { final Field rawFieldMaps = FMLDeobfuscatingRemapper.class.getDeclaredField("rawFieldMaps"); final boolean wasAccessible = rawFieldMaps.isAccessible(); if (!wasAccessible) rawFieldMaps.setAccessible(true); fieldMappings = (Map>) rawFieldMaps.get(FMLDeobfuscatingRemapper.INSTANCE); if (!wasAccessible) rawFieldMaps.setAccessible(false); } catch (IllegalAccessException | NoSuchFieldException e) { throw new IllegalStateException("Could not access rawFieldMaps of FMLDeobfuscatingRemapper", e); } try { final Field rawMethodMaps = FMLDeobfuscatingRemapper.class.getDeclaredField("rawMethodMaps"); final boolean wasAccessible = rawMethodMaps.isAccessible(); if (!wasAccessible) rawMethodMaps.setAccessible(true); methodMappings = (Map>) rawMethodMaps.get(FMLDeobfuscatingRemapper.INSTANCE); if (!wasAccessible) rawMethodMaps.setAccessible(false); } catch (IllegalAccessException | NoSuchFieldException e) { throw new IllegalStateException("Could not access rawMethodMaps of FMLDeobfuscatingRemapper", e); } try { modifiersField = AccessTransformer.class.getDeclaredField("modifiers"); } catch (NoSuchFieldException e) { throw new IllegalStateException("Could not access modifiers field of AccessTransformer", e); } } public void apply(IClassTransformer modAT) { final Multimap modifiersMap = getModifiers(modAT); if (modifiersMap.isEmpty()) return; modifiersMap.forEach(this::applySingleModifier); if (modifierDesc != null) { modifierDesc.setAccessible(false); modifierDesc = null; } if (modifierName != null) { modifierName.setAccessible(false); modifierName = null; } } @SuppressWarnings("unchecked") @Nonnull private Multimap getModifiers(IClassTransformer modAT) { final boolean wasAccessible = modifiersField.isAccessible(); if (!wasAccessible) modifiersField.setAccessible(true); final Multimap modifiersMap; // String to AccessTransformer.Modifier try { modifiersMap = (Multimap) modifiersField.get(modAT); } catch (IllegalAccessException | ClassCastException e) { throw new IllegalStateException("Could not access modifiers field of " + modAT, e); } finally { if (!wasAccessible) modifiersField.setAccessible(false); } return modifiersMap; } private void applySingleModifier(String className, Object modifier) { final String classKey = className.replaceAll("\\.", "/"); final String desc, name; try { name = getName(modifier); if (name.equals("*")) return; // doesn't need mapping desc = getDesc(modifier); } catch (RuntimeException e) { e.printStackTrace(); return; } if (desc.isEmpty() && fieldMappings.containsKey(classKey)) { final Map classFieldMappings = fieldMappings.get(classKey); classFieldMappings.keySet().stream() .filter(obfNameWithType -> obfNameWithType.startsWith(name + ":")) .findAny() .ifPresent(obfNameWithType -> { final String newName = classFieldMappings.get(obfNameWithType); System.out.printf("Remapping class %s field %s -> %s%n", className, name, newName); setName(modifier, newName); }); } else if (methodMappings.containsKey(classKey)) { final Map classMethodMappings = methodMappings.get(classKey); classMethodMappings.keySet().stream() .filter(obfNameWithType -> obfNameWithType.startsWith(name + "(") && obfNameWithType.endsWith(desc)) .findAny() .ifPresent(obfNameWithType -> { final String newName = classMethodMappings.get(obfNameWithType); System.out.printf("Remapping class %s method %s %s -> %s%n", className, name, desc, newName); setName(modifier, newName); }); } } private String getDesc(Object modifier) { Objects.requireNonNull(modifier, "Modifier may not be null"); ensureModifierDesc(modifier); try { return (String) modifierDesc.get(modifier); } catch (IllegalAccessException e) { throw new IllegalStateException("Could not access desc field", e); } } private void ensureModifierDesc(@Nonnull Object modifier) { if (modifierDesc == null) { try { modifierDesc = modifier.getClass().getDeclaredField("desc"); } catch (NoSuchFieldException e) { throw new IllegalStateException("Could not find desc field", e); } } if (!modifierDesc.isAccessible()) modifierDesc.setAccessible(true); } private String getName(Object modifier) { Objects.requireNonNull(modifier, "Modifier may not be null"); ensureModifierName(modifier); try { return (String) modifierName.get(modifier); } catch (IllegalAccessException e) { throw new IllegalStateException("Could not access name field", e); } } private void setName(Object modifier, String newName) { Objects.requireNonNull(modifier, "Modifier may not be null"); ensureModifierName(modifier); try { modifierName.set(modifier, newName); } catch (IllegalAccessException e) { throw new IllegalStateException("Could not access name field", e); } } private void ensureModifierName(@Nonnull Object modifier) { if (modifierName == null) { try { modifierName = modifier.getClass().getDeclaredField("name"); } catch (NoSuchFieldException e) { throw new IllegalStateException("Could not find name field", e); } } if (!modifierName.isAccessible()) modifierName.setAccessible(true); } } ================================================ FILE: common/logisticspipes/asm/ModDependentField.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ModDependentField { String modId(); } ================================================ FILE: common/logisticspipes/asm/ModDependentInterface.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ModDependentInterface { String[] modId(); String[] interfacePath(); } ================================================ FILE: common/logisticspipes/asm/ModDependentMethod.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ModDependentMethod { String modId(); } ================================================ FILE: common/logisticspipes/asm/ModDependentMethodName.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ModDependentMethodName { String modId(); String newName(); String version(); } ================================================ FILE: common/logisticspipes/asm/ModVersionedClass.java ================================================ package logisticspipes.asm; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ModVersionedClass { String modId(); String version(); // Everything below this version will cause the fallback String classData(); // Fallback class data Base64 encoded String classDataDev(); // Fallbacl class data Baste64 encoded for dev } ================================================ FILE: common/logisticspipes/asm/ParamProfiler.java ================================================ package logisticspipes.asm; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; import java.util.WeakHashMap; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; public class ParamProfiler { private static final boolean isActive = false; private static volatile long minMethodId = 0; public static byte[] handleClass(byte[] bytes) { if (!isActive) return bytes; final ClassReader reader = new ClassReader(bytes); final ClassNode node = new ClassNode(); reader.accept(node, 0); final String className = node.name; for (final MethodNode m : node.methods) { final String methodName = m.name; final String methodDesc = m.desc; final boolean isConst = methodName.contains("<") || methodName.contains(">"); if (isConst) continue; final long methodId = minMethodId++; final List varList = new ArrayList<>(); if (!methodDesc.startsWith("(")) throw new UnsupportedOperationException(methodDesc); outer: for (int i = 1; i < methodDesc.length(); i++) { switch (methodDesc.charAt(i)) { case ')': break outer; case 'L': int startA = i; while (methodDesc.charAt(i) != ';') i++; varList.add(methodDesc.substring(startA, i + 1)); break; case '[': int startB = i; while (methodDesc.charAt(i) == '[') i++; if (methodDesc.charAt(i) == 'L') { while (methodDesc.charAt(i) != ';') i++; } varList.add(methodDesc.substring(startB, i + 1)); break; default: varList.add(String.valueOf(methodDesc.charAt(i))); } } final List