From b429095f88c5c5324e8609c84c8e0e958fb1c8aa Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Wed, 9 Jun 2021 07:53:21 +0100 Subject: [PATCH] Reformat everything --- .../dan200/computercraft/ComputerCraft.java | 96 +- .../computercraft/ComputerCraftAPIImpl.java | 148 ++-- .../computercraft/api/ComputerCraftAPI.java | 151 ++-- .../api/client/TransformedModel.java | 75 +- .../api/filesystem/FileAttributes.java | 35 +- .../filesystem/FileOperationException.java | 21 +- .../api/filesystem/IFileSystem.java | 15 +- .../computercraft/api/filesystem/IMount.java | 39 +- .../api/filesystem/IWritableMount.java | 30 +- .../computercraft/api/lua/IArguments.java | 253 +++--- .../api/lua/IComputerSystem.java | 7 +- .../api/lua/IDynamicLuaObject.java | 13 +- .../dan200/computercraft/api/lua/ILuaAPI.java | 12 +- .../computercraft/api/lua/ILuaAPIFactory.java | 9 +- .../computercraft/api/lua/ILuaCallback.java | 5 +- .../computercraft/api/lua/ILuaContext.java | 5 +- .../computercraft/api/lua/ILuaFunction.java | 5 +- .../computercraft/api/lua/ILuaObject.java | 5 +- .../computercraft/api/lua/ILuaTask.java | 5 +- .../computercraft/api/lua/LuaException.java | 19 +- .../computercraft/api/lua/LuaFunction.java | 19 +- .../computercraft/api/lua/LuaValues.java | 99 ++- .../computercraft/api/lua/MethodResult.java | 91 +- .../api/lua/ObjectArguments.java | 48 +- .../computercraft/api/media/IMedia.java | 26 +- .../api/media/IMediaProvider.java | 9 +- .../api/network/IPacketNetwork.java | 13 +- .../api/network/IPacketReceiver.java | 17 +- .../api/network/IPacketSender.java | 7 +- .../computercraft/api/network/Packet.java | 54 +- .../api/network/wired/IWiredElement.java | 10 +- .../api/network/wired/IWiredNetwork.java | 24 +- .../network/wired/IWiredNetworkChange.java | 8 +- .../api/network/wired/IWiredNode.java | 30 +- .../api/network/wired/IWiredSender.java | 7 +- .../api/peripheral/IComputerAccess.java | 67 +- .../api/peripheral/IDynamicPeripheral.java | 24 +- .../api/peripheral/IPeripheral.java | 18 +- .../api/peripheral/IPeripheralProvider.java | 16 +- .../api/peripheral/IPeripheralTile.java | 11 +- .../api/peripheral/IWorkMonitor.java | 25 +- .../api/peripheral/NotAttachedException.java | 13 +- .../api/pocket/AbstractPocketUpgrade.java | 29 +- .../api/pocket/IPocketAccess.java | 21 +- .../api/pocket/IPocketUpgrade.java | 23 +- .../redstone/IBundledRedstoneProvider.java | 13 +- .../api/turtle/AbstractTurtleUpgrade.java | 37 +- .../computercraft/api/turtle/FakePlayer.java | 158 ++-- .../api/turtle/ITurtleAccess.java | 55 +- .../api/turtle/ITurtleCommand.java | 5 +- .../api/turtle/ITurtleUpgrade.java | 41 +- .../api/turtle/TurtleAnimation.java | 3 +- .../api/turtle/TurtleCommandResult.java | 41 +- .../computercraft/api/turtle/TurtleSide.java | 3 +- .../api/turtle/TurtleUpgradeType.java | 9 +- .../computercraft/api/turtle/TurtleVerb.java | 3 +- .../api/turtle/event/TurtleAction.java | 3 +- .../api/turtle/event/TurtleActionEvent.java | 36 +- .../api/turtle/event/TurtleAttackEvent.java | 33 +- .../api/turtle/event/TurtleBlockEvent.java | 103 ++- .../api/turtle/event/TurtleEvent.java | 23 +- .../turtle/event/TurtleInspectItemEvent.java | 43 +- .../turtle/event/TurtleInventoryEvent.java | 46 +- .../api/turtle/event/TurtlePlayerEvent.java | 20 +- .../api/turtle/event/TurtleRefuelEvent.java | 38 +- .../computercraft/client/ClientRegistry.java | 100 ++- .../client/ClientTableFormatter.java | 58 +- .../computercraft/client/FrameInfo.java | 28 +- .../client/gui/FixedWidthFontRenderer.java | 491 ++++++----- .../computercraft/client/gui/GuiComputer.java | 106 ++- .../client/gui/GuiDiskDrive.java | 33 +- .../computercraft/client/gui/GuiPrinter.java | 38 +- .../computercraft/client/gui/GuiPrintout.java | 106 ++- .../computercraft/client/gui/GuiTurtle.java | 93 +- .../client/gui/widgets/WidgetTerminal.java | 341 ++++--- .../client/gui/widgets/WidgetWrapper.java | 61 +- .../proxy/ComputerCraftProxyClient.java | 125 +-- .../client/render/CableHighlightRenderer.java | 52 +- .../client/render/ComputerBorderRenderer.java | 125 +-- .../client/render/ItemMapLikeRenderer.java | 135 +-- .../client/render/ItemPocketRenderer.java | 105 +-- .../client/render/ItemPrintoutRenderer.java | 78 +- .../client/render/ModelTransformer.java | 77 +- .../render/MonitorHighlightRenderer.java | 147 ++-- .../render/MonitorTextureBufferShader.java | 179 ++-- .../client/render/PrintoutRenderer.java | 240 ++--- .../render/TileEntityMonitorRenderer.java | 277 +++--- .../render/TileEntityTurtleRenderer.java | 220 ++--- .../client/render/TurtleModelLoader.java | 101 ++- .../client/render/TurtleMultiModel.java | 102 ++- .../client/render/TurtlePlayerRenderer.java | 27 +- .../client/render/TurtleSmartItemModel.java | 132 +-- .../computercraft/core/apis/ApiFactories.java | 26 +- .../core/apis/ComputerAccess.java | 138 +-- .../dan200/computercraft/core/apis/FSAPI.java | 358 +++++--- .../core/apis/FastLuaException.java | 20 +- .../computercraft/core/apis/HTTPAPI.java | 4 +- .../core/apis/IAPIEnvironment.java | 45 +- .../computercraft/core/apis/LuaDateTime.java | 409 +++++---- .../dan200/computercraft/core/apis/OSAPI.java | 329 ++++--- .../core/apis/PeripheralAPI.java | 329 ++++--- .../computercraft/core/apis/RedstoneAPI.java | 88 +- .../computercraft/core/apis/TableHelper.java | 209 +++-- .../computercraft/core/apis/TermAPI.java | 35 +- .../computercraft/core/apis/TermMethods.java | 210 +++-- .../core/apis/http/CheckUrl.java | 48 +- .../core/apis/http/HTTPRequestException.java | 11 +- .../core/apis/http/NetworkUtils.java | 134 +-- .../core/apis/http/Resource.java | 93 +- .../core/apis/http/ResourceGroup.java | 43 +- .../core/apis/http/ResourceQueue.java | 41 +- .../core/apis/http/options/Action.java | 8 +- .../core/apis/http/options/AddressRule.java | 64 +- .../apis/http/options/AddressRuleConfig.java | 189 ++-- .../core/apis/http/options/Options.java | 9 +- .../apis/http/options/PartialOptions.java | 45 +- .../core/apis/http/request/HttpRequest.java | 278 +++--- .../apis/http/request/HttpResponseHandle.java | 28 +- .../core/apis/http/websocket/Websocket.java | 217 +++-- .../apis/http/websocket/WebsocketHandle.java | 106 ++- .../apis/http/websocket/WebsocketHandler.java | 113 ++- .../core/asm/DeclaringClassLoader.java | 13 +- .../computercraft/core/asm/Generator.java | 415 +++++---- .../computercraft/core/asm/IntCache.java | 35 +- .../computercraft/core/asm/LuaMethod.java | 28 +- .../computercraft/core/asm/NamedMethod.java | 15 +- .../computercraft/core/asm/ObjectSource.java | 22 +- .../core/asm/PeripheralMethod.java | 36 +- .../computercraft/core/asm/Reflect.java | 104 ++- .../computercraft/core/asm/TaskCallback.java | 58 +- .../core/computer/ApiWrapper.java | 21 +- .../computercraft/core/computer/Computer.java | 128 ++- .../core/computer/ComputerExecutor.java | 460 ++++++---- .../core/computer/ComputerSide.java | 23 +- .../core/computer/ComputerSystem.java | 34 +- .../core/computer/ComputerThread.java | 357 +++++--- .../core/computer/Environment.java | 211 +++-- .../core/computer/IComputerEnvironment.java | 18 +- .../core/computer/MainThread.java | 107 ++- .../core/computer/MainThreadExecutor.java | 109 ++- .../core/computer/TimeoutState.java | 47 +- .../core/filesystem/ComboMount.java | 109 ++- .../core/filesystem/EmptyMount.java | 29 +- .../core/filesystem/FileMount.java | 392 +++++---- .../core/filesystem/FileSystemException.java | 8 +- .../filesystem/FileSystemWrapperMount.java | 192 ++-- .../core/filesystem/JarMount.java | 283 +++--- .../core/filesystem/MountWrapper.java | 366 +++++--- .../core/filesystem/ResourceMount.java | 276 +++--- .../core/filesystem/SubMount.java | 46 +- .../computercraft/core/lua/BasicFunction.java | 45 +- .../core/lua/CobaltLuaMachine.java | 689 ++++++++------- .../computercraft/core/lua/ILuaMachine.java | 18 +- .../computercraft/core/lua/MachineResult.java | 38 +- .../core/lua/ResultInterpreterFunction.java | 109 ++- .../core/lua/VarargArguments.java | 114 +-- .../computercraft/core/terminal/Terminal.java | 329 ++++--- .../core/tracking/ComputerTracker.java | 86 +- .../computercraft/core/tracking/Tracker.java | 20 +- .../computercraft/core/tracking/Tracking.java | 95 +- .../core/tracking/TrackingContext.java | 104 ++- .../core/tracking/TrackingField.java | 81 +- .../fabric/events/ClientUnloadWorldEvent.java | 5 +- .../mixin/AffineTransformationAccess.java | 22 +- .../fabric/mixin/BakedQuadAccess.java | 14 +- .../fabric/mixin/ChatHudAccess.java | 16 +- .../fabric/mixin/HeldItemRendererAccess.java | 22 +- .../fabric/mixin/MinecraftServerAccess.java | 14 +- .../fabric/mixin/MixinBlock.java | 26 +- .../fabric/mixin/MixinEntity.java | 26 +- .../fabric/mixin/MixinHeldItemRenderer.java | 59 +- .../mixin/MixinItemFrameEntityRenderer.java | 33 +- .../fabric/mixin/MixinMinecraftClient.java | 20 +- .../fabric/mixin/MixinScreen.java | 23 +- .../MixinServerPlayerInteractionManager.java | 24 +- .../fabric/mixin/MixinServerWorld.java | 20 +- .../fabric/mixin/MixinWorld.java | 51 +- .../fabric/mixin/MixinWorldRenderer.java | 59 +- .../fabric/mixin/MusicDiscItemAccessor.java | 5 +- .../fabric/mixin/SignBlockEntityAccess.java | 14 +- .../fabric/mixin/SoundEventAccess.java | 14 +- .../fabric/mixin/WorldSavePathAccess.java | 12 +- .../computercraft/shared/BundledRedstone.java | 55 +- .../shared/ComputerCraftRegistry.java | 380 ++++---- .../computercraft/shared/MediaProviders.java | 47 +- .../computercraft/shared/Peripherals.java | 52 +- .../computercraft/shared/PocketUpgrades.java | 4 +- .../shared/TurtlePermissions.java | 22 +- .../computercraft/shared/TurtleUpgrades.java | 10 +- .../shared/command/CommandComputerCraft.java | 1 - .../shared/command/CommandUtils.java | 69 +- .../shared/command/Exceptions.java | 35 +- .../arguments/ArgumentSerializers.java | 32 +- .../command/arguments/ChoiceArgumentType.java | 62 +- .../arguments/ComputerArgumentType.java | 74 +- .../arguments/ComputersArgumentType.java | 195 ++-- .../command/arguments/RepeatArgumentType.java | 125 +-- .../arguments/TrackingFieldArgumentType.java | 17 +- .../shared/command/builder/ArgCommand.java | 5 +- .../command/builder/CommandBuilder.java | 115 +-- .../command/builder/CommandNodeBuilder.java | 5 +- .../builder/HelpingArgumentBuilder.java | 205 +++-- .../shared/command/text/ChatHelpers.java | 2 +- .../command/text/ServerTableFormatter.java | 36 +- .../shared/command/text/TableBuilder.java | 103 ++- .../shared/command/text/TableFormatter.java | 116 +-- .../shared/common/BlockGeneric.java | 67 +- .../shared/common/ClientTerminal.java | 68 +- .../shared/common/ColourableRecipe.java | 57 +- .../shared/common/ContainerHeldItem.java | 60 +- .../DefaultBundledRedstoneProvider.java | 28 +- .../shared/common/IBundledRedstoneBlock.java | 7 +- .../shared/common/IColouredItem.java | 35 +- .../shared/common/ITerminal.java | 3 +- .../shared/common/ServerTerminal.java | 78 +- .../shared/common/TileGeneric.java | 68 +- .../shared/computer/apis/CommandAPI.java | 201 +++-- .../shared/computer/blocks/BlockComputer.java | 40 +- .../computer/blocks/BlockComputerBase.java | 153 ++-- .../computer/blocks/ComputerPeripheral.java | 39 +- .../shared/computer/blocks/ComputerProxy.java | 52 +- .../shared/computer/blocks/IComputerTile.java | 7 +- .../computer/blocks/TileCommandComputer.java | 110 ++- .../shared/computer/blocks/TileComputer.java | 76 +- .../computer/blocks/TileComputerBase.java | 348 +++++--- .../shared/computer/core/ClientComputer.java | 89 +- .../computer/core/ClientComputerRegistry.java | 8 +- .../shared/computer/core/ComputerFamily.java | 3 +- .../computer/core/ComputerRegistry.java | 51 +- .../shared/computer/core/ComputerState.java | 18 +- .../shared/computer/core/IComputer.java | 16 +- .../computer/core/IContainerComputer.java | 8 +- .../shared/computer/core/InputHandler.java | 83 +- .../shared/computer/core/InputState.java | 84 +- .../shared/computer/core/ServerComputer.java | 252 ++++-- .../computer/core/ServerComputerRegistry.java | 56 +- .../computer/inventory/ContainerComputer.java | 14 +- .../inventory/ContainerComputerBase.java | 79 +- .../inventory/ContainerViewComputer.java | 34 +- .../computer/items/ComputerItemFactory.java | 35 +- .../shared/computer/items/IComputerItem.java | 20 +- .../shared/computer/items/ItemComputer.java | 38 +- .../computer/items/ItemComputerBase.java | 64 +- .../recipe/ComputerConvertRecipe.java | 45 +- .../computer/recipe/ComputerFamilyRecipe.java | 72 +- .../recipe/ComputerUpgradeRecipe.java | 39 +- .../data/BlockNamedEntityLootCondition.java | 30 +- .../data/ConstantLootConditionSerializer.java | 22 +- .../data/HasComputerIdLootCondition.java | 31 +- .../data/PlayerCreativeLootCondition.java | 30 +- .../integration/ModMenuIntegration.java | 8 +- .../shared/media/items/ItemDisk.java | 102 ++- .../shared/media/items/ItemPrintout.java | 127 +-- .../shared/media/items/ItemTreasureDisk.java | 111 ++- .../shared/media/items/RecordMedia.java | 30 +- .../shared/media/recipes/DiskRecipe.java | 69 +- .../shared/media/recipes/PrintoutRecipe.java | 117 ++- .../shared/network/NetworkHandler.java | 145 +-- .../shared/network/NetworkMessage.java | 17 +- .../client/ChatTableClientMessage.java | 89 +- .../network/client/ComputerClientMessage.java | 35 +- .../client/ComputerDataClientMessage.java | 38 +- .../client/ComputerDeletedClientMessage.java | 17 +- .../client/ComputerTerminalClientMessage.java | 35 +- .../network/client/MonitorClientMessage.java | 37 +- .../client/PlayRecordClientMessage.java | 65 +- .../shared/network/client/TerminalState.java | 165 ++-- .../container/ComputerContainerData.java | 35 +- .../network/container/ContainerData.java | 36 +- .../container/HeldItemContainerData.java | 24 +- .../container/ViewComputerContainerData.java | 52 +- .../server/ComputerActionServerMessage.java | 57 +- .../network/server/ComputerServerMessage.java | 40 +- .../network/server/KeyEventServerMessage.java | 44 +- .../server/MouseEventServerMessage.java | 64 +- .../server/QueueEventServerMessage.java | 41 +- .../server/RequestComputerMessage.java | 33 +- .../commandblock/CommandBlockPeripheral.java | 49 +- .../peripheral/diskdrive/BlockDiskDrive.java | 74 +- .../diskdrive/ContainerDiskDrive.java | 75 +- .../diskdrive/DiskDrivePeripheral.java | 104 ++- .../peripheral/diskdrive/DiskDriveState.java | 15 +- .../peripheral/diskdrive/TileDiskDrive.java | 427 +++++---- .../peripheral/generic/GenericPeripheral.java | 12 +- .../peripheral/generic/data/BlockData.java | 9 +- .../peripheral/generic/data/DataHelpers.java | 9 +- .../peripheral/generic/data/ItemData.java | 14 +- .../generic/methods/InventoryMethods.java | 45 +- .../peripheral/modem/ModemPeripheral.java | 177 ++-- .../shared/peripheral/modem/ModemShapes.java | 22 +- .../shared/peripheral/modem/ModemState.java | 79 +- .../peripheral/modem/wired/BlockCable.java | 217 ++--- .../modem/wired/BlockWiredModemFull.java | 24 +- .../modem/wired/CableModemVariant.java | 77 +- .../peripheral/modem/wired/CableShapes.java | 181 ++-- .../modem/wired/ItemBlockCable.java | 140 +-- .../peripheral/modem/wired/TileCable.java | 320 ++++--- .../modem/wired/TileWiredModemFull.java | 324 ++++--- .../modem/wired/WiredModemElement.java | 53 +- .../wired/WiredModemLocalPeripheral.java | 104 ++- .../modem/wired/WiredModemPeripheral.java | 305 ++++--- .../modem/wireless/BlockWirelessModem.java | 76 +- .../modem/wireless/TileWirelessModem.java | 87 +- .../wireless/WirelessModemPeripheral.java | 34 +- .../modem/wireless/WirelessNetwork.java | 90 +- .../peripheral/monitor/BlockMonitor.java | 68 +- .../peripheral/monitor/ClientMonitor.java | 144 +-- .../peripheral/monitor/MonitorEdgeState.java | 60 +- .../peripheral/monitor/MonitorPeripheral.java | 67 +- .../peripheral/monitor/MonitorRenderer.java | 45 +- .../peripheral/monitor/ServerMonitor.java | 67 +- .../peripheral/monitor/TileMonitor.java | 598 ++++++++----- .../shared/peripheral/monitor/XYPair.java | 92 +- .../peripheral/printer/BlockPrinter.java | 76 +- .../peripheral/printer/ContainerPrinter.java | 104 ++- .../peripheral/printer/PrinterPeripheral.java | 71 +- .../peripheral/printer/TilePrinter.java | 398 +++++---- .../peripheral/speaker/BlockSpeaker.java | 31 +- .../peripheral/speaker/SpeakerPeripheral.java | 106 ++- .../peripheral/speaker/TileSpeaker.java | 40 +- .../shared/pocket/apis/PocketAPI.java | 92 +- .../pocket/core/PocketServerComputer.java | 141 +-- .../inventory/ContainerPocketComputer.java | 48 +- .../pocket/items/ItemPocketComputer.java | 358 +++++--- .../items/PocketComputerItemFactory.java | 26 +- .../pocket/peripherals/PocketModem.java | 38 +- .../peripherals/PocketModemPeripheral.java | 25 +- .../pocket/peripherals/PocketSpeaker.java | 31 +- .../peripherals/PocketSpeakerPeripheral.java | 16 +- .../recipes/PocketComputerUpgradeRecipe.java | 85 +- .../proxy/ComputerCraftProxyCommon.java | 95 +- .../shared/turtle/FurnaceRefuelHandler.java | 53 +- .../shared/turtle/SignInspectHandler.java | 28 +- .../shared/turtle/apis/TurtleAPI.java | 342 +++---- .../shared/turtle/blocks/BlockTurtle.java | 120 +-- .../shared/turtle/blocks/ITurtleTile.java | 12 +- .../shared/turtle/blocks/TileTurtle.java | 439 +++++---- .../shared/turtle/core/InteractDirection.java | 24 +- .../shared/turtle/core/MoveDirection.java | 30 +- .../shared/turtle/core/TurnDirection.java | 3 +- .../shared/turtle/core/TurtleBrain.java | 833 ++++++++++-------- .../turtle/core/TurtleCommandQueueEntry.java | 6 +- .../turtle/core/TurtleCompareCommand.java | 50 +- .../turtle/core/TurtleCompareToCommand.java | 25 +- .../turtle/core/TurtleCraftCommand.java | 41 +- .../turtle/core/TurtleDetectCommand.java | 20 +- .../shared/turtle/core/TurtleDropCommand.java | 74 +- .../turtle/core/TurtleEquipCommand.java | 75 +- .../turtle/core/TurtleInspectCommand.java | 56 +- .../shared/turtle/core/TurtleMoveCommand.java | 144 +-- .../turtle/core/TurtlePlaceCommand.java | 354 +++++--- .../shared/turtle/core/TurtlePlayer.java | 143 +-- .../turtle/core/TurtleRefuelCommand.java | 42 +- .../shared/turtle/core/TurtleSuckCommand.java | 136 +-- .../shared/turtle/core/TurtleToolCommand.java | 77 +- .../turtle/core/TurtleTransferToCommand.java | 39 +- .../shared/turtle/core/TurtleTurnCommand.java | 56 +- .../turtle/inventory/ContainerTurtle.java | 132 +-- .../shared/turtle/items/ITurtleItem.java | 18 +- .../shared/turtle/items/ItemTurtle.java | 142 +-- .../turtle/items/TurtleItemFactory.java | 47 +- .../shared/turtle/recipes/TurtleRecipe.java | 45 +- .../turtle/recipes/TurtleUpgradeRecipe.java | 144 +-- .../upgrades/CraftingTablePeripheral.java | 34 +- .../shared/turtle/upgrades/TurtleAxe.java | 21 +- .../turtle/upgrades/TurtleCraftingTable.java | 46 +- .../shared/turtle/upgrades/TurtleHoe.java | 42 +- .../upgrades/TurtleInventoryCrafting.java | 210 +++-- .../shared/turtle/upgrades/TurtleModem.java | 131 +-- .../shared/turtle/upgrades/TurtleShovel.java | 42 +- .../shared/turtle/upgrades/TurtleSpeaker.java | 71 +- .../shared/turtle/upgrades/TurtleSword.java | 28 +- .../shared/turtle/upgrades/TurtleTool.java | 222 ++--- .../computercraft/shared/util/Colour.java | 73 +- .../shared/util/ColourTracker.java | 18 +- .../shared/util/ColourUtils.java | 10 +- .../shared/util/CommentedConfigSpec.java | 42 +- .../computercraft/shared/util/Config.java | 421 ++++----- .../shared/util/DefaultInventory.java | 19 +- .../shared/util/DefaultSidedInventory.java | 17 +- .../shared/util/DirectionUtil.java | 43 +- .../shared/util/DropConsumer.java | 72 +- .../shared/util/FakeNetHandler.java | 224 +++-- .../shared/util/FixedPointTileEntityType.java | 40 +- .../computercraft/shared/util/Holiday.java | 3 +- .../shared/util/HolidayUtil.java | 27 +- .../computercraft/shared/util/IDAssigner.java | 95 +- .../shared/util/ImpostorRecipe.java | 71 +- .../shared/util/ImpostorShapelessRecipe.java | 92 +- .../shared/util/InventoryDelegate.java | 75 +- .../shared/util/InventoryUtil.java | 137 +-- .../computercraft/shared/util/IoUtil.java | 19 +- .../shared/util/ItemStorage.java | 237 +++-- .../computercraft/shared/util/NBTUtil.java | 290 +++--- .../computercraft/shared/util/Palette.java | 93 +- .../computercraft/shared/util/RecipeUtil.java | 104 ++- .../computercraft/shared/util/RecordUtil.java | 11 +- .../shared/util/RedstoneUtil.java | 14 +- .../shared/util/SingleIntArray.java | 12 +- .../computercraft/shared/util/StringUtil.java | 32 +- .../shared/util/ThreadUtils.java | 40 +- .../shared/util/TickScheduler.java | 44 +- .../shared/util/ValidatingSlot.java | 15 +- .../shared/util/WaterloggableHelpers.java | 28 +- .../computercraft/shared/util/WorldUtil.java | 196 +++-- .../shared/wired/InvariantChecker.java | 38 +- .../shared/wired/WiredNetwork.java | 503 ++++++----- .../shared/wired/WiredNetworkChange.java | 107 ++- .../computercraft/shared/wired/WiredNode.java | 134 +-- 409 files changed, 20797 insertions(+), 15102 deletions(-) diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java index 0e5ff357b..c77ba5d3c 100644 --- a/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/src/main/java/dan200/computercraft/ComputerCraft.java @@ -6,15 +6,6 @@ package dan200.computercraft; -import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks; -import static dan200.computercraft.shared.ComputerCraftRegistry.init; - -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.concurrent.TimeUnit; - import dan200.computercraft.api.turtle.event.TurtleAction; import dan200.computercraft.core.apis.http.options.Action; import dan200.computercraft.core.apis.http.options.AddressRule; @@ -32,22 +23,31 @@ import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe; import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon; import dan200.computercraft.shared.turtle.recipes.TurtleRecipe; import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe; -import dan200.computercraft.shared.util.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import net.minecraft.item.ItemGroup; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; - +import dan200.computercraft.shared.util.ImpostorRecipe; +import dan200.computercraft.shared.util.ImpostorShapelessRecipe; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourcePackActivationType; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -public final class ComputerCraft implements ModInitializer { +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks; +import static dan200.computercraft.shared.ComputerCraftRegistry.init; + +public final class ComputerCraft implements ModInitializer +{ public static final String MOD_ID = "computercraft"; // Configuration fields @@ -61,16 +61,15 @@ public final class ComputerCraft implements ModInitializer { public static boolean commandRequireCreative = true; public static int computerThreads = 1; - public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10); - public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); + public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( 10 ); + public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( 5 ); public static boolean httpEnabled = true; public static boolean httpWebsocketEnabled = true; public static List httpRules = Collections.unmodifiableList( Arrays.asList( - AddressRule.parse( "$private", null, Action.DENY.toPartial() ), - AddressRule.parse( "*", null, Action.ALLOW.toPartial() ) - )); - + AddressRule.parse( "$private", null, Action.DENY.toPartial() ), + AddressRule.parse( "*", null, Action.ALLOW.toPartial() ) + ) ); public static int httpMaxRequests = 16; public static int httpMaxWebsockets = 4; @@ -89,7 +88,7 @@ public final class ComputerCraft implements ModInitializer { public static int advancedTurtleFuelLimit = 100000; public static boolean turtlesObeyBlockProtection = true; public static boolean turtlesCanPush = true; - public static EnumSet turtleDisabledActions = EnumSet.noneOf(TurtleAction.class); + public static EnumSet turtleDisabledActions = EnumSet.noneOf( TurtleAction.class ); public static int computerTermWidth = 51; public static int computerTermHeight = 19; @@ -99,7 +98,6 @@ public final class ComputerCraft implements ModInitializer { public static int pocketTermWidth = 26; public static int pocketTermHeight = 20; - public static int monitorWidth = 8; public static int monitorHeight = 6; @@ -108,30 +106,32 @@ public final class ComputerCraft implements ModInitializer { public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry(); // Logging - public static final Logger log = LogManager.getLogger(MOD_ID); + public static final Logger log = LogManager.getLogger( MOD_ID ); - public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(ModBlocks.COMPUTER_NORMAL)); + public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build( new Identifier( MOD_ID, "main" ), () -> new ItemStack( ModBlocks.COMPUTER_NORMAL ) ); @Override - public void onInitialize() { + public void onInitialize() + { ComputerCraftProxyCommon.init(); - - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "colour"), ColourableRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "computer_upgrade"), ComputerUpgradeRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "pocket_computer_upgrade"), PocketComputerUpgradeRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "disk"), DiskRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "printout"), PrintoutRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "turtle"), TurtleRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "turtle_upgrade"), TurtleUpgradeRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "impostor_shaped"), ImpostorRecipe.SERIALIZER); - Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "impostor_shapeless"), ImpostorShapelessRecipe.SERIALIZER); - Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, "block_named"), BlockNamedEntityLootCondition.TYPE); - Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, "player_creative"), PlayerCreativeLootCondition.TYPE); - Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, "has_id"), HasComputerIdLootCondition.TYPE); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "colour" ), ColourableRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "computer_upgrade" ), ComputerUpgradeRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, + new Identifier( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ), + PocketComputerUpgradeRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "disk" ), DiskRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "printout" ), PrintoutRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "turtle" ), TurtleRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "turtle_upgrade" ), TurtleUpgradeRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "impostor_shaped" ), ImpostorRecipe.SERIALIZER ); + Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "impostor_shapeless" ), ImpostorShapelessRecipe.SERIALIZER ); + Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, "block_named" ), BlockNamedEntityLootCondition.TYPE ); + Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, "player_creative" ), PlayerCreativeLootCondition.TYPE ); + Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, "has_id" ), HasComputerIdLootCondition.TYPE ); init(); - FabricLoader.getInstance().getModContainer(MOD_ID).ifPresent(modContainer -> { - ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MOD_ID, "classic"), modContainer, ResourcePackActivationType.NORMAL); - ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MOD_ID, "overhaul"), modContainer, ResourcePackActivationType.NORMAL); - }); + FabricLoader.getInstance().getModContainer( MOD_ID ).ifPresent( modContainer -> { + ResourceManagerHelper.registerBuiltinResourcePack( new Identifier( MOD_ID, "classic" ), modContainer, ResourcePackActivationType.NORMAL ); + ResourceManagerHelper.registerBuiltinResourcePack( new Identifier( MOD_ID, "overhaul" ), modContainer, ResourcePackActivationType.NORMAL ); + } ); } -} \ No newline at end of file +} diff --git a/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java b/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java index 7176f3e61..f7e630d02 100644 --- a/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java +++ b/src/main/java/dan200/computercraft/ComputerCraftAPIImpl.java @@ -6,13 +6,6 @@ package dan200.computercraft; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; @@ -31,18 +24,14 @@ import dan200.computercraft.core.asm.GenericMethod; import dan200.computercraft.core.filesystem.FileMount; import dan200.computercraft.core.filesystem.ResourceMount; import dan200.computercraft.fabric.mixin.MinecraftServerAccess; -import dan200.computercraft.shared.BundledRedstone; -import dan200.computercraft.shared.MediaProviders; -import dan200.computercraft.shared.Peripherals; -import dan200.computercraft.shared.PocketUpgrades; -import dan200.computercraft.shared.TurtleUpgrades; +import dan200.computercraft.shared.*; import dan200.computercraft.shared.peripheral.modem.wired.TileCable; import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; import dan200.computercraft.shared.util.IDAssigner; import dan200.computercraft.shared.wired.WiredNode; import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; - +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.entity.BlockEntity; import net.minecraft.resource.ReloadableResourceManager; import net.minecraft.server.MinecraftServer; @@ -52,24 +41,35 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import net.minecraft.world.World; -import net.fabricmc.loader.api.FabricLoader; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; -public final class ComputerCraftAPIImpl implements IComputerCraftAPI { +public final class ComputerCraftAPIImpl implements IComputerCraftAPI +{ public static final ComputerCraftAPIImpl INSTANCE = new ComputerCraftAPIImpl(); private String version; - private ComputerCraftAPIImpl() { + private ComputerCraftAPIImpl() + { } - public static InputStream getResourceFile(String domain, String subPath) { + public static InputStream getResourceFile( String domain, String subPath ) + { MinecraftServer server = GameInstanceUtils.getServer(); - if (server != null) { - ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess)server).getServerResourceManager().getResourceManager(); - try { - return manager.getResource(new Identifier(domain, subPath)) - .getInputStream(); - } catch (IOException ignored) { + if( server != null ) + { + ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess) server).getServerResourceManager().getResourceManager(); + try + { + return manager.getResource( new Identifier( domain, subPath ) ) + .getInputStream(); + } + catch( IOException ignored ) + { return null; } } @@ -78,71 +78,86 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI { @Nonnull @Override - public String getInstalledVersion() { - if (this.version != null) { + public String getInstalledVersion() + { + if( this.version != null ) + { return this.version; } return this.version = FabricLoader.getInstance() - .getModContainer(ComputerCraft.MOD_ID) - .map(x -> x.getMetadata() - .getVersion() - .toString()) - .orElse("unknown"); + .getModContainer( ComputerCraft.MOD_ID ) + .map( x -> x.getMetadata() + .getVersion() + .toString() ) + .orElse( "unknown" ); } @Override - public int createUniqueNumberedSaveDir(@Nonnull World world, @Nonnull String parentSubPath) { - return IDAssigner.getNextId(parentSubPath); + public int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath ) + { + return IDAssigner.getNextId( parentSubPath ); } @Override - public IWritableMount createSaveDirMount(@Nonnull World world, @Nonnull String subPath, long capacity) { - try { - return new FileMount(new File(IDAssigner.getDir(), subPath), capacity); - } catch (Exception e) { + public IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity ) + { + try + { + return new FileMount( new File( IDAssigner.getDir(), subPath ), capacity ); + } + catch( Exception e ) + { return null; } } @Override - public IMount createResourceMount(@Nonnull String domain, @Nonnull String subPath) { + public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath ) + { MinecraftServer server = GameInstanceUtils.getServer(); - if (server != null) { - ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess)server).getServerResourceManager().getResourceManager(); - ResourceMount mount = ResourceMount.get(domain, subPath, manager); - return mount.exists("") ? mount : null; + if( server != null ) + { + ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess) server).getServerResourceManager().getResourceManager(); + ResourceMount mount = ResourceMount.get( domain, subPath, manager ); + return mount.exists( "" ) ? mount : null; } return null; } @Override - public void registerPeripheralProvider(@Nonnull IPeripheralProvider provider) { - Peripherals.register(provider); + public void registerPeripheralProvider( @Nonnull IPeripheralProvider provider ) + { + Peripherals.register( provider ); } @Override - public void registerTurtleUpgrade(@Nonnull ITurtleUpgrade upgrade) { - TurtleUpgrades.register(upgrade); + public void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade ) + { + TurtleUpgrades.register( upgrade ); } @Override - public void registerBundledRedstoneProvider(@Nonnull IBundledRedstoneProvider provider) { - BundledRedstone.register(provider); + public void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider ) + { + BundledRedstone.register( provider ); } @Override - public int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side) { - return BundledRedstone.getDefaultOutput(world, pos, side); + public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ) + { + return BundledRedstone.getDefaultOutput( world, pos, side ); } @Override - public void registerMediaProvider(@Nonnull IMediaProvider provider) { - MediaProviders.register(provider); + public void registerMediaProvider( @Nonnull IMediaProvider provider ) + { + MediaProviders.register( provider ); } @Override - public void registerPocketUpgrade(@Nonnull IPocketUpgrade upgrade) { - PocketUpgrades.register(upgrade); + public void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade ) + { + PocketUpgrades.register( upgrade ); } @Override @@ -153,28 +168,35 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI { @Nonnull @Override - public IPacketNetwork getWirelessNetwork() { + public IPacketNetwork getWirelessNetwork() + { return WirelessNetwork.getUniversal(); } @Override - public void registerAPIFactory(@Nonnull ILuaAPIFactory factory) { - ApiFactories.register(factory); + public void registerAPIFactory( @Nonnull ILuaAPIFactory factory ) + { + ApiFactories.register( factory ); } @Nonnull @Override - public IWiredNode createWiredNodeForElement(@Nonnull IWiredElement element) { - return new WiredNode(element); + public IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element ) + { + return new WiredNode( element ); } @Nullable @Override - public IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side) { - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileCable) { - return ((TileCable) tile).getElement(side); - } else if (tile instanceof TileWiredModemFull) { + public IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side ) + { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileCable ) + { + return ((TileCable) tile).getElement( side ); + } + else if( tile instanceof TileWiredModemFull ) + { return ((TileWiredModemFull) tile).getElement(); } return null; diff --git a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java index 9699b6173..c1f8ed540 100644 --- a/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java +++ b/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java @@ -6,9 +6,6 @@ package dan200.computercraft.api; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.lua.GenericSource; @@ -24,43 +21,53 @@ import dan200.computercraft.api.peripheral.IPeripheralProvider; import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.turtle.ITurtleUpgrade; - import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * The static entry point to the ComputerCraft API. * * Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is fully loaded. */ -public final class ComputerCraftAPI { +public final class ComputerCraftAPI +{ private static IComputerCraftAPI instance; @Nonnull @Deprecated - public static String getAPIVersion() { + public static String getAPIVersion() + { return getInstalledVersion(); } @Nonnull - public static String getInstalledVersion() { + public static String getInstalledVersion() + { return getInstance().getInstalledVersion(); } @Nonnull - private static IComputerCraftAPI getInstance() { - if (instance != null) { + private static IComputerCraftAPI getInstance() + { + if( instance != null ) + { return instance; } - try { - return instance = (IComputerCraftAPI) Class.forName("dan200.computercraft.ComputerCraftAPIImpl") - .getField("INSTANCE") - .get(null); - } catch (ReflectiveOperationException e) { - throw new IllegalStateException("Cannot find ComputerCraft API", e); + try + { + return instance = (IComputerCraftAPI) Class.forName( "dan200.computercraft.ComputerCraftAPIImpl" ) + .getField( "INSTANCE" ) + .get( null ); + } + catch( ReflectiveOperationException e ) + { + throw new IllegalStateException( "Cannot find ComputerCraft API", e ); } } @@ -69,15 +76,16 @@ public final class ComputerCraftAPI { * * Use in conjunction with createSaveDirMount() to create a unique place for your peripherals or media items to store files. * - * @param world The world for which the save dir should be created. This should be the server side world object. + * @param world The world for which the save dir should be created. This should be the server side world object. * @param parentSubPath The folder path within the save directory where the new directory should be created. eg: "computercraft/disk" * @return The numerical value of the name of the new folder, or -1 if the folder could not be created for some reason. * - * eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now available for writing. + * eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now available for writing. * @see #createSaveDirMount(World, String, long) */ - public static int createUniqueNumberedSaveDir(@Nonnull World world, @Nonnull String parentSubPath) { - return getInstance().createUniqueNumberedSaveDir(world, parentSubPath); + public static int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath ) + { + return getInstance().createUniqueNumberedSaveDir( world, parentSubPath ); } /** @@ -86,12 +94,12 @@ public final class ComputerCraftAPI { * Use in conjunction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a folder from the users save directory onto a computers * file system. * - * @param world The world for which the save dir can be found. This should be the server side world object. - * @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42". Use createUniqueNumberedSaveDir() - * to create a new numbered folder to use. + * @param world The world for which the save dir can be found. This should be the server side world object. + * @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42". Use createUniqueNumberedSaveDir() + * to create a new numbered folder to use. * @param capacity The amount of data that can be stored in the directory before it fills up, in bytes. * @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable() to mount this on a - * Computers' file system. + * Computers' file system. * @see #createUniqueNumberedSaveDir(World, String) * @see IComputerAccess#mount(String, IMount) * @see IComputerAccess#mountWritable(String, IWritableMount) @@ -99,8 +107,9 @@ public final class ComputerCraftAPI { * @see IWritableMount */ @Nullable - public static IWritableMount createSaveDirMount(@Nonnull World world, @Nonnull String subPath, long capacity) { - return getInstance().createSaveDirMount(world, subPath, capacity); + public static IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity ) + { + return getInstance().createSaveDirMount( world, subPath, capacity ); } /** @@ -114,7 +123,7 @@ public final class ComputerCraftAPI { * "/data/computercraft/lua/rom". We construct a mount for that with * {@code createResourceMount("computercraft", "lua/rom")}. * - * @param domain The domain under which to look for resources. eg: "mymod". + * @param domain The domain under which to look for resources. eg: "mymod". * @param subPath The subPath under which to look for resources. eg: "lua/myfiles". * @return The mount, or {@code null} if it could be created for some reason. * @see IComputerAccess#mount(String, IMount) @@ -122,8 +131,9 @@ public final class ComputerCraftAPI { * @see IMount */ @Nullable - public static IMount createResourceMount(@Nonnull String domain, @Nonnull String subPath) { - return getInstance().createResourceMount(domain, subPath); + public static IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath ) + { + return getInstance().createResourceMount( domain, subPath ); } /** @@ -133,8 +143,9 @@ public final class ComputerCraftAPI { * @see IPeripheral * @see IPeripheralProvider */ - public static void registerPeripheralProvider(@Nonnull IPeripheralProvider provider) { - getInstance().registerPeripheralProvider(provider); + public static void registerPeripheralProvider( @Nonnull IPeripheralProvider provider ) + { + getInstance().registerPeripheralProvider( provider ); } /** @@ -155,8 +166,9 @@ public final class ComputerCraftAPI { * @param upgrade The turtle upgrade to register. * @see ITurtleUpgrade */ - public static void registerTurtleUpgrade(@Nonnull ITurtleUpgrade upgrade) { - getInstance().registerTurtleUpgrade(upgrade); + public static void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade ) + { + getInstance().registerTurtleUpgrade( upgrade ); } /** @@ -165,22 +177,24 @@ public final class ComputerCraftAPI { * @param provider The bundled redstone provider to register. * @see IBundledRedstoneProvider */ - public static void registerBundledRedstoneProvider(@Nonnull IBundledRedstoneProvider provider) { - getInstance().registerBundledRedstoneProvider(provider); + public static void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider ) + { + getInstance().registerBundledRedstoneProvider( provider ); } /** * If there is a Computer or Turtle at a certain position in the world, get it's bundled redstone output. * * @param world The world this block is in. - * @param pos The position this block is at. - * @param side The side to extract the bundled redstone output from. + * @param pos The position this block is at. + * @param side The side to extract the bundled redstone output from. * @return If there is a block capable of emitting bundled redstone at the location, it's signal (0-65535) will be returned. If there is no block - * capable of emitting bundled redstone at the location, -1 will be returned. + * capable of emitting bundled redstone at the location, -1 will be returned. * @see IBundledRedstoneProvider */ - public static int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side) { - return getInstance().getBundledRedstoneOutput(world, pos, side); + public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ) + { + return getInstance().getBundledRedstoneOutput( world, pos, side ); } /** @@ -189,12 +203,14 @@ public final class ComputerCraftAPI { * @param provider The media provider to register. * @see IMediaProvider */ - public static void registerMediaProvider(@Nonnull IMediaProvider provider) { - getInstance().registerMediaProvider(provider); + public static void registerMediaProvider( @Nonnull IMediaProvider provider ) + { + getInstance().registerMediaProvider( provider ); } - public static void registerPocketUpgrade(@Nonnull IPocketUpgrade upgrade) { - getInstance().registerPocketUpgrade(upgrade); + public static void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade ) + { + getInstance().registerPocketUpgrade( upgrade ); } /** @@ -202,12 +218,14 @@ public final class ComputerCraftAPI { * * @return The global wireless network, or {@code null} if it could not be fetched. */ - public static IPacketNetwork getWirelessNetwork() { + public static IPacketNetwork getWirelessNetwork() + { return getInstance().getWirelessNetwork(); } - public static void registerAPIFactory(@Nonnull ILuaAPIFactory factory) { - getInstance().registerAPIFactory(factory); + public static void registerAPIFactory( @Nonnull ILuaAPIFactory factory ) + { + getInstance().registerAPIFactory( factory ); } /** @@ -218,59 +236,62 @@ public final class ComputerCraftAPI { * @see IWiredElement#getNode() */ @Nonnull - public static IWiredNode createWiredNodeForElement(@Nonnull IWiredElement element) { - return getInstance().createWiredNodeForElement(element); + public static IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element ) + { + return getInstance().createWiredNodeForElement( element ); } /** * Get the wired network element for a block in world. * * @param world The world the block exists in - * @param pos The position the block exists in - * @param side The side to extract the network element from + * @param pos The position the block exists in + * @param side The side to extract the network element from * @return The element's node * @see IWiredElement#getNode() */ @Nullable - public static IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side) { - return getInstance().getWiredElementAt(world, pos, side); + public static IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side ) + { + return getInstance().getWiredElementAt( world, pos, side ); } - public interface IComputerCraftAPI { + public interface IComputerCraftAPI + { @Nonnull String getInstalledVersion(); - int createUniqueNumberedSaveDir(@Nonnull World world, @Nonnull String parentSubPath); + int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath ); @Nullable - IWritableMount createSaveDirMount(@Nonnull World world, @Nonnull String subPath, long capacity); + IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity ); @Nullable - IMount createResourceMount(@Nonnull String domain, @Nonnull String subPath); + IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath ); - void registerPeripheralProvider(@Nonnull IPeripheralProvider provider); + void registerPeripheralProvider( @Nonnull IPeripheralProvider provider ); void registerGenericSource( @Nonnull GenericSource source ); - void registerTurtleUpgrade(@Nonnull ITurtleUpgrade upgrade); + void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade ); - void registerBundledRedstoneProvider(@Nonnull IBundledRedstoneProvider provider); + void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider ); - int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side); + int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ); - void registerMediaProvider(@Nonnull IMediaProvider provider); + void registerMediaProvider( @Nonnull IMediaProvider provider ); - void registerPocketUpgrade(@Nonnull IPocketUpgrade upgrade); + void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade ); @Nonnull IPacketNetwork getWirelessNetwork(); - void registerAPIFactory(@Nonnull ILuaAPIFactory factory); + void registerAPIFactory( @Nonnull ILuaAPIFactory factory ); @Nonnull - IWiredNode createWiredNodeForElement(@Nonnull IWiredElement element); + IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element ); @Nullable - IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side); + IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side ); } } diff --git a/src/main/java/dan200/computercraft/api/client/TransformedModel.java b/src/main/java/dan200/computercraft/api/client/TransformedModel.java index 911bfbb90..a62350b07 100644 --- a/src/main/java/dan200/computercraft/api/client/TransformedModel.java +++ b/src/main/java/dan200/computercraft/api/client/TransformedModel.java @@ -6,12 +6,9 @@ package dan200.computercraft.api.client; -import java.util.Objects; - -import javax.annotation.Nonnull; - import dan200.computercraft.fabric.mixin.AffineTransformationAccess; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModelManager; @@ -20,64 +17,78 @@ import net.minecraft.client.util.math.AffineTransformation; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; +import java.util.Objects; /** * A model to render, combined with a transformation matrix to apply. */ -@Environment (EnvType.CLIENT) -public final class TransformedModel { +@Environment( EnvType.CLIENT ) +public final class TransformedModel +{ private final BakedModel model; private final AffineTransformation matrix; - public TransformedModel(@Nonnull BakedModel model, @Nonnull AffineTransformation matrix) { - this.model = Objects.requireNonNull(model); - this.matrix = Objects.requireNonNull(matrix); + public TransformedModel( @Nonnull BakedModel model, @Nonnull AffineTransformation matrix ) + { + this.model = Objects.requireNonNull( model ); + this.matrix = Objects.requireNonNull( matrix ); } - public TransformedModel(@Nonnull BakedModel model) { - this.model = Objects.requireNonNull(model); + public TransformedModel( @Nonnull BakedModel model ) + { + this.model = Objects.requireNonNull( model ); this.matrix = AffineTransformation.identity(); } - public static TransformedModel of(@Nonnull ModelIdentifier location) { + public static TransformedModel of( @Nonnull ModelIdentifier location ) + { BakedModelManager modelManager = MinecraftClient.getInstance() - .getBakedModelManager(); - return new TransformedModel(modelManager.getModel(location)); + .getBakedModelManager(); + return new TransformedModel( modelManager.getModel( location ) ); } - public static TransformedModel of(@Nonnull ItemStack item, @Nonnull AffineTransformation transform) { + public static TransformedModel of( @Nonnull ItemStack item, @Nonnull AffineTransformation transform ) + { BakedModel model = MinecraftClient.getInstance() - .getItemRenderer() - .getModels() - .getModel(item); - return new TransformedModel(model, transform); + .getItemRenderer() + .getModels() + .getModel( item ); + return new TransformedModel( model, transform ); } @Nonnull - public BakedModel getModel() { + public BakedModel getModel() + { return this.model; } @Nonnull - public AffineTransformation getMatrix() { + public AffineTransformation getMatrix() + { return this.matrix; } - public void push(MatrixStack matrixStack) { + public void push( MatrixStack matrixStack ) + { matrixStack.push(); AffineTransformationAccess access = (AffineTransformationAccess) (Object) this.matrix; - if (access.getTranslation() != null) - matrixStack.translate(access.getTranslation().getX(), access.getTranslation().getY(), access.getTranslation().getZ()); + if( access.getTranslation() != null ) + { + matrixStack.translate( access.getTranslation().getX(), access.getTranslation().getY(), access.getTranslation().getZ() ); + } - matrixStack.multiply(this.matrix.getRotation2()); + matrixStack.multiply( this.matrix.getRotation2() ); - if (access.getScale() != null) - matrixStack.scale(access.getScale().getX(), access.getScale().getY(), access.getScale().getZ()); + if( access.getScale() != null ) + { + matrixStack.scale( access.getScale().getX(), access.getScale().getY(), access.getScale().getZ() ); + } - if (access.getRotation1() != null) - matrixStack.multiply(access.getRotation1()); + if( access.getRotation1() != null ) + { + matrixStack.multiply( access.getRotation1() ); + } } } diff --git a/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java b/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java index 2c79271a0..ce05e8181 100644 --- a/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java +++ b/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java @@ -13,59 +13,70 @@ import java.time.Instant; /** * A simple version of {@link BasicFileAttributes}, which provides what information a {@link IMount} already exposes. */ -final class FileAttributes implements BasicFileAttributes { - private static final FileTime EPOCH = FileTime.from(Instant.EPOCH); +final class FileAttributes implements BasicFileAttributes +{ + private static final FileTime EPOCH = FileTime.from( Instant.EPOCH ); private final boolean isDirectory; private final long size; - FileAttributes(boolean isDirectory, long size) { + FileAttributes( boolean isDirectory, long size ) + { this.isDirectory = isDirectory; this.size = size; } @Override - public FileTime lastModifiedTime() { + public FileTime lastModifiedTime() + { return EPOCH; } @Override - public FileTime lastAccessTime() { + public FileTime lastAccessTime() + { return EPOCH; } @Override - public FileTime creationTime() { + public FileTime creationTime() + { return EPOCH; } @Override - public boolean isRegularFile() { + public boolean isRegularFile() + { return !this.isDirectory; } @Override - public boolean isDirectory() { + public boolean isDirectory() + { return this.isDirectory; } @Override - public boolean isSymbolicLink() { + public boolean isSymbolicLink() + { return false; } @Override - public boolean isOther() { + public boolean isOther() + { return false; } @Override - public long size() { + public long size() + { return this.size; } @Override - public Object fileKey() { + public Object fileKey() + { return null; } } diff --git a/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java b/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java index a10ab5e43..a0d4de1aa 100644 --- a/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java +++ b/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java @@ -6,34 +6,37 @@ package dan200.computercraft.api.filesystem; -import java.io.IOException; -import java.util.Objects; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.io.IOException; +import java.util.Objects; /** * An {@link IOException} which occurred on a specific file. * * This may be thrown from a {@link IMount} or {@link IWritableMount} to give more information about a failure. */ -public class FileOperationException extends IOException { +public class FileOperationException extends IOException +{ private static final long serialVersionUID = -8809108200853029849L; private final String filename; - public FileOperationException(@Nullable String filename, @Nonnull String message) { - super(Objects.requireNonNull(message, "message cannot be null")); + public FileOperationException( @Nullable String filename, @Nonnull String message ) + { + super( Objects.requireNonNull( message, "message cannot be null" ) ); this.filename = filename; } - public FileOperationException(@Nonnull String message) { - super(Objects.requireNonNull(message, "message cannot be null")); + public FileOperationException( @Nonnull String message ) + { + super( Objects.requireNonNull( message, "message cannot be null" ) ); this.filename = null; } @Nullable - public String getFilename() { + public String getFilename() + { return this.filename; } } diff --git a/src/main/java/dan200/computercraft/api/filesystem/IFileSystem.java b/src/main/java/dan200/computercraft/api/filesystem/IFileSystem.java index 8736fd865..8c74731e3 100644 --- a/src/main/java/dan200/computercraft/api/filesystem/IFileSystem.java +++ b/src/main/java/dan200/computercraft/api/filesystem/IFileSystem.java @@ -13,31 +13,32 @@ import java.io.IOException; * * This exists for use by various APIs - one should not attempt to mount it. */ -public interface IFileSystem extends IWritableMount { +public interface IFileSystem extends IWritableMount +{ /** * Combine two paths together, reducing them into a normalised form. * - * @param path The main path. + * @param path The main path. * @param child The path to append. * @return The combined, normalised path. */ - String combine(String path, String child); + String combine( String path, String child ); /** * Copy files from one location to another. * * @param from The location to copy from. - * @param to The location to copy to. This should not exist. + * @param to The location to copy to. This should not exist. * @throws IOException If the copy failed. */ - void copy(String from, String to) throws IOException; + void copy( String from, String to ) throws IOException; /** * Move files from one location to another. * * @param from The location to move from. - * @param to The location to move to. This should not exist. + * @param to The location to move to. This should not exist. * @throws IOException If the move failed. */ - void move(String from, String to) throws IOException; + void move( String from, String to ) throws IOException; } diff --git a/src/main/java/dan200/computercraft/api/filesystem/IMount.java b/src/main/java/dan200/computercraft/api/filesystem/IMount.java index 055d0e464..f767bcd5a 100644 --- a/src/main/java/dan200/computercraft/api/filesystem/IMount.java +++ b/src/main/java/dan200/computercraft/api/filesystem/IMount.java @@ -6,18 +6,16 @@ package dan200.computercraft.api.filesystem; +import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.api.peripheral.IComputerAccess; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.nio.file.attribute.BasicFileAttributes; import java.util.List; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.ComputerCraftAPI; -import dan200.computercraft.api.peripheral.IComputerAccess; - -import net.minecraft.world.World; - /** * Represents a read only part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)}. * @@ -29,26 +27,27 @@ import net.minecraft.world.World; * @see IComputerAccess#mount(String, IMount) * @see IWritableMount */ -public interface IMount { +public interface IMount +{ /** * Returns the file names of all the files in a directory. * - * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms". + * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms". * @param contents A list of strings. Add all the file names to this list. * @throws IOException If the file was not a directory, or could not be listed. */ - void list(@Nonnull String path, @Nonnull List contents) throws IOException; + void list( @Nonnull String path, @Nonnull List contents ) throws IOException; /** * Opens a file with a given path, and returns an {@link ReadableByteChannel} representing its contents. * * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @return A channel representing the contents of the file. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to - * seek to arbitrary positions when using binary mode. + * seek to arbitrary positions when using binary mode. * @throws IOException If the file does not exist, or could not be opened. */ @Nonnull - ReadableByteChannel openForRead(@Nonnull String path) throws IOException; + ReadableByteChannel openForRead( @Nonnull String path ) throws IOException; /** * Get attributes about the given file. @@ -58,11 +57,13 @@ public interface IMount { * @throws IOException If the file does not exist, or attributes could not be fetched. */ @Nonnull - default BasicFileAttributes getAttributes(@Nonnull String path) throws IOException { - if (!this.exists(path)) { - throw new FileOperationException(path, "No such file"); + default BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException + { + if( !this.exists( path ) ) + { + throw new FileOperationException( path, "No such file" ); } - return new FileAttributes(this.isDirectory(path), this.getSize(path)); + return new FileAttributes( this.isDirectory( path ), this.getSize( path ) ); } /** @@ -72,7 +73,7 @@ public interface IMount { * @return If the file exists. * @throws IOException If an error occurs when checking the existence of the file. */ - boolean exists(@Nonnull String path) throws IOException; + boolean exists( @Nonnull String path ) throws IOException; /** * Returns whether a file with a given path is a directory or not. @@ -81,7 +82,7 @@ public interface IMount { * @return If the file exists and is a directory * @throws IOException If an error occurs when checking whether the file is a directory. */ - boolean isDirectory(@Nonnull String path) throws IOException; + boolean isDirectory( @Nonnull String path ) throws IOException; /** * Returns the size of a file with a given path, in bytes. @@ -90,5 +91,5 @@ public interface IMount { * @return The size of the file, in bytes. * @throws IOException If the file does not exist, or its size could not be determined. */ - long getSize(@Nonnull String path) throws IOException; + long getSize( @Nonnull String path ) throws IOException; } diff --git a/src/main/java/dan200/computercraft/api/filesystem/IWritableMount.java b/src/main/java/dan200/computercraft/api/filesystem/IWritableMount.java index 91ef9ae78..d39eec86c 100644 --- a/src/main/java/dan200/computercraft/api/filesystem/IWritableMount.java +++ b/src/main/java/dan200/computercraft/api/filesystem/IWritableMount.java @@ -6,18 +6,16 @@ package dan200.computercraft.api.filesystem; +import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.api.peripheral.IComputerAccess; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; import java.io.IOException; import java.io.OutputStream; import java.nio.channels.WritableByteChannel; import java.util.OptionalLong; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.ComputerCraftAPI; -import dan200.computercraft.api.peripheral.IComputerAccess; - -import net.minecraft.world.World; - /** * Represents a part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)} or {@link * IComputerAccess#mountWritable(String, IWritableMount)}, that can also be written to. @@ -30,14 +28,15 @@ import net.minecraft.world.World; * @see IComputerAccess#mountWritable(String, IWritableMount) * @see IMount */ -public interface IWritableMount extends IMount { +public interface IWritableMount extends IMount +{ /** * Creates a directory at a given path inside the virtual file system. * * @param path A file path in normalised format, relative to the mount location. ie: "programs/mynewprograms". * @throws IOException If the directory already exists or could not be created. */ - void makeDirectory(@Nonnull String path) throws IOException; + void makeDirectory( @Nonnull String path ) throws IOException; /** * Deletes a directory at a given path inside the virtual file system. @@ -45,29 +44,29 @@ public interface IWritableMount extends IMount { * @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms". * @throws IOException If the file does not exist or could not be deleted. */ - void delete(@Nonnull String path) throws IOException; + void delete( @Nonnull String path ) throws IOException; /** * Opens a file with a given path, and returns an {@link OutputStream} for writing to it. * * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary - * positions when using binary mode. + * positions when using binary mode. * @throws IOException If the file could not be opened for writing. */ @Nonnull - WritableByteChannel openForWrite(@Nonnull String path) throws IOException; + WritableByteChannel openForWrite( @Nonnull String path ) throws IOException; /** * Opens a file with a given path, and returns an {@link OutputStream} for appending to it. * * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary - * positions when using binary mode. + * positions when using binary mode. * @throws IOException If the file could not be opened for writing. */ @Nonnull - WritableByteChannel openForAppend(@Nonnull String path) throws IOException; + WritableByteChannel openForAppend( @Nonnull String path ) throws IOException; /** * Get the amount of free space on the mount, in bytes. You should decrease this value as the user writes to the mount, and write operations should fail @@ -84,7 +83,8 @@ public interface IWritableMount extends IMount { * @return The capacity of this mount, in bytes. */ @Nonnull - default OptionalLong getCapacity() { + default OptionalLong getCapacity() + { return OptionalLong.empty(); } } diff --git a/src/main/java/dan200/computercraft/api/lua/IArguments.java b/src/main/java/dan200/computercraft/api/lua/IArguments.java index 4d2e36e15..2d4d73983 100644 --- a/src/main/java/dan200/computercraft/api/lua/IArguments.java +++ b/src/main/java/dan200/computercraft/api/lua/IArguments.java @@ -6,19 +6,19 @@ package dan200.computercraft.api.lua; -import static dan200.computercraft.api.lua.LuaValues.checkFinite; - +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Map; import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import static dan200.computercraft.api.lua.LuaValues.checkFinite; /** * The arguments passed to a function. */ -public interface IArguments { +public interface IArguments +{ /** * Drop a number of arguments. The returned arguments instance will access arguments at position {@code i + count}, rather than {@code i}. However, * errors will still use the given argument index. @@ -26,12 +26,14 @@ public interface IArguments { * @param count The number of arguments to drop. * @return The new {@link IArguments} instance. */ - IArguments drop(int count); + IArguments drop( int count ); - default Object[] getAll() { + default Object[] getAll() + { Object[] result = new Object[this.count()]; - for (int i = 0; i < result.length; i++) { - result[i] = this.get(i); + for( int i = 0; i < result.length; i++ ) + { + result[i] = this.get( i ); } return result; } @@ -58,7 +60,7 @@ public interface IArguments { * @return The argument's value, or {@code null} if not present. */ @Nullable - Object get(int index); + Object get( int index ); /** * Get an argument as an integer. @@ -67,8 +69,9 @@ public interface IArguments { * @return The argument's value. * @throws LuaException If the value is not an integer. */ - default int getInt(int index) throws LuaException { - return (int) this.getLong(index); + default int getInt( int index ) throws LuaException + { + return (int) this.getLong( index ); } /** @@ -78,13 +81,15 @@ public interface IArguments { * @return The argument's value. * @throws LuaException If the value is not a long. */ - default long getLong(int index) throws LuaException { - Object value = this.get(index); - if (!(value instanceof Number)) { - throw LuaValues.badArgumentOf(index, "number", value); + default long getLong( int index ) throws LuaException + { + Object value = this.get( index ); + if( !(value instanceof Number) ) + { + throw LuaValues.badArgumentOf( index, "number", value ); } - return LuaValues.checkFiniteNum(index, (Number) value) - .longValue(); + return LuaValues.checkFiniteNum( index, (Number) value ) + .longValue(); } /** @@ -94,8 +99,9 @@ public interface IArguments { * @return The argument's value. * @throws LuaException If the value is not finite. */ - default double getFiniteDouble(int index) throws LuaException { - return checkFinite(index, this.getDouble(index)); + default double getFiniteDouble( int index ) throws LuaException + { + return checkFinite( index, this.getDouble( index ) ); } /** @@ -106,10 +112,12 @@ public interface IArguments { * @throws LuaException If the value is not a number. * @see #getFiniteDouble(int) if you require this to be finite (i.e. not infinite or NaN). */ - default double getDouble(int index) throws LuaException { - Object value = this.get(index); - if (!(value instanceof Number)) { - throw LuaValues.badArgumentOf(index, "number", value); + default double getDouble( int index ) throws LuaException + { + Object value = this.get( index ); + if( !(value instanceof Number) ) + { + throw LuaValues.badArgumentOf( index, "number", value ); } return ((Number) value).doubleValue(); } @@ -121,10 +129,12 @@ public interface IArguments { * @return The argument's value. * @throws LuaException If the value is not a boolean. */ - default boolean getBoolean(int index) throws LuaException { - Object value = this.get(index); - if (!(value instanceof Boolean)) { - throw LuaValues.badArgumentOf(index, "boolean", value); + default boolean getBoolean( int index ) throws LuaException + { + Object value = this.get( index ); + if( !(value instanceof Boolean) ) + { + throw LuaValues.badArgumentOf( index, "boolean", value ); } return (Boolean) value; } @@ -137,8 +147,9 @@ public interface IArguments { * @throws LuaException If the value is not a string. */ @Nonnull - default ByteBuffer getBytes(int index) throws LuaException { - return LuaValues.encode(this.getString(index)); + default ByteBuffer getBytes( int index ) throws LuaException + { + return LuaValues.encode( this.getString( index ) ); } /** @@ -149,10 +160,12 @@ public interface IArguments { * @throws LuaException If the value is not a string. */ @Nonnull - default String getString(int index) throws LuaException { - Object value = this.get(index); - if (!(value instanceof String)) { - throw LuaValues.badArgumentOf(index, "string", value); + default String getString( int index ) throws LuaException + { + Object value = this.get( index ); + if( !(value instanceof String) ) + { + throw LuaValues.badArgumentOf( index, "string", value ); } return (String) value; } @@ -162,13 +175,14 @@ public interface IArguments { * * @param index The argument number. * @param klass The type of enum to parse. - * @param The type of enum to parse. + * @param The type of enum to parse. * @return The argument's value. * @throws LuaException If the value is not a string or not a valid option for this enum. */ @Nonnull - default > T getEnum(int index, Class klass) throws LuaException { - return LuaValues.checkEnum(index, klass, this.getString(index)); + default > T getEnum( int index, Class klass ) throws LuaException + { + return LuaValues.checkEnum( index, klass, this.getString( index ) ); } /** @@ -179,10 +193,12 @@ public interface IArguments { * @throws LuaException If the value is not a table. */ @Nonnull - default Map getTable(int index) throws LuaException { - Object value = this.get(index); - if (!(value instanceof Map)) { - throw LuaValues.badArgumentOf(index, "table", value); + default Map getTable( int index ) throws LuaException + { + Object value = this.get( index ); + if( !(value instanceof Map) ) + { + throw LuaValues.badArgumentOf( index, "table", value ); } return (Map) value; } @@ -194,8 +210,9 @@ public interface IArguments { * @return The argument's value, or {@link Optional#empty()} if not present. This is a read only buffer. * @throws LuaException If the value is not a string. */ - default Optional optBytes(int index) throws LuaException { - return this.optString(index).map(LuaValues::encode); + default Optional optBytes( int index ) throws LuaException + { + return this.optString( index ).map( LuaValues::encode ); } /** @@ -205,15 +222,18 @@ public interface IArguments { * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a string. */ - default Optional optString(int index) throws LuaException { - Object value = this.get(index); - if (value == null) { + default Optional optString( int index ) throws LuaException + { + Object value = this.get( index ); + if( value == null ) + { return Optional.empty(); } - if (!(value instanceof String)) { - throw LuaValues.badArgumentOf(index, "string", value); + if( !(value instanceof String) ) + { + throw LuaValues.badArgumentOf( index, "string", value ); } - return Optional.of((String) value); + return Optional.of( (String) value ); } /** @@ -221,26 +241,28 @@ public interface IArguments { * * @param index The argument number. * @param klass The type of enum to parse. - * @param The type of enum to parse. + * @param The type of enum to parse. * @return The argument's value. * @throws LuaException If the value is not a string or not a valid option for this enum. */ @Nonnull - default > Optional optEnum(int index, Class klass) throws LuaException { - Optional str = this.optString(index); - return str.isPresent() ? Optional.of(LuaValues.checkEnum(index, klass, str.get())) : Optional.empty(); + default > Optional optEnum( int index, Class klass ) throws LuaException + { + Optional str = this.optString( index ); + return str.isPresent() ? Optional.of( LuaValues.checkEnum( index, klass, str.get() ) ) : Optional.empty(); } /** * Get an argument as a double. * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a number. */ - default double optDouble(int index, double def) throws LuaException { - return this.optDouble(index).orElse(def); + default double optDouble( int index, double def ) throws LuaException + { + return this.optDouble( index ).orElse( def ); } /** @@ -251,27 +273,31 @@ public interface IArguments { * @throws LuaException If the value is not a number. */ @Nonnull - default Optional optDouble(int index) throws LuaException { - Object value = this.get(index); - if (value == null) { + default Optional optDouble( int index ) throws LuaException + { + Object value = this.get( index ); + if( value == null ) + { return Optional.empty(); } - if (!(value instanceof Number)) { - throw LuaValues.badArgumentOf(index, "number", value); + if( !(value instanceof Number) ) + { + throw LuaValues.badArgumentOf( index, "number", value ); } - return Optional.of(((Number) value).doubleValue()); + return Optional.of( ((Number) value).doubleValue() ); } /** * Get an argument as an int. * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a number. */ - default int optInt(int index, int def) throws LuaException { - return this.optInt(index).orElse(def); + default int optInt( int index, int def ) throws LuaException + { + return this.optInt( index ).orElse( def ); } /** @@ -282,8 +308,9 @@ public interface IArguments { * @throws LuaException If the value is not a number. */ @Nonnull - default Optional optInt(int index) throws LuaException { - return this.optLong(index).map(Long::intValue); + default Optional optInt( int index ) throws LuaException + { + return this.optLong( index ).map( Long::intValue ); } /** @@ -293,40 +320,45 @@ public interface IArguments { * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a number. */ - default Optional optLong(int index) throws LuaException { - Object value = this.get(index); - if (value == null) { + default Optional optLong( int index ) throws LuaException + { + Object value = this.get( index ); + if( value == null ) + { return Optional.empty(); } - if (!(value instanceof Number)) { - throw LuaValues.badArgumentOf(index, "number", value); + if( !(value instanceof Number) ) + { + throw LuaValues.badArgumentOf( index, "number", value ); } - return Optional.of(LuaValues.checkFiniteNum(index, (Number) value) - .longValue()); + return Optional.of( LuaValues.checkFiniteNum( index, (Number) value ) + .longValue() ); } /** * Get an argument as a long. * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a number. */ - default long optLong(int index, long def) throws LuaException { - return this.optLong(index).orElse(def); + default long optLong( int index, long def ) throws LuaException + { + return this.optLong( index ).orElse( def ); } /** * Get an argument as a finite number (not infinite or NaN). * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not finite. */ - default double optFiniteDouble(int index, double def) throws LuaException { - return this.optFiniteDouble(index).orElse(def); + default double optFiniteDouble( int index, double def ) throws LuaException + { + return this.optFiniteDouble( index ).orElse( def ); } /** @@ -336,10 +368,12 @@ public interface IArguments { * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not finite. */ - default Optional optFiniteDouble(int index) throws LuaException { - Optional value = this.optDouble(index); - if (value.isPresent()) { - LuaValues.checkFiniteNum(index, value.get()); + default Optional optFiniteDouble( int index ) throws LuaException + { + Optional value = this.optDouble( index ); + if( value.isPresent() ) + { + LuaValues.checkFiniteNum( index, value.get() ); } return value; } @@ -348,12 +382,13 @@ public interface IArguments { * Get an argument as a boolean. * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a boolean. */ - default boolean optBoolean(int index, boolean def) throws LuaException { - return this.optBoolean(index).orElse(def); + default boolean optBoolean( int index, boolean def ) throws LuaException + { + return this.optBoolean( index ).orElse( def ); } /** @@ -363,39 +398,44 @@ public interface IArguments { * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a boolean. */ - default Optional optBoolean(int index) throws LuaException { - Object value = this.get(index); - if (value == null) { + default Optional optBoolean( int index ) throws LuaException + { + Object value = this.get( index ); + if( value == null ) + { return Optional.empty(); } - if (!(value instanceof Boolean)) { - throw LuaValues.badArgumentOf(index, "boolean", value); + if( !(value instanceof Boolean) ) + { + throw LuaValues.badArgumentOf( index, "boolean", value ); } - return Optional.of((Boolean) value); + return Optional.of( (Boolean) value ); } /** * Get an argument as a string. * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a string. */ - default String optString(int index, String def) throws LuaException { - return this.optString(index).orElse(def); + default String optString( int index, String def ) throws LuaException + { + return this.optString( index ).orElse( def ); } /** * Get an argument as a table. * * @param index The argument number. - * @param def The default value, if this argument is not given. + * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a table. */ - default Map optTable(int index, Map def) throws LuaException { - return this.optTable(index).orElse(def); + default Map optTable( int index, Map def ) throws LuaException + { + return this.optTable( index ).orElse( def ); } /** @@ -405,14 +445,17 @@ public interface IArguments { * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a table. */ - default Optional> optTable(int index) throws LuaException { - Object value = this.get(index); - if (value == null) { + default Optional> optTable( int index ) throws LuaException + { + Object value = this.get( index ); + if( value == null ) + { return Optional.empty(); } - if (!(value instanceof Map)) { - throw LuaValues.badArgumentOf(index, "map", value); + if( !(value instanceof Map) ) + { + throw LuaValues.badArgumentOf( index, "map", value ); } - return Optional.of((Map) value); + return Optional.of( (Map) value ); } } diff --git a/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java b/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java index 6495786ca..d9069b52a 100644 --- a/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java +++ b/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java @@ -6,15 +6,16 @@ package dan200.computercraft.api.lua; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IFileSystem; import dan200.computercraft.api.peripheral.IComputerAccess; +import javax.annotation.Nullable; + /** * An interface passed to {@link ILuaAPIFactory} in order to provide additional information about a computer. */ -public interface IComputerSystem extends IComputerAccess { +public interface IComputerSystem extends IComputerAccess +{ /** * Get the file system for this computer. * diff --git a/src/main/java/dan200/computercraft/api/lua/IDynamicLuaObject.java b/src/main/java/dan200/computercraft/api/lua/IDynamicLuaObject.java index 9365ee574..49c4d6a47 100644 --- a/src/main/java/dan200/computercraft/api/lua/IDynamicLuaObject.java +++ b/src/main/java/dan200/computercraft/api/lua/IDynamicLuaObject.java @@ -6,17 +6,18 @@ package dan200.computercraft.api.lua; -import javax.annotation.Nonnull; - import dan200.computercraft.api.peripheral.IDynamicPeripheral; +import javax.annotation.Nonnull; + /** * An interface for representing custom objects returned by peripherals or other Lua objects. * * Generally, one does not need to implement this type - it is sufficient to return an object with some methods annotated with {@link LuaFunction}. {@link * IDynamicLuaObject} is useful when you wish your available methods to change at runtime. */ -public interface IDynamicLuaObject { +public interface IDynamicLuaObject +{ /** * Get the names of the methods that this object implements. This should not change over the course of the object's lifetime. * @@ -29,12 +30,12 @@ public interface IDynamicLuaObject { /** * Called when a user calls one of the methods that this object implements. * - * @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield. - * @param method An integer identifying which method index from {@link #getMethodNames()} the computer wishes to call. + * @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield. + * @param method An integer identifying which method index from {@link #getMethodNames()} the computer wishes to call. * @param arguments The arguments for this method. * @return The result of this function. Either an immediate value ({@link MethodResult#of(Object...)} or an instruction to yield. * @throws LuaException If the function threw an exception. */ @Nonnull - MethodResult callMethod(@Nonnull ILuaContext context, int method, @Nonnull IArguments arguments) throws LuaException; + MethodResult callMethod( @Nonnull ILuaContext context, int method, @Nonnull IArguments arguments ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java b/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java index 4d6115f3b..ca33136dc 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java @@ -18,7 +18,8 @@ import dan200.computercraft.api.ComputerCraftAPI; * @see ILuaAPIFactory * @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory) */ -public interface ILuaAPI { +public interface ILuaAPI +{ /** * Get the globals this API will be assigned to. This will override any other global, so you should * @@ -31,13 +32,15 @@ public interface ILuaAPI { * * One should only interact with the file system. */ - default void startup() { + default void startup() + { } /** * Called every time the computer is ticked. This can be used to process various. */ - default void update() { + default void update() + { } /** @@ -45,6 +48,7 @@ public interface ILuaAPI { * * This should reset the state of the object, disposing any remaining file handles, or other resources. */ - default void shutdown() { + default void shutdown() + { } } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java b/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java index 93567e1f7..9b4fbbc47 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java @@ -6,11 +6,11 @@ package dan200.computercraft.api.lua; +import dan200.computercraft.api.ComputerCraftAPI; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import dan200.computercraft.api.ComputerCraftAPI; - /** * Construct an {@link ILuaAPI} for a specific computer. * @@ -18,7 +18,8 @@ import dan200.computercraft.api.ComputerCraftAPI; * @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory) */ @FunctionalInterface -public interface ILuaAPIFactory { +public interface ILuaAPIFactory +{ /** * Create a new API instance for a given computer. * @@ -26,5 +27,5 @@ public interface ILuaAPIFactory { * @return The created API, or {@code null} if one should not be injected. */ @Nullable - ILuaAPI create(@Nonnull IComputerSystem computer); + ILuaAPI create( @Nonnull IComputerSystem computer ); } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java b/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java index ec7769afa..b24e4b25e 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java @@ -13,7 +13,8 @@ import javax.annotation.Nonnull; * * @see MethodResult#yield(Object[], ILuaCallback) */ -public interface ILuaCallback { +public interface ILuaCallback +{ /** * Resume this coroutine. * @@ -22,5 +23,5 @@ public interface ILuaCallback { * @throws LuaException On an error. */ @Nonnull - MethodResult resume(Object[] args) throws LuaException; + MethodResult resume( Object[] args ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaContext.java b/src/main/java/dan200/computercraft/api/lua/ILuaContext.java index a26f84372..d871786e4 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaContext.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaContext.java @@ -12,7 +12,8 @@ import javax.annotation.Nonnull; * An interface passed to peripherals and {@link IDynamicLuaObject}s by computers or turtles, providing methods that allow the peripheral call to interface * with the computer. */ -public interface ILuaContext { +public interface ILuaContext +{ /** * Queue a task to be executed on the main server thread at the beginning of next tick, but do not wait for it to complete. This should be used when you * need to interact with the world in a thread-safe manner but do not care about the result or you wish to run asynchronously. @@ -25,5 +26,5 @@ public interface ILuaContext { * @throws LuaException If the task could not be queued. * @see LuaFunction#mainThread() To run functions on the main thread and return their results synchronously. */ - long issueMainThreadTask(@Nonnull ILuaTask task) throws LuaException; + long issueMainThreadTask( @Nonnull ILuaTask task ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java b/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java index 1218d7a4f..70d900c2c 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java @@ -15,7 +15,8 @@ import javax.annotation.Nonnull; * @see MethodResult#of(Object) */ @FunctionalInterface -public interface ILuaFunction { +public interface ILuaFunction +{ /** * Call this function with a series of arguments. Note, this will always be called on the computer thread, and so its implementation must be * thread-safe. @@ -25,5 +26,5 @@ public interface ILuaFunction { * @throws LuaException Upon Lua errors. */ @Nonnull - MethodResult call(@Nonnull IArguments arguments) throws LuaException; + MethodResult call( @Nonnull IArguments arguments ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaObject.java b/src/main/java/dan200/computercraft/api/lua/ILuaObject.java index 8dfc72366..eba77bc19 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaObject.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaObject.java @@ -8,10 +8,11 @@ package dan200.computercraft.api.lua; import javax.annotation.Nonnull; import javax.annotation.Nullable; -public interface ILuaObject { +public interface ILuaObject +{ @Nonnull String[] getMethodNames(); @Nullable - Object[] callMethod(@Nonnull ILuaContext context, int method, @Nonnull Object[] arguments) throws LuaException, InterruptedException; + Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException; } diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaTask.java b/src/main/java/dan200/computercraft/api/lua/ILuaTask.java index f80238d23..44a429ed4 100644 --- a/src/main/java/dan200/computercraft/api/lua/ILuaTask.java +++ b/src/main/java/dan200/computercraft/api/lua/ILuaTask.java @@ -15,13 +15,14 @@ import javax.annotation.Nullable; * @see ILuaContext#issueMainThreadTask(ILuaTask) */ @FunctionalInterface -public interface ILuaTask { +public interface ILuaTask +{ /** * Execute this task. * * @return The arguments to add to the {@code task_completed} event. * @throws LuaException If you throw any exception from this function, a lua error will be raised with the same message as your exception. Use this - * to throw appropriate errors if the wrong arguments are supplied to your method. + * to throw appropriate errors if the wrong arguments are supplied to your method. */ @Nullable Object[] execute() throws LuaException; diff --git a/src/main/java/dan200/computercraft/api/lua/LuaException.java b/src/main/java/dan200/computercraft/api/lua/LuaException.java index 8f479b38b..21d799c4a 100644 --- a/src/main/java/dan200/computercraft/api/lua/LuaException.java +++ b/src/main/java/dan200/computercraft/api/lua/LuaException.java @@ -11,19 +11,22 @@ import javax.annotation.Nullable; /** * An exception representing an error in Lua, like that raised by the {@code error()} function. */ -public class LuaException extends Exception { +public class LuaException extends Exception +{ private static final long serialVersionUID = -6136063076818512651L; private final boolean hasLevel; private final int level; - public LuaException(@Nullable String message) { - super(message); + public LuaException( @Nullable String message ) + { + super( message ); this.hasLevel = false; this.level = 1; } - public LuaException(@Nullable String message, int level) { - super(message); + public LuaException( @Nullable String message, int level ) + { + super( message ); this.hasLevel = true; this.level = level; } @@ -33,7 +36,8 @@ public class LuaException extends Exception { * * @return Whether this has an explicit level. */ - public boolean hasLevel() { + public boolean hasLevel() + { return this.hasLevel; } @@ -42,7 +46,8 @@ public class LuaException extends Exception { * * @return The level to raise the error at. */ - public int getLevel() { + public int getLevel() + { return this.level; } } diff --git a/src/main/java/dan200/computercraft/api/lua/LuaFunction.java b/src/main/java/dan200/computercraft/api/lua/LuaFunction.java index 3e4421328..064149466 100644 --- a/src/main/java/dan200/computercraft/api/lua/LuaFunction.java +++ b/src/main/java/dan200/computercraft/api/lua/LuaFunction.java @@ -6,17 +6,13 @@ package dan200.computercraft.api.lua; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Map; -import java.util.Optional; - import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; +import java.lang.annotation.*; +import java.util.Map; +import java.util.Optional; + /** * Used to mark a Java function which is callable from Lua. * @@ -41,9 +37,10 @@ import dan200.computercraft.api.peripheral.IPeripheral; * {@link MethodResult#of(Object...)}. */ @Documented -@Retention (RetentionPolicy.RUNTIME) -@Target (ElementType.METHOD) -public @interface LuaFunction { +@Retention( RetentionPolicy.RUNTIME ) +@Target( ElementType.METHOD ) +public @interface LuaFunction +{ /** * Explicitly specify the method names of this function. If not given, it uses the name of the annotated method. * diff --git a/src/main/java/dan200/computercraft/api/lua/LuaValues.java b/src/main/java/dan200/computercraft/api/lua/LuaValues.java index b20fbbc3b..a78091060 100644 --- a/src/main/java/dan200/computercraft/api/lua/LuaValues.java +++ b/src/main/java/dan200/computercraft/api/lua/LuaValues.java @@ -6,19 +6,20 @@ package dan200.computercraft.api.lua; -import java.nio.ByteBuffer; -import java.util.Map; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.nio.ByteBuffer; +import java.util.Map; /** * Various utility functions for operating with Lua values. * * @see IArguments */ -public final class LuaValues { - private LuaValues() { +public final class LuaValues +{ + private LuaValues() + { } /** @@ -28,41 +29,45 @@ public final class LuaValues { * @return The encoded string. */ @Nonnull - public static ByteBuffer encode(@Nonnull String string) { + public static ByteBuffer encode( @Nonnull String string ) + { byte[] chars = new byte[string.length()]; - for (int i = 0; i < chars.length; i++) { - char c = string.charAt(i); + for( int i = 0; i < chars.length; i++ ) + { + char c = string.charAt( i ); chars[i] = c < 256 ? (byte) c : 63; } - return ByteBuffer.wrap(chars) - .asReadOnlyBuffer(); + return ByteBuffer.wrap( chars ) + .asReadOnlyBuffer(); } /** * Construct a "bad argument" exception, from an expected type and the actual value provided. * - * @param index The argument number, starting from 0. + * @param index The argument number, starting from 0. * @param expected The expected type for this argument. - * @param actual The actual value provided for this argument. + * @param actual The actual value provided for this argument. * @return The constructed exception, which should be thrown immediately. */ @Nonnull - public static LuaException badArgumentOf(int index, @Nonnull String expected, @Nullable Object actual) { - return badArgument(index, expected, getType(actual)); + public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual ) + { + return badArgument( index, expected, getType( actual ) ); } /** * Construct a "bad argument" exception, from an expected and actual type. * - * @param index The argument number, starting from 0. + * @param index The argument number, starting from 0. * @param expected The expected type for this argument. - * @param actual The provided type for this argument. + * @param actual The provided type for this argument. * @return The constructed exception, which should be thrown immediately. */ @Nonnull - public static LuaException badArgument(int index, @Nonnull String expected, @Nonnull String actual) { - return new LuaException("bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")"); + public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual ) + { + return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" ); } /** @@ -72,20 +77,26 @@ public final class LuaValues { * @return A string representation of the given value's type, in a similar format to that provided by Lua's {@code type} function. */ @Nonnull - public static String getType(@Nullable Object value) { - if (value == null) { + public static String getType( @Nullable Object value ) + { + if( value == null ) + { return "nil"; } - if (value instanceof String) { + if( value instanceof String ) + { return "string"; } - if (value instanceof Boolean) { + if( value instanceof Boolean ) + { return "boolean"; } - if (value instanceof Number) { + if( value instanceof Number ) + { return "number"; } - if (value instanceof Map) { + if( value instanceof Map ) + { return "table"; } return "userdata"; @@ -99,8 +110,9 @@ public final class LuaValues { * @return The input {@code value}. * @throws LuaException If this is not a finite number. */ - public static Number checkFiniteNum(int index, Number value) throws LuaException { - checkFinite(index, value.doubleValue()); + public static Number checkFiniteNum( int index, Number value ) throws LuaException + { + checkFinite( index, value.doubleValue() ); return value; } @@ -112,9 +124,11 @@ public final class LuaValues { * @return The input {@code value}. * @throws LuaException If this is not a finite number. */ - public static double checkFinite(int index, double value) throws LuaException { - if (!Double.isFinite(value)) { - throw badArgument(index, "number", getNumericType(value)); + public static double checkFinite( int index, double value ) throws LuaException + { + if( !Double.isFinite( value ) ) + { + throw badArgument( index, "number", getNumericType( value ) ); } return value; } @@ -127,14 +141,18 @@ public final class LuaValues { * @return This value's numeric type. */ @Nonnull - public static String getNumericType(double value) { - if (Double.isNaN(value)) { + public static String getNumericType( double value ) + { + if( Double.isNaN( value ) ) + { return "nan"; } - if (value == Double.POSITIVE_INFINITY) { + if( value == Double.POSITIVE_INFINITY ) + { return "inf"; } - if (value == Double.NEGATIVE_INFINITY) { + if( value == Double.NEGATIVE_INFINITY ) + { return "-inf"; } return "number"; @@ -146,18 +164,21 @@ public final class LuaValues { * @param index The argument index to check. * @param klass The class of the enum instance. * @param value The value to extract. - * @param The type of enum we are extracting. + * @param The type of enum we are extracting. * @return The parsed enum value. * @throws LuaException If this is not a known enum value. */ - public static > T checkEnum(int index, Class klass, String value) throws LuaException { - for (T possibility : klass.getEnumConstants()) { - if (possibility.name() - .equalsIgnoreCase(value)) { + public static > T checkEnum( int index, Class klass, String value ) throws LuaException + { + for( T possibility : klass.getEnumConstants() ) + { + if( possibility.name() + .equalsIgnoreCase( value ) ) + { return possibility; } } - throw new LuaException("bad argument #" + (index + 1) + " (unknown option " + value + ")"); + throw new LuaException( "bad argument #" + (index + 1) + " (unknown option " + value + ")" ); } } diff --git a/src/main/java/dan200/computercraft/api/lua/MethodResult.java b/src/main/java/dan200/computercraft/api/lua/MethodResult.java index 33e2fc037..c7ee1d3ae 100644 --- a/src/main/java/dan200/computercraft/api/lua/MethodResult.java +++ b/src/main/java/dan200/computercraft/api/lua/MethodResult.java @@ -6,36 +6,38 @@ package dan200.computercraft.api.lua; +import dan200.computercraft.api.peripheral.IComputerAccess; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Map; import java.util.Objects; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import dan200.computercraft.api.peripheral.IComputerAccess; - /** * The result of invoking a Lua method. * * Method results either return a value immediately ({@link #of(Object...)} or yield control to the parent coroutine. When the current coroutine is resumed, * we invoke the provided {@link ILuaCallback#resume(Object[])} callback. */ -public final class MethodResult { - private static final MethodResult empty = new MethodResult(null, null); +public final class MethodResult +{ + private static final MethodResult empty = new MethodResult( null, null ); private final Object[] result; private final ILuaCallback callback; private final int adjust; - private MethodResult(Object[] arguments, ILuaCallback callback) { + private MethodResult( Object[] arguments, ILuaCallback callback ) + { this.result = arguments; this.callback = callback; this.adjust = 0; } - private MethodResult(Object[] arguments, ILuaCallback callback, int adjust) { + private MethodResult( Object[] arguments, ILuaCallback callback, int adjust ) + { this.result = arguments; this.callback = callback; this.adjust = adjust; @@ -47,7 +49,8 @@ public final class MethodResult { * @return A method result which returns immediately with no values. */ @Nonnull - public static MethodResult of() { + public static MethodResult of() + { return empty; } @@ -64,8 +67,9 @@ public final class MethodResult { * @return A method result which returns immediately with the given value. */ @Nonnull - public static MethodResult of(@Nullable Object value) { - return new MethodResult(new Object[] {value}, null); + public static MethodResult of( @Nullable Object value ) + { + return new MethodResult( new Object[] { value }, null ); } /** @@ -75,43 +79,47 @@ public final class MethodResult { * @return A method result which returns immediately with the given values. */ @Nonnull - public static MethodResult of(@Nullable Object... values) { - return values == null || values.length == 0 ? empty : new MethodResult(values, null); + public static MethodResult of( @Nullable Object... values ) + { + return values == null || values.length == 0 ? empty : new MethodResult( values, null ); } /** * Wait for an event to occur on the computer, suspending the thread until it arises. This method is exactly equivalent to {@code os.pullEvent()} in * lua. * - * @param filter A specific event to wait for, or null to wait for any event. + * @param filter A specific event to wait for, or null to wait for any event. * @param callback The callback to resume with the name of the event that occurred, and any event parameters. * @return The method result which represents this yield. * @see IComputerAccess#queueEvent(String, Object[]) */ @Nonnull - public static MethodResult pullEvent(@Nullable String filter, @Nonnull ILuaCallback callback) { - Objects.requireNonNull(callback, "callback cannot be null"); - return new MethodResult(new Object[] {filter}, results -> { - if (results.length >= 1 && results[0].equals("terminate")) { - throw new LuaException("Terminated", 0); + public static MethodResult pullEvent( @Nullable String filter, @Nonnull ILuaCallback callback ) + { + Objects.requireNonNull( callback, "callback cannot be null" ); + return new MethodResult( new Object[] { filter }, results -> { + if( results.length >= 1 && results[0].equals( "terminate" ) ) + { + throw new LuaException( "Terminated", 0 ); } - return callback.resume(results); - }); + return callback.resume( results ); + } ); } /** * The same as {@link #pullEvent(String, ILuaCallback)}, except "terminated" events are ignored. Only use this if you want to prevent program * termination, which is not recommended. This method is exactly equivalent to {@code os.pullEventRaw()} in Lua. * - * @param filter A specific event to wait for, or null to wait for any event. + * @param filter A specific event to wait for, or null to wait for any event. * @param callback The callback to resume with the name of the event that occurred, and any event parameters. * @return The method result which represents this yield. * @see #pullEvent(String, ILuaCallback) */ @Nonnull - public static MethodResult pullEventRaw(@Nullable String filter, @Nonnull ILuaCallback callback) { - Objects.requireNonNull(callback, "callback cannot be null"); - return new MethodResult(new Object[] {filter}, callback); + public static MethodResult pullEventRaw( @Nullable String filter, @Nonnull ILuaCallback callback ) + { + Objects.requireNonNull( callback, "callback cannot be null" ); + return new MethodResult( new Object[] { filter }, callback ); } /** @@ -119,27 +127,31 @@ public final class MethodResult { * {@code pullEvent()} if you wish to wait for events. * * @param arguments An object array containing the arguments to pass to coroutine.yield() - * @param callback The callback to resume with an array containing the return values from coroutine.yield() + * @param callback The callback to resume with an array containing the return values from coroutine.yield() * @return The method result which represents this yield. * @see #pullEvent(String, ILuaCallback) */ @Nonnull - public static MethodResult yield(@Nullable Object[] arguments, @Nonnull ILuaCallback callback) { - Objects.requireNonNull(callback, "callback cannot be null"); - return new MethodResult(arguments, callback); + public static MethodResult yield( @Nullable Object[] arguments, @Nonnull ILuaCallback callback ) + { + Objects.requireNonNull( callback, "callback cannot be null" ); + return new MethodResult( arguments, callback ); } @Nullable - public Object[] getResult() { + public Object[] getResult() + { return this.result; } @Nullable - public ILuaCallback getCallback() { + public ILuaCallback getCallback() + { return this.callback; } - public int getErrorAdjust() { + public int getErrorAdjust() + { return this.adjust; } @@ -150,13 +162,16 @@ public final class MethodResult { * @return The new {@link MethodResult} with an adjusted error. This has no effect on immediate results. */ @Nonnull - public MethodResult adjustError(int adjust) { - if (adjust < 0) { - throw new IllegalArgumentException("cannot adjust by a negative amount"); + public MethodResult adjustError( int adjust ) + { + if( adjust < 0 ) + { + throw new IllegalArgumentException( "cannot adjust by a negative amount" ); } - if (adjust == 0 || this.callback == null) { + if( adjust == 0 || this.callback == null ) + { return this; } - return new MethodResult(this.result, this.callback, this.adjust + adjust); + return new MethodResult( this.result, this.callback, this.adjust + adjust ); } } diff --git a/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java b/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java index 0c47d52e8..d0c58833b 100644 --- a/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java +++ b/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java @@ -6,61 +6,71 @@ package dan200.computercraft.api.lua; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.List; import java.util.Objects; -import javax.annotation.Nullable; - /** * An implementation of {@link IArguments} which wraps an array of {@link Object}. */ -public final class ObjectArguments implements IArguments { +public final class ObjectArguments implements IArguments +{ private static final IArguments EMPTY = new ObjectArguments(); private final List args; @Deprecated - @SuppressWarnings ("unused") - public ObjectArguments(IArguments arguments) { + @SuppressWarnings( "unused" ) + public ObjectArguments( IArguments arguments ) + { throw new IllegalStateException(); } - public ObjectArguments(Object... args) { - this.args = Arrays.asList(args); + public ObjectArguments( Object... args ) + { + this.args = Arrays.asList( args ); } - public ObjectArguments(List args) { - this.args = Objects.requireNonNull(args); + public ObjectArguments( List args ) + { + this.args = Objects.requireNonNull( args ); } @Override - public IArguments drop(int count) { - if (count < 0) { - throw new IllegalStateException("count cannot be negative"); + public IArguments drop( int count ) + { + if( count < 0 ) + { + throw new IllegalStateException( "count cannot be negative" ); } - if (count == 0) { + if( count == 0 ) + { return this; } - if (count >= this.args.size()) { + if( count >= this.args.size() ) + { return EMPTY; } - return new ObjectArguments(this.args.subList(count, this.args.size())); + return new ObjectArguments( this.args.subList( count, this.args.size() ) ); } @Override - public Object[] getAll() { + public Object[] getAll() + { return this.args.toArray(); } @Override - public int count() { + public int count() + { return this.args.size(); } @Nullable @Override - public Object get(int index) { - return index >= this.args.size() ? null : this.args.get(index); + public Object get( int index ) + { + return index >= this.args.size() ? null : this.args.get( index ); } } diff --git a/src/main/java/dan200/computercraft/api/media/IMedia.java b/src/main/java/dan200/computercraft/api/media/IMedia.java index c002aab23..986da717e 100644 --- a/src/main/java/dan200/computercraft/api/media/IMedia.java +++ b/src/main/java/dan200/computercraft/api/media/IMedia.java @@ -6,22 +6,22 @@ package dan200.computercraft.api.media; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IMount; - import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.sound.SoundEvent; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * Represents an item that can be placed in a disk drive and used by a Computer. * * Implement this interface on your {@link Item} class to allow it to be used in the drive. Alternatively, register a {@link IMediaProvider}. */ -public interface IMedia { +public interface IMedia +{ /** * Get a string representing the label of this item. Will be called via {@code disk.getLabel()} in lua. * @@ -29,7 +29,7 @@ public interface IMedia { * @return The label. ie: "Dan's Programs". */ @Nullable - String getLabel(@Nonnull ItemStack stack); + String getLabel( @Nonnull ItemStack stack ); /** * Set a string representing the label of this item. Will be called vi {@code disk.setLabel()} in lua. @@ -38,7 +38,8 @@ public interface IMedia { * @param label The string to set the label to. * @return true if the label was updated, false if the label may not be modified. */ - default boolean setLabel(@Nonnull ItemStack stack, @Nullable String label) { + default boolean setLabel( @Nonnull ItemStack stack, @Nullable String label ) + { return false; } @@ -49,7 +50,8 @@ public interface IMedia { * @return The name, or null if this item does not represent an item with audio. */ @Nullable - default String getAudioTitle(@Nonnull ItemStack stack) { + default String getAudioTitle( @Nonnull ItemStack stack ) + { return null; } @@ -60,7 +62,8 @@ public interface IMedia { * @return The name, or null if this item does not represent an item with audio. */ @Nullable - default SoundEvent getAudio(@Nonnull ItemStack stack) { + default SoundEvent getAudio( @Nonnull ItemStack stack ) + { return null; } @@ -71,14 +74,15 @@ public interface IMedia { * @param stack The {@link ItemStack} to modify. * @param world The world in which the item and disk drive reside. * @return The mount, or null if this item does not represent an item with data. If the mount returned also implements {@link - * dan200.computercraft.api.filesystem.IWritableMount}, it will mounted using mountWritable() + * dan200.computercraft.api.filesystem.IWritableMount}, it will mounted using mountWritable() * @see IMount * @see dan200.computercraft.api.filesystem.IWritableMount * @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String, long) * @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(String, String) */ @Nullable - default IMount createDataMount(@Nonnull ItemStack stack, @Nonnull World world) { + default IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world ) + { return null; } } diff --git a/src/main/java/dan200/computercraft/api/media/IMediaProvider.java b/src/main/java/dan200/computercraft/api/media/IMediaProvider.java index 28bf56bd7..7afa1e632 100644 --- a/src/main/java/dan200/computercraft/api/media/IMediaProvider.java +++ b/src/main/java/dan200/computercraft/api/media/IMediaProvider.java @@ -6,18 +6,19 @@ package dan200.computercraft.api.media; +import net.minecraft.item.ItemStack; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import net.minecraft.item.ItemStack; - /** * This interface is used to provide {@link IMedia} implementations for {@link ItemStack}. * * @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider) */ @FunctionalInterface -public interface IMediaProvider { +public interface IMediaProvider +{ /** * Produce an IMedia implementation from an ItemStack. * @@ -26,5 +27,5 @@ public interface IMediaProvider { * @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider) */ @Nullable - IMedia getMedia(@Nonnull ItemStack stack); + IMedia getMedia( @Nonnull ItemStack stack ); } diff --git a/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java b/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java index 324505ff6..b897717c6 100644 --- a/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java +++ b/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java @@ -14,20 +14,21 @@ import javax.annotation.Nonnull; * @see Packet * @see IPacketReceiver */ -public interface IPacketNetwork { +public interface IPacketNetwork +{ /** * Add a receiver to the network. * * @param receiver The receiver to register to the network. */ - void addReceiver(@Nonnull IPacketReceiver receiver); + void addReceiver( @Nonnull IPacketReceiver receiver ); /** * Remove a receiver from the network. * * @param receiver The device to remove from the network. */ - void removeReceiver(@Nonnull IPacketReceiver receiver); + void removeReceiver( @Nonnull IPacketReceiver receiver ); /** * Determine whether this network is wireless. @@ -41,11 +42,11 @@ public interface IPacketNetwork { * interdimensional ones). * * @param packet The packet to send. - * @param range The maximum distance this packet will be sent. + * @param range The maximum distance this packet will be sent. * @see #transmitInterdimensional(Packet) * @see IPacketReceiver#receiveSameDimension(Packet, double) */ - void transmitSameDimension(@Nonnull Packet packet, double range); + void transmitSameDimension( @Nonnull Packet packet, double range ); /** * Submit a packet for transmitting across the network. This will route the packet through the network, sending it to all receivers across all @@ -55,5 +56,5 @@ public interface IPacketNetwork { * @see #transmitSameDimension(Packet, double) * @see IPacketReceiver#receiveDifferentDimension(Packet) */ - void transmitInterdimensional(@Nonnull Packet packet); + void transmitInterdimensional( @Nonnull Packet packet ); } diff --git a/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java b/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java index 0b1c2c200..660344a2b 100644 --- a/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java +++ b/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java @@ -6,15 +6,16 @@ package dan200.computercraft.api.network; -import javax.annotation.Nonnull; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import javax.annotation.Nonnull; + /** * An object on an {@link IPacketNetwork}, capable of receiving packets. */ -public interface IPacketReceiver { +public interface IPacketReceiver +{ /** * Get the world in which this packet receiver exists. * @@ -59,25 +60,25 @@ public interface IPacketReceiver { /** * Receive a network packet from the same dimension. * - * @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate - * modem event. + * @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate + * modem event. * @param distance The distance this packet has travelled from the source. * @see Packet * @see #getRange() * @see IPacketNetwork#transmitSameDimension(Packet, double) * @see IPacketNetwork#transmitInterdimensional(Packet) */ - void receiveSameDimension(@Nonnull Packet packet, double distance); + void receiveSameDimension( @Nonnull Packet packet, double distance ); /** * Receive a network packet from a different dimension. * * @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate - * modem event. + * modem event. * @see Packet * @see IPacketNetwork#transmitInterdimensional(Packet) * @see IPacketNetwork#transmitSameDimension(Packet, double) * @see #isInterdimensional() */ - void receiveDifferentDimension(@Nonnull Packet packet); + void receiveDifferentDimension( @Nonnull Packet packet ); } diff --git a/src/main/java/dan200/computercraft/api/network/IPacketSender.java b/src/main/java/dan200/computercraft/api/network/IPacketSender.java index c5e15a06d..f3c06a397 100644 --- a/src/main/java/dan200/computercraft/api/network/IPacketSender.java +++ b/src/main/java/dan200/computercraft/api/network/IPacketSender.java @@ -6,15 +6,16 @@ package dan200.computercraft.api.network; -import javax.annotation.Nonnull; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import javax.annotation.Nonnull; + /** * An object on a {@link IPacketNetwork}, capable of sending packets. */ -public interface IPacketSender { +public interface IPacketSender +{ /** * Get the world in which this packet sender exists. * diff --git a/src/main/java/dan200/computercraft/api/network/Packet.java b/src/main/java/dan200/computercraft/api/network/Packet.java index a15c4f9a7..58251e01f 100644 --- a/src/main/java/dan200/computercraft/api/network/Packet.java +++ b/src/main/java/dan200/computercraft/api/network/Packet.java @@ -6,10 +6,9 @@ package dan200.computercraft.api.network; -import java.util.Objects; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Objects; /** * Represents a packet which may be sent across a {@link IPacketNetwork}. @@ -20,7 +19,8 @@ import javax.annotation.Nullable; * @see IPacketReceiver#receiveDifferentDimension(Packet) * @see IPacketReceiver#receiveSameDimension(Packet, double) */ -public class Packet { +public class Packet +{ private final int channel; private final int replyChannel; private final Object payload; @@ -30,14 +30,15 @@ public class Packet { /** * Create a new packet, ready for transmitting across the network. * - * @param channel The channel to send the packet along. Receiving devices should only process packets from on channels they are listening to. + * @param channel The channel to send the packet along. Receiving devices should only process packets from on channels they are listening to. * @param replyChannel The channel to reply on. - * @param payload The contents of this packet. This should be a "valid" Lua object, safe for queuing as an event or returning from a peripheral - * call. - * @param sender The object which sent this packet. + * @param payload The contents of this packet. This should be a "valid" Lua object, safe for queuing as an event or returning from a peripheral + * call. + * @param sender The object which sent this packet. */ - public Packet(int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender) { - Objects.requireNonNull(sender, "sender cannot be null"); + public Packet( int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender ) + { + Objects.requireNonNull( sender, "sender cannot be null" ); this.channel = channel; this.replyChannel = replyChannel; @@ -50,7 +51,8 @@ public class Packet { * * @return This packet's channel. */ - public int getChannel() { + public int getChannel() + { return this.channel; } @@ -59,7 +61,8 @@ public class Packet { * * @return This channel to reply on. */ - public int getReplyChannel() { + public int getReplyChannel() + { return this.replyChannel; } @@ -69,7 +72,8 @@ public class Packet { * @return The packet's payload */ @Nullable - public Object getPayload() { + public Object getPayload() + { return this.payload; } @@ -79,12 +83,14 @@ public class Packet { * @return The sending object. */ @Nonnull - public IPacketSender getSender() { + public IPacketSender getSender() + { return this.sender; } @Override - public int hashCode() { + public int hashCode() + { int result; result = this.channel; result = 31 * result + this.replyChannel; @@ -94,25 +100,31 @@ public class Packet { } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals( Object o ) + { + if( this == o ) + { return true; } - if (o == null || this.getClass() != o.getClass()) { + if( o == null || this.getClass() != o.getClass() ) + { return false; } Packet packet = (Packet) o; - if (this.channel != packet.channel) { + if( this.channel != packet.channel ) + { return false; } - if (this.replyChannel != packet.replyChannel) { + if( this.replyChannel != packet.replyChannel ) + { return false; } - if (!Objects.equals(this.payload, packet.payload)) { + if( !Objects.equals( this.payload, packet.payload ) ) + { return false; } - return this.sender.equals(packet.sender); + return this.sender.equals( packet.sender ); } } diff --git a/src/main/java/dan200/computercraft/api/network/wired/IWiredElement.java b/src/main/java/dan200/computercraft/api/network/wired/IWiredElement.java index f4d4daaf1..5ca0ddb9f 100644 --- a/src/main/java/dan200/computercraft/api/network/wired/IWiredElement.java +++ b/src/main/java/dan200/computercraft/api/network/wired/IWiredElement.java @@ -6,10 +6,10 @@ package dan200.computercraft.api.network.wired; -import javax.annotation.Nonnull; - import dan200.computercraft.api.ComputerCraftAPI; +import javax.annotation.Nonnull; + /** * An object which may be part of a wired network. * @@ -19,13 +19,15 @@ import dan200.computercraft.api.ComputerCraftAPI; * Elements are generally tied to a block or tile entity in world. In such as case, one should provide the {@link IWiredElement} capability for the * appropriate sides. */ -public interface IWiredElement extends IWiredSender { +public interface IWiredElement extends IWiredSender +{ /** * Called when objects on the network change. This may occur when network nodes are added or removed, or when peripherals change. * * @param change The change which occurred. * @see IWiredNetworkChange */ - default void networkChanged(@Nonnull IWiredNetworkChange change) { + default void networkChanged( @Nonnull IWiredNetworkChange change ) + { } } diff --git a/src/main/java/dan200/computercraft/api/network/wired/IWiredNetwork.java b/src/main/java/dan200/computercraft/api/network/wired/IWiredNetwork.java index dc7dac86f..fa44c4d1b 100644 --- a/src/main/java/dan200/computercraft/api/network/wired/IWiredNetwork.java +++ b/src/main/java/dan200/computercraft/api/network/wired/IWiredNetwork.java @@ -6,11 +6,10 @@ package dan200.computercraft.api.network.wired; -import java.util.Map; +import dan200.computercraft.api.peripheral.IPeripheral; import javax.annotation.Nonnull; - -import dan200.computercraft.api.peripheral.IPeripheral; +import java.util.Map; /** * A wired network is composed of one of more {@link IWiredNode}s, a set of connections between them, and a series of peripherals. @@ -24,28 +23,29 @@ import dan200.computercraft.api.peripheral.IPeripheral; * * @see IWiredNode#getNetwork() */ -public interface IWiredNetwork { +public interface IWiredNetwork +{ /** * Create a connection between two nodes. * * This should only be used on the server thread. * - * @param left The first node to connect + * @param left The first node to connect * @param right The second node to connect * @return {@code true} if a connection was created or {@code false} if the connection already exists. - * @throws IllegalStateException If neither node is on the network. + * @throws IllegalStateException If neither node is on the network. * @throws IllegalArgumentException If {@code left} and {@code right} are equal. * @see IWiredNode#connectTo(IWiredNode) * @see IWiredNetwork#connect(IWiredNode, IWiredNode) */ - boolean connect(@Nonnull IWiredNode left, @Nonnull IWiredNode right); + boolean connect( @Nonnull IWiredNode left, @Nonnull IWiredNode right ); /** * Destroy a connection between this node and another. * * This should only be used on the server thread. * - * @param left The first node in the connection. + * @param left The first node in the connection. * @param right The second node in the connection. * @return {@code true} if a connection was destroyed or {@code false} if no connection exists. * @throws IllegalArgumentException If either node is not on the network. @@ -53,7 +53,7 @@ public interface IWiredNetwork { * @see IWiredNode#disconnectFrom(IWiredNode) * @see IWiredNetwork#connect(IWiredNode, IWiredNode) */ - boolean disconnect(@Nonnull IWiredNode left, @Nonnull IWiredNode right); + boolean disconnect( @Nonnull IWiredNode left, @Nonnull IWiredNode right ); /** * Sever all connections this node has, removing it from this network. @@ -65,17 +65,17 @@ public interface IWiredNetwork { * @throws IllegalArgumentException If the node is not in the network. * @see IWiredNode#remove() */ - boolean remove(@Nonnull IWiredNode node); + boolean remove( @Nonnull IWiredNode node ); /** * Update the peripherals a node provides. * * This should only be used on the server thread. You should only call this on nodes that your network element owns. * - * @param node The node to attach peripherals for. + * @param node The node to attach peripherals for. * @param peripherals The new peripherals for this node. * @throws IllegalArgumentException If the node is not in the network. * @see IWiredNode#updatePeripherals(Map) */ - void updatePeripherals(@Nonnull IWiredNode node, @Nonnull Map peripherals); + void updatePeripherals( @Nonnull IWiredNode node, @Nonnull Map peripherals ); } diff --git a/src/main/java/dan200/computercraft/api/network/wired/IWiredNetworkChange.java b/src/main/java/dan200/computercraft/api/network/wired/IWiredNetworkChange.java index 4f9428427..bef4b1048 100644 --- a/src/main/java/dan200/computercraft/api/network/wired/IWiredNetworkChange.java +++ b/src/main/java/dan200/computercraft/api/network/wired/IWiredNetworkChange.java @@ -6,18 +6,18 @@ package dan200.computercraft.api.network.wired; -import java.util.Map; +import dan200.computercraft.api.peripheral.IPeripheral; import javax.annotation.Nonnull; - -import dan200.computercraft.api.peripheral.IPeripheral; +import java.util.Map; /** * Represents a change to the objects on a wired network. * * @see IWiredElement#networkChanged(IWiredNetworkChange) */ -public interface IWiredNetworkChange { +public interface IWiredNetworkChange +{ /** * A set of peripherals which have been removed. Note that there may be entries with the same name in the added and removed set, but with a different * peripheral. diff --git a/src/main/java/dan200/computercraft/api/network/wired/IWiredNode.java b/src/main/java/dan200/computercraft/api/network/wired/IWiredNode.java index c4fa6d4c0..233da434c 100644 --- a/src/main/java/dan200/computercraft/api/network/wired/IWiredNode.java +++ b/src/main/java/dan200/computercraft/api/network/wired/IWiredNode.java @@ -6,13 +6,12 @@ package dan200.computercraft.api.network.wired; -import java.util.Map; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.network.IPacketNetwork; import dan200.computercraft.api.peripheral.IPeripheral; +import javax.annotation.Nonnull; +import java.util.Map; + /** * Wired nodes act as a layer between {@link IWiredElement}s and {@link IWiredNetwork}s. * @@ -25,7 +24,8 @@ import dan200.computercraft.api.peripheral.IPeripheral; * * Wired nodes also provide several convenience methods for interacting with a wired network. These should only ever be used on the main server thread. */ -public interface IWiredNode extends IPacketNetwork { +public interface IWiredNode extends IPacketNetwork +{ /** * The associated element for this network node. * @@ -44,8 +44,9 @@ public interface IWiredNode extends IPacketNetwork { * @see IWiredNetwork#connect(IWiredNode, IWiredNode) * @see IWiredNode#disconnectFrom(IWiredNode) */ - default boolean connectTo(@Nonnull IWiredNode node) { - return this.getNetwork().connect(this, node); + default boolean connectTo( @Nonnull IWiredNode node ) + { + return this.getNetwork().connect( this, node ); } /** @@ -69,8 +70,9 @@ public interface IWiredNode extends IPacketNetwork { * @see IWiredNetwork#disconnect(IWiredNode, IWiredNode) * @see IWiredNode#connectTo(IWiredNode) */ - default boolean disconnectFrom(@Nonnull IWiredNode node) { - return this.getNetwork().disconnect(this, node); + default boolean disconnectFrom( @Nonnull IWiredNode node ) + { + return this.getNetwork().disconnect( this, node ); } /** @@ -82,8 +84,9 @@ public interface IWiredNode extends IPacketNetwork { * @throws IllegalArgumentException If the node is not in the network. * @see IWiredNetwork#remove(IWiredNode) */ - default boolean remove() { - return this.getNetwork().remove(this); + default boolean remove() + { + return this.getNetwork().remove( this ); } /** @@ -94,7 +97,8 @@ public interface IWiredNode extends IPacketNetwork { * @param peripherals The new peripherals for this node. * @see IWiredNetwork#updatePeripherals(IWiredNode, Map) */ - default void updatePeripherals(@Nonnull Map peripherals) { - this.getNetwork().updatePeripherals(this, peripherals); + default void updatePeripherals( @Nonnull Map peripherals ) + { + this.getNetwork().updatePeripherals( this, peripherals ); } } diff --git a/src/main/java/dan200/computercraft/api/network/wired/IWiredSender.java b/src/main/java/dan200/computercraft/api/network/wired/IWiredSender.java index e03ee5df1..c306b0a6b 100644 --- a/src/main/java/dan200/computercraft/api/network/wired/IWiredSender.java +++ b/src/main/java/dan200/computercraft/api/network/wired/IWiredSender.java @@ -6,16 +6,17 @@ package dan200.computercraft.api.network.wired; -import javax.annotation.Nonnull; - import dan200.computercraft.api.network.IPacketSender; +import javax.annotation.Nonnull; + /** * An object on a {@link IWiredNetwork} capable of sending packets. * * Unlike a regular {@link IPacketSender}, this must be associated with the node you are attempting to to send the packet from. */ -public interface IWiredSender extends IPacketSender { +public interface IWiredSender extends IPacketSender +{ /** * The node in the network representing this object. * diff --git a/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java b/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java index 732266ec1..30d4c6522 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java +++ b/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java @@ -6,11 +6,6 @@ package dan200.computercraft.api.peripheral; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; @@ -18,21 +13,25 @@ import dan200.computercraft.api.lua.ILuaCallback; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaTask; import dan200.computercraft.api.lua.MethodResult; - import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Map; + /** * The interface passed to peripherals by computers or turtles, providing methods that they can call. This should not be implemented by your classes. Do not * interact with computers except via this interface. */ -public interface IComputerAccess { +public interface IComputerAccess +{ /** * Mount a mount onto the computer's file system in a read only mode. * * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. - * @param mount The mount object to mount on the computer. + * @param mount The mount object to mount on the computer. * @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a file in the desired location. - * Store this value if you wish to unmount the mount later. + * Store this value if you wish to unmount the mount later. * @throws NotAttachedException If the peripheral has been detached. * @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createResourceMount(String, String) @@ -42,18 +41,19 @@ public interface IComputerAccess { * @see IMount */ @Nullable - default String mount(@Nonnull String desiredLocation, @Nonnull IMount mount) { - return this.mount(desiredLocation, mount, this.getAttachmentName()); + default String mount( @Nonnull String desiredLocation, @Nonnull IMount mount ) + { + return this.mount( desiredLocation, mount, this.getAttachmentName() ); } /** * Mount a mount onto the computer's file system in a read only mode. * * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. - * @param mount The mount object to mount on the computer. - * @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}. + * @param mount The mount object to mount on the computer. + * @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}. * @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a file in the desired location. - * Store this value if you wish to unmount the mount later. + * Store this value if you wish to unmount the mount later. * @throws NotAttachedException If the peripheral has been detached. * @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createResourceMount(String, String) @@ -63,7 +63,7 @@ public interface IComputerAccess { * @see IMount */ @Nullable - String mount(@Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName); + String mount( @Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName ); /** * Get a string, unique to the computer, by which the computer refers to this peripheral. For directly attached peripherals this will be @@ -80,9 +80,9 @@ public interface IComputerAccess { * Mount a mount onto the computer's file system in a writable mode. * * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. - * @param mount The mount object to mount on the computer. + * @param mount The mount object to mount on the computer. * @return The location on the computer's file system where you the mount mounted, or null if there was already a file in the desired location. Store - * this value if you wish to unmount the mount later. + * this value if you wish to unmount the mount later. * @throws NotAttachedException If the peripheral has been detached. * @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createResourceMount(String, String) @@ -91,18 +91,19 @@ public interface IComputerAccess { * @see IMount */ @Nullable - default String mountWritable(@Nonnull String desiredLocation, @Nonnull IWritableMount mount) { - return this.mountWritable(desiredLocation, mount, this.getAttachmentName()); + default String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount ) + { + return this.mountWritable( desiredLocation, mount, this.getAttachmentName() ); } /** * Mount a mount onto the computer's file system in a writable mode. * * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. - * @param mount The mount object to mount on the computer. - * @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}. + * @param mount The mount object to mount on the computer. + * @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}. * @return The location on the computer's file system where you the mount mounted, or null if there was already a file in the desired location. Store - * this value if you wish to unmount the mount later. + * this value if you wish to unmount the mount later. * @throws NotAttachedException If the peripheral has been detached. * @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createResourceMount(String, String) @@ -110,7 +111,7 @@ public interface IComputerAccess { * @see #unmount(String) * @see IMount */ - String mountWritable(@Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName); + String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName ); /** * Unmounts a directory previously mounted onto the computers file system by {@link #mount(String, IMount)} or {@link #mountWritable(String, @@ -122,13 +123,13 @@ public interface IComputerAccess { * Note that you cannot unmount another peripheral's mounts. * * @param location The desired location in the computers file system of the directory to unmount. This must be the location of a directory - * previously mounted by {@link #mount(String, IMount)} or {@link #mountWritable(String, IWritableMount)}, as indicated by their return value. - * @throws NotAttachedException If the peripheral has been detached. + * previously mounted by {@link #mount(String, IMount)} or {@link #mountWritable(String, IWritableMount)}, as indicated by their return value. + * @throws NotAttachedException If the peripheral has been detached. * @throws IllegalStateException If the mount does not exist, or was mounted by another peripheral. * @see #mount(String, IMount) * @see #mountWritable(String, IWritableMount) */ - void unmount(@Nullable String location); + void unmount( @Nullable String location ); /** * Returns the numerical ID of this computer. @@ -144,17 +145,17 @@ public interface IComputerAccess { * Causes an event to be raised on this computer, which the computer can respond to by calling {@code os.pullEvent()}. This can be used to notify the * computer when things happen in the world or to this peripheral. * - * @param event A string identifying the type of event that has occurred, this will be returned as the first value from {@code os.pullEvent()}. It - * is recommended that you you choose a name that is unique, and recognisable as originating from your peripheral. eg: If your peripheral type is - * "button", a suitable event would be "button_pressed". + * @param event A string identifying the type of event that has occurred, this will be returned as the first value from {@code os.pullEvent()}. It + * is recommended that you you choose a name that is unique, and recognisable as originating from your peripheral. eg: If your peripheral type is + * "button", a suitable event would be "button_pressed". * @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will be supplied as extra return values to - * os.pullEvent(). Objects in the array will be converted to lua data types in the same fashion as the return values of IPeripheral.callMethod(). + * os.pullEvent(). Objects in the array will be converted to lua data types in the same fashion as the return values of IPeripheral.callMethod(). * - * You may supply {@code null} to indicate that no arguments are to be supplied. + * You may supply {@code null} to indicate that no arguments are to be supplied. * @throws NotAttachedException If the peripheral has been detached. * @see MethodResult#pullEvent(String, ILuaCallback) */ - void queueEvent(@Nonnull String event, @Nullable Object... arguments); + void queueEvent( @Nonnull String event, @Nullable Object... arguments ); /** * Get a set of peripherals that this computer access can "see", along with their attachment name. @@ -178,7 +179,7 @@ public interface IComputerAccess { * @see #getAvailablePeripherals() */ @Nullable - IPeripheral getAvailablePeripheral(@Nonnull String name); + IPeripheral getAvailablePeripheral( @Nonnull String name ); /** * Get a {@link IWorkMonitor} for tasks your peripheral might execute on the main (server) thread. diff --git a/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java b/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java index 9842600dc..e06c14096 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java +++ b/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java @@ -6,14 +6,9 @@ package dan200.computercraft.api.peripheral; -import javax.annotation.Nonnull; +import dan200.computercraft.api.lua.*; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.IDynamicLuaObject; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; -import dan200.computercraft.api.lua.MethodResult; +import javax.annotation.Nonnull; /** * A peripheral whose methods are not known at runtime. @@ -21,7 +16,8 @@ import dan200.computercraft.api.lua.MethodResult; * This behaves similarly to {@link IDynamicLuaObject}, though also accepting the current {@link IComputerAccess}. Generally one may use {@link LuaFunction} * instead of implementing this interface. */ -public interface IDynamicPeripheral extends IPeripheral { +public interface IDynamicPeripheral extends IPeripheral +{ /** * Should return an array of strings that identify the methods that this peripheral exposes to Lua. This will be called once before each attachment, and * should not change when called multiple times. @@ -38,16 +34,16 @@ public interface IDynamicPeripheral extends IPeripheral { * * Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe when interacting with Minecraft objects. * - * @param computer The interface to the computer that is making the call. Remember that multiple computers can be attached to a peripheral at once. - * @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield. - * @param method An integer identifying which of the methods from getMethodNames() the computercraft wishes to call. The integer indicates the index - * into the getMethodNames() table that corresponds to the string passed into peripheral.call() + * @param computer The interface to the computer that is making the call. Remember that multiple computers can be attached to a peripheral at once. + * @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield. + * @param method An integer identifying which of the methods from getMethodNames() the computercraft wishes to call. The integer indicates the index + * into the getMethodNames() table that corresponds to the string passed into peripheral.call() * @param arguments The arguments for this method. * @return A {@link MethodResult} containing the values to return or the action to perform. * @throws LuaException If you throw any exception from this function, a lua error will be raised with the same message as your exception. Use this - * to throw appropriate errors if the wrong arguments are supplied to your method. + * to throw appropriate errors if the wrong arguments are supplied to your method. * @see #getMethodNames() */ @Nonnull - MethodResult callMethod(@Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull IArguments arguments) throws LuaException; + MethodResult callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull IArguments arguments ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java b/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java index 73e7a04d6..09a63c64d 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java +++ b/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java @@ -6,11 +6,11 @@ package dan200.computercraft.api.peripheral; +import dan200.computercraft.api.lua.LuaFunction; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import dan200.computercraft.api.lua.LuaFunction; - /** * The interface that defines a peripheral. * @@ -19,7 +19,8 @@ import dan200.computercraft.api.lua.LuaFunction; * * Peripherals should provide a series of methods to the user, either using {@link LuaFunction} or by implementing {@link IDynamicPeripheral}. */ -public interface IPeripheral { +public interface IPeripheral +{ /** * Should return a string that uniquely identifies this type of peripheral. This can be queried from lua by calling {@code peripheral.getType()} * @@ -42,7 +43,8 @@ public interface IPeripheral { * @param computer The interface to the computer that is being attached. Remember that multiple computers can be attached to a peripheral at once. * @see #detach */ - default void attach(@Nonnull IComputerAccess computer) { + default void attach( @Nonnull IComputerAccess computer ) + { } /** @@ -58,7 +60,8 @@ public interface IPeripheral { * @param computer The interface to the computer that is being detached. Remember that multiple computers can be attached to a peripheral at once. * @see #attach */ - default void detach(@Nonnull IComputerAccess computer) { + default void detach( @Nonnull IComputerAccess computer ) + { } /** @@ -67,7 +70,8 @@ public interface IPeripheral { * @return The object this peripheral targets */ @Nullable - default Object getTarget() { + default Object getTarget() + { return null; } @@ -80,5 +84,5 @@ public interface IPeripheral { * @param other The peripheral to compare against. This may be {@code null}. * @return Whether these peripherals are equivalent. */ - boolean equals(@Nullable IPeripheral other); + boolean equals( @Nullable IPeripheral other ); } diff --git a/src/main/java/dan200/computercraft/api/peripheral/IPeripheralProvider.java b/src/main/java/dan200/computercraft/api/peripheral/IPeripheralProvider.java index 5697ad681..ae704dfc7 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/IPeripheralProvider.java +++ b/src/main/java/dan200/computercraft/api/peripheral/IPeripheralProvider.java @@ -6,15 +6,14 @@ package dan200.computercraft.api.peripheral; -import java.util.Optional; - -import javax.annotation.Nonnull; - import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import java.util.Optional; + /** * This interface is used to create peripheral implementations for blocks. * @@ -23,16 +22,17 @@ import net.minecraft.world.World; * @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider) */ @FunctionalInterface -public interface IPeripheralProvider { +public interface IPeripheralProvider +{ /** * Produce an peripheral implementation from a block location. * * @param world The world the block is in. - * @param pos The position the block is at. - * @param side The side to get the peripheral from. + * @param pos The position the block is at. + * @param side The side to get the peripheral from. * @return A peripheral, or {@link Optional#empty()} if there is not a peripheral here you'd like to handle. * @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider) */ @Nonnull - IPeripheral getPeripheral(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side); + IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ); } diff --git a/src/main/java/dan200/computercraft/api/peripheral/IPeripheralTile.java b/src/main/java/dan200/computercraft/api/peripheral/IPeripheralTile.java index 4b463dc1b..b12d7f5c0 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/IPeripheralTile.java +++ b/src/main/java/dan200/computercraft/api/peripheral/IPeripheralTile.java @@ -5,19 +5,20 @@ */ package dan200.computercraft.api.peripheral; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * A {@link net.minecraft.block.entity.BlockEntity} which may act as a peripheral. * * If you need more complex capabilities (such as handling TEs not belonging to your mod), you should use {@link IPeripheralProvider}. */ -public interface IPeripheralTile { +public interface IPeripheralTile +{ /** * Get the peripheral on the given {@code side}. * @@ -26,5 +27,5 @@ public interface IPeripheralTile { * @see IPeripheralProvider#getPeripheral(World, BlockPos, Direction) */ @Nullable - IPeripheral getPeripheral(@Nonnull Direction side); + IPeripheral getPeripheral( @Nonnull Direction side ); } diff --git a/src/main/java/dan200/computercraft/api/peripheral/IWorkMonitor.java b/src/main/java/dan200/computercraft/api/peripheral/IWorkMonitor.java index 22b0863f6..bddfb4985 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/IWorkMonitor.java +++ b/src/main/java/dan200/computercraft/api/peripheral/IWorkMonitor.java @@ -6,11 +6,10 @@ package dan200.computercraft.api.peripheral; +import javax.annotation.Nonnull; import java.util.Objects; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; - /** * Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every computer receives a fair share of any * processing time. @@ -25,7 +24,8 @@ import javax.annotation.Nonnull; * * @see IComputerAccess#getMainThreadMonitor() */ -public interface IWorkMonitor { +public interface IWorkMonitor +{ /** * If the owning computer is currently allowed to execute work, and has ample time to do so. * @@ -42,17 +42,22 @@ public interface IWorkMonitor { * @param runnable The task to run. * @return If the task was actually run (namely, {@link #canWork()} returned {@code true}). */ - default boolean runWork(@Nonnull Runnable runnable) { - Objects.requireNonNull(runnable, "runnable should not be null"); - if (!this.canWork()) { + default boolean runWork( @Nonnull Runnable runnable ) + { + Objects.requireNonNull( runnable, "runnable should not be null" ); + if( !this.canWork() ) + { return false; } long start = System.nanoTime(); - try { + try + { runnable.run(); - } finally { - this.trackWork(System.nanoTime() - start, TimeUnit.NANOSECONDS); + } + finally + { + this.trackWork( System.nanoTime() - start, TimeUnit.NANOSECONDS ); } return true; @@ -71,5 +76,5 @@ public interface IWorkMonitor { * @param time The time some task took to run * @param unit The unit that {@code time} was measured in. */ - void trackWork(long time, @Nonnull TimeUnit unit); + void trackWork( long time, @Nonnull TimeUnit unit ); } diff --git a/src/main/java/dan200/computercraft/api/peripheral/NotAttachedException.java b/src/main/java/dan200/computercraft/api/peripheral/NotAttachedException.java index 4690c9b3a..335841cfb 100644 --- a/src/main/java/dan200/computercraft/api/peripheral/NotAttachedException.java +++ b/src/main/java/dan200/computercraft/api/peripheral/NotAttachedException.java @@ -9,14 +9,17 @@ package dan200.computercraft.api.peripheral; /** * Thrown when performing operations on {@link IComputerAccess} when the current peripheral is no longer attached to the computer. */ -public class NotAttachedException extends IllegalStateException { +public class NotAttachedException extends IllegalStateException +{ private static final long serialVersionUID = 1221244785535553536L; - public NotAttachedException() { - super("You are not attached to this computer"); + public NotAttachedException() + { + super( "You are not attached to this computer" ); } - public NotAttachedException(String s) { - super(s); + public NotAttachedException( String s ) + { + super( s ); } } diff --git a/src/main/java/dan200/computercraft/api/pocket/AbstractPocketUpgrade.java b/src/main/java/dan200/computercraft/api/pocket/AbstractPocketUpgrade.java index 9e6ca54c1..16f183441 100644 --- a/src/main/java/dan200/computercraft/api/pocket/AbstractPocketUpgrade.java +++ b/src/main/java/dan200/computercraft/api/pocket/AbstractPocketUpgrade.java @@ -6,34 +6,38 @@ package dan200.computercraft.api.pocket; -import javax.annotation.Nonnull; - import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; import net.minecraft.util.Util; +import javax.annotation.Nonnull; + /** * A base class for {@link IPocketUpgrade}s. * * One does not have to use this, but it does provide a convenient template. */ -public abstract class AbstractPocketUpgrade implements IPocketUpgrade { +public abstract class AbstractPocketUpgrade implements IPocketUpgrade +{ private final Identifier id; private final String adjective; private final ItemStack stack; - protected AbstractPocketUpgrade(Identifier id, ItemConvertible item) { - this(id, Util.createTranslationKey("upgrade", id) + ".adjective", item); + protected AbstractPocketUpgrade( Identifier id, ItemConvertible item ) + { + this( id, Util.createTranslationKey( "upgrade", id ) + ".adjective", item ); } - protected AbstractPocketUpgrade(Identifier id, String adjective, ItemConvertible item) { + protected AbstractPocketUpgrade( Identifier id, String adjective, ItemConvertible item ) + { this.id = id; this.adjective = adjective; - this.stack = new ItemStack(item); + this.stack = new ItemStack( item ); } - protected AbstractPocketUpgrade(Identifier id, String adjective, ItemStack stack) { + protected AbstractPocketUpgrade( Identifier id, String adjective, ItemStack stack ) + { this.id = id; this.adjective = adjective; this.stack = stack; @@ -42,19 +46,22 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade { @Nonnull @Override - public final Identifier getUpgradeID() { + public final Identifier getUpgradeID() + { return this.id; } @Nonnull @Override - public final String getUnlocalisedAdjective() { + public final String getUnlocalisedAdjective() + { return this.adjective; } @Nonnull @Override - public final ItemStack getCraftingItem() { + public final ItemStack getCraftingItem() + { return this.stack; } } diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java index 792703fc9..fe82eb5ab 100644 --- a/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java @@ -6,21 +6,20 @@ package dan200.computercraft.api.pocket; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; - import net.minecraft.entity.Entity; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Identifier; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Map; + /** * Wrapper class for pocket computers. */ -public interface IPocketAccess { +public interface IPocketAccess +{ /** * Gets the entity holding this item. * @@ -43,10 +42,10 @@ public interface IPocketAccess { * Set the colour of the pocket computer to a RGB number. * * @param colour The colour this pocket computer should be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or - * -1 to reset to the default colour. + * -1 to reset to the default colour. * @see #getColour() */ - void setColour(int colour); + void setColour( int colour ); /** * Get the colour of this pocket computer's light as a RGB number. @@ -60,10 +59,10 @@ public interface IPocketAccess { * Set the colour of the pocket computer's light to a RGB number. * * @param colour The colour this modem's light will be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or -1 - * to reset to the default colour. + * to reset to the default colour. * @see #getLight() */ - void setLight(int colour); + void setLight( int colour ); /** * Get the upgrade-specific NBT. diff --git a/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java b/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java index a9e9c8517..d8b9d0c13 100644 --- a/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java +++ b/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java @@ -6,15 +6,14 @@ package dan200.computercraft.api.pocket; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.IUpgradeBase; import dan200.computercraft.api.peripheral.IPeripheral; - import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * Additional peripherals for pocket computers. * @@ -33,29 +32,31 @@ public interface IPocketUpgrade extends IUpgradeBase * @see #update(IPocketAccess, IPeripheral) */ @Nullable - IPeripheral createPeripheral(@Nonnull IPocketAccess access); + IPeripheral createPeripheral( @Nonnull IPocketAccess access ); /** * Called when the pocket computer item stack updates. * - * @param access The access object for the pocket item stack. + * @param access The access object for the pocket item stack. * @param peripheral The peripheral for this upgrade. * @see #createPeripheral(IPocketAccess) */ - default void update(@Nonnull IPocketAccess access, @Nullable IPeripheral peripheral) { + default void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) + { } /** * Called when the pocket computer is right clicked. * - * @param world The world the computer is in. - * @param access The access object for the pocket item stack. + * @param world The world the computer is in. + * @param access The access object for the pocket item stack. * @param peripheral The peripheral for this upgrade. * @return {@code true} to stop the GUI from opening, otherwise false. You should always provide some code path which returns {@code false}, such as - * requiring the player to be sneaking - otherwise they will be unable to access the GUI. + * requiring the player to be sneaking - otherwise they will be unable to access the GUI. * @see #createPeripheral(IPocketAccess) */ - default boolean onRightClick(@Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral) { + default boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) + { return false; } } diff --git a/src/main/java/dan200/computercraft/api/redstone/IBundledRedstoneProvider.java b/src/main/java/dan200/computercraft/api/redstone/IBundledRedstoneProvider.java index 90f00db0f..ad92f3903 100644 --- a/src/main/java/dan200/computercraft/api/redstone/IBundledRedstoneProvider.java +++ b/src/main/java/dan200/computercraft/api/redstone/IBundledRedstoneProvider.java @@ -6,27 +6,28 @@ package dan200.computercraft.api.redstone; -import javax.annotation.Nonnull; - import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; +import javax.annotation.Nonnull; + /** * This interface is used to provide bundled redstone output for blocks. * * @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider) */ @FunctionalInterface -public interface IBundledRedstoneProvider { +public interface IBundledRedstoneProvider +{ /** * Produce an bundled redstone output from a block location. * * @param world The world this block is in. - * @param pos The position this block is at. - * @param side The side to extract the bundled redstone output from. + * @param pos The position this block is at. + * @param side The side to extract the bundled redstone output from. * @return A number in the range 0-65535 to indicate this block is providing output, or -1 if you do not wish to handle this block. * @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider) */ - int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side); + int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ); } diff --git a/src/main/java/dan200/computercraft/api/turtle/AbstractTurtleUpgrade.java b/src/main/java/dan200/computercraft/api/turtle/AbstractTurtleUpgrade.java index d099f6148..34b5bc1cf 100644 --- a/src/main/java/dan200/computercraft/api/turtle/AbstractTurtleUpgrade.java +++ b/src/main/java/dan200/computercraft/api/turtle/AbstractTurtleUpgrade.java @@ -6,65 +6,74 @@ package dan200.computercraft.api.turtle; -import javax.annotation.Nonnull; - import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; import net.minecraft.util.Util; +import javax.annotation.Nonnull; + /** * A base class for {@link ITurtleUpgrade}s. * * One does not have to use this, but it does provide a convenient template. */ -public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade { +public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade +{ private final Identifier id; private final TurtleUpgradeType type; private final String adjective; private final ItemStack stack; - protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, String adjective, ItemConvertible item) { - this(id, type, adjective, new ItemStack(item)); + protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, String adjective, ItemConvertible item ) + { + this( id, type, adjective, new ItemStack( item ) ); } - protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, String adjective, ItemStack stack) { + protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, String adjective, ItemStack stack ) + { this.id = id; this.type = type; this.adjective = adjective; this.stack = stack; } - protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, ItemConvertible item) { - this(id, type, new ItemStack(item)); + protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, ItemConvertible item ) + { + this( id, type, new ItemStack( item ) ); } - protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, ItemStack stack) { - this(id, type, Util.createTranslationKey("upgrade", id) + ".adjective", stack); + protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, ItemStack stack ) + { + this( id, type, Util.createTranslationKey( "upgrade", id ) + ".adjective", stack ); } @Nonnull @Override - public final Identifier getUpgradeID() { + public final Identifier getUpgradeID() + { return this.id; } @Nonnull @Override - public final String getUnlocalisedAdjective() { + public final String getUnlocalisedAdjective() + { return this.adjective; } @Nonnull @Override - public final TurtleUpgradeType getType() { + public final TurtleUpgradeType getType() + { return this.type; } @Nonnull @Override - public final ItemStack getCraftingItem() { + public final ItemStack getCraftingItem() + { return this.stack; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/FakePlayer.java b/src/main/java/dan200/computercraft/api/turtle/FakePlayer.java index 7c17ad6a2..f1cfd1790 100644 --- a/src/main/java/dan200/computercraft/api/turtle/FakePlayer.java +++ b/src/main/java/dan200/computercraft/api/turtle/FakePlayer.java @@ -5,18 +5,10 @@ */ package dan200.computercraft.api.turtle; -import java.util.Collection; -import java.util.OptionalInt; -import java.util.UUID; - -import javax.annotation.Nullable; -import javax.crypto.Cipher; - import com.mojang.authlib.GameProfile; import io.netty.channel.ChannelHandlerContext; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; - import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.command.argument.EntityAnchorArgumentType; @@ -26,11 +18,7 @@ import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.passive.HorseBaseEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.MessageType; -import net.minecraft.network.NetworkSide; -import net.minecraft.network.NetworkState; -import net.minecraft.network.Packet; +import net.minecraft.network.*; import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket; import net.minecraft.network.packet.c2s.play.VehicleMoveC2SPacket; import net.minecraft.recipe.Recipe; @@ -50,15 +38,23 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.village.TradeOfferList; import net.minecraft.world.GameMode; +import javax.annotation.Nullable; +import javax.crypto.Cipher; +import java.util.Collection; +import java.util.OptionalInt; +import java.util.UUID; + /** * A wrapper for {@link ServerPlayerEntity} which denotes a "fake" player. * * Please note that this does not implement any of the traditional fake player behaviour. It simply exists to prevent me passing in normal players. */ -public class FakePlayer extends ServerPlayerEntity { - public FakePlayer(ServerWorld world, GameProfile gameProfile) { - super(world.getServer(), world, gameProfile, new ServerPlayerInteractionManager(world)); - this.networkHandler = new FakeNetHandler(this); +public class FakePlayer extends ServerPlayerEntity +{ + public FakePlayer( ServerWorld world, GameProfile gameProfile ) + { + super( world.getServer(), world, gameProfile, new ServerPlayerInteractionManager( world ) ); + this.networkHandler = new FakeNetHandler( this ); } // region Direct networkHandler access @@ -75,20 +71,23 @@ public class FakePlayer extends ServerPlayerEntity { public void playerTick() { } @Override - public void onDeath(DamageSource damage) { } + public void onDeath( DamageSource damage ) { } @Override - public Entity moveToWorld(ServerWorld destination) { + public Entity moveToWorld( ServerWorld destination ) + { return this; } @Override - public void wakeUp(boolean bl, boolean updateSleepingPlayers) { + public void wakeUp( boolean bl, boolean updateSleepingPlayers ) + { } @Override - public boolean startRiding(Entity entity, boolean flag) { + public boolean startRiding( Entity entity, boolean flag ) + { return false; } @@ -96,33 +95,34 @@ public class FakePlayer extends ServerPlayerEntity { public void stopRiding() { } @Override - public void openEditSignScreen(SignBlockEntity tile) { } + public void openEditSignScreen( SignBlockEntity tile ) { } @Override - public OptionalInt openHandledScreen(@Nullable NamedScreenHandlerFactory container) { + public OptionalInt openHandledScreen( @Nullable NamedScreenHandlerFactory container ) + { return OptionalInt.empty(); } @Override - public void sendTradeOffers(int id, TradeOfferList list, int level, int experience, boolean levelled, boolean refreshable) { } + public void sendTradeOffers( int id, TradeOfferList list, int level, int experience, boolean levelled, boolean refreshable ) { } @Override - public void openHorseInventory(HorseBaseEntity horse, Inventory inventory) { } + public void openHorseInventory( HorseBaseEntity horse, Inventory inventory ) { } @Override - public void openEditBookScreen(ItemStack stack, Hand hand) { } + public void openEditBookScreen( ItemStack stack, Hand hand ) { } @Override - public void openCommandBlockScreen(CommandBlockBlockEntity block) { } + public void openCommandBlockScreen( CommandBlockBlockEntity block ) { } @Override - public void onSlotUpdate(ScreenHandler container, int slot, ItemStack stack) { } + public void onSlotUpdate( ScreenHandler container, int slot, ItemStack stack ) { } @Override - public void onHandlerRegistered(ScreenHandler container, DefaultedList defaultedList) { } + public void onHandlerRegistered( ScreenHandler container, DefaultedList defaultedList ) { } @Override - public void onPropertyUpdate(ScreenHandler container, int key, int value) { } + public void onPropertyUpdate( ScreenHandler container, int key, int value ) { } @Override public void closeHandledScreen() { } @@ -131,136 +131,154 @@ public class FakePlayer extends ServerPlayerEntity { public void updateCursorStack() { } @Override - public int unlockRecipes(Collection> recipes) { + public int unlockRecipes( Collection> recipes ) + { return 0; } // Indirect @Override - public int lockRecipes(Collection> recipes) { + public int lockRecipes( Collection> recipes ) + { return 0; } @Override - public void sendMessage(Text textComponent, boolean status) { } + public void sendMessage( Text textComponent, boolean status ) { } @Override protected void consumeItem() { } @Override - public void lookAt(EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d) {} + public void lookAt( EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d ) {} @Override - public void method_14222(EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target) { } + public void method_14222( EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target ) { } @Override - protected void onStatusEffectApplied(StatusEffectInstance statusEffectInstance) { } + protected void onStatusEffectApplied( StatusEffectInstance statusEffectInstance ) { } @Override - protected void onStatusEffectUpgraded(StatusEffectInstance statusEffectInstance, boolean particles) { } + protected void onStatusEffectUpgraded( StatusEffectInstance statusEffectInstance, boolean particles ) { } @Override - protected void onStatusEffectRemoved(StatusEffectInstance statusEffectInstance) { } + protected void onStatusEffectRemoved( StatusEffectInstance statusEffectInstance ) { } @Override - public void requestTeleport(double x, double y, double z) { } + public void requestTeleport( double x, double y, double z ) { } @Override - public void setGameMode(GameMode gameMode) { } + public void setGameMode( GameMode gameMode ) { } @Override - public void sendMessage(Text message, MessageType type, UUID senderUuid) { + public void sendMessage( Text message, MessageType type, UUID senderUuid ) + { } @Override - public String getIp() { + public String getIp() + { return "[Fake Player]"; } @Override - public void sendResourcePackUrl(String url, String hash) { } + public void sendResourcePackUrl( String url, String hash ) { } @Override - public void onStoppedTracking(Entity entity) { } + public void onStoppedTracking( Entity entity ) { } @Override - public void setCameraEntity(Entity entity) { } + public void setCameraEntity( Entity entity ) { } @Override - public void teleport(ServerWorld serverWorld, double x, double y, double z, float pitch, float yaw) { } + public void teleport( ServerWorld serverWorld, double x, double y, double z, float pitch, float yaw ) { } @Override - public void sendInitialChunkPackets(ChunkPos chunkPos, Packet packet, Packet packet2) { } + public void sendInitialChunkPackets( ChunkPos chunkPos, Packet packet, Packet packet2 ) { } @Override - public void sendUnloadChunkPacket(ChunkPos chunkPos) { } + public void sendUnloadChunkPacket( ChunkPos chunkPos ) { } @Override - public void playSound(SoundEvent soundEvent, SoundCategory soundCategory, float volume, float pitch) { } + public void playSound( SoundEvent soundEvent, SoundCategory soundCategory, float volume, float pitch ) { } - private static class FakeNetHandler extends ServerPlayNetworkHandler { - FakeNetHandler(ServerPlayerEntity player) { - super(player.server, new FakeConnection(), player); + private static class FakeNetHandler extends ServerPlayNetworkHandler + { + FakeNetHandler( ServerPlayerEntity player ) + { + super( player.server, new FakeConnection(), player ); } @Override - public void disconnect(Text message) { } + public void disconnect( Text message ) { } @Override - public void onVehicleMove(VehicleMoveC2SPacket move) { } + public void onVehicleMove( VehicleMoveC2SPacket move ) { } @Override - public void onRequestCommandCompletions(RequestCommandCompletionsC2SPacket packet) { } + public void onRequestCommandCompletions( RequestCommandCompletionsC2SPacket packet ) { } @Override - public void sendPacket(Packet packet, @Nullable GenericFutureListener> listener) { } + public void sendPacket( Packet packet, @Nullable GenericFutureListener> listener ) { } } - private static class FakeConnection extends ClientConnection { - FakeConnection() { - super(NetworkSide.CLIENTBOUND); + private static class FakeConnection extends ClientConnection + { + FakeConnection() + { + super( NetworkSide.CLIENTBOUND ); } @Override - public void channelActive(ChannelHandlerContext active) { + public void channelActive( ChannelHandlerContext active ) + { } @Override - public void setState(NetworkState state) { + public void setState( NetworkState state ) + { } @Override - public void exceptionCaught(ChannelHandlerContext context, Throwable err) { + public void exceptionCaught( ChannelHandlerContext context, Throwable err ) + { } @Override - protected void channelRead0(ChannelHandlerContext context, Packet packet) { + protected void channelRead0( ChannelHandlerContext context, Packet packet ) + { } @Override - public void send(Packet packet, @Nullable GenericFutureListener> listener) { + public void send( Packet packet, @Nullable GenericFutureListener> listener ) + { } @Override - public void tick() { + public void tick() + { } @Override - public void disconnect(Text message) { + public void disconnect( Text message ) + { } @Override - public void setupEncryption(Cipher cipher, Cipher cipher2) { - super.setupEncryption(cipher, cipher2); + public void setupEncryption( Cipher cipher, Cipher cipher2 ) + { + super.setupEncryption( cipher, cipher2 ); } @Override - public void disableAutoRead() { + public void disableAutoRead() + { } @Override - public void setCompressionThreshold(int size) { + public void setCompressionThreshold( int size ) + { } } } diff --git a/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java b/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java index f7edbbe7d..14c96c638 100644 --- a/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java +++ b/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java @@ -6,15 +6,11 @@ package dan200.computercraft.api.turtle; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.mojang.authlib.GameProfile; import dan200.computercraft.api.lua.ILuaCallback; import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.util.ItemStorage; - import net.minecraft.inventory.Inventory; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.math.BlockPos; @@ -22,12 +18,16 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * The interface passed to turtle by turtles, providing methods that they can call. * * This should not be implemented by your classes. Do not interact with turtles except via this interface and {@link ITurtleUpgrade}. */ -public interface ITurtleAccess { +public interface ITurtleAccess +{ /** * Returns the world in which the turtle resides. * @@ -51,11 +51,11 @@ public interface ITurtleAccess { * using {@link #playAnimation(TurtleAnimation)}. * * @param world The new world to move it to - * @param pos The new position to move it to. + * @param pos The new position to move it to. * @return Whether the movement was successful. It may fail if the block was not loaded or the block placement was cancelled. * @throws UnsupportedOperationException When attempting to teleport on the client side. */ - boolean teleportTo(@Nonnull World world, @Nonnull BlockPos pos); + boolean teleportTo( @Nonnull World world, @Nonnull BlockPos pos ); /** * Returns a vector containing the floating point co-ordinates at which the turtle is rendered. This will shift when the turtle is moving. @@ -65,7 +65,7 @@ public interface ITurtleAccess { * @see #getVisualYaw(float) */ @Nonnull - Vec3d getVisualPosition(float f); + Vec3d getVisualPosition( float f ); /** * Returns the yaw the turtle is facing when it is rendered. @@ -74,7 +74,7 @@ public interface ITurtleAccess { * @return The yaw the turtle is facing. * @see #getVisualPosition(float) */ - float getVisualYaw(float f); + float getVisualYaw( float f ); /** * Returns the world direction the turtle is currently facing. @@ -92,7 +92,7 @@ public interface ITurtleAccess { * @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west). * @see #getDirection() */ - void setDirection(@Nonnull Direction dir); + void setDirection( @Nonnull Direction dir ); /** * Get the currently selected slot in the turtle's inventory. @@ -111,7 +111,7 @@ public interface ITurtleAccess { * @see #getInventory() * @see #getSelectedSlot() */ - void setSelectedSlot(int slot); + void setSelectedSlot( int slot ); /** * Get the colour of this turtle as a RGB number. @@ -125,10 +125,10 @@ public interface ITurtleAccess { * Set the colour of the turtle to a RGB number. * * @param colour The colour this turtle should be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or -1 to - * reset to the default colour. + * reset to the default colour. * @see #getColour() */ - void setColour(int colour); + void setColour( int colour ); /** * Get the player who owns this turtle, namely whoever placed it. @@ -165,7 +165,7 @@ public interface ITurtleAccess { * @see #addFuel(int) * @see #consumeFuel(int) */ - void setFuelLevel(int fuel); + void setFuelLevel( int fuel ); /** * Get the maximum amount of fuel a turtle can hold. @@ -179,10 +179,10 @@ public interface ITurtleAccess { * * @param fuel The amount of fuel to consume. * @return Whether the turtle was able to consume the amount of fuel specified. Will return false if you supply a number greater than the current fuel - * level of the turtle. No fuel will be consumed if {@code false} is returned. + * level of the turtle. No fuel will be consumed if {@code false} is returned. * @throws UnsupportedOperationException When attempting to consume fuel on the client side. */ - boolean consumeFuel(int fuel); + boolean consumeFuel( int fuel ); /** * Increase the turtle's fuel level by the given amount. @@ -190,7 +190,7 @@ public interface ITurtleAccess { * @param fuel The amount to refuel with. * @throws UnsupportedOperationException When attempting to refuel on the client side. */ - void addFuel(int fuel); + void addFuel( int fuel ); /** * Adds a custom command to the turtles command queue. Unlike peripheral methods, these custom commands will be executed on the main thread, so are @@ -205,7 +205,7 @@ public interface ITurtleAccess { * @see MethodResult#pullEvent(String, ILuaCallback) */ @Nonnull - MethodResult executeCommand(@Nonnull ITurtleCommand command); + MethodResult executeCommand( @Nonnull ITurtleCommand command ); /** * Start playing a specific animation. This will prevent other turtle commands from executing until it is finished. @@ -214,7 +214,7 @@ public interface ITurtleAccess { * @throws UnsupportedOperationException When attempting to execute play an animation on the client side. * @see TurtleAnimation */ - void playAnimation(@Nonnull TurtleAnimation animation); + void playAnimation( @Nonnull TurtleAnimation animation ); /** * Returns the turtle on the specified side of the turtle, if there is one. @@ -224,16 +224,16 @@ public interface ITurtleAccess { * @see #setUpgrade(TurtleSide, ITurtleUpgrade) */ @Nullable - ITurtleUpgrade getUpgrade(@Nonnull TurtleSide side); + ITurtleUpgrade getUpgrade( @Nonnull TurtleSide side ); /** * Set the upgrade for a given side, resetting peripherals and clearing upgrade specific data. * - * @param side The side to set the upgrade on. + * @param side The side to set the upgrade on. * @param upgrade The upgrade to set, may be {@code null} to clear. * @see #getUpgrade(TurtleSide) */ - void setUpgrade(@Nonnull TurtleSide side, @Nullable ITurtleUpgrade upgrade); + void setUpgrade( @Nonnull TurtleSide side, @Nullable ITurtleUpgrade upgrade ); /** * Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one. @@ -242,7 +242,7 @@ public interface ITurtleAccess { * @return The peripheral created by the upgrade on the specified side of the turtle, {@code null} if none exists. */ @Nullable - IPeripheral getPeripheral(@Nonnull TurtleSide side); + IPeripheral getPeripheral( @Nonnull TurtleSide side ); /** * Get an upgrade-specific NBT compound, which can be used to store arbitrary data. @@ -255,7 +255,7 @@ public interface ITurtleAccess { * @see #updateUpgradeNBTData(TurtleSide) */ @Nonnull - CompoundTag getUpgradeNBTData(@Nullable TurtleSide side); + CompoundTag getUpgradeNBTData( @Nullable TurtleSide side ); /** * Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the client and persisted. @@ -263,10 +263,11 @@ public interface ITurtleAccess { * @param side The side to mark dirty. * @see #updateUpgradeNBTData(TurtleSide) */ - void updateUpgradeNBTData(@Nonnull TurtleSide side); + void updateUpgradeNBTData( @Nonnull TurtleSide side ); - default ItemStorage getItemHandler() { - return ItemStorage.wrap(this.getInventory()); + default ItemStorage getItemHandler() + { + return ItemStorage.wrap( this.getInventory() ); } /** diff --git a/src/main/java/dan200/computercraft/api/turtle/ITurtleCommand.java b/src/main/java/dan200/computercraft/api/turtle/ITurtleCommand.java index 12babcf33..134bb346d 100644 --- a/src/main/java/dan200/computercraft/api/turtle/ITurtleCommand.java +++ b/src/main/java/dan200/computercraft/api/turtle/ITurtleCommand.java @@ -14,7 +14,8 @@ import javax.annotation.Nonnull; * @see ITurtleAccess#executeCommand(ITurtleCommand) */ @FunctionalInterface -public interface ITurtleCommand { +public interface ITurtleCommand +{ /** * Will be called by the turtle on the main thread when it is time to execute the custom command. * @@ -29,5 +30,5 @@ public interface ITurtleCommand { * @see TurtleCommandResult */ @Nonnull - TurtleCommandResult execute(@Nonnull ITurtleAccess turtle); + TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ); } diff --git a/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java b/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java index 0ba94365e..bc9d9e018 100644 --- a/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java +++ b/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java @@ -6,18 +6,16 @@ package dan200.computercraft.api.turtle; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.IUpgradeBase; import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.peripheral.IPeripheral; - -import net.minecraft.util.math.Direction; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.util.math.Direction; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * The primary interface for defining an update for Turtles. A turtle update can either be a new tool, or a new peripheral. @@ -42,28 +40,30 @@ public interface ITurtleUpgrade extends IUpgradeBase * TurtleSide)}. It will be attached, detached and have methods called in the same manner as a Computer peripheral. * * @param turtle Access to the turtle that the peripheral is being created for. - * @param side Which side of the turtle (left or right) that the upgrade resides on. + * @param side Which side of the turtle (left or right) that the upgrade resides on. * @return The newly created peripheral. You may return {@code null} if this upgrade is a Tool and this method is not expected to be called. */ @Nullable - default IPeripheral createPeripheral(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { + default IPeripheral createPeripheral( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side ) + { return null; } /** * Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called by the turtle, and the tool is required to do some work. * - * @param turtle Access to the turtle that the tool resides on. - * @param side Which side of the turtle (left or right) the tool resides on. - * @param verb Which action (dig or attack) the turtle is being called on to perform. + * @param turtle Access to the turtle that the tool resides on. + * @param side Which side of the turtle (left or right) the tool resides on. + * @param verb Which action (dig or attack) the turtle is being called on to perform. * @param direction Which world direction the action should be performed in, relative to the turtles position. This will either be up, down, or the - * direction the turtle is facing, depending on whether dig, digUp or digDown was called. + * direction the turtle is facing, depending on whether dig, digUp or digDown was called. * @return Whether the turtle was able to perform the action, and hence whether the {@code turtle.dig()} or {@code turtle.attack()} lua method should - * return true. If true is returned, the tool will perform a swinging animation. You may return {@code null} if this turtle is a Peripheral and - * this method is not expected to be called. + * return true. If true is returned, the tool will perform a swinging animation. You may return {@code null} if this turtle is a Peripheral and + * this method is not expected to be called. */ @Nonnull - default TurtleCommandResult useTool(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction) { + default TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction ) + { return TurtleCommandResult.failure(); } @@ -71,19 +71,20 @@ public interface ITurtleUpgrade extends IUpgradeBase * Called to obtain the model to be used when rendering a turtle peripheral. * * @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models! - * @param side Which side of the turtle (left or right) the upgrade resides on. + * @param side Which side of the turtle (left or right) the upgrade resides on. * @return The model that you wish to be used to render your upgrade. */ @Nonnull - @Environment (EnvType.CLIENT) - TransformedModel getModel(@Nullable ITurtleAccess turtle, @Nonnull TurtleSide side); + @Environment( EnvType.CLIENT ) + TransformedModel getModel( @Nullable ITurtleAccess turtle, @Nonnull TurtleSide side ); /** * Called once per tick for each turtle which has the upgrade equipped. * * @param turtle Access to the turtle that the upgrade resides on. - * @param side Which side of the turtle (left or right) the upgrade resides on. + * @param side Which side of the turtle (left or right) the upgrade resides on. */ - default void update(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { + default void update( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side ) + { } } diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleAnimation.java b/src/main/java/dan200/computercraft/api/turtle/TurtleAnimation.java index 4b7efa9de..f4468b5c9 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleAnimation.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleAnimation.java @@ -13,7 +13,8 @@ package dan200.computercraft.api.turtle; * * @see ITurtleAccess#playAnimation(TurtleAnimation) */ -public enum TurtleAnimation { +public enum TurtleAnimation +{ /** * An animation which does nothing. This takes no time to complete. * diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java b/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java index 6d0d569ea..70974fc24 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java @@ -15,14 +15,16 @@ import javax.annotation.Nullable; * @see ITurtleCommand#execute(ITurtleAccess) * @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction) */ -public final class TurtleCommandResult { - private static final TurtleCommandResult EMPTY_SUCCESS = new TurtleCommandResult(true, null, null); - private static final TurtleCommandResult EMPTY_FAILURE = new TurtleCommandResult(false, null, null); +public final class TurtleCommandResult +{ + private static final TurtleCommandResult EMPTY_SUCCESS = new TurtleCommandResult( true, null, null ); + private static final TurtleCommandResult EMPTY_FAILURE = new TurtleCommandResult( false, null, null ); private final boolean success; private final String errorMessage; private final Object[] results; - private TurtleCommandResult(boolean success, String errorMessage, Object[] results) { + private TurtleCommandResult( boolean success, String errorMessage, Object[] results ) + { this.success = success; this.errorMessage = errorMessage; this.results = results; @@ -34,7 +36,8 @@ public final class TurtleCommandResult { * @return A successful command result with no values. */ @Nonnull - public static TurtleCommandResult success() { + public static TurtleCommandResult success() + { return EMPTY_SUCCESS; } @@ -45,11 +48,13 @@ public final class TurtleCommandResult { * @return A successful command result with the given values. */ @Nonnull - public static TurtleCommandResult success(@Nullable Object[] results) { - if (results == null || results.length == 0) { + public static TurtleCommandResult success( @Nullable Object[] results ) + { + if( results == null || results.length == 0 ) + { return EMPTY_SUCCESS; } - return new TurtleCommandResult(true, null, results); + return new TurtleCommandResult( true, null, results ); } /** @@ -58,7 +63,8 @@ public final class TurtleCommandResult { * @return A failed command result with no message. */ @Nonnull - public static TurtleCommandResult failure() { + public static TurtleCommandResult failure() + { return EMPTY_FAILURE; } @@ -69,11 +75,13 @@ public final class TurtleCommandResult { * @return A failed command result with a message. */ @Nonnull - public static TurtleCommandResult failure(@Nullable String errorMessage) { - if (errorMessage == null) { + public static TurtleCommandResult failure( @Nullable String errorMessage ) + { + if( errorMessage == null ) + { return EMPTY_FAILURE; } - return new TurtleCommandResult(false, errorMessage, null); + return new TurtleCommandResult( false, errorMessage, null ); } /** @@ -81,7 +89,8 @@ public final class TurtleCommandResult { * * @return If the command was successful. */ - public boolean isSuccess() { + public boolean isSuccess() + { return this.success; } @@ -91,7 +100,8 @@ public final class TurtleCommandResult { * @return The command's error message, or {@code null} if it was a success. */ @Nullable - public String getErrorMessage() { + public String getErrorMessage() + { return this.errorMessage; } @@ -101,7 +111,8 @@ public final class TurtleCommandResult { * @return The command's result, or {@code null} if it was a failure. */ @Nullable - public Object[] getResults() { + public Object[] getResults() + { return this.results; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleSide.java b/src/main/java/dan200/computercraft/api/turtle/TurtleSide.java index be448090a..86edade62 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleSide.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleSide.java @@ -9,7 +9,8 @@ package dan200.computercraft.api.turtle; /** * An enum representing the two sides of the turtle that a turtle turtle might reside. */ -public enum TurtleSide { +public enum TurtleSide +{ /** * The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle). */ diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeType.java b/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeType.java index 6ac4537e0..a6c6fede4 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeType.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeType.java @@ -11,7 +11,8 @@ package dan200.computercraft.api.turtle; * * @see ITurtleUpgrade#getType() */ -public enum TurtleUpgradeType { +public enum TurtleUpgradeType +{ /** * A tool is rendered as an item on the side of the turtle, and responds to the {@code turtle.dig()} and {@code turtle.attack()} methods (Such as * pickaxe or sword on Mining and Melee turtles). @@ -30,11 +31,13 @@ public enum TurtleUpgradeType { */ BOTH; - public boolean isTool() { + public boolean isTool() + { return this == TOOL || this == BOTH; } - public boolean isPeripheral() { + public boolean isPeripheral() + { return this == PERIPHERAL || this == BOTH; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleVerb.java b/src/main/java/dan200/computercraft/api/turtle/TurtleVerb.java index c057bdc1d..d4622b1a0 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleVerb.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleVerb.java @@ -12,7 +12,8 @@ package dan200.computercraft.api.turtle; * @see ITurtleUpgrade#getType() * @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction) */ -public enum TurtleVerb { +public enum TurtleVerb +{ /** * The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}. */ diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleAction.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleAction.java index d3397af67..ca5ccecf6 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleAction.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleAction.java @@ -11,7 +11,8 @@ package dan200.computercraft.api.turtle.event; * * @see TurtleActionEvent */ -public enum TurtleAction { +public enum TurtleAction +{ /** * A turtle moves to a new position. * diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleActionEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleActionEvent.java index e336b7606..ac1e93952 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleActionEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleActionEvent.java @@ -6,30 +6,32 @@ package dan200.computercraft.api.turtle.event; -import java.util.Objects; +import dan200.computercraft.api.turtle.ITurtleAccess; +import dan200.computercraft.api.turtle.TurtleCommandResult; import javax.annotation.Nonnull; import javax.annotation.Nullable; - -import dan200.computercraft.api.turtle.ITurtleAccess; -import dan200.computercraft.api.turtle.TurtleCommandResult; +import java.util.Objects; /** * An event fired when a turtle is performing a known action. */ -public class TurtleActionEvent extends TurtleEvent { +public class TurtleActionEvent extends TurtleEvent +{ private final TurtleAction action; private String failureMessage; private boolean cancelled = false; - public TurtleActionEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action) { - super(turtle); + public TurtleActionEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action ) + { + super( turtle ); - Objects.requireNonNull(action, "action cannot be null"); + Objects.requireNonNull( action, "action cannot be null" ); this.action = action; } - public TurtleAction getAction() { + public TurtleAction getAction() + { return this.action; } @@ -43,8 +45,9 @@ public class TurtleActionEvent extends TurtleEvent { * @deprecated Use {@link #setCanceled(boolean, String)} instead. */ @Deprecated - public void setCanceled(boolean cancel) { - this.setCanceled(cancel, null); + public void setCanceled( boolean cancel ) + { + this.setCanceled( cancel, null ); } /** @@ -52,11 +55,12 @@ public class TurtleActionEvent extends TurtleEvent { * * If {@code cancel} is {@code true}, this action will not be carried out. * - * @param cancel The new canceled value. + * @param cancel The new canceled value. * @param failureMessage The message to return to the user explaining the failure. * @see TurtleCommandResult#failure(String) */ - public void setCanceled(boolean cancel, @Nullable String failureMessage) { + public void setCanceled( boolean cancel, @Nullable String failureMessage ) + { this.cancelled = true; this.failureMessage = cancel ? failureMessage : null; } @@ -69,11 +73,13 @@ public class TurtleActionEvent extends TurtleEvent { * @see #setCanceled(boolean, String) */ @Nullable - public String getFailureMessage() { + public String getFailureMessage() + { return this.failureMessage; } - public boolean isCancelled() { + public boolean isCancelled() + { return this.cancelled; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleAttackEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleAttackEvent.java index dc5ab0cc7..4a8440d39 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleAttackEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleAttackEvent.java @@ -6,33 +6,33 @@ package dan200.computercraft.api.turtle.event; -import java.util.Objects; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; - import net.minecraft.entity.Entity; +import javax.annotation.Nonnull; +import java.util.Objects; + /** * Fired when a turtle attempts to attack an entity. * * @see TurtleAction#ATTACK */ -public class TurtleAttackEvent extends TurtlePlayerEvent { +public class TurtleAttackEvent extends TurtlePlayerEvent +{ private final Entity target; private final ITurtleUpgrade upgrade; private final TurtleSide side; - public TurtleAttackEvent(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull Entity target, @Nonnull ITurtleUpgrade upgrade, - @Nonnull TurtleSide side) { - super(turtle, TurtleAction.ATTACK, player); - Objects.requireNonNull(target, "target cannot be null"); - Objects.requireNonNull(upgrade, "upgrade cannot be null"); - Objects.requireNonNull(side, "side cannot be null"); + public TurtleAttackEvent( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull Entity target, @Nonnull ITurtleUpgrade upgrade, + @Nonnull TurtleSide side ) + { + super( turtle, TurtleAction.ATTACK, player ); + Objects.requireNonNull( target, "target cannot be null" ); + Objects.requireNonNull( upgrade, "upgrade cannot be null" ); + Objects.requireNonNull( side, "side cannot be null" ); this.target = target; this.upgrade = upgrade; this.side = side; @@ -44,7 +44,8 @@ public class TurtleAttackEvent extends TurtlePlayerEvent { * @return The entity being attacked. */ @Nonnull - public Entity getTarget() { + public Entity getTarget() + { return this.target; } @@ -54,7 +55,8 @@ public class TurtleAttackEvent extends TurtlePlayerEvent { * @return The upgrade responsible for attacking. */ @Nonnull - public ITurtleUpgrade getUpgrade() { + public ITurtleUpgrade getUpgrade() + { return this.upgrade; } @@ -64,7 +66,8 @@ public class TurtleAttackEvent extends TurtlePlayerEvent { * @return The upgrade's side. */ @Nonnull - public TurtleSide getSide() { + public TurtleSide getSide() + { return this.side; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleBlockEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleBlockEvent.java index 59987558e..1b8ded608 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleBlockEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleBlockEvent.java @@ -6,22 +6,20 @@ package dan200.computercraft.api.turtle.event; -import java.util.Map; -import java.util.Objects; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; - import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import java.util.Map; +import java.util.Objects; + /** * A general event for when a turtle interacts with a block or region. * @@ -31,16 +29,18 @@ import net.minecraft.world.World; * * Be aware that some events (such as {@link TurtleInventoryEvent}) do not necessarily interact with a block, simply objects within that block space. */ -public abstract class TurtleBlockEvent extends TurtlePlayerEvent { +public abstract class TurtleBlockEvent extends TurtlePlayerEvent +{ private final World world; private final BlockPos pos; - protected TurtleBlockEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, - @Nonnull BlockPos pos) { - super(turtle, action, player); + protected TurtleBlockEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, + @Nonnull BlockPos pos ) + { + super( turtle, action, player ); - Objects.requireNonNull(world, "world cannot be null"); - Objects.requireNonNull(pos, "pos cannot be null"); + Objects.requireNonNull( world, "world cannot be null" ); + Objects.requireNonNull( pos, "pos cannot be null" ); this.world = world; this.pos = pos; } @@ -50,7 +50,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @return The world the turtle is interacting in. */ - public World getWorld() { + public World getWorld() + { return this.world; } @@ -59,7 +60,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @return The position the turtle is interacting with. */ - public BlockPos getPos() { + public BlockPos getPos() + { return this.pos; } @@ -68,18 +70,20 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @see TurtleAction#DIG */ - public static class Dig extends TurtleBlockEvent { + public static class Dig extends TurtleBlockEvent + { private final BlockState block; private final ITurtleUpgrade upgrade; private final TurtleSide side; - public Dig(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState block, - @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side) { - super(turtle, TurtleAction.DIG, player, world, pos); + public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState block, + @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side ) + { + super( turtle, TurtleAction.DIG, player, world, pos ); - Objects.requireNonNull(block, "block cannot be null"); - Objects.requireNonNull(upgrade, "upgrade cannot be null"); - Objects.requireNonNull(side, "side cannot be null"); + Objects.requireNonNull( block, "block cannot be null" ); + Objects.requireNonNull( upgrade, "upgrade cannot be null" ); + Objects.requireNonNull( side, "side cannot be null" ); this.block = block; this.upgrade = upgrade; this.side = side; @@ -91,7 +95,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * @return The block which is going to be broken. */ @Nonnull - public BlockState getBlock() { + public BlockState getBlock() + { return this.block; } @@ -101,7 +106,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * @return The upgrade doing the digging. */ @Nonnull - public ITurtleUpgrade getUpgrade() { + public ITurtleUpgrade getUpgrade() + { return this.upgrade; } @@ -111,7 +117,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * @return The upgrade's side. */ @Nonnull - public TurtleSide getSide() { + public TurtleSide getSide() + { return this.side; } } @@ -121,9 +128,11 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @see TurtleAction#MOVE */ - public static class Move extends TurtleBlockEvent { - public Move(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos) { - super(turtle, TurtleAction.MOVE, player, world, pos); + public static class Move extends TurtleBlockEvent + { + public Move( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos ) + { + super( turtle, TurtleAction.MOVE, player, world, pos ); } } @@ -132,13 +141,15 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @see TurtleAction#PLACE */ - public static class Place extends TurtleBlockEvent { + public static class Place extends TurtleBlockEvent + { private final ItemStack stack; - public Place(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack) { - super(turtle, TurtleAction.PLACE, player, world, pos); + public Place( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack ) + { + super( turtle, TurtleAction.PLACE, player, world, pos ); - Objects.requireNonNull(stack, "stack cannot be null"); + Objects.requireNonNull( stack, "stack cannot be null" ); this.stack = stack; } @@ -148,7 +159,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * @return The item stack to be placed. */ @Nonnull - public ItemStack getStack() { + public ItemStack getStack() + { return this.stack; } } @@ -160,16 +172,18 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @see TurtleAction#INSPECT */ - public static class Inspect extends TurtleBlockEvent { + public static class Inspect extends TurtleBlockEvent + { private final BlockState state; private final Map data; - public Inspect(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, - @Nonnull Map data) { - super(turtle, TurtleAction.INSPECT, player, world, pos); + public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, + @Nonnull Map data ) + { + super( turtle, TurtleAction.INSPECT, player, world, pos ); - Objects.requireNonNull(state, "state cannot be null"); - Objects.requireNonNull(data, "data cannot be null"); + Objects.requireNonNull( state, "state cannot be null" ); + Objects.requireNonNull( data, "data cannot be null" ); this.data = data; this.state = state; } @@ -180,7 +194,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * @return The inspected block state. */ @Nonnull - public BlockState getState() { + public BlockState getState() + { return this.state; } @@ -190,7 +205,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * @return This block's inspection data. */ @Nonnull - public Map getData() { + public Map getData() + { return this.data; } @@ -199,9 +215,10 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent { * * @param newData The data to add. Note all values should be convertible to Lua (see {@link MethodResult#of(Object)}). */ - public void addData(@Nonnull Map newData) { - Objects.requireNonNull(newData, "newData cannot be null"); - this.data.putAll(newData); + public void addData( @Nonnull Map newData ) + { + Objects.requireNonNull( newData, "newData cannot be null" ); + this.data.putAll( newData ); } } } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleEvent.java index ee3a63318..7d11a1432 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleEvent.java @@ -6,13 +6,12 @@ package dan200.computercraft.api.turtle.event; -import java.util.Objects; - -import javax.annotation.Nonnull; - import com.google.common.eventbus.EventBus; import dan200.computercraft.api.turtle.ITurtleAccess; +import javax.annotation.Nonnull; +import java.util.Objects; + /** * A base class for all events concerning a turtle. This will only ever constructed and fired on the server side, so sever specific methods on {@link * ITurtleAccess} are safe to use. @@ -21,18 +20,21 @@ import dan200.computercraft.api.turtle.ITurtleAccess; * * @see TurtleActionEvent */ -public abstract class TurtleEvent { +public abstract class TurtleEvent +{ public static final EventBus EVENT_BUS = new EventBus(); private final ITurtleAccess turtle; - protected TurtleEvent(@Nonnull ITurtleAccess turtle) { - Objects.requireNonNull(turtle, "turtle cannot be null"); + protected TurtleEvent( @Nonnull ITurtleAccess turtle ) + { + Objects.requireNonNull( turtle, "turtle cannot be null" ); this.turtle = turtle; } - public static boolean post(TurtleActionEvent event) { - EVENT_BUS.post(event); + public static boolean post( TurtleActionEvent event ) + { + EVENT_BUS.post( event ); return event.isCancelled(); } @@ -42,7 +44,8 @@ public abstract class TurtleEvent { * @return The access for this turtle. */ @Nonnull - public ITurtleAccess getTurtle() { + public ITurtleAccess getTurtle() + { return this.turtle; } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleInspectItemEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleInspectItemEvent.java index 183431e5e..3da00d484 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleInspectItemEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleInspectItemEvent.java @@ -6,16 +6,14 @@ package dan200.computercraft.api.turtle.event; -import java.util.Map; -import java.util.Objects; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.turtle.ITurtleAccess; - import net.minecraft.item.ItemStack; +import javax.annotation.Nonnull; +import java.util.Map; +import java.util.Objects; + /** * Fired when a turtle gathers data on an item in its inventory. * @@ -24,21 +22,24 @@ import net.minecraft.item.ItemStack; * * @see TurtleAction#INSPECT_ITEM */ -public class TurtleInspectItemEvent extends TurtleActionEvent { +public class TurtleInspectItemEvent extends TurtleActionEvent +{ private final ItemStack stack; private final Map data; private final boolean mainThread; @Deprecated - public TurtleInspectItemEvent(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map data) { - this(turtle, stack, data, false); + public TurtleInspectItemEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map data ) + { + this( turtle, stack, data, false ); } - public TurtleInspectItemEvent(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map data, boolean mainThread) { - super(turtle, TurtleAction.INSPECT_ITEM); + public TurtleInspectItemEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map data, boolean mainThread ) + { + super( turtle, TurtleAction.INSPECT_ITEM ); - Objects.requireNonNull(stack, "stack cannot be null"); - Objects.requireNonNull(data, "data cannot be null"); + Objects.requireNonNull( stack, "stack cannot be null" ); + Objects.requireNonNull( data, "data cannot be null" ); this.stack = stack; this.data = data; this.mainThread = mainThread; @@ -50,7 +51,8 @@ public class TurtleInspectItemEvent extends TurtleActionEvent { * @return The item stack which is being inspected. This should not be modified. */ @Nonnull - public ItemStack getStack() { + public ItemStack getStack() + { return this.stack; } @@ -60,7 +62,8 @@ public class TurtleInspectItemEvent extends TurtleActionEvent { * @return This items's inspection data. */ @Nonnull - public Map getData() { + public Map getData() + { return this.data; } @@ -69,7 +72,8 @@ public class TurtleInspectItemEvent extends TurtleActionEvent { * * @return If this is run on the main thread. */ - public boolean onMainThread() { + public boolean onMainThread() + { return this.mainThread; } @@ -78,8 +82,9 @@ public class TurtleInspectItemEvent extends TurtleActionEvent { * * @param newData The data to add. Note all values should be convertible to Lua (see {@link MethodResult#of(Object)}). */ - public void addData(@Nonnull Map newData) { - Objects.requireNonNull(newData, "newData cannot be null"); - this.data.putAll(newData); + public void addData( @Nonnull Map newData ) + { + Objects.requireNonNull( newData, "newData cannot be null" ); + this.data.putAll( newData ); } } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleInventoryEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleInventoryEvent.java index 5ce7c83dd..61ff87594 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleInventoryEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleInventoryEvent.java @@ -6,28 +6,28 @@ package dan200.computercraft.api.turtle.event; -import java.util.Objects; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.ITurtleAccess; - import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Objects; + /** * Fired when a turtle attempts to interact with an inventory. */ -public abstract class TurtleInventoryEvent extends TurtleBlockEvent { +public abstract class TurtleInventoryEvent extends TurtleBlockEvent +{ private final Inventory handler; - protected TurtleInventoryEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, - @Nonnull BlockPos pos, @Nullable Inventory handler) { - super(turtle, action, player, world, pos); + protected TurtleInventoryEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, + @Nonnull BlockPos pos, @Nullable Inventory handler ) + { + super( turtle, action, player, world, pos ); this.handler = handler; } @@ -37,7 +37,8 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent { * @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world. */ @Nullable - public Inventory getItemHandler() { + public Inventory getItemHandler() + { return this.handler; } @@ -46,9 +47,11 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent { * * @see TurtleAction#SUCK */ - public static class Suck extends TurtleInventoryEvent { - public Suck(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler) { - super(turtle, TurtleAction.SUCK, player, world, pos, handler); + public static class Suck extends TurtleInventoryEvent + { + public Suck( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler ) + { + super( turtle, TurtleAction.SUCK, player, world, pos, handler ); } } @@ -57,14 +60,16 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent { * * @see TurtleAction#DROP */ - public static class Drop extends TurtleInventoryEvent { + public static class Drop extends TurtleInventoryEvent + { private final ItemStack stack; - public Drop(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler, - @Nonnull ItemStack stack) { - super(turtle, TurtleAction.DROP, player, world, pos, handler); + public Drop( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler, + @Nonnull ItemStack stack ) + { + super( turtle, TurtleAction.DROP, player, world, pos, handler ); - Objects.requireNonNull(stack, "stack cannot be null"); + Objects.requireNonNull( stack, "stack cannot be null" ); this.stack = stack; } @@ -74,7 +79,8 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent { * @return The item stack which will be dropped. This should not be modified. */ @Nonnull - public ItemStack getStack() { + public ItemStack getStack() + { return this.stack; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtlePlayerEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtlePlayerEvent.java index a48bf353a..54d79753c 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtlePlayerEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtlePlayerEvent.java @@ -6,25 +6,26 @@ package dan200.computercraft.api.turtle.event; -import java.util.Objects; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.ITurtleAccess; +import javax.annotation.Nonnull; +import java.util.Objects; + /** * An action done by a turtle which is normally done by a player. * * {@link #getPlayer()} may be used to modify the player's attributes or perform permission checks. */ -public abstract class TurtlePlayerEvent extends TurtleActionEvent { +public abstract class TurtlePlayerEvent extends TurtleActionEvent +{ private final FakePlayer player; - protected TurtlePlayerEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player) { - super(turtle, action); + protected TurtlePlayerEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player ) + { + super( turtle, action ); - Objects.requireNonNull(player, "player cannot be null"); + Objects.requireNonNull( player, "player cannot be null" ); this.player = player; } @@ -36,7 +37,8 @@ public abstract class TurtlePlayerEvent extends TurtleActionEvent { * @return A {@link FakePlayer} representing this turtle. */ @Nonnull - public FakePlayer getPlayer() { + public FakePlayer getPlayer() + { return this.player; } } diff --git a/src/main/java/dan200/computercraft/api/turtle/event/TurtleRefuelEvent.java b/src/main/java/dan200/computercraft/api/turtle/event/TurtleRefuelEvent.java index ca0bdc7be..97c7e3a32 100644 --- a/src/main/java/dan200/computercraft/api/turtle/event/TurtleRefuelEvent.java +++ b/src/main/java/dan200/computercraft/api/turtle/event/TurtleRefuelEvent.java @@ -6,14 +6,12 @@ package dan200.computercraft.api.turtle.event; -import java.util.Objects; +import dan200.computercraft.api.turtle.ITurtleAccess; +import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; import javax.annotation.Nullable; - -import dan200.computercraft.api.turtle.ITurtleAccess; - -import net.minecraft.item.ItemStack; +import java.util.Objects; /** * Fired when a turtle attempts to refuel from an item. @@ -21,14 +19,16 @@ import net.minecraft.item.ItemStack; * One may use {@link #setCanceled(boolean, String)} to prevent refueling from this specific item. Additionally, you may use {@link #setHandler(Handler)} to * register a custom fuel provider. */ -public class TurtleRefuelEvent extends TurtleActionEvent { +public class TurtleRefuelEvent extends TurtleActionEvent +{ private final ItemStack stack; private Handler handler; - public TurtleRefuelEvent(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { - super(turtle, TurtleAction.REFUEL); + public TurtleRefuelEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack ) + { + super( turtle, TurtleAction.REFUEL ); - Objects.requireNonNull(turtle, "turtle cannot be null"); + Objects.requireNonNull( turtle, "turtle cannot be null" ); this.stack = stack; } @@ -39,7 +39,8 @@ public class TurtleRefuelEvent extends TurtleActionEvent { * * @return The stack to refuel from. */ - public ItemStack getStack() { + public ItemStack getStack() + { return this.stack; } @@ -50,7 +51,8 @@ public class TurtleRefuelEvent extends TurtleActionEvent { * @see #setHandler(Handler) */ @Nullable - public Handler getHandler() { + public Handler getHandler() + { return this.handler; } @@ -62,7 +64,8 @@ public class TurtleRefuelEvent extends TurtleActionEvent { * @param handler The new refuel handler. * @see #getHandler() */ - public void setHandler(@Nullable Handler handler) { + public void setHandler( @Nullable Handler handler ) + { this.handler = handler; } @@ -70,16 +73,17 @@ public class TurtleRefuelEvent extends TurtleActionEvent { * Handles refuelling a turtle from a specific item. */ @FunctionalInterface - public interface Handler { + public interface Handler + { /** * Refuel a turtle using an item. * * @param turtle The turtle to refuel. - * @param stack The stack to refuel with. - * @param slot The slot the stack resides within. This may be used to modify the inventory afterwards. - * @param limit The maximum number of refuel operations to perform. This will often correspond to the number of items to consume. + * @param stack The stack to refuel with. + * @param slot The slot the stack resides within. This may be used to modify the inventory afterwards. + * @param limit The maximum number of refuel operations to perform. This will often correspond to the number of items to consume. * @return The amount of fuel gained. */ - int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int slot, int limit); + int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int slot, int limit ); } } diff --git a/src/main/java/dan200/computercraft/client/ClientRegistry.java b/src/main/java/dan200/computercraft/client/ClientRegistry.java index ad02b7ae5..b1dd6e568 100644 --- a/src/main/java/dan200/computercraft/client/ClientRegistry.java +++ b/src/main/java/dan200/computercraft/client/ClientRegistry.java @@ -6,9 +6,6 @@ package dan200.computercraft.client; -import java.util.HashSet; -import java.util.function.Consumer; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.IColouredItem; @@ -16,7 +13,8 @@ import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.media.items.ItemTreasureDisk; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.util.Colour; - +import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; +import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.ModelLoader; @@ -27,17 +25,18 @@ import net.minecraft.client.util.ModelIdentifier; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; -import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; +import java.util.HashSet; +import java.util.function.Consumer; /** * Registers textures and models for items. */ -@SuppressWarnings ({ +@SuppressWarnings( { "MethodCallSideOnly", "LocalVariableDeclarationSideOnly" -}) -public final class ClientRegistry { +} ) +public final class ClientRegistry +{ private static final String[] EXTRA_MODELS = new String[] { "turtle_modem_normal_off_left", "turtle_modem_normal_on_left", @@ -56,7 +55,7 @@ public final class ClientRegistry { "turtle_colour", "turtle_elf_overlay", - }; + }; private static final String[] EXTRA_TEXTURES = new String[] { // TODO: Gather these automatically from the model. Sadly the model loader isn't available @@ -65,59 +64,66 @@ public final class ClientRegistry { "block/turtle_elf_overlay", "block/turtle_crafty_face", "block/turtle_speaker_face", - }; + }; private ClientRegistry() {} - public static void onTextureStitchEvent(SpriteAtlasTexture atlasTexture, ClientSpriteRegistryCallback.Registry registry) { - for (String extra : EXTRA_TEXTURES) { - registry.register(new Identifier(ComputerCraft.MOD_ID, extra)); + public static void onTextureStitchEvent( SpriteAtlasTexture atlasTexture, ClientSpriteRegistryCallback.Registry registry ) + { + for( String extra : EXTRA_TEXTURES ) + { + registry.register( new Identifier( ComputerCraft.MOD_ID, extra ) ); } } - @SuppressWarnings ("NewExpressionSideOnly") - public static void onModelBakeEvent(ResourceManager manager, Consumer out) { - for (String model : EXTRA_MODELS) { - out.accept(new ModelIdentifier(new Identifier(ComputerCraft.MOD_ID, model), "inventory")); + @SuppressWarnings( "NewExpressionSideOnly" ) + public static void onModelBakeEvent( ResourceManager manager, Consumer out ) + { + for( String model : EXTRA_MODELS ) + { + out.accept( new ModelIdentifier( new Identifier( ComputerCraft.MOD_ID, model ), "inventory" ) ); } } - public static void onItemColours() { - ColorProviderRegistry.ITEM.register((stack, layer) -> { - return layer == 1 ? ((ItemDisk) stack.getItem()).getColour(stack) : 0xFFFFFF; - }, ComputerCraftRegistry.ModItems.DISK); + public static void onItemColours() + { + ColorProviderRegistry.ITEM.register( ( stack, layer ) -> { + return layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF; + }, ComputerCraftRegistry.ModItems.DISK ); - ColorProviderRegistry.ITEM.register((stack, layer) -> layer == 1 ? ItemTreasureDisk.getColour(stack) : 0xFFFFFF, - ComputerCraftRegistry.ModItems.TREASURE_DISK); + ColorProviderRegistry.ITEM.register( ( stack, layer ) -> layer == 1 ? ItemTreasureDisk.getColour( stack ) : 0xFFFFFF, + ComputerCraftRegistry.ModItems.TREASURE_DISK ); - ColorProviderRegistry.ITEM.register((stack, layer) -> { - switch (layer) { - case 0: - default: - return 0xFFFFFF; - case 1: // Frame colour - return IColouredItem.getColourBasic(stack); - case 2: // Light colour + ColorProviderRegistry.ITEM.register( ( stack, layer ) -> { + switch( layer ) { - int light = ItemPocketComputer.getLightState(stack); - return light == -1 ? Colour.BLACK.getHex() : light; + case 0: + default: + return 0xFFFFFF; + case 1: // Frame colour + return IColouredItem.getColourBasic( stack ); + case 2: // Light colour + { + int light = ItemPocketComputer.getLightState( stack ); + return light == -1 ? Colour.BLACK.getHex() : light; + } } - } - }, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED); + }, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED ); // Setup turtle colours - ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour(stack) : 0xFFFFFF, - ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, - ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED); + ColorProviderRegistry.ITEM.register( ( stack, tintIndex ) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour( stack ) : 0xFFFFFF, + ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, + ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED ); } - private static BakedModel bake(ModelLoader loader, UnbakedModel model, Identifier identifier) { - model.getTextureDependencies(loader::getOrLoadModel, new HashSet<>()); - return model.bake(loader, - spriteIdentifier -> MinecraftClient.getInstance() - .getSpriteAtlas(spriteIdentifier.getAtlasId()) - .apply(spriteIdentifier.getTextureId()), - ModelRotation.X0_Y0, - identifier); + private static BakedModel bake( ModelLoader loader, UnbakedModel model, Identifier identifier ) + { + model.getTextureDependencies( loader::getOrLoadModel, new HashSet<>() ); + return model.bake( loader, + spriteIdentifier -> MinecraftClient.getInstance() + .getSpriteAtlas( spriteIdentifier.getAtlasId() ) + .apply( spriteIdentifier.getTextureId() ), + ModelRotation.X0_Y0, + identifier ); } } diff --git a/src/main/java/dan200/computercraft/client/ClientTableFormatter.java b/src/main/java/dan200/computercraft/client/ClientTableFormatter.java index d3cd9b7bf..a7ccd63d1 100644 --- a/src/main/java/dan200/computercraft/client/ClientTableFormatter.java +++ b/src/main/java/dan200/computercraft/client/ClientTableFormatter.java @@ -6,64 +6,70 @@ package dan200.computercraft.client; -import javax.annotation.Nullable; - import dan200.computercraft.fabric.mixin.ChatHudAccess; import dan200.computercraft.shared.command.text.ChatHelpers; import dan200.computercraft.shared.command.text.TableBuilder; import dan200.computercraft.shared.command.text.TableFormatter; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import org.apache.commons.lang3.StringUtils; - import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.math.MathHelper; +import org.apache.commons.lang3.StringUtils; -@SuppressWarnings ({ +import javax.annotation.Nullable; + +@SuppressWarnings( { "MethodCallSideOnly", "LocalVariableDeclarationSideOnly" -}) -public class ClientTableFormatter implements TableFormatter { +} ) +public class ClientTableFormatter implements TableFormatter +{ public static final ClientTableFormatter INSTANCE = new ClientTableFormatter(); private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap(); @Override @Nullable - public Text getPadding(Text component, int width) { - int extraWidth = width - this.getWidth(component); - if (extraWidth <= 0) { + public Text getPadding( Text component, int width ) + { + int extraWidth = width - this.getWidth( component ); + if( extraWidth <= 0 ) + { return null; } TextRenderer renderer = renderer(); - float spaceWidth = renderer.getWidth(" "); - int spaces = MathHelper.floor(extraWidth / spaceWidth); + float spaceWidth = renderer.getWidth( " " ); + int spaces = MathHelper.floor( extraWidth / spaceWidth ); int extra = extraWidth - (int) (spaces * spaceWidth); - return ChatHelpers.coloured(StringUtils.repeat(' ', spaces) + StringUtils.repeat((char) 712, extra), Formatting.GRAY); + return ChatHelpers.coloured( StringUtils.repeat( ' ', spaces ) + StringUtils.repeat( (char) 712, extra ), Formatting.GRAY ); } - private static TextRenderer renderer() { + private static TextRenderer renderer() + { return MinecraftClient.getInstance().textRenderer; } @Override - public int getColumnPadding() { + public int getColumnPadding() + { return 3; } @Override - public int getWidth(Text component) { - return renderer().getWidth(component); + public int getWidth( Text component ) + { + return renderer().getWidth( component ); } @Override - public void writeLine(int id, Text component) { + public void writeLine( int id, Text component ) + { MinecraftClient mc = MinecraftClient.getInstance(); ChatHud chat = mc.inGameHud.getChatHud(); @@ -71,20 +77,22 @@ public class ClientTableFormatter implements TableFormatter { // int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() ); // List list = RenderComponentsUtil.func_238505_a_( component, maxWidth, mc.fontRenderer ); // if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id ); - ((ChatHudAccess)chat).callAddMessage(component, id); + ((ChatHudAccess) chat).callAddMessage( component, id ); } @Override - public int display(TableBuilder table) { + public int display( TableBuilder table ) + { ChatHud chat = MinecraftClient.getInstance().inGameHud.getChatHud(); - int lastHeight = lastHeights.get(table.getId()); + int lastHeight = lastHeights.get( table.getId() ); - int height = TableFormatter.super.display(table); - lastHeights.put(table.getId(), height); + int height = TableFormatter.super.display( table ); + lastHeights.put( table.getId(), height ); - for (int i = height; i < lastHeight; i++) { - ((ChatHudAccess)chat).callRemoveMessage(i + table.getId()); + for( int i = height; i < lastHeight; i++ ) + { + ((ChatHudAccess) chat).callRemoveMessage( i + table.getId() ); } return height; } diff --git a/src/main/java/dan200/computercraft/client/FrameInfo.java b/src/main/java/dan200/computercraft/client/FrameInfo.java index 9380b6e0b..7afc250e9 100644 --- a/src/main/java/dan200/computercraft/client/FrameInfo.java +++ b/src/main/java/dan200/computercraft/client/FrameInfo.java @@ -8,38 +8,46 @@ package dan200.computercraft.client; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -public final class FrameInfo { +public final class FrameInfo +{ private static int tick; private static long renderFrame; - static { + static + { } - private FrameInfo() { + private FrameInfo() + { } - public static void init() { - ClientTickEvents.START_CLIENT_TICK.register(m -> { + public static void init() + { + ClientTickEvents.START_CLIENT_TICK.register( m -> { tick++; - }); + } ); } - public static boolean getGlobalCursorBlink() { + public static boolean getGlobalCursorBlink() + { return (tick / 8) % 2 == 0; } - public static long getRenderFrame() { + public static long getRenderFrame() + { return renderFrame; } // TODO Call this in a callback - public static void onTick() { + public static void onTick() + { tick++; } // TODO Call this in a callback - public static void onRenderFrame() { + public static void onRenderFrame() + { renderFrame++; } } diff --git a/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java b/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java index 59d855fca..48a8b6aed 100644 --- a/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java +++ b/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java @@ -6,159 +6,175 @@ package dan200.computercraft.client.gui; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.client.FrameInfo; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Palette; -import org.lwjgl.opengl.GL11; - import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.VertexFormat; -import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.render.*; import net.minecraft.client.util.math.AffineTransformation; import net.minecraft.util.Identifier; import net.minecraft.util.math.Matrix4f; +import org.lwjgl.opengl.GL11; -public final class FixedWidthFontRenderer { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public final class FixedWidthFontRenderer +{ public static final int FONT_HEIGHT = 9; public static final int FONT_WIDTH = 6; public static final float WIDTH = 256.0f; public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH; public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH; private static final Matrix4f IDENTITY = AffineTransformation.identity() - .getMatrix(); - private static final Identifier FONT = new Identifier("computercraft", "textures/gui/term_font.png"); + .getMatrix(); + private static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" ); public static final RenderLayer TYPE = Type.MAIN; - private FixedWidthFontRenderer() { + private FixedWidthFontRenderer() + { } - public static void drawString(float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, - @Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize) { + public static void drawString( float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, + @Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize ) + { bindFont(); VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() - .getBufferBuilders() - .getEntityVertexConsumers(); - drawString(IDENTITY, - ((VertexConsumerProvider) renderer).getBuffer(TYPE), - x, - y, - text, - textColour, - backgroundColour, - palette, - greyscale, - leftMarginSize, - rightMarginSize); + .getBufferBuilders() + .getEntityVertexConsumers(); + drawString( IDENTITY, + ((VertexConsumerProvider) renderer).getBuffer( TYPE ), + x, + y, + text, + textColour, + backgroundColour, + palette, + greyscale, + leftMarginSize, + rightMarginSize ); renderer.draw(); } - private static void bindFont() { + private static void bindFont() + { MinecraftClient.getInstance() - .getTextureManager() - .bindTexture(FONT); - RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP); + .getTextureManager() + .bindTexture( FONT ); + RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP ); } - public static void drawString(@Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text, - @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, - float leftMarginSize, float rightMarginSize) { - if (backgroundColour != null) { - drawBackground(transform, renderer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT); + public static void drawString( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text, + @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, + float leftMarginSize, float rightMarginSize ) + { + if( backgroundColour != null ) + { + drawBackground( transform, renderer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT ); } - for (int i = 0; i < text.length(); i++) { - double[] colour = palette.getColour(getColour(textColour.charAt(i), Colour.BLACK)); + for( int i = 0; i < text.length(); i++ ) + { + double[] colour = palette.getColour( getColour( textColour.charAt( i ), Colour.BLACK ) ); float r, g, b; - if (greyscale) { - r = g = b = toGreyscale(colour); - } else { + if( greyscale ) + { + r = g = b = toGreyscale( colour ); + } + else + { r = (float) colour[0]; g = (float) colour[1]; b = (float) colour[2]; } // Draw char - int index = text.charAt(i); - if (index > 255) { + int index = text.charAt( i ); + if( index > 255 ) + { index = '?'; } - drawChar(transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b); + drawChar( transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b ); } } - private static void drawBackground(@Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, - @Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, float leftMarginSize, - float rightMarginSize, float height) { - if (leftMarginSize > 0) { - drawQuad(transform, renderer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt(0)); + private static void drawBackground( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, + @Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, float leftMarginSize, + float rightMarginSize, float height ) + { + if( leftMarginSize > 0 ) + { + drawQuad( transform, renderer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt( 0 ) ); } - if (rightMarginSize > 0) { - drawQuad(transform, - renderer, - x + backgroundColour.length() * FONT_WIDTH, - y, - rightMarginSize, - height, - palette, - greyscale, - backgroundColour.charAt(backgroundColour.length() - 1)); + if( rightMarginSize > 0 ) + { + drawQuad( transform, + renderer, + x + backgroundColour.length() * FONT_WIDTH, + y, + rightMarginSize, + height, + palette, + greyscale, + backgroundColour.charAt( backgroundColour.length() - 1 ) ); } // Batch together runs of identical background cells. int blockStart = 0; char blockColour = '\0'; - for (int i = 0; i < backgroundColour.length(); i++) { - char colourIndex = backgroundColour.charAt(i); - if (colourIndex == blockColour) { + for( int i = 0; i < backgroundColour.length(); i++ ) + { + char colourIndex = backgroundColour.charAt( i ); + if( colourIndex == blockColour ) + { continue; } - if (blockColour != '\0') { - drawQuad(transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour); + if( blockColour != '\0' ) + { + drawQuad( transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour ); } blockColour = colourIndex; blockStart = i; } - if (blockColour != '\0') { - drawQuad(transform, - renderer, - x + blockStart * FONT_WIDTH, - y, - FONT_WIDTH * (backgroundColour.length() - blockStart), - height, - palette, - greyscale, - blockColour); + if( blockColour != '\0' ) + { + drawQuad( transform, + renderer, + x + blockStart * FONT_WIDTH, + y, + FONT_WIDTH * (backgroundColour.length() - blockStart), + height, + palette, + greyscale, + blockColour ); } } - public static int getColour(char c, Colour def) { - return 15 - Terminal.getColour(c, def); + public static int getColour( char c, Colour def ) + { + return 15 - Terminal.getColour( c, def ); } - public static float toGreyscale(double[] rgb) { + public static float toGreyscale( double[] rgb ) + { return (float) ((rgb[0] + rgb[1] + rgb[2]) / 3); } - private static void drawChar(Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b) { + private static void drawChar( Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b ) + { // Short circuit to avoid the common case - the texture should be blank here after all. - if (index == '\0' || index == ' ') { + if( index == '\0' || index == ' ' ) + { return; } @@ -168,217 +184,238 @@ public final class FixedWidthFontRenderer { int xStart = 1 + column * (FONT_WIDTH + 2); int yStart = 1 + row * (FONT_HEIGHT + 2); - buffer.vertex(transform, x, y, 0f) - .color(r, g, b, 1.0f) - .texture(xStart / WIDTH, yStart / WIDTH) - .next(); - buffer.vertex(transform, x, y + FONT_HEIGHT, 0f) - .color(r, g, b, 1.0f) - .texture(xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH) - .next(); - buffer.vertex(transform, x + FONT_WIDTH, y, 0f) - .color(r, g, b, 1.0f) - .texture((xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH) - .next(); - buffer.vertex(transform, x + FONT_WIDTH, y, 0f) - .color(r, g, b, 1.0f) - .texture((xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH) - .next(); - buffer.vertex(transform, x, y + FONT_HEIGHT, 0f) - .color(r, g, b, 1.0f) - .texture(xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH) - .next(); - buffer.vertex(transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f) - .color(r, g, b, 1.0f) - .texture((xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH) - .next(); + buffer.vertex( transform, x, y, 0f ) + .color( r, g, b, 1.0f ) + .texture( xStart / WIDTH, yStart / WIDTH ) + .next(); + buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ) + .color( r, g, b, 1.0f ) + .texture( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ) + .next(); + buffer.vertex( transform, x + FONT_WIDTH, y, 0f ) + .color( r, g, b, 1.0f ) + .texture( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ) + .next(); + buffer.vertex( transform, x + FONT_WIDTH, y, 0f ) + .color( r, g, b, 1.0f ) + .texture( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ) + .next(); + buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ) + .color( r, g, b, 1.0f ) + .texture( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ) + .next(); + buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ) + .color( r, g, b, 1.0f ) + .texture( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ) + .next(); } - private static void drawQuad(Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette, - boolean greyscale, char colourIndex) { - double[] colour = palette.getColour(getColour(colourIndex, Colour.BLACK)); + private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette, + boolean greyscale, char colourIndex ) + { + double[] colour = palette.getColour( getColour( colourIndex, Colour.BLACK ) ); float r, g, b; - if (greyscale) { - r = g = b = toGreyscale(colour); - } else { + if( greyscale ) + { + r = g = b = toGreyscale( colour ); + } + else + { r = (float) colour[0]; g = (float) colour[1]; b = (float) colour[2]; } - drawQuad(transform, buffer, x, y, width, height, r, g, b); + drawQuad( transform, buffer, x, y, width, height, r, g, b ); } - private static void drawQuad(Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b) { - buffer.vertex(transform, x, y, 0) - .color(r, g, b, 1.0f) - .texture(BACKGROUND_START, BACKGROUND_START) - .next(); - buffer.vertex(transform, x, y + height, 0) - .color(r, g, b, 1.0f) - .texture(BACKGROUND_START, BACKGROUND_END) - .next(); - buffer.vertex(transform, x + width, y, 0) - .color(r, g, b, 1.0f) - .texture(BACKGROUND_END, BACKGROUND_START) - .next(); - buffer.vertex(transform, x + width, y, 0) - .color(r, g, b, 1.0f) - .texture(BACKGROUND_END, BACKGROUND_START) - .next(); - buffer.vertex(transform, x, y + height, 0) - .color(r, g, b, 1.0f) - .texture(BACKGROUND_START, BACKGROUND_END) - .next(); - buffer.vertex(transform, x + width, y + height, 0) - .color(r, g, b, 1.0f) - .texture(BACKGROUND_END, BACKGROUND_END) - .next(); + private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b ) + { + buffer.vertex( transform, x, y, 0 ) + .color( r, g, b, 1.0f ) + .texture( BACKGROUND_START, BACKGROUND_START ) + .next(); + buffer.vertex( transform, x, y + height, 0 ) + .color( r, g, b, 1.0f ) + .texture( BACKGROUND_START, BACKGROUND_END ) + .next(); + buffer.vertex( transform, x + width, y, 0 ) + .color( r, g, b, 1.0f ) + .texture( BACKGROUND_END, BACKGROUND_START ) + .next(); + buffer.vertex( transform, x + width, y, 0 ) + .color( r, g, b, 1.0f ) + .texture( BACKGROUND_END, BACKGROUND_START ) + .next(); + buffer.vertex( transform, x, y + height, 0 ) + .color( r, g, b, 1.0f ) + .texture( BACKGROUND_START, BACKGROUND_END ) + .next(); + buffer.vertex( transform, x + width, y + height, 0 ) + .color( r, g, b, 1.0f ) + .texture( BACKGROUND_END, BACKGROUND_END ) + .next(); } - public static void drawTerminalWithoutCursor(@Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, - @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, - float leftMarginSize, float rightMarginSize) { + public static void drawTerminalWithoutCursor( @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, + @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, + float leftMarginSize, float rightMarginSize ) + { Palette palette = terminal.getPalette(); int height = terminal.getHeight(); // Top and bottom margins - drawBackground(transform, - buffer, - x, - y - topMarginSize, - terminal.getBackgroundColourLine(0), - palette, - greyscale, - leftMarginSize, - rightMarginSize, - topMarginSize); + drawBackground( transform, + buffer, + x, + y - topMarginSize, + terminal.getBackgroundColourLine( 0 ), + palette, + greyscale, + leftMarginSize, + rightMarginSize, + topMarginSize ); - drawBackground(transform, - buffer, - x, - y + height * FONT_HEIGHT, - terminal.getBackgroundColourLine(height - 1), - palette, - greyscale, - leftMarginSize, - rightMarginSize, - bottomMarginSize); + drawBackground( transform, + buffer, + x, + y + height * FONT_HEIGHT, + terminal.getBackgroundColourLine( height - 1 ), + palette, + greyscale, + leftMarginSize, + rightMarginSize, + bottomMarginSize ); // The main text - for (int i = 0; i < height; i++) { - drawString(transform, - buffer, - x, - y + FixedWidthFontRenderer.FONT_HEIGHT * i, - terminal.getLine(i), - terminal.getTextColourLine(i), - terminal.getBackgroundColourLine(i), - palette, - greyscale, - leftMarginSize, - rightMarginSize); + for( int i = 0; i < height; i++ ) + { + drawString( transform, + buffer, + x, + y + FixedWidthFontRenderer.FONT_HEIGHT * i, + terminal.getLine( i ), + terminal.getTextColourLine( i ), + terminal.getBackgroundColourLine( i ), + palette, + greyscale, + leftMarginSize, + rightMarginSize ); } } - public static void drawCursor(@Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, - boolean greyscale) { + public static void drawCursor( @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, + boolean greyscale ) + { Palette palette = terminal.getPalette(); int width = terminal.getWidth(); int height = terminal.getHeight(); int cursorX = terminal.getCursorX(); int cursorY = terminal.getCursorY(); - if (terminal.getCursorBlink() && cursorX >= 0 && cursorX < width && cursorY >= 0 && cursorY < height && FrameInfo.getGlobalCursorBlink()) { - double[] colour = palette.getColour(15 - terminal.getTextColour()); + if( terminal.getCursorBlink() && cursorX >= 0 && cursorX < width && cursorY >= 0 && cursorY < height && FrameInfo.getGlobalCursorBlink() ) + { + double[] colour = palette.getColour( 15 - terminal.getTextColour() ); float r, g, b; - if (greyscale) { - r = g = b = toGreyscale(colour); - } else { + if( greyscale ) + { + r = g = b = toGreyscale( colour ); + } + else + { r = (float) colour[0]; g = (float) colour[1]; b = (float) colour[2]; } - drawChar(transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b); + drawChar( transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b ); } } - public static void drawTerminal(@Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, - boolean greyscale, float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize) { - drawTerminalWithoutCursor(transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize); - drawCursor(transform, buffer, x, y, terminal, greyscale); + public static void drawTerminal( @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, + boolean greyscale, float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize ) + { + drawTerminalWithoutCursor( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize ); + drawCursor( transform, buffer, x, y, terminal, greyscale ); } - public static void drawTerminal(@Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, - float bottomMarginSize, float leftMarginSize, float rightMarginSize) { + public static void drawTerminal( @Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, + float bottomMarginSize, float leftMarginSize, float rightMarginSize ) + { bindFont(); VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() - .getBufferBuilders() - .getEntityVertexConsumers(); - VertexConsumer buffer = renderer.getBuffer(TYPE); - drawTerminal(transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize); - renderer.draw(TYPE); + .getBufferBuilders() + .getEntityVertexConsumers(); + VertexConsumer buffer = renderer.getBuffer( TYPE ); + drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize ); + renderer.draw( TYPE ); } - public static void drawTerminal(float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, - float leftMarginSize, float rightMarginSize) { - drawTerminal(IDENTITY, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize); + public static void drawTerminal( float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, + float leftMarginSize, float rightMarginSize ) + { + drawTerminal( IDENTITY, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize ); } - public static void drawEmptyTerminal(float x, float y, float width, float height) { - drawEmptyTerminal(IDENTITY, x, y, width, height); + public static void drawEmptyTerminal( float x, float y, float width, float height ) + { + drawEmptyTerminal( IDENTITY, x, y, width, height ); } - public static void drawEmptyTerminal(@Nonnull Matrix4f transform, float x, float y, float width, float height) { + public static void drawEmptyTerminal( @Nonnull Matrix4f transform, float x, float y, float width, float height ) + { bindFont(); VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() - .getBufferBuilders() - .getEntityVertexConsumers(); - drawEmptyTerminal(transform, renderer, x, y, width, height); + .getBufferBuilders() + .getEntityVertexConsumers(); + drawEmptyTerminal( transform, renderer, x, y, width, height ); renderer.draw(); } - public static void drawEmptyTerminal(@Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, - float height) { + public static void drawEmptyTerminal( @Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, + float height ) + { Colour colour = Colour.BLACK; - drawQuad(transform, renderer.getBuffer(TYPE), x, y, width, height, colour.getR(), colour.getG(), colour.getB()); + drawQuad( transform, renderer.getBuffer( TYPE ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() ); } - public static void drawBlocker(@Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, float height) { + public static void drawBlocker( @Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, float height ) + { Colour colour = Colour.BLACK; - drawQuad(transform, renderer.getBuffer(Type.BLOCKER), x, y, width, height, colour.getR(), colour.getG(), colour.getB()); + drawQuad( transform, renderer.getBuffer( Type.BLOCKER ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() ); } - private static final class Type extends RenderPhase { + private static final class Type extends RenderPhase + { private static final int GL_MODE = GL11.GL_TRIANGLES; private static final VertexFormat FORMAT = VertexFormats.POSITION_COLOR_TEXTURE; - static final RenderLayer MAIN = RenderLayer.of("terminal_font", FORMAT, GL_MODE, 1024, false, false, // useDelegate, needsSorting - RenderLayer.MultiPhaseParameters.builder() - .texture(new RenderPhase.Texture(FONT, - false, - false)) // blur, minimap - .alpha(ONE_TENTH_ALPHA) - .lightmap(DISABLE_LIGHTMAP) - .writeMaskState(COLOR_MASK) - .build(false)); + static final RenderLayer MAIN = RenderLayer.of( "terminal_font", FORMAT, GL_MODE, 1024, false, false, // useDelegate, needsSorting + RenderLayer.MultiPhaseParameters.builder() + .texture( new RenderPhase.Texture( FONT, + false, + false ) ) // blur, minimap + .alpha( ONE_TENTH_ALPHA ) + .lightmap( DISABLE_LIGHTMAP ) + .writeMaskState( COLOR_MASK ) + .build( false ) ); - static final RenderLayer BLOCKER = RenderLayer.of("terminal_blocker", FORMAT, GL_MODE, 256, false, false, // useDelegate, needsSorting - RenderLayer.MultiPhaseParameters.builder() - .texture(new RenderPhase.Texture(FONT, - false, - false)) // blur, minimap - .alpha(ONE_TENTH_ALPHA) - .writeMaskState(DEPTH_MASK) - .lightmap(DISABLE_LIGHTMAP) - .build(false)); + static final RenderLayer BLOCKER = RenderLayer.of( "terminal_blocker", FORMAT, GL_MODE, 256, false, false, // useDelegate, needsSorting + RenderLayer.MultiPhaseParameters.builder() + .texture( new RenderPhase.Texture( FONT, + false, + false ) ) // blur, minimap + .alpha( ONE_TENTH_ALPHA ) + .writeMaskState( DEPTH_MASK ) + .lightmap( DISABLE_LIGHTMAP ) + .build( false ) ); - private Type(String name, Runnable setup, Runnable destroy) { - super(name, setup, destroy); + private Type( String name, Runnable setup, Runnable destroy ) + { + super( name, setup, destroy ); } } } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java index 64c8c5701..0a8268615 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java @@ -6,11 +6,6 @@ package dan200.computercraft.client.gui; -import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER; -import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN; - -import javax.annotation.Nonnull; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.widgets.WidgetTerminal; @@ -22,14 +17,19 @@ import dan200.computercraft.shared.computer.inventory.ContainerComputer; import dan200.computercraft.shared.computer.inventory.ContainerComputerBase; import dan200.computercraft.shared.computer.inventory.ContainerViewComputer; import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; -import org.lwjgl.glfw.GLFW; - import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.text.Text; +import org.lwjgl.glfw.GLFW; -public final class GuiComputer extends HandledScreen { +import javax.annotation.Nonnull; + +import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER; +import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN; + +public final class GuiComputer extends HandledScreen +{ private final ComputerFamily family; private final ClientComputer computer; private final int termWidth; @@ -38,8 +38,9 @@ public final class GuiComputer extends HandledS private WidgetTerminal terminal; private WidgetWrapper terminalWrapper; - private GuiComputer(T container, PlayerInventory player, Text title, int termWidth, int termHeight) { - super(container, player, title); + private GuiComputer( T container, PlayerInventory player, Text title, int termWidth, int termHeight ) + { + super( container, player, title ); this.family = container.getFamily(); this.computer = (ClientComputer) container.getComputer(); this.termWidth = termWidth; @@ -47,22 +48,26 @@ public final class GuiComputer extends HandledS this.terminal = null; } - public static GuiComputer create(ContainerComputer container, PlayerInventory inventory, Text component) { - return new GuiComputer<>(container, inventory, component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight); + public static GuiComputer create( ContainerComputer container, PlayerInventory inventory, Text component ) + { + return new GuiComputer<>( container, inventory, component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight ); } - public static GuiComputer createPocket(ContainerPocketComputer container, PlayerInventory inventory, Text component) { - return new GuiComputer<>(container, inventory, component, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight); + public static GuiComputer createPocket( ContainerPocketComputer container, PlayerInventory inventory, Text component ) + { + return new GuiComputer<>( container, inventory, component, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight ); } - public static GuiComputer createView(ContainerViewComputer container, PlayerInventory inventory, Text component) { - return new GuiComputer<>(container, inventory, component, container.getWidth(), container.getHeight()); + public static GuiComputer createView( ContainerViewComputer container, PlayerInventory inventory, Text component ) + { + return new GuiComputer<>( container, inventory, component, container.getWidth(), container.getHeight() ); } @Override - protected void init() { - this.client.keyboard.setRepeatEvents(true); + protected void init() + { + this.client.keyboard.setRepeatEvents( true ); int termPxWidth = this.termWidth * FixedWidthFontRenderer.FONT_WIDTH; int termPxHeight = this.termHeight * FixedWidthFontRenderer.FONT_HEIGHT; @@ -72,67 +77,76 @@ public final class GuiComputer extends HandledS super.init(); - this.terminal = new WidgetTerminal(this.client, () -> this.computer, this.termWidth, this.termHeight, MARGIN, MARGIN, MARGIN, MARGIN); - this.terminalWrapper = new WidgetWrapper(this.terminal, MARGIN + BORDER + this.x, MARGIN + BORDER + this.y, termPxWidth, termPxHeight); + this.terminal = new WidgetTerminal( this.client, () -> this.computer, this.termWidth, this.termHeight, MARGIN, MARGIN, MARGIN, MARGIN ); + this.terminalWrapper = new WidgetWrapper( this.terminal, MARGIN + BORDER + this.x, MARGIN + BORDER + this.y, termPxWidth, termPxHeight ); - this.children.add(this.terminalWrapper); - this.setFocused(this.terminalWrapper); + this.children.add( this.terminalWrapper ); + this.setFocused( this.terminalWrapper ); } @Override - public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) { - super.render(stack, mouseX, mouseY, partialTicks); - this.drawMouseoverTooltip(stack, mouseX, mouseY); + public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks ) + { + super.render( stack, mouseX, mouseY, partialTicks ); + this.drawMouseoverTooltip( stack, mouseX, mouseY ); } @Override - protected void drawForeground(@Nonnull MatrixStack transform, int mouseX, int mouseY) { + protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY ) + { // Skip rendering labels. } @Override - public void drawBackground(@Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY) { + public void drawBackground( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY ) + { // Draw terminal - this.terminal.draw(this.terminalWrapper.getX(), this.terminalWrapper.getY()); + this.terminal.draw( this.terminalWrapper.getX(), this.terminalWrapper.getY() ); // Draw a border around the terminal - RenderSystem.color4f(1, 1, 1, 1); + RenderSystem.color4f( 1, 1, 1, 1 ); this.client.getTextureManager() - .bindTexture(ComputerBorderRenderer.getTexture(this.family)); - ComputerBorderRenderer.render(this.terminalWrapper.getX() - MARGIN, this.terminalWrapper.getY() - MARGIN, - this.getZOffset(), this.terminalWrapper.getWidth() + MARGIN * 2, this.terminalWrapper.getHeight() + MARGIN * 2); + .bindTexture( ComputerBorderRenderer.getTexture( this.family ) ); + ComputerBorderRenderer.render( this.terminalWrapper.getX() - MARGIN, this.terminalWrapper.getY() - MARGIN, + this.getZOffset(), this.terminalWrapper.getWidth() + MARGIN * 2, this.terminalWrapper.getHeight() + MARGIN * 2 ); } @Override - public boolean mouseDragged(double x, double y, int button, double deltaX, double deltaY) { - return (this.getFocused() != null && this.getFocused().mouseDragged(x, y, button, deltaX, deltaY)) || super.mouseDragged(x, y, button, deltaX, deltaY); + public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY ) + { + return (this.getFocused() != null && this.getFocused().mouseDragged( x, y, button, deltaX, deltaY )) || super.mouseDragged( x, y, button, deltaX, deltaY ); } - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - return (this.getFocused() != null && this.getFocused().mouseReleased(mouseX, mouseY, button)) || super.mouseReleased(x, y, button); - } + @Override + public boolean mouseReleased( double mouseX, double mouseY, int button ) + { + return (this.getFocused() != null && this.getFocused().mouseReleased( mouseX, mouseY, button )) || super.mouseReleased( x, y, button ); + } @Override - public boolean keyPressed(int key, int scancode, int modifiers) { + public boolean keyPressed( int key, int scancode, int modifiers ) + { // Forward the tab key to the terminal, rather than moving between controls. - if (key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper) { - return this.getFocused().keyPressed(key, scancode, modifiers); + if( key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper ) + { + return this.getFocused().keyPressed( key, scancode, modifiers ); } - return super.keyPressed(key, scancode, modifiers); + return super.keyPressed( key, scancode, modifiers ); } @Override - public void removed() { + public void removed() + { super.removed(); - this.children.remove(this.terminal); + this.children.remove( this.terminal ); this.terminal = null; - this.client.keyboard.setRepeatEvents(false); + this.client.keyboard.setRepeatEvents( false ); } @Override - public void tick() { + public void tick() + { super.tick(); this.terminal.update(); } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiDiskDrive.java b/src/main/java/dan200/computercraft/client/gui/GuiDiskDrive.java index 676cd8d16..b098d37c5 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiDiskDrive.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiDiskDrive.java @@ -6,36 +6,39 @@ package dan200.computercraft.client.gui; -import javax.annotation.Nonnull; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive; - import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -public class GuiDiskDrive extends HandledScreen { - private static final Identifier BACKGROUND = new Identifier("computercraft", "textures/gui/disk_drive.png"); +import javax.annotation.Nonnull; - public GuiDiskDrive(ContainerDiskDrive container, PlayerInventory player, Text title) { - super(container, player, title); +public class GuiDiskDrive extends HandledScreen +{ + private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/disk_drive.png" ); + + public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player, Text title ) + { + super( container, player, title ); } @Override - public void render(@Nonnull MatrixStack transform, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(transform); - super.render(transform, mouseX, mouseY, partialTicks); - this.drawMouseoverTooltip(transform, mouseX, mouseY); + public void render( @Nonnull MatrixStack transform, int mouseX, int mouseY, float partialTicks ) + { + this.renderBackground( transform ); + super.render( transform, mouseX, mouseY, partialTicks ); + this.drawMouseoverTooltip( transform, mouseX, mouseY ); } @Override - protected void drawBackground(@Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY) { - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY ) + { + RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); this.client.getTextureManager() - .bindTexture(BACKGROUND); - this.drawTexture(transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); + .bindTexture( BACKGROUND ); + this.drawTexture( transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight ); } } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiPrinter.java b/src/main/java/dan200/computercraft/client/gui/GuiPrinter.java index 0e2f2f4bc..48988356a 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiPrinter.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiPrinter.java @@ -6,22 +6,23 @@ package dan200.computercraft.client.gui; -import javax.annotation.Nonnull; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.shared.peripheral.printer.ContainerPrinter; - import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -public class GuiPrinter extends HandledScreen { - private static final Identifier BACKGROUND = new Identifier("computercraft", "textures/gui/printer.png"); +import javax.annotation.Nonnull; - public GuiPrinter(ContainerPrinter container, PlayerInventory player, Text title) { - super(container, player, title); +public class GuiPrinter extends HandledScreen +{ + private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/printer.png" ); + + public GuiPrinter( ContainerPrinter container, PlayerInventory player, Text title ) + { + super( container, player, title ); } /*@Override @@ -33,21 +34,24 @@ public class GuiPrinter extends HandledScreen { }*/ @Override - public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(stack); - super.render(stack, mouseX, mouseY, partialTicks); - this.drawMouseoverTooltip(stack, mouseX, mouseY); + public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks ) + { + this.renderBackground( stack ); + super.render( stack, mouseX, mouseY, partialTicks ); + this.drawMouseoverTooltip( stack, mouseX, mouseY ); } @Override - protected void drawBackground(@Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY) { - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY ) + { + RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); this.client.getTextureManager() - .bindTexture(BACKGROUND); - this.drawTexture(transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); + .bindTexture( BACKGROUND ); + this.drawTexture( transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight ); - if (this.getScreenHandler().isPrinting()) { - this.drawTexture(transform, this.x + 34, this.y + 21, 176, 0, 25, 45); + if( this.getScreenHandler().isPrinting() ) + { + this.drawTexture( transform, this.x + 34, this.y + 21, 176, 0, 25, 45 ); } } } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java b/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java index 49bacd902..c944aaed4 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java @@ -6,20 +6,10 @@ package dan200.computercraft.client.gui; -import static dan200.computercraft.client.render.PrintoutRenderer.X_TEXT_MARGIN; -import static dan200.computercraft.client.render.PrintoutRenderer.Y_SIZE; -import static dan200.computercraft.client.render.PrintoutRenderer.Y_TEXT_MARGIN; -import static dan200.computercraft.client.render.PrintoutRenderer.drawBorder; -import static dan200.computercraft.client.render.PrintoutRenderer.drawText; - -import javax.annotation.Nonnull; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.media.items.ItemPrintout; -import org.lwjgl.glfw.GLFW; - import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.render.VertexConsumerProvider; @@ -27,53 +17,68 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.text.Text; import net.minecraft.util.math.Matrix4f; +import org.lwjgl.glfw.GLFW; -public class GuiPrintout extends HandledScreen { +import javax.annotation.Nonnull; + +import static dan200.computercraft.client.render.PrintoutRenderer.*; + +public class GuiPrintout extends HandledScreen +{ private final boolean m_book; private final int m_pages; private final TextBuffer[] m_text; private final TextBuffer[] m_colours; private int m_page; - public GuiPrintout(ContainerHeldItem container, PlayerInventory player, Text title) { - super(container, player, title); + public GuiPrintout( ContainerHeldItem container, PlayerInventory player, Text title ) + { + super( container, player, title ); this.backgroundHeight = Y_SIZE; - String[] text = ItemPrintout.getText(container.getStack()); + String[] text = ItemPrintout.getText( container.getStack() ); this.m_text = new TextBuffer[text.length]; - for (int i = 0; i < this.m_text.length; i++) { - this.m_text[i] = new TextBuffer(text[i]); + for( int i = 0; i < this.m_text.length; i++ ) + { + this.m_text[i] = new TextBuffer( text[i] ); } - String[] colours = ItemPrintout.getColours(container.getStack()); + String[] colours = ItemPrintout.getColours( container.getStack() ); this.m_colours = new TextBuffer[colours.length]; - for (int i = 0; i < this.m_colours.length; i++) { - this.m_colours[i] = new TextBuffer(colours[i]); + for( int i = 0; i < this.m_colours.length; i++ ) + { + this.m_colours[i] = new TextBuffer( colours[i] ); } this.m_page = 0; - this.m_pages = Math.max(this.m_text.length / ItemPrintout.LINES_PER_PAGE, 1); + this.m_pages = Math.max( this.m_text.length / ItemPrintout.LINES_PER_PAGE, 1 ); this.m_book = ((ItemPrintout) container.getStack() - .getItem()).getType() == ItemPrintout.Type.BOOK; + .getItem()).getType() == ItemPrintout.Type.BOOK; } @Override - public boolean mouseScrolled(double x, double y, double delta) { - if (super.mouseScrolled(x, y, delta)) { + public boolean mouseScrolled( double x, double y, double delta ) + { + if( super.mouseScrolled( x, y, delta ) ) + { return true; } - if (delta < 0) { + if( delta < 0 ) + { // Scroll up goes to the next page - if (this.m_page < this.m_pages - 1) { + if( this.m_page < this.m_pages - 1 ) + { this.m_page++; } return true; } - if (delta > 0) { + if( delta > 0 ) + { // Scroll down goes to the previous page - if (this.m_page > 0) { + if( this.m_page > 0 ) + { this.m_page--; } return true; @@ -83,51 +88,60 @@ public class GuiPrintout extends HandledScreen { } @Override - public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) { + public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks ) + { // We must take the background further back in order to not overlap with our printed pages. - this.setZOffset(this.getZOffset() - 1); - this.renderBackground(stack); - this.setZOffset(this.getZOffset() + 1); + this.setZOffset( this.getZOffset() - 1 ); + this.renderBackground( stack ); + this.setZOffset( this.getZOffset() + 1 ); - super.render(stack, mouseX, mouseY, partialTicks); + super.render( stack, mouseX, mouseY, partialTicks ); } @Override - protected void drawForeground(@Nonnull MatrixStack transform, int mouseX, int mouseY) { + protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY ) + { // Skip rendering labels. } @Override - protected void drawBackground(@Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY) { + protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY ) + { // Draw the printout - RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f); + RenderSystem.color4f( 1.0f, 1.0f, 1.0f, 1.0f ); RenderSystem.enableDepthTest(); VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() - .getBufferBuilders() - .getEntityVertexConsumers(); + .getBufferBuilders() + .getEntityVertexConsumers(); Matrix4f matrix = transform.peek() - .getModel(); - drawBorder(matrix, renderer, this.x, this.y, this.getZOffset(), this.m_page, this.m_pages, this.m_book); - drawText(matrix, renderer, this.x + X_TEXT_MARGIN, this.y + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * this.m_page, this.m_text, this.m_colours); + .getModel(); + drawBorder( matrix, renderer, this.x, this.y, this.getZOffset(), this.m_page, this.m_pages, this.m_book ); + drawText( matrix, renderer, this.x + X_TEXT_MARGIN, this.y + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * this.m_page, this.m_text, this.m_colours ); renderer.draw(); } @Override - public boolean keyPressed(int key, int scancode, int modifiers) { - if (super.keyPressed(key, scancode, modifiers)) { + public boolean keyPressed( int key, int scancode, int modifiers ) + { + if( super.keyPressed( key, scancode, modifiers ) ) + { return true; } - if (key == GLFW.GLFW_KEY_RIGHT) { - if (this.m_page < this.m_pages - 1) { + if( key == GLFW.GLFW_KEY_RIGHT ) + { + if( this.m_page < this.m_pages - 1 ) + { this.m_page++; } return true; } - if (key == GLFW.GLFW_KEY_LEFT) { - if (this.m_page > 0) { + if( key == GLFW.GLFW_KEY_LEFT ) + { + if( this.m_page > 0 ) + { this.m_page--; } return true; diff --git a/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java b/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java index 609c656ef..4a731ad2a 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiTurtle.java @@ -6,8 +6,6 @@ package dan200.computercraft.client.gui; -import javax.annotation.Nonnull; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.widgets.WidgetTerminal; @@ -15,25 +13,28 @@ import dan200.computercraft.client.gui.widgets.WidgetWrapper; import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; -import org.lwjgl.glfw.GLFW; - import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import org.lwjgl.glfw.GLFW; -public class GuiTurtle extends HandledScreen { - private static final Identifier BACKGROUND_NORMAL = new Identifier("computercraft", "textures/gui/turtle_normal.png"); - private static final Identifier BACKGROUND_ADVANCED = new Identifier("computercraft", "textures/gui/turtle_advanced.png"); +import javax.annotation.Nonnull; + +public class GuiTurtle extends HandledScreen +{ + private static final Identifier BACKGROUND_NORMAL = new Identifier( "computercraft", "textures/gui/turtle_normal.png" ); + private static final Identifier BACKGROUND_ADVANCED = new Identifier( "computercraft", "textures/gui/turtle_advanced.png" ); private final ComputerFamily m_family; private final ClientComputer m_computer; private ContainerTurtle m_container; private WidgetTerminal terminal; private WidgetWrapper terminalWrapper; - public GuiTurtle(ContainerTurtle container, PlayerInventory player, Text title) { - super(container, player, title); + public GuiTurtle( ContainerTurtle container, PlayerInventory player, Text title ) + { + super( container, player, title ); this.m_container = container; this.m_family = container.getFamily(); @@ -44,82 +45,92 @@ public class GuiTurtle extends HandledScreen { } @Override - protected void init() { + protected void init() + { super.init(); - this.client.keyboard.setRepeatEvents(true); + this.client.keyboard.setRepeatEvents( true ); int termPxWidth = ComputerCraft.turtleTermWidth * FixedWidthFontRenderer.FONT_WIDTH; int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT; - this.terminal = new WidgetTerminal(this.client, () -> this.m_computer, ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight, 2, 2, 2, 2); - this.terminalWrapper = new WidgetWrapper(this.terminal, 2 + 8 + this.x, 2 + 8 + this.y, termPxWidth, termPxHeight); + this.terminal = new WidgetTerminal( this.client, () -> this.m_computer, ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight, 2, 2, 2, 2 ); + this.terminalWrapper = new WidgetWrapper( this.terminal, 2 + 8 + this.x, 2 + 8 + this.y, termPxWidth, termPxHeight ); - this.children.add(this.terminalWrapper); - this.setFocused(this.terminalWrapper); + this.children.add( this.terminalWrapper ); + this.setFocused( this.terminalWrapper ); } @Override - public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(stack); - super.render(stack, mouseX, mouseY, partialTicks); - this.drawMouseoverTooltip(stack, mouseX, mouseY); + public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks ) + { + this.renderBackground( stack ); + super.render( stack, mouseX, mouseY, partialTicks ); + this.drawMouseoverTooltip( stack, mouseX, mouseY ); } @Override - protected void drawForeground(@Nonnull MatrixStack transform, int mouseX, int mouseY) { + protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY ) + { // Skip rendering labels. } @Override - protected void drawBackground(@Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY) { + protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY ) + { // Draw term Identifier texture = this.m_family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL; - this.terminal.draw(this.terminalWrapper.getX(), this.terminalWrapper.getY()); + this.terminal.draw( this.terminalWrapper.getX(), this.terminalWrapper.getY() ); // Draw border/inventory - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); this.client.getTextureManager() - .bindTexture(texture); - this.drawTexture(transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); + .bindTexture( texture ); + this.drawTexture( transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight ); // Draw selection slot int slot = this.m_container.getSelectedSlot(); - if (slot >= 0) { + if( slot >= 0 ) + { int slotX = slot % 4; int slotY = slot / 4; - this.drawTexture(transform, this.x + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, this.y + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, - 0, - 217, - 24, - 24); + this.drawTexture( transform, this.x + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, this.y + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, + 0, + 217, + 24, + 24 ); } } @Override - public boolean mouseDragged(double x, double y, int button, double deltaX, double deltaY) { - return (this.getFocused() != null && this.getFocused().mouseDragged(x, y, button, deltaX, deltaY)) || super.mouseDragged(x, y, button, deltaX, deltaY); + public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY ) + { + return (this.getFocused() != null && this.getFocused().mouseDragged( x, y, button, deltaX, deltaY )) || super.mouseDragged( x, y, button, deltaX, deltaY ); } @Override - public boolean keyPressed(int key, int scancode, int modifiers) { + public boolean keyPressed( int key, int scancode, int modifiers ) + { // Forward the tab key to the terminal, rather than moving between controls. - if (key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper) { - return this.getFocused().keyPressed(key, scancode, modifiers); + if( key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper ) + { + return this.getFocused().keyPressed( key, scancode, modifiers ); } - return super.keyPressed(key, scancode, modifiers); + return super.keyPressed( key, scancode, modifiers ); } @Override - public void removed() { + public void removed() + { super.removed(); - this.children.remove(this.terminal); + this.children.remove( this.terminal ); this.terminal = null; - this.client.keyboard.setRepeatEvents(false); + this.client.keyboard.setRepeatEvents( false ); } @Override - public void tick() { + public void tick() + { super.tick(); this.terminal.update(); } diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java index 5899f6f2e..b0ce38000 100644 --- a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java +++ b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java @@ -6,23 +6,23 @@ package dan200.computercraft.client.gui.widgets; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; - -import java.util.BitSet; -import java.util.function.Supplier; - import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.IComputer; -import org.lwjgl.glfw.GLFW; - import net.minecraft.SharedConstants; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; +import org.lwjgl.glfw.GLFW; -public class WidgetTerminal implements Element { +import java.util.BitSet; +import java.util.function.Supplier; + +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; + +public class WidgetTerminal implements Element +{ private static final float TERMINATE_TIME = 0.5f; private final MinecraftClient client; @@ -33,7 +33,7 @@ public class WidgetTerminal implements Element { private final int rightMargin; private final int topMargin; private final int bottomMargin; - private final BitSet keysDown = new BitSet(256); + private final BitSet keysDown = new BitSet( 256 ); private boolean focused; private float terminateTimer = -1; private float rebootTimer = -1; @@ -42,8 +42,9 @@ public class WidgetTerminal implements Element { private int lastMouseX = -1; private int lastMouseY = -1; - public WidgetTerminal(MinecraftClient client, Supplier computer, int termWidth, int termHeight, int leftMargin, int rightMargin, - int topMargin, int bottomMargin) { + public WidgetTerminal( MinecraftClient client, Supplier computer, int termWidth, int termHeight, int leftMargin, int rightMargin, + int topMargin, int bottomMargin ) + { this.client = client; this.computer = computer; this.termWidth = termWidth; @@ -55,20 +56,23 @@ public class WidgetTerminal implements Element { } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { + public boolean mouseClicked( double mouseX, double mouseY, int button ) + { ClientComputer computer = this.computer.get(); - if (computer == null || !computer.isColour() || button < 0 || button > 2) { + if( computer == null || !computer.isColour() || button < 0 || button > 2 ) + { return false; } Terminal term = computer.getTerminal(); - if (term != null) { + if( term != null ) + { int charX = (int) (mouseX / FONT_WIDTH); int charY = (int) (mouseY / FONT_HEIGHT); - charX = Math.min(Math.max(charX, 0), term.getWidth() - 1); - charY = Math.min(Math.max(charY, 0), term.getHeight() - 1); + charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); + charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); - computer.mouseClick(button + 1, charX + 1, charY + 1); + computer.mouseClick( button + 1, charX + 1, charY + 1 ); this.lastMouseButton = button; this.lastMouseX = charX; @@ -79,21 +83,25 @@ public class WidgetTerminal implements Element { } @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { + public boolean mouseReleased( double mouseX, double mouseY, int button ) + { ClientComputer computer = this.computer.get(); - if (computer == null || !computer.isColour() || button < 0 || button > 2) { + if( computer == null || !computer.isColour() || button < 0 || button > 2 ) + { return false; } Terminal term = computer.getTerminal(); - if (term != null) { + if( term != null ) + { int charX = (int) (mouseX / FONT_WIDTH); int charY = (int) (mouseY / FONT_HEIGHT); - charX = Math.min(Math.max(charX, 0), term.getWidth() - 1); - charY = Math.min(Math.max(charY, 0), term.getHeight() - 1); + charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); + charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); - if (this.lastMouseButton == button) { - computer.mouseUp(this.lastMouseButton + 1, charX + 1, charY + 1); + if( this.lastMouseButton == button ) + { + computer.mouseUp( this.lastMouseButton + 1, charX + 1, charY + 1 ); this.lastMouseButton = -1; } @@ -105,21 +113,25 @@ public class WidgetTerminal implements Element { } @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double v2, double v3) { + public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 ) + { ClientComputer computer = this.computer.get(); - if (computer == null || !computer.isColour() || button < 0 || button > 2) { + if( computer == null || !computer.isColour() || button < 0 || button > 2 ) + { return false; } Terminal term = computer.getTerminal(); - if (term != null) { + if( term != null ) + { int charX = (int) (mouseX / FONT_WIDTH); int charY = (int) (mouseY / FONT_HEIGHT); - charX = Math.min(Math.max(charX, 0), term.getWidth() - 1); - charY = Math.min(Math.max(charY, 0), term.getHeight() - 1); + charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); + charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); - if (button == this.lastMouseButton && (charX != this.lastMouseX || charY != this.lastMouseY)) { - computer.mouseDrag(button + 1, charX + 1, charY + 1); + if( button == this.lastMouseButton && (charX != this.lastMouseX || charY != this.lastMouseY) ) + { + computer.mouseDrag( button + 1, charX + 1, charY + 1 ); this.lastMouseX = charX; this.lastMouseY = charY; } @@ -129,20 +141,23 @@ public class WidgetTerminal implements Element { } @Override - public boolean mouseScrolled(double mouseX, double mouseY, double delta) { + public boolean mouseScrolled( double mouseX, double mouseY, double delta ) + { ClientComputer computer = this.computer.get(); - if (computer == null || !computer.isColour() || delta == 0) { + if( computer == null || !computer.isColour() || delta == 0 ) + { return false; } Terminal term = computer.getTerminal(); - if (term != null) { + if( term != null ) + { int charX = (int) (mouseX / FONT_WIDTH); int charY = (int) (mouseY / FONT_HEIGHT); - charX = Math.min(Math.max(charX, 0), term.getWidth() - 1); - charY = Math.min(Math.max(charY, 0), term.getHeight() - 1); + charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 ); + charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 ); - computer.mouseScroll(delta < 0 ? 1 : -1, charX + 1, charY + 1); + computer.mouseScroll( delta < 0 ? 1 : -1, charX + 1, charY + 1 ); this.lastMouseX = charX; this.lastMouseY = charY; @@ -152,65 +167,82 @@ public class WidgetTerminal implements Element { } @Override - public boolean keyPressed(int key, int scancode, int modifiers) { - if (key == GLFW.GLFW_KEY_ESCAPE) { + public boolean keyPressed( int key, int scancode, int modifiers ) + { + if( key == GLFW.GLFW_KEY_ESCAPE ) + { return false; } - if ((modifiers & GLFW.GLFW_MOD_CONTROL) != 0) { - switch (key) { - case GLFW.GLFW_KEY_T: - if (this.terminateTimer < 0) { - this.terminateTimer = 0; - } - return true; - case GLFW.GLFW_KEY_S: - if (this.shutdownTimer < 0) { - this.shutdownTimer = 0; - } - return true; - case GLFW.GLFW_KEY_R: - if (this.rebootTimer < 0) { - this.rebootTimer = 0; - } - return true; - - case GLFW.GLFW_KEY_V: - // Ctrl+V for paste - String clipboard = this.client.keyboard.getClipboard(); - if (clipboard != null) { - // Clip to the first occurrence of \r or \n - int newLineIndex1 = clipboard.indexOf("\r"); - int newLineIndex2 = clipboard.indexOf("\n"); - if (newLineIndex1 >= 0 && newLineIndex2 >= 0) { - clipboard = clipboard.substring(0, Math.min(newLineIndex1, newLineIndex2)); - } else if (newLineIndex1 >= 0) { - clipboard = clipboard.substring(0, newLineIndex1); - } else if (newLineIndex2 >= 0) { - clipboard = clipboard.substring(0, newLineIndex2); + if( (modifiers & GLFW.GLFW_MOD_CONTROL) != 0 ) + { + switch( key ) + { + case GLFW.GLFW_KEY_T: + if( this.terminateTimer < 0 ) + { + this.terminateTimer = 0; } - - // Filter the string - clipboard = SharedConstants.stripInvalidChars(clipboard); - if (!clipboard.isEmpty()) { - // Clip to 512 characters and queue the event - if (clipboard.length() > 512) { - clipboard = clipboard.substring(0, 512); - } - this.queueEvent("paste", clipboard); - } - return true; - } + case GLFW.GLFW_KEY_S: + if( this.shutdownTimer < 0 ) + { + this.shutdownTimer = 0; + } + return true; + case GLFW.GLFW_KEY_R: + if( this.rebootTimer < 0 ) + { + this.rebootTimer = 0; + } + return true; + + case GLFW.GLFW_KEY_V: + // Ctrl+V for paste + String clipboard = this.client.keyboard.getClipboard(); + if( clipboard != null ) + { + // Clip to the first occurrence of \r or \n + int newLineIndex1 = clipboard.indexOf( "\r" ); + int newLineIndex2 = clipboard.indexOf( "\n" ); + if( newLineIndex1 >= 0 && newLineIndex2 >= 0 ) + { + clipboard = clipboard.substring( 0, Math.min( newLineIndex1, newLineIndex2 ) ); + } + else if( newLineIndex1 >= 0 ) + { + clipboard = clipboard.substring( 0, newLineIndex1 ); + } + else if( newLineIndex2 >= 0 ) + { + clipboard = clipboard.substring( 0, newLineIndex2 ); + } + + // Filter the string + clipboard = SharedConstants.stripInvalidChars( clipboard ); + if( !clipboard.isEmpty() ) + { + // Clip to 512 characters and queue the event + if( clipboard.length() > 512 ) + { + clipboard = clipboard.substring( 0, 512 ); + } + this.queueEvent( "paste", clipboard ); + } + + return true; + } } } - if (key >= 0 && this.terminateTimer < 0 && this.rebootTimer < 0 && this.shutdownTimer < 0) { + if( key >= 0 && this.terminateTimer < 0 && this.rebootTimer < 0 && this.shutdownTimer < 0 ) + { // Queue the "key" event and add to the down set - boolean repeat = this.keysDown.get(key); - this.keysDown.set(key); + boolean repeat = this.keysDown.get( key ); + this.keysDown.set( key ); IComputer computer = this.computer.get(); - if (computer != null) { - computer.keyDown(key, repeat); + if( computer != null ) + { + computer.keyDown( key, repeat ); } } @@ -218,62 +250,73 @@ public class WidgetTerminal implements Element { } @Override - public boolean keyReleased(int key, int scancode, int modifiers) { + public boolean keyReleased( int key, int scancode, int modifiers ) + { // Queue the "key_up" event and remove from the down set - if (key >= 0 && this.keysDown.get(key)) { - this.keysDown.set(key, false); + if( key >= 0 && this.keysDown.get( key ) ) + { + this.keysDown.set( key, false ); IComputer computer = this.computer.get(); - if (computer != null) { - computer.keyUp(key); + if( computer != null ) + { + computer.keyUp( key ); } } - switch (key) { - case GLFW.GLFW_KEY_T: - this.terminateTimer = -1; - break; - case GLFW.GLFW_KEY_R: - this.rebootTimer = -1; - break; - case GLFW.GLFW_KEY_S: - this.shutdownTimer = -1; - break; - case GLFW.GLFW_KEY_LEFT_CONTROL: - case GLFW.GLFW_KEY_RIGHT_CONTROL: - this.terminateTimer = this.rebootTimer = this.shutdownTimer = -1; - break; + switch( key ) + { + case GLFW.GLFW_KEY_T: + this.terminateTimer = -1; + break; + case GLFW.GLFW_KEY_R: + this.rebootTimer = -1; + break; + case GLFW.GLFW_KEY_S: + this.shutdownTimer = -1; + break; + case GLFW.GLFW_KEY_LEFT_CONTROL: + case GLFW.GLFW_KEY_RIGHT_CONTROL: + this.terminateTimer = this.rebootTimer = this.shutdownTimer = -1; + break; } return true; } @Override - public boolean charTyped(char ch, int modifiers) { - if (ch >= 32 && ch <= 126 || ch >= 160 && ch <= 255) // printable chars in byte range + public boolean charTyped( char ch, int modifiers ) + { + if( ch >= 32 && ch <= 126 || ch >= 160 && ch <= 255 ) // printable chars in byte range { // Queue the "char" event - this.queueEvent("char", Character.toString(ch)); + this.queueEvent( "char", Character.toString( ch ) ); } return true; } @Override - public boolean changeFocus(boolean reversed) { - if (this.focused) { + public boolean changeFocus( boolean reversed ) + { + if( this.focused ) + { // When blurring, we should make all keys go up - for (int key = 0; key < this.keysDown.size(); key++) { - if (this.keysDown.get(key)) { - this.queueEvent("key_up", key); + for( int key = 0; key < this.keysDown.size(); key++ ) + { + if( this.keysDown.get( key ) ) + { + this.queueEvent( "key_up", key ); } } this.keysDown.clear(); // When blurring, we should make the last mouse button go up - if (this.lastMouseButton > 0) { + if( this.lastMouseButton > 0 ) + { IComputer computer = this.computer.get(); - if (computer != null) { - computer.mouseUp(this.lastMouseButton + 1, this.lastMouseX + 1, this.lastMouseY + 1); + if( computer != null ) + { + computer.mouseUp( this.lastMouseButton + 1, this.lastMouseX + 1, this.lastMouseY + 1 ); } this.lastMouseButton = -1; } @@ -285,56 +328,72 @@ public class WidgetTerminal implements Element { } @Override - public boolean isMouseOver(double x, double y) { + public boolean isMouseOver( double x, double y ) + { return true; } - private void queueEvent(String event, Object... args) { + private void queueEvent( String event, Object... args ) + { ClientComputer computer = this.computer.get(); - if (computer != null) { - computer.queueEvent(event, args); + if( computer != null ) + { + computer.queueEvent( event, args ); } } - public void update() { - if (this.terminateTimer >= 0 && this.terminateTimer < TERMINATE_TIME && (this.terminateTimer += 0.05f) > TERMINATE_TIME) { - this.queueEvent("terminate"); + public void update() + { + if( this.terminateTimer >= 0 && this.terminateTimer < TERMINATE_TIME && (this.terminateTimer += 0.05f) > TERMINATE_TIME ) + { + this.queueEvent( "terminate" ); } - if (this.shutdownTimer >= 0 && this.shutdownTimer < TERMINATE_TIME && (this.shutdownTimer += 0.05f) > TERMINATE_TIME) { + if( this.shutdownTimer >= 0 && this.shutdownTimer < TERMINATE_TIME && (this.shutdownTimer += 0.05f) > TERMINATE_TIME ) + { ClientComputer computer = this.computer.get(); - if (computer != null) { + if( computer != null ) + { computer.shutdown(); } } - if (this.rebootTimer >= 0 && this.rebootTimer < TERMINATE_TIME && (this.rebootTimer += 0.05f) > TERMINATE_TIME) { + if( this.rebootTimer >= 0 && this.rebootTimer < TERMINATE_TIME && (this.rebootTimer += 0.05f) > TERMINATE_TIME ) + { ClientComputer computer = this.computer.get(); - if (computer != null) { + if( computer != null ) + { computer.reboot(); } } } - private void queueEvent(String event) { + private void queueEvent( String event ) + { ClientComputer computer = this.computer.get(); - if (computer != null) { - computer.queueEvent(event); + if( computer != null ) + { + computer.queueEvent( event ); } } - public void draw(int originX, int originY) { - synchronized (this.computer) { + public void draw( int originX, int originY ) + { + synchronized( this.computer ) + { // Draw the screen contents ClientComputer computer = this.computer.get(); Terminal terminal = computer != null ? computer.getTerminal() : null; - if (terminal != null) { - FixedWidthFontRenderer.drawTerminal(originX, originY, terminal, !computer.isColour(), this.topMargin, this.bottomMargin, this.leftMargin, - this.rightMargin); - } else { - FixedWidthFontRenderer.drawEmptyTerminal(originX - this.leftMargin, - originY - this.rightMargin, this.termWidth * FONT_WIDTH + this.leftMargin + this.rightMargin, - this.termHeight * FONT_HEIGHT + this.topMargin + this.bottomMargin); + if( terminal != null ) + { + FixedWidthFontRenderer.drawTerminal( originX, originY, terminal, !computer.isColour(), this.topMargin, this.bottomMargin, this.leftMargin, + this.rightMargin ); + } + else + { + FixedWidthFontRenderer.drawEmptyTerminal( originX - this.leftMargin, + originY - this.rightMargin, this.termWidth * FONT_WIDTH + this.leftMargin + this.rightMargin, + this.termHeight * FONT_HEIGHT + this.topMargin + this.bottomMargin ); } } } diff --git a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java index 3b8b424ee..3b7da58a8 100644 --- a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java +++ b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetWrapper.java @@ -8,14 +8,16 @@ package dan200.computercraft.client.gui.widgets; import net.minecraft.client.gui.Element; -public class WidgetWrapper implements Element { +public class WidgetWrapper implements Element +{ private final Element listener; private final int x; private final int y; private final int width; private final int height; - public WidgetWrapper(Element listener, int x, int y, int width, int height) { + public WidgetWrapper( Element listener, int x, int y, int width, int height ) + { this.listener = listener; this.x = x; this.y = y; @@ -24,68 +26,81 @@ public class WidgetWrapper implements Element { } @Override - public boolean mouseClicked(double x, double y, int button) { + public boolean mouseClicked( double x, double y, int button ) + { double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseClicked(dx, dy, button); + return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseClicked( dx, dy, button ); } @Override - public boolean mouseReleased(double x, double y, int button) { + public boolean mouseReleased( double x, double y, int button ) + { double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseReleased(dx, dy, button); + return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseReleased( dx, dy, button ); } @Override - public boolean mouseDragged(double x, double y, int button, double deltaX, double deltaY) { + public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY ) + { double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseDragged(dx, dy, button, deltaX, deltaY); + return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseDragged( dx, dy, button, deltaX, deltaY ); } @Override - public boolean mouseScrolled(double x, double y, double delta) { + public boolean mouseScrolled( double x, double y, double delta ) + { double dx = x - this.x, dy = y - this.y; - return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseScrolled(dx, dy, delta); + return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height && this.listener.mouseScrolled( dx, dy, delta ); } @Override - public boolean keyPressed(int key, int scancode, int modifiers) { - return this.listener.keyPressed(key, scancode, modifiers); + public boolean keyPressed( int key, int scancode, int modifiers ) + { + return this.listener.keyPressed( key, scancode, modifiers ); } @Override - public boolean keyReleased(int key, int scancode, int modifiers) { - return this.listener.keyReleased(key, scancode, modifiers); + public boolean keyReleased( int key, int scancode, int modifiers ) + { + return this.listener.keyReleased( key, scancode, modifiers ); } @Override - public boolean charTyped(char character, int modifiers) { - return this.listener.charTyped(character, modifiers); + public boolean charTyped( char character, int modifiers ) + { + return this.listener.charTyped( character, modifiers ); } @Override - public boolean changeFocus(boolean b) { - return this.listener.changeFocus(b); + public boolean changeFocus( boolean b ) + { + return this.listener.changeFocus( b ); } @Override - public boolean isMouseOver(double x, double y) { + public boolean isMouseOver( double x, double y ) + { double dx = x - this.x, dy = y - this.y; return dx >= 0 && dx < this.width && dy >= 0 && dy < this.height; } - public int getX() { + public int getX() + { return this.x; } - public int getY() { + public int getY() + { return this.y; } - public int getWidth() { + public int getWidth() + { return this.width; } - public int getHeight() { + public int getHeight() + { return this.height; } } diff --git a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java index fd1e78f7e..fa7c0a8f1 100644 --- a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java +++ b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java @@ -6,16 +6,10 @@ package dan200.computercraft.client.proxy; -import java.util.function.Supplier; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.ClientRegistry; import dan200.computercraft.client.FrameInfo; -import dan200.computercraft.client.gui.GuiComputer; -import dan200.computercraft.client.gui.GuiDiskDrive; -import dan200.computercraft.client.gui.GuiPrinter; -import dan200.computercraft.client.gui.GuiPrintout; -import dan200.computercraft.client.gui.GuiTurtle; +import dan200.computercraft.client.gui.*; import dan200.computercraft.client.render.TileEntityMonitorRenderer; import dan200.computercraft.client.render.TileEntityTurtleRenderer; import dan200.computercraft.client.render.TurtleModelLoader; @@ -33,105 +27,112 @@ import dan200.computercraft.shared.peripheral.printer.ContainerPrinter; import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; - import dan200.computercraft.shared.util.Config; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.item.ModelPredicateProvider; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.item.Item; -import net.minecraft.screen.PlayerScreenHandler; -import net.minecraft.util.Identifier; - import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry; import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry; import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; import net.fabricmc.fabric.mixin.object.builder.ModelPredicateProviderRegistrySpecificAccessor; +import net.minecraft.client.item.ModelPredicateProvider; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.item.Item; +import net.minecraft.screen.PlayerScreenHandler; +import net.minecraft.util.Identifier; -@Environment (EnvType.CLIENT) -public final class ComputerCraftProxyClient implements ClientModInitializer { +import java.util.function.Supplier; - private static void initEvents() { +@Environment( EnvType.CLIENT ) +public final class ComputerCraftProxyClient implements ClientModInitializer +{ + + private static void initEvents() + { ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register( ( blockEntity, world ) -> { - if(blockEntity instanceof TileGeneric ) { - ((TileGeneric)blockEntity).onChunkUnloaded(); + if( blockEntity instanceof TileGeneric ) + { + ((TileGeneric) blockEntity).onChunkUnloaded(); } - }); + } ); ClientUnloadWorldEvent.EVENT.register( () -> ClientMonitor.destroyAll() ); // Config - ClientLifecycleEvents.CLIENT_STARTED.register(Config::clientStarted); + ClientLifecycleEvents.CLIENT_STARTED.register( Config::clientStarted ); } @Override - public void onInitializeClient() { + public void onInitializeClient() + { FrameInfo.init(); registerContainers(); // While turtles themselves are not transparent, their upgrades may be. - BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, RenderLayer.getTranslucent() ); + BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED, RenderLayer.getTranslucent() ); // Monitors' textures have transparent fronts and so count as cutouts. - BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.MONITOR_NORMAL, RenderLayer.getCutout()); - BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.MONITOR_ADVANCED, RenderLayer.getCutout()); + BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.MONITOR_NORMAL, RenderLayer.getCutout() ); + BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.MONITOR_ADVANCED, RenderLayer.getCutout() ); // Setup TESRs - BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.MONITOR_NORMAL, TileEntityMonitorRenderer::new); - BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.MONITOR_ADVANCED, TileEntityMonitorRenderer::new); - BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.TURTLE_NORMAL, TileEntityTurtleRenderer::new); - BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.TURTLE_ADVANCED, TileEntityTurtleRenderer::new); + BlockEntityRendererRegistry.INSTANCE.register( ComputerCraftRegistry.ModTiles.MONITOR_NORMAL, TileEntityMonitorRenderer::new ); + BlockEntityRendererRegistry.INSTANCE.register( ComputerCraftRegistry.ModTiles.MONITOR_ADVANCED, TileEntityMonitorRenderer::new ); + BlockEntityRendererRegistry.INSTANCE.register( ComputerCraftRegistry.ModTiles.TURTLE_NORMAL, TileEntityTurtleRenderer::new ); + BlockEntityRendererRegistry.INSTANCE.register( ComputerCraftRegistry.ModTiles.TURTLE_ADVANCED, TileEntityTurtleRenderer::new ); - ClientSpriteRegistryCallback.event(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE) - .register(ClientRegistry::onTextureStitchEvent); - ModelLoadingRegistry.INSTANCE.registerAppender(ClientRegistry::onModelBakeEvent); - ModelLoadingRegistry.INSTANCE.registerResourceProvider(loader -> (name, context) -> TurtleModelLoader.INSTANCE.accepts(name) ? - TurtleModelLoader.INSTANCE.loadModel( - name) : null); + ClientSpriteRegistryCallback.event( PlayerScreenHandler.BLOCK_ATLAS_TEXTURE ) + .register( ClientRegistry::onTextureStitchEvent ); + ModelLoadingRegistry.INSTANCE.registerAppender( ClientRegistry::onModelBakeEvent ); + ModelLoadingRegistry.INSTANCE.registerResourceProvider( loader -> ( name, context ) -> TurtleModelLoader.INSTANCE.accepts( name ) ? + TurtleModelLoader.INSTANCE.loadModel( + name ) : null ); - EntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModEntities.TURTLE_PLAYER, TurtlePlayerRenderer::new); + EntityRendererRegistry.INSTANCE.register( ComputerCraftRegistry.ModEntities.TURTLE_PLAYER, TurtlePlayerRenderer::new ); - registerItemProperty("state", - (stack, world, player) -> ItemPocketComputer.getState(stack) - .ordinal(), - () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, - () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED); - registerItemProperty("state", - (stack, world, player) -> IColouredItem.getColourBasic(stack) != -1 ? 1 : 0, - () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, - () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED); + registerItemProperty( "state", + ( stack, world, player ) -> ItemPocketComputer.getState( stack ) + .ordinal(), + () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, + () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED ); + registerItemProperty( "state", + ( stack, world, player ) -> IColouredItem.getColourBasic( stack ) != -1 ? 1 : 0, + () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, + () -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED ); ClientRegistry.onItemColours(); initEvents(); } // My IDE doesn't think so, but we do actually need these generics. - private static void registerContainers() { - ScreenRegistry.>register(ComputerCraftRegistry.ModContainers.COMPUTER, GuiComputer::create); - ScreenRegistry.>register(ComputerCraftRegistry.ModContainers.POCKET_COMPUTER, - GuiComputer::createPocket); - ScreenRegistry.register(ComputerCraftRegistry.ModContainers.TURTLE, GuiTurtle::new); + private static void registerContainers() + { + ScreenRegistry.>register( ComputerCraftRegistry.ModContainers.COMPUTER, GuiComputer::create ); + ScreenRegistry.>register( ComputerCraftRegistry.ModContainers.POCKET_COMPUTER, + GuiComputer::createPocket ); + ScreenRegistry.register( ComputerCraftRegistry.ModContainers.TURTLE, GuiTurtle::new ); - ScreenRegistry.register(ComputerCraftRegistry.ModContainers.PRINTER, GuiPrinter::new); - ScreenRegistry.register(ComputerCraftRegistry.ModContainers.DISK_DRIVE, GuiDiskDrive::new); - ScreenRegistry.register(ComputerCraftRegistry.ModContainers.PRINTOUT, GuiPrintout::new); + ScreenRegistry.register( ComputerCraftRegistry.ModContainers.PRINTER, GuiPrinter::new ); + ScreenRegistry.register( ComputerCraftRegistry.ModContainers.DISK_DRIVE, GuiDiskDrive::new ); + ScreenRegistry.register( ComputerCraftRegistry.ModContainers.PRINTOUT, GuiPrintout::new ); - ScreenRegistry.>register(ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, - GuiComputer::createView); + ScreenRegistry.>register( ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, + GuiComputer::createView ); } @SafeVarargs - private static void registerItemProperty(String name, ModelPredicateProvider getter, Supplier... items) { - Identifier id = new Identifier(ComputerCraft.MOD_ID, name); - for (Supplier item : items) { - ModelPredicateProviderRegistrySpecificAccessor.callRegister(item.get(), id, getter); + private static void registerItemProperty( String name, ModelPredicateProvider getter, Supplier... items ) + { + Identifier id = new Identifier( ComputerCraft.MOD_ID, name ); + for( Supplier item : items ) + { + ModelPredicateProviderRegistrySpecificAccessor.callRegister( item.get(), id, getter ); } } } diff --git a/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java b/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java index 032393650..1c1190d1f 100644 --- a/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java @@ -10,7 +10,8 @@ import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.peripheral.modem.wired.BlockCable; import dan200.computercraft.shared.peripheral.modem.wired.CableShapes; import dan200.computercraft.shared.util.WorldUtil; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; @@ -23,48 +24,49 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment (EnvType.CLIENT) -public final class CableHighlightRenderer { - private CableHighlightRenderer() { +@Environment( EnvType.CLIENT ) +public final class CableHighlightRenderer +{ + private CableHighlightRenderer() + { } /** * Draw an outline for a specific part of a cable "Multipart". */ - public static boolean drawHighlight(MatrixStack stack, VertexConsumer consumer, Entity entity, double d, double e, double f, BlockPos pos, - BlockState state) { + public static boolean drawHighlight( MatrixStack stack, VertexConsumer consumer, Entity entity, double d, double e, double f, BlockPos pos, + BlockState state ) + { World world = entity.getEntityWorld(); Camera info = MinecraftClient.getInstance().gameRenderer.getCamera(); // We only care about instances with both cable and modem. - if (state.getBlock() != ComputerCraftRegistry.ModBlocks.CABLE || state.get(BlockCable.MODEM) - .getFacing() == null || !state.get(BlockCable.CABLE)) { + if( state.getBlock() != ComputerCraftRegistry.ModBlocks.CABLE || state.get( BlockCable.MODEM ) + .getFacing() == null || !state.get( BlockCable.CABLE ) ) + { return false; } - VoxelShape shape = WorldUtil.isVecInside(CableShapes.getModemShape(state), - new Vec3d(d, e, f).subtract(pos.getX(), - pos.getY(), - pos.getZ())) ? CableShapes.getModemShape(state) : CableShapes.getCableShape( - state); + VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), + new Vec3d( d, e, f ).subtract( pos.getX(), + pos.getY(), + pos.getZ() ) ) ? CableShapes.getModemShape( state ) : CableShapes.getCableShape( + state ); Vec3d cameraPos = info.getPos(); double xOffset = pos.getX() - cameraPos.getX(); double yOffset = pos.getY() - cameraPos.getY(); double zOffset = pos.getZ() - cameraPos.getZ(); Matrix4f matrix4f = stack.peek() - .getModel(); - shape.forEachEdge((x1, y1, z1, x2, y2, z2) -> { - consumer.vertex(matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset)) - .color(0, 0, 0, 0.4f) - .next(); - consumer.vertex(matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset)) - .color(0, 0, 0, 0.4f) - .next(); - }); + .getModel(); + shape.forEachEdge( ( x1, y1, z1, x2, y2, z2 ) -> { + consumer.vertex( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) ) + .color( 0, 0, 0, 0.4f ) + .next(); + consumer.vertex( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) ) + .color( 0, 0, 0, 0.4f ) + .next(); + } ); return true; } diff --git a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java index 8efd22185..d28e67d31 100644 --- a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java @@ -5,25 +5,25 @@ */ package dan200.computercraft.client.render; -import javax.annotation.Nonnull; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ComputerFamily; -import org.lwjgl.opengl.GL11; - import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexFormats; import net.minecraft.util.Identifier; import net.minecraft.util.math.Matrix4f; +import org.lwjgl.opengl.GL11; -public class ComputerBorderRenderer { - public static final Identifier BACKGROUND_NORMAL = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_normal.png"); - public static final Identifier BACKGROUND_ADVANCED = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png"); - public static final Identifier BACKGROUND_COMMAND = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_command.png"); - public static final Identifier BACKGROUND_COLOUR = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_colour.png"); +import javax.annotation.Nonnull; + +public class ComputerBorderRenderer +{ + public static final Identifier BACKGROUND_NORMAL = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_normal.png" ); + public static final Identifier BACKGROUND_ADVANCED = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png" ); + public static final Identifier BACKGROUND_COMMAND = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_command.png" ); + public static final Identifier BACKGROUND_COLOUR = new Identifier( ComputerCraft.MOD_ID, "textures/gui/corners_colour.png" ); /** * The margin between the terminal and its border. */ @@ -44,7 +44,8 @@ public class ComputerBorderRenderer { public static final int LIGHT_HEIGHT = 8; private static final float TEX_SCALE = 1 / 256.0f; - static { + static + { IDENTITY.loadIdentity(); } @@ -53,7 +54,8 @@ public class ComputerBorderRenderer { private final int z; private final float r, g, b; - public ComputerBorderRenderer(Matrix4f transform, VertexConsumer builder, int z, float r, float g, float b) { + public ComputerBorderRenderer( Matrix4f transform, VertexConsumer builder, int z, float r, float g, float b ) + { this.transform = transform; this.builder = builder; this.z = z; @@ -64,34 +66,39 @@ public class ComputerBorderRenderer { @Nonnull - public static Identifier getTexture(@Nonnull ComputerFamily family) { - switch (family) { - case NORMAL: - default: - return BACKGROUND_NORMAL; - case ADVANCED: - return BACKGROUND_ADVANCED; - case COMMAND: - return BACKGROUND_COMMAND; + public static Identifier getTexture( @Nonnull ComputerFamily family ) + { + switch( family ) + { + case NORMAL: + default: + return BACKGROUND_NORMAL; + case ADVANCED: + return BACKGROUND_ADVANCED; + case COMMAND: + return BACKGROUND_COMMAND; } } - public static void render(int x, int y, int z, int width, int height) { + public static void render( int x, int y, int z, int width, int height ) + { Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR_TEXTURE); + buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_COLOR_TEXTURE ); - render(IDENTITY, buffer, x, y, z, width, height); + render( IDENTITY, buffer, x, y, z, width, height ); RenderSystem.enableAlphaTest(); tessellator.draw(); } - public static void render(Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height) { - render(transform, buffer, x, y, z, width, height, 1, 1, 1); + public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height ) + { + render( transform, buffer, x, y, z, width, height, 1, 1, 1 ); } - public static void render(Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height, float r, float g, float b) { + public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height, float r, float g, float b ) + { render( transform, buffer, x, y, z, width, height, false, r, g, b ); } @@ -106,13 +113,13 @@ public class ComputerBorderRenderer { int endY = y + height; // Vertical bars - this.renderLine(x - BORDER, y, 0, CORNER_TOP_Y, BORDER, endY - y); - this.renderLine(endX, y, BORDER_RIGHT_X, CORNER_TOP_Y, BORDER, endY - y); + this.renderLine( x - BORDER, y, 0, CORNER_TOP_Y, BORDER, endY - y ); + this.renderLine( endX, y, BORDER_RIGHT_X, CORNER_TOP_Y, BORDER, endY - y ); // Top bar - this.renderLine(x, y - BORDER, 0, 0, endX - x, BORDER); - this.renderCorner(x - BORDER, y - BORDER, CORNER_LEFT_X, CORNER_TOP_Y); - this.renderCorner(endX, y - BORDER, CORNER_RIGHT_X, CORNER_TOP_Y); + this.renderLine( x, y - BORDER, 0, 0, endX - x, BORDER ); + this.renderCorner( x - BORDER, y - BORDER, CORNER_LEFT_X, CORNER_TOP_Y ); + this.renderCorner( endX, y - BORDER, CORNER_RIGHT_X, CORNER_TOP_Y ); // Bottom bar. We allow for drawing a stretched version, which allows for additional elements (such as the // pocket computer's lights). @@ -124,40 +131,44 @@ public class ComputerBorderRenderer { } else { - this.renderLine(x, endY, 0, BORDER, endX - x, BORDER); - this.renderCorner(x - BORDER, endY, CORNER_LEFT_X, CORNER_BOTTOM_Y); - this.renderCorner(endX, endY, CORNER_RIGHT_X, CORNER_BOTTOM_Y); + this.renderLine( x, endY, 0, BORDER, endX - x, BORDER ); + this.renderCorner( x - BORDER, endY, CORNER_LEFT_X, CORNER_BOTTOM_Y ); + this.renderCorner( endX, endY, CORNER_RIGHT_X, CORNER_BOTTOM_Y ); } } - private void renderLine(int x, int y, int u, int v, int width, int height) { - this.renderTexture(x, y, u, v, width, height, BORDER, BORDER); + private void renderLine( int x, int y, int u, int v, int width, int height ) + { + this.renderTexture( x, y, u, v, width, height, BORDER, BORDER ); } - private void renderCorner(int x, int y, int u, int v) { - this.renderTexture(x, y, u, v, BORDER, BORDER, BORDER, BORDER); + private void renderCorner( int x, int y, int u, int v ) + { + this.renderTexture( x, y, u, v, BORDER, BORDER, BORDER, BORDER ); } - private void renderTexture(int x, int y, int u, int v, int width, int height) { - this.renderTexture(x, y, u, v, width, height, width, height); + private void renderTexture( int x, int y, int u, int v, int width, int height ) + { + this.renderTexture( x, y, u, v, width, height, width, height ); } - private void renderTexture(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) { - this.builder.vertex(this.transform, x, y + height, this.z) - .color(this.r, this.g, this.b, 1.0f) - .texture(u * TEX_SCALE, (v + textureHeight) * TEX_SCALE) - .next(); - this.builder.vertex(this.transform, x + width, y + height, this.z) - .color(this.r, this.g, this.b, 1.0f) - .texture((u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE) - .next(); - this.builder.vertex(this.transform, x + width, y, this.z) - .color(this.r, this.g, this.b, 1.0f) - .texture((u + textureWidth) * TEX_SCALE, v * TEX_SCALE) - .next(); - this.builder.vertex(this.transform, x, y, this.z) - .color(this.r, this.g, this.b, 1.0f) - .texture(u * TEX_SCALE, v * TEX_SCALE) - .next(); + private void renderTexture( int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight ) + { + this.builder.vertex( this.transform, x, y + height, this.z ) + .color( this.r, this.g, this.b, 1.0f ) + .texture( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ) + .next(); + this.builder.vertex( this.transform, x + width, y + height, this.z ) + .color( this.r, this.g, this.b, 1.0f ) + .texture( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ) + .next(); + this.builder.vertex( this.transform, x + width, y, this.z ) + .color( this.r, this.g, this.b, 1.0f ) + .texture( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ) + .next(); + this.builder.vertex( this.transform, x, y, this.z ) + .color( this.r, this.g, this.b, 1.0f ) + .texture( u * TEX_SCALE, v * TEX_SCALE ) + .next(); } } diff --git a/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java index 8eb76f6d0..502ebce10 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java @@ -7,7 +7,8 @@ package dan200.computercraft.client.render; import dan200.computercraft.fabric.mixin.HeldItemRendererAccess; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.item.HeldItemRenderer; @@ -19,28 +20,30 @@ import net.minecraft.util.Arm; import net.minecraft.util.Hand; import net.minecraft.util.math.MathHelper; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment (EnvType.CLIENT) -public abstract class ItemMapLikeRenderer { - public void renderItemFirstPerson(MatrixStack transform, VertexConsumerProvider render, int lightTexture, Hand hand, float pitch, float equipProgress - , float swingProgress, ItemStack stack) { +@Environment( EnvType.CLIENT ) +public abstract class ItemMapLikeRenderer +{ + public void renderItemFirstPerson( MatrixStack transform, VertexConsumerProvider render, int lightTexture, Hand hand, float pitch, float equipProgress + , float swingProgress, ItemStack stack ) + { PlayerEntity player = MinecraftClient.getInstance().player; transform.push(); - if (hand == Hand.MAIN_HAND && player.getOffHandStack() - .isEmpty()) { - this.renderItemFirstPersonCenter(transform, render, lightTexture, pitch, equipProgress, swingProgress, stack); - } else { - this.renderItemFirstPersonSide(transform, - render, - lightTexture, - hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm() - .getOpposite(), - equipProgress, - swingProgress, - stack); + if( hand == Hand.MAIN_HAND && player.getOffHandStack() + .isEmpty() ) + { + this.renderItemFirstPersonCenter( transform, render, lightTexture, pitch, equipProgress, swingProgress, stack ); + } + else + { + this.renderItemFirstPersonSide( transform, + render, + lightTexture, + hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm() + .getOpposite(), + equipProgress, + swingProgress, + stack ); } transform.pop(); } @@ -48,85 +51,89 @@ public abstract class ItemMapLikeRenderer { /** * Render an item in the middle of the screen. * - * @param transform The matrix transformation stack - * @param render The buffer to render to + * @param transform The matrix transformation stack + * @param render The buffer to render to * @param combinedLight The current light level - * @param pitch The pitch of the player + * @param pitch The pitch of the player * @param equipProgress The equip progress of this item * @param swingProgress The swing progress of this item - * @param stack The stack to render + * @param stack The stack to render */ - private void renderItemFirstPersonCenter(MatrixStack transform, VertexConsumerProvider render, int combinedLight, float pitch, float equipProgress, - float swingProgress, ItemStack stack) { + private void renderItemFirstPersonCenter( MatrixStack transform, VertexConsumerProvider render, int combinedLight, float pitch, float equipProgress, + float swingProgress, ItemStack stack ) + { MinecraftClient minecraft = MinecraftClient.getInstance(); HeldItemRenderer renderer = minecraft.getHeldItemRenderer(); // Setup the appropriate transformations. This is just copied from the // corresponding method in ItemRenderer. - float swingRt = MathHelper.sqrt(swingProgress); - float tX = -0.2f * MathHelper.sin(swingProgress * (float) Math.PI); - float tZ = -0.4f * MathHelper.sin(swingRt * (float) Math.PI); - transform.translate(0, -tX / 2, tZ); + float swingRt = MathHelper.sqrt( swingProgress ); + float tX = -0.2f * MathHelper.sin( swingProgress * (float) Math.PI ); + float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI ); + transform.translate( 0, -tX / 2, tZ ); HeldItemRendererAccess access = (HeldItemRendererAccess) renderer; - float pitchAngle = access.callGetMapAngle(pitch); - transform.translate(0, 0.04F + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f); - transform.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(pitchAngle * -85.0f)); - if (!minecraft.player.isInvisible()) { + float pitchAngle = access.callGetMapAngle( pitch ); + transform.translate( 0, 0.04F + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f ); + transform.multiply( Vector3f.POSITIVE_X.getDegreesQuaternion( pitchAngle * -85.0f ) ); + if( !minecraft.player.isInvisible() ) + { transform.push(); - transform.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90.0F)); - access.callRenderArm(transform, render, combinedLight, Arm.RIGHT); - access.callRenderArm(transform, render, combinedLight, Arm.LEFT); + transform.multiply( Vector3f.POSITIVE_Y.getDegreesQuaternion( 90.0F ) ); + access.callRenderArm( transform, render, combinedLight, Arm.RIGHT ); + access.callRenderArm( transform, render, combinedLight, Arm.LEFT ); transform.pop(); } - float rX = MathHelper.sin(swingRt * (float) Math.PI); - transform.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(rX * 20.0F)); - transform.scale(2.0F, 2.0F, 2.0F); + float rX = MathHelper.sin( swingRt * (float) Math.PI ); + transform.multiply( Vector3f.POSITIVE_X.getDegreesQuaternion( rX * 20.0F ) ); + transform.scale( 2.0F, 2.0F, 2.0F ); - this.renderItem(transform, render, stack); + this.renderItem( transform, render, stack ); } /** * Renders the item to one side of the player. * - * @param transform The matrix transformation stack - * @param render The buffer to render to + * @param transform The matrix transformation stack + * @param render The buffer to render to * @param combinedLight The current light level - * @param side The side to render on + * @param side The side to render on * @param equipProgress The equip progress of this item * @param swingProgress The swing progress of this item - * @param stack The stack to render + * @param stack The stack to render */ - private void renderItemFirstPersonSide(MatrixStack transform, VertexConsumerProvider render, int combinedLight, Arm side, float equipProgress, - float swingProgress, ItemStack stack) { + private void renderItemFirstPersonSide( MatrixStack transform, VertexConsumerProvider render, int combinedLight, Arm side, float equipProgress, + float swingProgress, ItemStack stack ) + { MinecraftClient minecraft = MinecraftClient.getInstance(); float offset = side == Arm.RIGHT ? 1f : -1f; - transform.translate(offset * 0.125f, -0.125f, 0f); + transform.translate( offset * 0.125f, -0.125f, 0f ); // If the player is not invisible then render a single arm - if (!minecraft.player.isInvisible()) { + if( !minecraft.player.isInvisible() ) + { transform.push(); - transform.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(offset * 10f)); - ((HeldItemRendererAccess)minecraft.getHeldItemRenderer()) - .callRenderArmHoldingItem(transform, render, combinedLight, equipProgress, swingProgress, side); + transform.multiply( Vector3f.POSITIVE_Z.getDegreesQuaternion( offset * 10f ) ); + ((HeldItemRendererAccess) minecraft.getHeldItemRenderer()) + .callRenderArmHoldingItem( transform, render, combinedLight, equipProgress, swingProgress, side ); transform.pop(); } // Setup the appropriate transformations. This is just copied from the // corresponding method in ItemRenderer. transform.push(); - transform.translate(offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f); - float f1 = MathHelper.sqrt(swingProgress); - float f2 = MathHelper.sin(f1 * (float) Math.PI); + transform.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f ); + float f1 = MathHelper.sqrt( swingProgress ); + float f2 = MathHelper.sin( f1 * (float) Math.PI ); float f3 = -0.5f * f2; - float f4 = 0.4f * MathHelper.sin(f1 * ((float) Math.PI * 2f)); - float f5 = -0.3f * MathHelper.sin(swingProgress * (float) Math.PI); - transform.translate(offset * f3, f4 - 0.3f * f2, f5); - transform.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(f2 * -45f)); - transform.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(offset * f2 * -30f)); + float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) ); + float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI ); + transform.translate( offset * f3, f4 - 0.3f * f2, f5 ); + transform.multiply( Vector3f.POSITIVE_X.getDegreesQuaternion( f2 * -45f ) ); + transform.multiply( Vector3f.POSITIVE_Y.getDegreesQuaternion( offset * f2 * -30f ) ); - this.renderItem(transform, render, stack); + this.renderItem( transform, render, stack ); transform.pop(); } @@ -135,8 +142,8 @@ public abstract class ItemMapLikeRenderer { * The main rendering method for the item. * * @param transform The matrix transformation stack - * @param render The buffer to render to - * @param stack The stack to render + * @param render The buffer to render to + * @param stack The stack to render */ - protected abstract void renderItem(MatrixStack transform, VertexConsumerProvider render, ItemStack stack); + protected abstract void renderItem( MatrixStack transform, VertexConsumerProvider render, ItemStack stack ); } diff --git a/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java index e0849849f..e073820cb 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java @@ -6,12 +6,6 @@ package dan200.computercraft.client.render; -import static dan200.computercraft.client.render.ComputerBorderRenderer.*; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; -import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER; -import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN; - import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.FixedWidthFontRenderer; @@ -20,8 +14,6 @@ import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.util.Colour; -import org.lwjgl.opengl.GL11; - import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; @@ -31,28 +23,37 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.Vector3f; import net.minecraft.item.ItemStack; import net.minecraft.util.math.Matrix4f; +import org.lwjgl.opengl.GL11; +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; import static dan200.computercraft.client.render.ComputerBorderRenderer.*; /** * Emulates map rendering for pocket computers. */ -public final class ItemPocketRenderer extends ItemMapLikeRenderer { +public final class ItemPocketRenderer extends ItemMapLikeRenderer +{ public static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer(); - private ItemPocketRenderer() { + private ItemPocketRenderer() + { } @Override - protected void renderItem(MatrixStack transform, VertexConsumerProvider render, ItemStack stack) { - ClientComputer computer = ItemPocketComputer.createClientComputer(stack); + protected void renderItem( MatrixStack transform, VertexConsumerProvider render, ItemStack stack ) + { + ClientComputer computer = ItemPocketComputer.createClientComputer( stack ); Terminal terminal = computer == null ? null : computer.getTerminal(); int termWidth, termHeight; - if (terminal == null) { + if( terminal == null ) + { termWidth = ComputerCraft.pocketTermWidth; termHeight = ComputerCraft.pocketTermHeight; - } else { + } + else + { termWidth = terminal.getWidth(); termHeight = terminal.getHeight(); } @@ -63,44 +64,49 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer { // Setup various transformations. Note that these are partially adapted from the corresponding method // in ItemRenderer transform.push(); - transform.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(180f)); - transform.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(180f)); - transform.scale(0.5f, 0.5f, 0.5f); + transform.multiply( Vector3f.POSITIVE_Y.getDegreesQuaternion( 180f ) ); + transform.multiply( Vector3f.POSITIVE_Z.getDegreesQuaternion( 180f ) ); + transform.scale( 0.5f, 0.5f, 0.5f ); - float scale = 0.75f / Math.max(width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT); - transform.scale(scale, scale, 0); - transform.translate(-0.5 * width, -0.5 * height, 0); + float scale = 0.75f / Math.max( width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT ); + transform.scale( scale, scale, 0 ); + transform.translate( -0.5 * width, -0.5 * height, 0 ); // Render the main frame ItemPocketComputer item = (ItemPocketComputer) stack.getItem(); ComputerFamily family = item.getFamily(); - int frameColour = item.getColour(stack); + int frameColour = item.getColour( stack ); Matrix4f matrix = transform.peek() - .getModel(); - renderFrame(matrix, family, frameColour, width, height); + .getModel(); + renderFrame( matrix, family, frameColour, width, height ); // Render the light - int lightColour = ItemPocketComputer.getLightState(stack); - if (lightColour == -1) { + int lightColour = ItemPocketComputer.getLightState( stack ); + if( lightColour == -1 ) + { lightColour = Colour.BLACK.getHex(); } - renderLight(matrix, lightColour, width, height); + renderLight( matrix, lightColour, width, height ); - if (computer != null && terminal != null) { - FixedWidthFontRenderer.drawTerminal(matrix, MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN); - } else { - FixedWidthFontRenderer.drawEmptyTerminal(matrix, 0, 0, width, height); + if( computer != null && terminal != null ) + { + FixedWidthFontRenderer.drawTerminal( matrix, MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN ); + } + else + { + FixedWidthFontRenderer.drawEmptyTerminal( matrix, 0, 0, width, height ); } transform.pop(); } - private static void renderFrame(Matrix4f transform, ComputerFamily family, int colour, int width, int height) { + private static void renderFrame( Matrix4f transform, ComputerFamily family, int colour, int width, int height ) + { RenderSystem.enableBlend(); MinecraftClient.getInstance() - .getTextureManager() - .bindTexture(colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture(family)); + .getTextureManager() + .bindTexture( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) ); float r = ((colour >>> 16) & 0xFF) / 255.0f; float g = ((colour >>> 8) & 0xFF) / 255.0f; @@ -108,14 +114,15 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer { Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR_TEXTURE); + buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_COLOR_TEXTURE ); - ComputerBorderRenderer.render(transform, buffer, 0, 0, 0, width, height, true, r, g, b); + ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, width, height, true, r, g, b ); tessellator.draw(); } - private static void renderLight(Matrix4f transform, int colour, int width, int height) { + private static void renderLight( Matrix4f transform, int colour, int width, int height ) + { RenderSystem.disableTexture(); float r = ((colour >>> 16) & 0xFF) / 255.0f; @@ -124,19 +131,19 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer { Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR); - buffer.vertex(transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, 0) - .color(r, g, b, 1.0f) - .next(); - buffer.vertex(transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, 0) - .color(r, g, b, 1.0f) - .next(); - buffer.vertex(transform, width, height + BORDER / 2.0f, 0) - .color(r, g, b, 1.0f) - .next(); - buffer.vertex(transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0) - .color(r, g, b, 1.0f) - .next(); + buffer.begin( GL11.GL_QUADS, VertexFormats.POSITION_COLOR ); + buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ) + .color( r, g, b, 1.0f ) + .next(); + buffer.vertex( transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ) + .color( r, g, b, 1.0f ) + .next(); + buffer.vertex( transform, width, height + BORDER / 2.0f, 0 ) + .color( r, g, b, 1.0f ) + .next(); + buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0 ) + .color( r, g, b, 1.0f ) + .next(); tessellator.draw(); RenderSystem.enableTexture(); diff --git a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java index dd54cae61..5878c61d3 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java @@ -6,88 +6,90 @@ package dan200.computercraft.client.render; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; -import static dan200.computercraft.client.render.PrintoutRenderer.COVER_SIZE; -import static dan200.computercraft.client.render.PrintoutRenderer.X_TEXT_MARGIN; -import static dan200.computercraft.client.render.PrintoutRenderer.Y_TEXT_MARGIN; -import static dan200.computercraft.client.render.PrintoutRenderer.drawBorder; -import static dan200.computercraft.client.render.PrintoutRenderer.drawText; -import static dan200.computercraft.client.render.PrintoutRenderer.offsetAt; -import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; -import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH; - import dan200.computercraft.shared.media.items.ItemPrintout; - import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.Vector3f; import net.minecraft.item.ItemStack; import net.minecraft.util.math.Matrix4f; +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; +import static dan200.computercraft.client.render.PrintoutRenderer.*; +import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; +import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH; + /** * Emulates map and item-frame rendering for printouts. */ -public final class ItemPrintoutRenderer extends ItemMapLikeRenderer { +public final class ItemPrintoutRenderer extends ItemMapLikeRenderer +{ public static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer(); - private ItemPrintoutRenderer() { + private ItemPrintoutRenderer() + { } @Override - protected void renderItem(MatrixStack transform, VertexConsumerProvider render, ItemStack stack) { - transform.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(180f)); - transform.scale(0.42f, 0.42f, -0.42f); - transform.translate(-0.5f, -0.48f, 0.0f); + protected void renderItem( MatrixStack transform, VertexConsumerProvider render, ItemStack stack ) + { + transform.multiply( Vector3f.POSITIVE_X.getDegreesQuaternion( 180f ) ); + transform.scale( 0.42f, 0.42f, -0.42f ); + transform.translate( -0.5f, -0.48f, 0.0f ); - drawPrintout(transform, render, stack); + drawPrintout( transform, render, stack ); } - private static void drawPrintout(MatrixStack transform, VertexConsumerProvider render, ItemStack stack) { - int pages = ItemPrintout.getPageCount(stack); + private static void drawPrintout( MatrixStack transform, VertexConsumerProvider render, ItemStack stack ) + { + int pages = ItemPrintout.getPageCount( stack ); boolean book = ((ItemPrintout) stack.getItem()).getType() == ItemPrintout.Type.BOOK; double width = LINE_MAX_LENGTH * FONT_WIDTH + X_TEXT_MARGIN * 2; double height = LINES_PER_PAGE * FONT_HEIGHT + Y_TEXT_MARGIN * 2; // Non-books will be left aligned - if (!book) { - width += offsetAt(pages); + if( !book ) + { + width += offsetAt( pages ); } double visualWidth = width, visualHeight = height; // Meanwhile books will be centred - if (book) { - visualWidth += 2 * COVER_SIZE + 2 * offsetAt(pages); + if( book ) + { + visualWidth += 2 * COVER_SIZE + 2 * offsetAt( pages ); visualHeight += 2 * COVER_SIZE; } - double max = Math.max(visualHeight, visualWidth); + double max = Math.max( visualHeight, visualWidth ); // Scale the printout to fit correctly. float scale = (float) (1.0 / max); - transform.scale(scale, scale, scale); - transform.translate((max - width) / 2.0, (max - height) / 2.0, 0.0); + transform.scale( scale, scale, scale ); + transform.translate( (max - width) / 2.0, (max - height) / 2.0, 0.0 ); Matrix4f matrix = transform.peek() - .getModel(); - drawBorder(matrix, render, 0, 0, -0.01f, 0, pages, book); - drawText(matrix, render, X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText(stack), ItemPrintout.getColours(stack)); + .getModel(); + drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book ); + drawText( matrix, render, X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) ); } - public boolean renderInFrame(MatrixStack matrixStack, VertexConsumerProvider consumerProvider, ItemStack stack) { - if (!(stack.getItem() instanceof ItemPrintout)) { + public boolean renderInFrame( MatrixStack matrixStack, VertexConsumerProvider consumerProvider, ItemStack stack ) + { + if( !(stack.getItem() instanceof ItemPrintout) ) + { return false; } // Move a little bit forward to ensure we're not clipping with the frame - matrixStack.translate(0.0f, 0.0f, -0.001f); - matrixStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(180f)); - matrixStack.scale(0.95f, 0.95f, -0.95f); - matrixStack.translate(-0.5f, -0.5f, 0.0f); + matrixStack.translate( 0.0f, 0.0f, -0.001f ); + matrixStack.multiply( Vector3f.POSITIVE_Z.getDegreesQuaternion( 180f ) ); + matrixStack.scale( 0.95f, 0.95f, -0.95f ); + matrixStack.translate( -0.5f, -0.5f, 0.0f ); - drawPrintout(matrixStack, consumerProvider, stack); + drawPrintout( matrixStack, consumerProvider, stack ); return true; } diff --git a/src/main/java/dan200/computercraft/client/render/ModelTransformer.java b/src/main/java/dan200/computercraft/client/render/ModelTransformer.java index 4dbe7460c..234969e7f 100644 --- a/src/main/java/dan200/computercraft/client/render/ModelTransformer.java +++ b/src/main/java/dan200/computercraft/client/render/ModelTransformer.java @@ -5,10 +5,9 @@ */ package dan200.computercraft.client.render; -import java.util.List; - import dan200.computercraft.fabric.mixin.BakedQuadAccess; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormatElement; import net.minecraft.client.render.VertexFormats; @@ -16,61 +15,71 @@ import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.util.math.Vector4f; import net.minecraft.util.math.Matrix4f; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import java.util.List; /** * Transforms vertices of a model, remaining aware of winding order, and rearranging vertices if needed. */ -@Environment (EnvType.CLIENT) -public final class ModelTransformer { +@Environment( EnvType.CLIENT ) +public final class ModelTransformer +{ private static final Matrix4f identity; - static { + static + { identity = new Matrix4f(); identity.loadIdentity(); } - private ModelTransformer() { + private ModelTransformer() + { } - public static void transformQuadsTo(List output, List input, Matrix4f transform) { - transformQuadsTo(VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, output, input, transform); + public static void transformQuadsTo( List output, List input, Matrix4f transform ) + { + transformQuadsTo( VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, output, input, transform ); } - public static void transformQuadsTo(VertexFormat format, List output, List input, Matrix4f transform) { - if (transform == null || transform.equals(identity)) { - output.addAll(input); - } else { - for (BakedQuad quad : input) { - output.add(doTransformQuad(format, quad, transform)); + public static void transformQuadsTo( VertexFormat format, List output, List input, Matrix4f transform ) + { + if( transform == null || transform.equals( identity ) ) + { + output.addAll( input ); + } + else + { + for( BakedQuad quad : input ) + { + output.add( doTransformQuad( format, quad, transform ) ); } } } - private static BakedQuad doTransformQuad(VertexFormat format, BakedQuad quad, Matrix4f transform) { + private static BakedQuad doTransformQuad( VertexFormat format, BakedQuad quad, Matrix4f transform ) + { int[] vertexData = quad.getVertexData().clone(); - BakedQuad copy = new BakedQuad(vertexData, -1, quad.getFace(), ((BakedQuadAccess)quad).getSprite(), true); + BakedQuad copy = new BakedQuad( vertexData, -1, quad.getFace(), ((BakedQuadAccess) quad).getSprite(), true ); int offsetBytes = 0; - for (int v = 0; v < 4; ++v) { - for (VertexFormatElement element : format.getElements()) // For each vertex element + for( int v = 0; v < 4; ++v ) + { + for( VertexFormatElement element : format.getElements() ) // For each vertex element { int start = offsetBytes / Integer.BYTES; - if (element.getType() == VertexFormatElement.Type.POSITION && element.getFormat() == VertexFormatElement.Format.FLOAT) // When we find a position element + if( element.getType() == VertexFormatElement.Type.POSITION && element.getFormat() == VertexFormatElement.Format.FLOAT ) // When we find a position element { - Vector4f pos = new Vector4f(Float.intBitsToFloat(vertexData[start]), - Float.intBitsToFloat(vertexData[start+1]), - Float.intBitsToFloat(vertexData[start+2]), - 1); + Vector4f pos = new Vector4f( Float.intBitsToFloat( vertexData[start] ), + Float.intBitsToFloat( vertexData[start + 1] ), + Float.intBitsToFloat( vertexData[start + 2] ), + 1 ); // Transform the position - pos.transform(transform); + pos.transform( transform ); // Insert the position - vertexData[start] = Float.floatToRawIntBits(pos.getX()); - vertexData[start+1] = Float.floatToRawIntBits(pos.getY()); - vertexData[start+2] = Float.floatToRawIntBits(pos.getZ()); + vertexData[start] = Float.floatToRawIntBits( pos.getX() ); + vertexData[start + 1] = Float.floatToRawIntBits( pos.getY() ); + vertexData[start + 2] = Float.floatToRawIntBits( pos.getZ() ); } offsetBytes += element.getSize(); } @@ -78,10 +87,12 @@ public final class ModelTransformer { return copy; } - public static BakedQuad transformQuad(VertexFormat format, BakedQuad input, Matrix4f transform) { - if (transform == null || transform.equals(identity)) { + public static BakedQuad transformQuad( VertexFormat format, BakedQuad input, Matrix4f transform ) + { + if( transform == null || transform.equals( identity ) ) + { return input; } - return doTransformQuad(format, input, transform); + return doTransformQuad( format, input, transform ); } } diff --git a/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java b/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java index 37cf73145..2a5d0e570 100644 --- a/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java @@ -6,17 +6,9 @@ package dan200.computercraft.client.render; -import static net.minecraft.util.math.Direction.DOWN; -import static net.minecraft.util.math.Direction.EAST; -import static net.minecraft.util.math.Direction.NORTH; -import static net.minecraft.util.math.Direction.SOUTH; -import static net.minecraft.util.math.Direction.UP; -import static net.minecraft.util.math.Direction.WEST; - -import java.util.EnumSet; - import dan200.computercraft.shared.peripheral.monitor.TileMonitor; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.client.MinecraftClient; @@ -29,96 +21,118 @@ import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import java.util.EnumSet; + +import static net.minecraft.util.math.Direction.*; /** * Overrides monitor highlighting to only render the outline of the whole monitor, rather than the current block. This means you do not get an * intrusive outline on top of the screen. */ -@Environment (EnvType.CLIENT) -public final class MonitorHighlightRenderer { - private MonitorHighlightRenderer() { +@Environment( EnvType.CLIENT ) +public final class MonitorHighlightRenderer +{ + private MonitorHighlightRenderer() + { } - public static boolean drawHighlight(MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double d, double e, double f, BlockPos pos - , BlockState blockState) { + public static boolean drawHighlight( MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double d, double e, double f, BlockPos pos + , BlockState blockState ) + { // Preserve normal behaviour when crouching. - if (entity.isInSneakingPose()) { + if( entity.isInSneakingPose() ) + { return false; } World world = entity.getEntityWorld(); - BlockEntity tile = world.getBlockEntity(pos); - if (!(tile instanceof TileMonitor)) { + BlockEntity tile = world.getBlockEntity( pos ); + if( !(tile instanceof TileMonitor) ) + { return false; } TileMonitor monitor = (TileMonitor) tile; // Determine which sides are part of the external faces of the monitor, and so which need to be rendered. - EnumSet faces = EnumSet.allOf(Direction.class); + EnumSet faces = EnumSet.allOf( Direction.class ); Direction front = monitor.getFront(); - faces.remove(front); - if (monitor.getXIndex() != 0) { - faces.remove(monitor.getRight() - .getOpposite()); + faces.remove( front ); + if( monitor.getXIndex() != 0 ) + { + faces.remove( monitor.getRight() + .getOpposite() ); } - if (monitor.getXIndex() != monitor.getWidth() - 1) { - faces.remove(monitor.getRight()); + if( monitor.getXIndex() != monitor.getWidth() - 1 ) + { + faces.remove( monitor.getRight() ); } - if (monitor.getYIndex() != 0) { - faces.remove(monitor.getDown() - .getOpposite()); + if( monitor.getYIndex() != 0 ) + { + faces.remove( monitor.getDown() + .getOpposite() ); } - if (monitor.getYIndex() != monitor.getHeight() - 1) { - faces.remove(monitor.getDown()); + if( monitor.getYIndex() != monitor.getHeight() - 1 ) + { + faces.remove( monitor.getDown() ); } Vec3d cameraPos = MinecraftClient.getInstance().gameRenderer.getCamera() - .getPos(); + .getPos(); matrixStack.push(); - matrixStack.translate(pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ()); + matrixStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() ); // I wish I could think of a better way to do this Matrix4f transform = matrixStack.peek() - .getModel(); - if (faces.contains(NORTH) || faces.contains(WEST)) { - line(vertexConsumer, transform, 0, 0, 0, UP); + .getModel(); + if( faces.contains( NORTH ) || faces.contains( WEST ) ) + { + line( vertexConsumer, transform, 0, 0, 0, UP ); } - if (faces.contains(SOUTH) || faces.contains(WEST)) { - line(vertexConsumer, transform, 0, 0, 1, UP); + if( faces.contains( SOUTH ) || faces.contains( WEST ) ) + { + line( vertexConsumer, transform, 0, 0, 1, UP ); } - if (faces.contains(NORTH) || faces.contains(EAST)) { - line(vertexConsumer, transform, 1, 0, 0, UP); + if( faces.contains( NORTH ) || faces.contains( EAST ) ) + { + line( vertexConsumer, transform, 1, 0, 0, UP ); } - if (faces.contains(SOUTH) || faces.contains(EAST)) { - line(vertexConsumer, transform, 1, 0, 1, UP); + if( faces.contains( SOUTH ) || faces.contains( EAST ) ) + { + line( vertexConsumer, transform, 1, 0, 1, UP ); } - if (faces.contains(NORTH) || faces.contains(DOWN)) { - line(vertexConsumer, transform, 0, 0, 0, EAST); + if( faces.contains( NORTH ) || faces.contains( DOWN ) ) + { + line( vertexConsumer, transform, 0, 0, 0, EAST ); } - if (faces.contains(SOUTH) || faces.contains(DOWN)) { - line(vertexConsumer, transform, 0, 0, 1, EAST); + if( faces.contains( SOUTH ) || faces.contains( DOWN ) ) + { + line( vertexConsumer, transform, 0, 0, 1, EAST ); } - if (faces.contains(NORTH) || faces.contains(UP)) { - line(vertexConsumer, transform, 0, 1, 0, EAST); + if( faces.contains( NORTH ) || faces.contains( UP ) ) + { + line( vertexConsumer, transform, 0, 1, 0, EAST ); } - if (faces.contains(SOUTH) || faces.contains(UP)) { - line(vertexConsumer, transform, 0, 1, 1, EAST); + if( faces.contains( SOUTH ) || faces.contains( UP ) ) + { + line( vertexConsumer, transform, 0, 1, 1, EAST ); } - if (faces.contains(WEST) || faces.contains(DOWN)) { - line(vertexConsumer, transform, 0, 0, 0, SOUTH); + if( faces.contains( WEST ) || faces.contains( DOWN ) ) + { + line( vertexConsumer, transform, 0, 0, 0, SOUTH ); } - if (faces.contains(EAST) || faces.contains(DOWN)) { - line(vertexConsumer, transform, 1, 0, 0, SOUTH); + if( faces.contains( EAST ) || faces.contains( DOWN ) ) + { + line( vertexConsumer, transform, 1, 0, 0, SOUTH ); } - if (faces.contains(WEST) || faces.contains(UP)) { - line(vertexConsumer, transform, 0, 1, 0, SOUTH); + if( faces.contains( WEST ) || faces.contains( UP ) ) + { + line( vertexConsumer, transform, 0, 1, 0, SOUTH ); } - if (faces.contains(EAST) || faces.contains(UP)) { - line(vertexConsumer, transform, 1, 1, 0, SOUTH); + if( faces.contains( EAST ) || faces.contains( UP ) ) + { + line( vertexConsumer, transform, 1, 1, 0, SOUTH ); } matrixStack.pop(); @@ -126,12 +140,13 @@ public final class MonitorHighlightRenderer { return true; } - private static void line(VertexConsumer buffer, Matrix4f transform, float x, float y, float z, Direction direction) { - buffer.vertex(transform, x, y, z) - .color(0, 0, 0, 0.4f) - .next(); - buffer.vertex(transform, x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ()) - .color(0, 0, 0, 0.4f) - .next(); + private static void line( VertexConsumer buffer, Matrix4f transform, float x, float y, float z, Direction direction ) + { + buffer.vertex( transform, x, y, z ) + .color( 0, 0, 0, 0.4f ) + .next(); + buffer.vertex( transform, x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ() ) + .color( 0, 0, 0, 0.4f ) + .next(); } } diff --git a/src/main/java/dan200/computercraft/client/render/MonitorTextureBufferShader.java b/src/main/java/dan200/computercraft/client/render/MonitorTextureBufferShader.java index 485d307cd..2fc785d17 100644 --- a/src/main/java/dan200/computercraft/client/render/MonitorTextureBufferShader.java +++ b/src/main/java/dan200/computercraft/client/render/MonitorTextureBufferShader.java @@ -5,27 +5,27 @@ */ package dan200.computercraft.client.render; -import java.io.InputStream; -import java.nio.FloatBuffer; - import com.google.common.base.Strings; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.shared.util.Palette; +import net.minecraft.client.texture.TextureUtil; +import net.minecraft.util.math.Matrix4f; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL20; -import net.minecraft.client.texture.TextureUtil; -import net.minecraft.util.math.Matrix4f; +import java.io.InputStream; +import java.nio.FloatBuffer; -class MonitorTextureBufferShader { +class MonitorTextureBufferShader +{ static final int TEXTURE_INDEX = GL13.GL_TEXTURE3; - private static final FloatBuffer MATRIX_BUFFER = BufferUtils.createFloatBuffer(16); - private static final FloatBuffer PALETTE_BUFFER = BufferUtils.createFloatBuffer(16 * 3); + private static final FloatBuffer MATRIX_BUFFER = BufferUtils.createFloatBuffer( 16 ); + private static final FloatBuffer PALETTE_BUFFER = BufferUtils.createFloatBuffer( 16 * 3 ); private static int uniformMv; @@ -39,124 +39,145 @@ class MonitorTextureBufferShader { private static boolean ok; private static int program; - static void setupUniform(Matrix4f transform, int width, int height, Palette palette, boolean greyscale) { + static void setupUniform( Matrix4f transform, int width, int height, Palette palette, boolean greyscale ) + { MATRIX_BUFFER.rewind(); - transform.writeToBuffer(MATRIX_BUFFER); + transform.writeToBuffer( MATRIX_BUFFER ); MATRIX_BUFFER.rewind(); - RenderSystem.glUniformMatrix4(uniformMv, false, MATRIX_BUFFER); + RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER ); - RenderSystem.glUniform1i(uniformWidth, width); - RenderSystem.glUniform1i(uniformHeight, height); + RenderSystem.glUniform1i( uniformWidth, width ); + RenderSystem.glUniform1i( uniformHeight, height ); PALETTE_BUFFER.rewind(); - for (int i = 0; i < 16; i++) { - double[] colour = palette.getColour(i); - if (greyscale) { - float f = FixedWidthFontRenderer.toGreyscale(colour); - PALETTE_BUFFER.put(f) - .put(f) - .put(f); - } else { - PALETTE_BUFFER.put((float) colour[0]) - .put((float) colour[1]) - .put((float) colour[2]); + for( int i = 0; i < 16; i++ ) + { + double[] colour = palette.getColour( i ); + if( greyscale ) + { + float f = FixedWidthFontRenderer.toGreyscale( colour ); + PALETTE_BUFFER.put( f ) + .put( f ) + .put( f ); + } + else + { + PALETTE_BUFFER.put( (float) colour[0] ) + .put( (float) colour[1] ) + .put( (float) colour[2] ); } } PALETTE_BUFFER.flip(); - RenderSystem.glUniform3(uniformPalette, PALETTE_BUFFER); + RenderSystem.glUniform3( uniformPalette, PALETTE_BUFFER ); } - static boolean use() { - if (initialised) { - if (ok) { - GlStateManager.useProgram(program); + static boolean use() + { + if( initialised ) + { + if( ok ) + { + GlStateManager.useProgram( program ); } return ok; } - if (ok = load()) { - GL20.glUseProgram(program); - RenderSystem.glUniform1i(uniformFont, 0); - RenderSystem.glUniform1i(uniformTbo, TEXTURE_INDEX - GL13.GL_TEXTURE0); + if( ok = load() ) + { + GL20.glUseProgram( program ); + RenderSystem.glUniform1i( uniformFont, 0 ); + RenderSystem.glUniform1i( uniformTbo, TEXTURE_INDEX - GL13.GL_TEXTURE0 ); } return ok; } - private static boolean load() { + private static boolean load() + { initialised = true; - try { - int vertexShader = loadShader(GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert"); - int fragmentShader = loadShader(GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag"); + try + { + int vertexShader = loadShader( GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert" ); + int fragmentShader = loadShader( GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag" ); program = GlStateManager.createProgram(); - GlStateManager.attachShader(program, vertexShader); - GlStateManager.attachShader(program, fragmentShader); - GL20.glBindAttribLocation(program, 0, "v_pos"); + GlStateManager.attachShader( program, vertexShader ); + GlStateManager.attachShader( program, fragmentShader ); + GL20.glBindAttribLocation( program, 0, "v_pos" ); - GlStateManager.linkProgram(program); - boolean ok = GlStateManager.getProgram(program, GL20.GL_LINK_STATUS) != 0; - String log = GlStateManager.getProgramInfoLog(program, Short.MAX_VALUE) - .trim(); - if (!Strings.isNullOrEmpty(log)) { - ComputerCraft.log.warn("Problems when linking monitor shader: {}", log); + GlStateManager.linkProgram( program ); + boolean ok = GlStateManager.getProgram( program, GL20.GL_LINK_STATUS ) != 0; + String log = GlStateManager.getProgramInfoLog( program, Short.MAX_VALUE ) + .trim(); + if( !Strings.isNullOrEmpty( log ) ) + { + ComputerCraft.log.warn( "Problems when linking monitor shader: {}", log ); } - GL20.glDetachShader(program, vertexShader); - GL20.glDetachShader(program, fragmentShader); - GlStateManager.deleteShader(vertexShader); - GlStateManager.deleteShader(fragmentShader); + GL20.glDetachShader( program, vertexShader ); + GL20.glDetachShader( program, fragmentShader ); + GlStateManager.deleteShader( vertexShader ); + GlStateManager.deleteShader( fragmentShader ); - if (!ok) { + if( !ok ) + { return false; } - uniformMv = getUniformLocation(program, "u_mv"); - uniformFont = getUniformLocation(program, "u_font"); - uniformWidth = getUniformLocation(program, "u_width"); - uniformHeight = getUniformLocation(program, "u_height"); - uniformTbo = getUniformLocation(program, "u_tbo"); - uniformPalette = getUniformLocation(program, "u_palette"); + uniformMv = getUniformLocation( program, "u_mv" ); + uniformFont = getUniformLocation( program, "u_font" ); + uniformWidth = getUniformLocation( program, "u_width" ); + uniformHeight = getUniformLocation( program, "u_height" ); + uniformTbo = getUniformLocation( program, "u_tbo" ); + uniformPalette = getUniformLocation( program, "u_palette" ); - ComputerCraft.log.info("Loaded monitor shader."); + ComputerCraft.log.info( "Loaded monitor shader." ); return true; - } catch (Exception e) { - ComputerCraft.log.error("Cannot load monitor shaders", e); + } + catch( Exception e ) + { + ComputerCraft.log.error( "Cannot load monitor shaders", e ); return false; } } - private static int loadShader(int kind, String path) { + private static int loadShader( int kind, String path ) + { InputStream stream = TileEntityMonitorRenderer.class.getClassLoader() - .getResourceAsStream(path); - if (stream == null) { - throw new IllegalArgumentException("Cannot find " + path); + .getResourceAsStream( path ); + if( stream == null ) + { + throw new IllegalArgumentException( "Cannot find " + path ); } - String contents = TextureUtil.readAllToString(stream); + String contents = TextureUtil.readAllToString( stream ); - int shader = GlStateManager.createShader(kind); + int shader = GlStateManager.createShader( kind ); - GlStateManager.shaderSource(shader, contents); - GlStateManager.compileShader(shader); + GlStateManager.shaderSource( shader, contents ); + GlStateManager.compileShader( shader ); - boolean ok = GlStateManager.getShader(shader, GL20.GL_COMPILE_STATUS) != 0; - String log = GlStateManager.getShaderInfoLog(shader, Short.MAX_VALUE) - .trim(); - if (!Strings.isNullOrEmpty(log)) { - ComputerCraft.log.warn("Problems when loading monitor shader {}: {}", path, log); + boolean ok = GlStateManager.getShader( shader, GL20.GL_COMPILE_STATUS ) != 0; + String log = GlStateManager.getShaderInfoLog( shader, Short.MAX_VALUE ) + .trim(); + if( !Strings.isNullOrEmpty( log ) ) + { + ComputerCraft.log.warn( "Problems when loading monitor shader {}: {}", path, log ); } - if (!ok) { - throw new IllegalStateException("Cannot compile shader " + path); + if( !ok ) + { + throw new IllegalStateException( "Cannot compile shader " + path ); } return shader; } - private static int getUniformLocation(int program, String name) { - int uniform = GlStateManager.getUniformLocation(program, name); - if (uniform == -1) { - throw new IllegalStateException("Cannot find uniform " + name); + private static int getUniformLocation( int program, String name ) + { + int uniform = GlStateManager.getUniformLocation( program, name ); + if( uniform == -1 ) + { + throw new IllegalStateException( "Cannot find uniform " + name ); } return uniform; } diff --git a/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java index 4b09e1106..489506aae 100644 --- a/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java @@ -6,23 +6,19 @@ package dan200.computercraft.client.render; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; -import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; - import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.util.Palette; -import org.lwjgl.opengl.GL11; - -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.render.*; import net.minecraft.util.Identifier; import net.minecraft.util.math.Matrix4f; +import org.lwjgl.opengl.GL11; -public final class PrintoutRenderer { +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; +import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; + +public final class PrintoutRenderer +{ /** * Width of a page. */ @@ -43,7 +39,7 @@ public final class PrintoutRenderer { * Size of the leather cover. */ public static final int COVER_SIZE = 12; - private static final Identifier BG = new Identifier("computercraft", "textures/gui/printout.png"); + private static final Identifier BG = new Identifier( "computercraft", "textures/gui/printout.png" ); private static final float BG_SIZE = 256.0f; /** * Width of the extra page texture. @@ -54,146 +50,160 @@ public final class PrintoutRenderer { private PrintoutRenderer() {} - public static void drawText(Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, TextBuffer[] text, TextBuffer[] colours) { - VertexConsumer buffer = renderer.getBuffer(FixedWidthFontRenderer.TYPE); - for (int line = 0; line < LINES_PER_PAGE && line < text.length; line++) { - FixedWidthFontRenderer.drawString(transform, - buffer, - x, - y + line * FONT_HEIGHT, - text[start + line], - colours[start + line], - null, - Palette.DEFAULT, - false, - 0, - 0); + public static void drawText( Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, TextBuffer[] text, TextBuffer[] colours ) + { + VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE ); + for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ ) + { + FixedWidthFontRenderer.drawString( transform, + buffer, + x, + y + line * FONT_HEIGHT, + text[start + line], + colours[start + line], + null, + Palette.DEFAULT, + false, + 0, + 0 ); } } - public static void drawText(Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, String[] text, String[] colours) { - VertexConsumer buffer = renderer.getBuffer(FixedWidthFontRenderer.TYPE); - for (int line = 0; line < LINES_PER_PAGE && line < text.length; line++) { - FixedWidthFontRenderer.drawString(transform, - buffer, - x, - y + line * FONT_HEIGHT, - new TextBuffer(text[start + line]), - new TextBuffer(colours[start + line]), - null, - Palette.DEFAULT, - false, - 0, - 0); + public static void drawText( Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, String[] text, String[] colours ) + { + VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE ); + for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ ) + { + FixedWidthFontRenderer.drawString( transform, + buffer, + x, + y + line * FONT_HEIGHT, + new TextBuffer( text[start + line] ), + new TextBuffer( colours[start + line] ), + null, + Palette.DEFAULT, + false, + 0, + 0 ); } } - public static void drawBorder(Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float z, int page, int pages, boolean isBook) { + public static void drawBorder( Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float z, int page, int pages, boolean isBook ) + { int leftPages = page; int rightPages = pages - page - 1; - VertexConsumer buffer = renderer.getBuffer(Type.TYPE); + VertexConsumer buffer = renderer.getBuffer( Type.TYPE ); - if (isBook) { + if( isBook ) + { // Border - float offset = offsetAt(pages); + float offset = offsetAt( pages ); float left = x - 4 - offset; float right = x + X_SIZE + offset - 4; // Left and right border - drawTexture(transform, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2); - drawTexture(transform, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2); + drawTexture( transform, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 ); + drawTexture( transform, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 ); // Draw centre panel (just stretched texture, sorry). - drawTexture(transform, - buffer, - x - offset, - y, - z - 0.02f, - X_SIZE + offset * 2, - Y_SIZE, - COVER_X + COVER_SIZE / 2.0f, - COVER_SIZE, - COVER_SIZE, - Y_SIZE); + drawTexture( transform, + buffer, + x - offset, + y, + z - 0.02f, + X_SIZE + offset * 2, + Y_SIZE, + COVER_X + COVER_SIZE / 2.0f, + COVER_SIZE, + COVER_SIZE, + Y_SIZE ); float borderX = left; - while (borderX < right) { - double thisWidth = Math.min(right - borderX, X_SIZE); - drawTexture(transform, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE); - drawTexture(transform, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE); + while( borderX < right ) + { + double thisWidth = Math.min( right - borderX, X_SIZE ); + drawTexture( transform, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE ); + drawTexture( transform, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE ); borderX += thisWidth; } } // Left half - drawTexture(transform, buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2.0f, Y_SIZE); - for (int n = 0; n <= leftPages; n++) { - drawTexture(transform, buffer, x - offsetAt(n), y, z - 1e-3f * n, - // Use the left "bold" fold for the outermost page - n == leftPages ? 0 : X_FOLD_SIZE, 0, X_FOLD_SIZE, Y_SIZE); + drawTexture( transform, buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2.0f, Y_SIZE ); + for( int n = 0; n <= leftPages; n++ ) + { + drawTexture( transform, buffer, x - offsetAt( n ), y, z - 1e-3f * n, + // Use the left "bold" fold for the outermost page + n == leftPages ? 0 : X_FOLD_SIZE, 0, X_FOLD_SIZE, Y_SIZE ); } // Right half - drawTexture(transform, buffer, x + X_SIZE / 2.0f, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2.0f, 0, X_SIZE / 2.0f, Y_SIZE); - for (int n = 0; n <= rightPages; n++) { - drawTexture(transform, buffer, x + (X_SIZE - X_FOLD_SIZE) + offsetAt(n), y, z - 1e-3f * n, - // Two folds, then the main page. Use the right "bold" fold for the outermost page. - X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0, X_FOLD_SIZE, Y_SIZE); + drawTexture( transform, buffer, x + X_SIZE / 2.0f, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2.0f, 0, X_SIZE / 2.0f, Y_SIZE ); + for( int n = 0; n <= rightPages; n++ ) + { + drawTexture( transform, buffer, x + (X_SIZE - X_FOLD_SIZE) + offsetAt( n ), y, z - 1e-3f * n, + // Two folds, then the main page. Use the right "bold" fold for the outermost page. + X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0, X_FOLD_SIZE, Y_SIZE ); } } - public static float offsetAt(int page) { - return (float) (32 * (1 - Math.pow(1.2, -page))); + public static float offsetAt( int page ) + { + return (float) (32 * (1 - Math.pow( 1.2, -page ))); } - private static void drawTexture(Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height) { - buffer.vertex(matrix, x, y + height, z) - .texture(u / BG_SIZE, (v + height) / BG_SIZE) - .next(); - buffer.vertex(matrix, x + width, y + height, z) - .texture((u + width) / BG_SIZE, (v + height) / BG_SIZE) - .next(); - buffer.vertex(matrix, x + width, y, z) - .texture((u + width) / BG_SIZE, v / BG_SIZE) - .next(); - buffer.vertex(matrix, x, y, z) - .texture(u / BG_SIZE, v / BG_SIZE) - .next(); + private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height ) + { + buffer.vertex( matrix, x, y + height, z ) + .texture( u / BG_SIZE, (v + height) / BG_SIZE ) + .next(); + buffer.vertex( matrix, x + width, y + height, z ) + .texture( (u + width) / BG_SIZE, (v + height) / BG_SIZE ) + .next(); + buffer.vertex( matrix, x + width, y, z ) + .texture( (u + width) / BG_SIZE, v / BG_SIZE ) + .next(); + buffer.vertex( matrix, x, y, z ) + .texture( u / BG_SIZE, v / BG_SIZE ) + .next(); } - private static void drawTexture(Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float width, float height, float u, float v, - float tWidth, float tHeight) { - buffer.vertex(matrix, x, y + height, z) - .texture(u / BG_SIZE, (v + tHeight) / BG_SIZE) - .next(); - buffer.vertex(matrix, x + width, y + height, z) - .texture((u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE) - .next(); - buffer.vertex(matrix, x + width, y, z) - .texture((u + tWidth) / BG_SIZE, v / BG_SIZE) - .next(); - buffer.vertex(matrix, x, y, z) - .texture(u / BG_SIZE, v / BG_SIZE) - .next(); + private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float width, float height, float u, float v, + float tWidth, float tHeight ) + { + buffer.vertex( matrix, x, y + height, z ) + .texture( u / BG_SIZE, (v + tHeight) / BG_SIZE ) + .next(); + buffer.vertex( matrix, x + width, y + height, z ) + .texture( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ) + .next(); + buffer.vertex( matrix, x + width, y, z ) + .texture( (u + tWidth) / BG_SIZE, v / BG_SIZE ) + .next(); + buffer.vertex( matrix, x, y, z ) + .texture( u / BG_SIZE, v / BG_SIZE ) + .next(); } - private static final class Type extends RenderPhase { - static final RenderLayer TYPE = RenderLayer.of("printout_background", - VertexFormats.POSITION_TEXTURE, - GL11.GL_QUADS, - 1024, - false, - false, - // useDelegate, needsSorting - RenderLayer.MultiPhaseParameters.builder() - .texture(new RenderPhase.Texture(BG, false, false)) // blur, minimap - .alpha(ONE_TENTH_ALPHA) - .lightmap(DISABLE_LIGHTMAP) - .build(false)); + private static final class Type extends RenderPhase + { + static final RenderLayer TYPE = RenderLayer.of( "printout_background", + VertexFormats.POSITION_TEXTURE, + GL11.GL_QUADS, + 1024, + false, + false, + // useDelegate, needsSorting + RenderLayer.MultiPhaseParameters.builder() + .texture( new RenderPhase.Texture( BG, false, false ) ) // blur, minimap + .alpha( ONE_TENTH_ALPHA ) + .lightmap( DISABLE_LIGHTMAP ) + .build( false ) ); - private Type(String name, Runnable setup, Runnable destroy) { - super(name, setup, destroy); + private Type( String name, Runnable setup, Runnable destroy ) + { + super( name, setup, destroy ); } } } diff --git a/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java b/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java index b096a93df..5390b812a 100644 --- a/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java @@ -6,14 +6,6 @@ package dan200.computercraft.client.render; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.getColour; - -import java.nio.ByteBuffer; - -import javax.annotation.Nonnull; - import com.mojang.blaze3d.platform.GlStateManager; import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.gui.FixedWidthFontRenderer; @@ -24,17 +16,8 @@ import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.DirectionUtil; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL31; - import net.minecraft.client.gl.VertexBuffer; -import net.minecraft.client.render.BufferBuilder; -import net.minecraft.client.render.Tessellator; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.render.*; import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.util.GlAllocationUtils; @@ -44,27 +27,40 @@ import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Matrix4f; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL31; -public class TileEntityMonitorRenderer extends BlockEntityRenderer { +import javax.annotation.Nonnull; +import java.nio.ByteBuffer; + +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*; + +public class TileEntityMonitorRenderer extends BlockEntityRenderer +{ /** * {@link TileMonitor#RENDER_MARGIN}, but a tiny bit of additional padding to ensure that there is no space between the monitor frame and contents. */ private static final float MARGIN = (float) (TileMonitor.RENDER_MARGIN * 1.1); private static final Matrix4f IDENTITY = AffineTransformation.identity() - .getMatrix(); + .getMatrix(); private static ByteBuffer tboContents; - public TileEntityMonitorRenderer(BlockEntityRenderDispatcher rendererDispatcher) { - super(rendererDispatcher); + public TileEntityMonitorRenderer( BlockEntityRenderDispatcher rendererDispatcher ) + { + super( rendererDispatcher ); } @Override - public void render(@Nonnull TileMonitor monitor, float partialTicks, @Nonnull MatrixStack transform, @Nonnull VertexConsumerProvider renderer, - int lightmapCoord, int overlayLight) { + public void render( @Nonnull TileMonitor monitor, float partialTicks, @Nonnull MatrixStack transform, @Nonnull VertexConsumerProvider renderer, + int lightmapCoord, int overlayLight ) + { // Render from the origin monitor ClientMonitor originTerminal = monitor.getClientMonitor(); - if (originTerminal == null) { + if( originTerminal == null ) + { return; } TileMonitor origin = originTerminal.getOrigin(); @@ -74,7 +70,8 @@ public class TileEntityMonitorRenderer extends BlockEntityRenderer // multiple times in a single frame to ensure compatibility with shaders which may run a // pass multiple times. long renderFrame = FrameInfo.getRenderFrame(); - if (originTerminal.lastRenderFrame == renderFrame && !monitorPos.equals(originTerminal.lastRenderPos)) { + if( originTerminal.lastRenderFrame == renderFrame && !monitorPos.equals( originTerminal.lastRenderPos ) ) + { return; } @@ -87,165 +84,179 @@ public class TileEntityMonitorRenderer extends BlockEntityRenderer Direction dir = origin.getDirection(); Direction front = origin.getFront(); float yaw = dir.asRotation(); - float pitch = DirectionUtil.toPitchAngle(front); + float pitch = DirectionUtil.toPitchAngle( front ); // Setup initial transform transform.push(); - transform.translate(originPos.getX() - monitorPos.getX() + 0.5, - originPos.getY() - monitorPos.getY() + 0.5, - originPos.getZ() - monitorPos.getZ() + 0.5); + transform.translate( originPos.getX() - monitorPos.getX() + 0.5, + originPos.getY() - monitorPos.getY() + 0.5, + originPos.getZ() - monitorPos.getZ() + 0.5 ); - transform.multiply(Vector3f.NEGATIVE_Y.getDegreesQuaternion(yaw)); - transform.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(pitch)); - transform.translate(-0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN, - origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN) + 0, - 0.5); + transform.multiply( Vector3f.NEGATIVE_Y.getDegreesQuaternion( yaw ) ); + transform.multiply( Vector3f.POSITIVE_X.getDegreesQuaternion( pitch ) ); + transform.translate( -0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN, + origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN) + 0, + 0.5 ); double xSize = origin.getWidth() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER); double ySize = origin.getHeight() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER); // Draw the contents Terminal terminal = originTerminal.getTerminal(); - if (terminal != null) { + if( terminal != null ) + { // Draw a terminal int width = terminal.getWidth(), height = terminal.getHeight(); int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT; double xScale = xSize / pixelWidth; double yScale = ySize / pixelHeight; transform.push(); - transform.scale((float) xScale, (float) -yScale, 1.0f); + transform.scale( (float) xScale, (float) -yScale, 1.0f ); Matrix4f matrix = transform.peek() - .getModel(); + .getModel(); // Sneaky hack here: we get a buffer now in order to flush existing ones and set up the appropriate // render state. I've no clue how well this'll work in future versions of Minecraft, but it does the trick // for now. - VertexConsumer buffer = renderer.getBuffer(FixedWidthFontRenderer.TYPE); + VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE ); FixedWidthFontRenderer.TYPE.startDrawing(); - renderTerminal(matrix, originTerminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale)); + renderTerminal( matrix, originTerminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale) ); // We don't draw the cursor with the VBO, as it's dynamic and so we'll end up refreshing far more than is // reasonable. - FixedWidthFontRenderer.drawCursor(matrix, buffer, 0, 0, terminal, !originTerminal.isColour()); + FixedWidthFontRenderer.drawCursor( matrix, buffer, 0, 0, terminal, !originTerminal.isColour() ); transform.pop(); - } else { - FixedWidthFontRenderer.drawEmptyTerminal(transform.peek() - .getModel(), - renderer, - -MARGIN, - MARGIN, - (float) (xSize + 2 * MARGIN), - (float) -(ySize + MARGIN * 2)); + } + else + { + FixedWidthFontRenderer.drawEmptyTerminal( transform.peek() + .getModel(), + renderer, + -MARGIN, + MARGIN, + (float) (xSize + 2 * MARGIN), + (float) -(ySize + MARGIN * 2) ); } - FixedWidthFontRenderer.drawBlocker(transform.peek() - .getModel(), - renderer, - (float) -TileMonitor.RENDER_MARGIN, - (float) TileMonitor.RENDER_MARGIN, - (float) (xSize + 2 * TileMonitor.RENDER_MARGIN), - (float) -(ySize + TileMonitor.RENDER_MARGIN * 2)); + FixedWidthFontRenderer.drawBlocker( transform.peek() + .getModel(), + renderer, + (float) -TileMonitor.RENDER_MARGIN, + (float) TileMonitor.RENDER_MARGIN, + (float) (xSize + 2 * TileMonitor.RENDER_MARGIN), + (float) -(ySize + TileMonitor.RENDER_MARGIN * 2) ); transform.pop(); } - private static void renderTerminal(Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin) { + private static void renderTerminal( Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin ) + { Terminal terminal = monitor.getTerminal(); MonitorRenderer renderType = MonitorRenderer.current(); boolean redraw = monitor.pollTerminalChanged(); - if (monitor.createBuffer(renderType)) { + if( monitor.createBuffer( renderType ) ) + { redraw = true; } - switch (renderType) { - case TBO: { - if (!MonitorTextureBufferShader.use()) { - return; - } - - int width = terminal.getWidth(), height = terminal.getHeight(); - int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT; - - if (redraw) { - int size = width * height * 3; - if (tboContents == null || tboContents.capacity() < size) { - tboContents = GlAllocationUtils.allocateByteBuffer(size); + switch( renderType ) + { + case TBO: + { + if( !MonitorTextureBufferShader.use() ) + { + return; } - ByteBuffer monitorBuffer = tboContents; - monitorBuffer.clear(); - for (int y = 0; y < height; y++) { - TextBuffer text = terminal.getLine(y), textColour = terminal.getTextColourLine(y), background = terminal.getBackgroundColourLine(y); - for (int x = 0; x < width; x++) { - monitorBuffer.put((byte) (text.charAt(x) & 0xFF)); - monitorBuffer.put((byte) getColour(textColour.charAt(x), Colour.WHITE)); - monitorBuffer.put((byte) getColour(background.charAt(x), Colour.BLACK)); + int width = terminal.getWidth(), height = terminal.getHeight(); + int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT; + + if( redraw ) + { + int size = width * height * 3; + if( tboContents == null || tboContents.capacity() < size ) + { + tboContents = GlAllocationUtils.allocateByteBuffer( size ); } + + ByteBuffer monitorBuffer = tboContents; + monitorBuffer.clear(); + for( int y = 0; y < height; y++ ) + { + TextBuffer text = terminal.getLine( y ), textColour = terminal.getTextColourLine( y ), background = terminal.getBackgroundColourLine( y ); + for( int x = 0; x < width; x++ ) + { + monitorBuffer.put( (byte) (text.charAt( x ) & 0xFF) ); + monitorBuffer.put( (byte) getColour( textColour.charAt( x ), Colour.WHITE ) ); + monitorBuffer.put( (byte) getColour( background.charAt( x ), Colour.BLACK ) ); + } + } + monitorBuffer.flip(); + + GlStateManager.bindBuffers( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer ); + GlStateManager.bufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW ); + GlStateManager.bindBuffers( GL31.GL_TEXTURE_BUFFER, 0 ); } - monitorBuffer.flip(); - GlStateManager.bindBuffers(GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer); - GlStateManager.bufferData(GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW); - GlStateManager.bindBuffers(GL31.GL_TEXTURE_BUFFER, 0); - } + // Nobody knows what they're doing! + GlStateManager.activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX ); + GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture ); + GlStateManager.activeTexture( GL13.GL_TEXTURE0 ); - // Nobody knows what they're doing! - GlStateManager.activeTexture(MonitorTextureBufferShader.TEXTURE_INDEX); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, monitor.tboTexture); - GlStateManager.activeTexture(GL13.GL_TEXTURE0); + MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() ); - MonitorTextureBufferShader.setupUniform(matrix, width, height, terminal.getPalette(), !monitor.isColour()); - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_TRIANGLE_STRIP, VertexFormats.POSITION); - buffer.vertex(-xMargin, -yMargin, 0) - .next(); - buffer.vertex(-xMargin, pixelHeight + yMargin, 0) - .next(); - buffer.vertex(pixelWidth + xMargin, -yMargin, 0) - .next(); - buffer.vertex(pixelWidth + xMargin, pixelHeight + yMargin, 0) - .next(); - tessellator.draw(); - - GlStateManager.useProgram(0); - break; - } - - case VBO: { - VertexBuffer vbo = monitor.buffer; - if (redraw) { Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder builder = tessellator.getBuffer(); - builder.begin(FixedWidthFontRenderer.TYPE.getDrawMode(), FixedWidthFontRenderer.TYPE.getVertexFormat()); - FixedWidthFontRenderer.drawTerminalWithoutCursor(IDENTITY, - builder, - 0, - 0, - terminal, - !monitor.isColour(), - yMargin, - yMargin, - xMargin, - xMargin); + BufferBuilder buffer = tessellator.getBuffer(); + buffer.begin( GL11.GL_TRIANGLE_STRIP, VertexFormats.POSITION ); + buffer.vertex( -xMargin, -yMargin, 0 ) + .next(); + buffer.vertex( -xMargin, pixelHeight + yMargin, 0 ) + .next(); + buffer.vertex( pixelWidth + xMargin, -yMargin, 0 ) + .next(); + buffer.vertex( pixelWidth + xMargin, pixelHeight + yMargin, 0 ) + .next(); + tessellator.draw(); - builder.end(); - vbo.upload(builder); + GlStateManager.useProgram( 0 ); + break; } - vbo.bind(); - FixedWidthFontRenderer.TYPE.getVertexFormat() - .startDrawing(0L); - vbo.draw(matrix, FixedWidthFontRenderer.TYPE.getDrawMode()); - VertexBuffer.unbind(); - FixedWidthFontRenderer.TYPE.getVertexFormat() - .endDrawing(); - break; - } + case VBO: + { + VertexBuffer vbo = monitor.buffer; + if( redraw ) + { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder builder = tessellator.getBuffer(); + builder.begin( FixedWidthFontRenderer.TYPE.getDrawMode(), FixedWidthFontRenderer.TYPE.getVertexFormat() ); + FixedWidthFontRenderer.drawTerminalWithoutCursor( IDENTITY, + builder, + 0, + 0, + terminal, + !monitor.isColour(), + yMargin, + yMargin, + xMargin, + xMargin ); + + builder.end(); + vbo.upload( builder ); + } + + vbo.bind(); + FixedWidthFontRenderer.TYPE.getVertexFormat() + .startDrawing( 0L ); + vbo.draw( matrix, FixedWidthFontRenderer.TYPE.getDrawMode() ); + VertexBuffer.unbind(); + FixedWidthFontRenderer.TYPE.getVertexFormat() + .endDrawing(); + break; + } } } } diff --git a/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java b/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java index 8a498cd0a..c657decd7 100644 --- a/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java @@ -6,11 +6,6 @@ package dan200.computercraft.client.render; -import java.util.List; -import java.util.Random; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; @@ -19,7 +14,6 @@ import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.Holiday; import dan200.computercraft.shared.util.HolidayUtil; - import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.render.TexturedRenderLayers; @@ -40,47 +34,62 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Vec3d; -public class TileEntityTurtleRenderer extends BlockEntityRenderer { - private static final ModelIdentifier NORMAL_TURTLE_MODEL = new ModelIdentifier("computercraft:turtle_normal", "inventory"); - private static final ModelIdentifier ADVANCED_TURTLE_MODEL = new ModelIdentifier("computercraft:turtle_advanced", "inventory"); - private static final ModelIdentifier COLOUR_TURTLE_MODEL = new ModelIdentifier("computercraft:turtle_colour", "inventory"); - private static final ModelIdentifier ELF_OVERLAY_MODEL = new ModelIdentifier("computercraft:turtle_elf_overlay", "inventory"); +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Random; - private final Random random = new Random(0); +public class TileEntityTurtleRenderer extends BlockEntityRenderer +{ + private static final ModelIdentifier NORMAL_TURTLE_MODEL = new ModelIdentifier( "computercraft:turtle_normal", "inventory" ); + private static final ModelIdentifier ADVANCED_TURTLE_MODEL = new ModelIdentifier( "computercraft:turtle_advanced", "inventory" ); + private static final ModelIdentifier COLOUR_TURTLE_MODEL = new ModelIdentifier( "computercraft:turtle_colour", "inventory" ); + private static final ModelIdentifier ELF_OVERLAY_MODEL = new ModelIdentifier( "computercraft:turtle_elf_overlay", "inventory" ); - public TileEntityTurtleRenderer(BlockEntityRenderDispatcher renderDispatcher) { - super(renderDispatcher); + private final Random random = new Random( 0 ); + + public TileEntityTurtleRenderer( BlockEntityRenderDispatcher renderDispatcher ) + { + super( renderDispatcher ); } - public static ModelIdentifier getTurtleModel(ComputerFamily family, boolean coloured) { - switch (family) { - case NORMAL: - default: - return coloured ? COLOUR_TURTLE_MODEL : NORMAL_TURTLE_MODEL; - case ADVANCED: - return coloured ? COLOUR_TURTLE_MODEL : ADVANCED_TURTLE_MODEL; + public static ModelIdentifier getTurtleModel( ComputerFamily family, boolean coloured ) + { + switch( family ) + { + case NORMAL: + default: + return coloured ? COLOUR_TURTLE_MODEL : NORMAL_TURTLE_MODEL; + case ADVANCED: + return coloured ? COLOUR_TURTLE_MODEL : ADVANCED_TURTLE_MODEL; } } - public static ModelIdentifier getTurtleOverlayModel(Identifier overlay, boolean christmas) { - if (overlay != null) { - return new ModelIdentifier(overlay, "inventory"); + public static ModelIdentifier getTurtleOverlayModel( Identifier overlay, boolean christmas ) + { + if( overlay != null ) + { + return new ModelIdentifier( overlay, "inventory" ); } - if (christmas) { + if( christmas ) + { return ELF_OVERLAY_MODEL; } return null; } - private static void renderQuads(@Nonnull MatrixStack transform, @Nonnull VertexConsumer buffer, int lightmapCoord, int overlayLight, - List quads, int[] tints) { + private static void renderQuads( @Nonnull MatrixStack transform, @Nonnull VertexConsumer buffer, int lightmapCoord, int overlayLight, + List quads, int[] tints ) + { MatrixStack.Entry matrix = transform.peek(); - for (BakedQuad bakedquad : quads) { + for( BakedQuad bakedquad : quads ) + { int tint = -1; - if (tints != null && bakedquad.hasColor()) { + if( tints != null && bakedquad.hasColor() ) + { int idx = bakedquad.getColorIndex(); - if (idx >= 0 && idx < tints.length) { + if( idx >= 0 && idx < tints.length ) + { tint = tints[bakedquad.getColorIndex()]; } } @@ -88,52 +97,54 @@ public class TileEntityTurtleRenderer extends BlockEntityRenderer { float f = (float) (tint >> 16 & 255) / 255.0F; float f1 = (float) (tint >> 8 & 255) / 255.0F; float f2 = (float) (tint & 255) / 255.0F; - buffer.quad(matrix, - bakedquad, - new float[] { - 1.0F, - 1.0F, - 1.0F, - 1.0F - }, - f, - f1, - f2, - new int[] { - lightmapCoord, - lightmapCoord, - lightmapCoord, - lightmapCoord - }, - overlayLight, - true); + buffer.quad( matrix, + bakedquad, + new float[] { + 1.0F, + 1.0F, + 1.0F, + 1.0F + }, + f, + f1, + f2, + new int[] { + lightmapCoord, + lightmapCoord, + lightmapCoord, + lightmapCoord + }, + overlayLight, + true ); } } @Override - public void render(@Nonnull TileTurtle turtle, float partialTicks, @Nonnull MatrixStack transform, @Nonnull VertexConsumerProvider renderer, - int lightmapCoord, int overlayLight) { + public void render( @Nonnull TileTurtle turtle, float partialTicks, @Nonnull MatrixStack transform, @Nonnull VertexConsumerProvider renderer, + int lightmapCoord, int overlayLight ) + { // Render the label String label = turtle.createProxy() - .getLabel(); + .getLabel(); HitResult hit = this.dispatcher.crosshairTarget; - if (label != null && hit.getType() == HitResult.Type.BLOCK && turtle.getPos() - .equals(((BlockHitResult) hit).getBlockPos())) { + if( label != null && hit.getType() == HitResult.Type.BLOCK && turtle.getPos() + .equals( ((BlockHitResult) hit).getBlockPos() ) ) + { MinecraftClient mc = MinecraftClient.getInstance(); TextRenderer font = mc.textRenderer; transform.push(); - transform.translate(0.5, 1.2, 0.5); - transform.multiply(mc.getEntityRenderDispatcher() - .getRotation()); - transform.scale(-0.025f, -0.025f, 0.025f); + transform.translate( 0.5, 1.2, 0.5 ); + transform.multiply( mc.getEntityRenderDispatcher() + .getRotation() ); + transform.scale( -0.025f, -0.025f, 0.025f ); Matrix4f matrix = transform.peek() - .getModel(); - int opacity = (int) (mc.options.getTextBackgroundOpacity(0.25f) * 255) << 24; - float width = -font.getWidth(label) / 2.0f; - font.draw(label, width, (float) 0, 0x20ffffff, false, matrix, renderer, true, opacity, lightmapCoord); - font.draw(label, width, (float) 0, 0xffffffff, false, matrix, renderer, false, 0, lightmapCoord); + .getModel(); + int opacity = (int) (mc.options.getTextBackgroundOpacity( 0.25f ) * 255) << 24; + float width = -font.getWidth( label ) / 2.0f; + font.draw( label, width, (float) 0, 0x20ffffff, false, matrix, renderer, true, opacity, lightmapCoord ); + font.draw( label, width, (float) 0, 0xffffffff, false, matrix, renderer, false, 0, lightmapCoord ); transform.pop(); } @@ -141,76 +152,83 @@ public class TileEntityTurtleRenderer extends BlockEntityRenderer { transform.push(); // Setup the transform. - Vec3d offset = turtle.getRenderOffset(partialTicks); - float yaw = turtle.getRenderYaw(partialTicks); - transform.translate(offset.x, offset.y, offset.z); + Vec3d offset = turtle.getRenderOffset( partialTicks ); + float yaw = turtle.getRenderYaw( partialTicks ); + transform.translate( offset.x, offset.y, offset.z ); - transform.translate(0.5f, 0.5f, 0.5f); - transform.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(180.0f - yaw)); - if (label != null && (label.equals("Dinnerbone") || label.equals("Grumm"))) { + transform.translate( 0.5f, 0.5f, 0.5f ); + transform.multiply( Vector3f.POSITIVE_Y.getDegreesQuaternion( 180.0f - yaw ) ); + if( label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )) ) + { // Flip the model - transform.scale(1.0f, -1.0f, 1.0f); + transform.scale( 1.0f, -1.0f, 1.0f ); } - transform.translate(-0.5f, -0.5f, -0.5f); + transform.translate( -0.5f, -0.5f, -0.5f ); // Render the turtle int colour = turtle.getColour(); ComputerFamily family = turtle.getFamily(); Identifier overlay = turtle.getOverlay(); - VertexConsumer buffer = renderer.getBuffer(TexturedRenderLayers.getEntityTranslucentCull()); - renderModel(transform, buffer, lightmapCoord, overlayLight, getTurtleModel(family, colour != -1), colour == -1 ? null : new int[] {colour}); + VertexConsumer buffer = renderer.getBuffer( TexturedRenderLayers.getEntityTranslucentCull() ); + renderModel( transform, buffer, lightmapCoord, overlayLight, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } ); // Render the overlay - ModelIdentifier overlayModel = getTurtleOverlayModel(overlay, HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS); - if (overlayModel != null) { - renderModel(transform, buffer, lightmapCoord, overlayLight, overlayModel, null); + ModelIdentifier overlayModel = getTurtleOverlayModel( overlay, HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS ); + if( overlayModel != null ) + { + renderModel( transform, buffer, lightmapCoord, overlayLight, overlayModel, null ); } // Render the upgrades - renderUpgrade(transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.LEFT, partialTicks); - renderUpgrade(transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.RIGHT, partialTicks); + renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.LEFT, partialTicks ); + renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.RIGHT, partialTicks ); transform.pop(); } - public static void renderUpgrade(@Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, TileTurtle turtle, - TurtleSide side, float f) { - ITurtleUpgrade upgrade = turtle.getUpgrade(side); - if (upgrade == null) { + public static void renderUpgrade( @Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, TileTurtle turtle, + TurtleSide side, float f ) + { + ITurtleUpgrade upgrade = turtle.getUpgrade( side ); + if( upgrade == null ) + { return; } transform.push(); - float toolAngle = turtle.getToolRenderAngle(side, f); - transform.translate(0.0f, 0.5f, 0.5f); - transform.multiply(Vector3f.NEGATIVE_X.getDegreesQuaternion(toolAngle)); - transform.translate(0.0f, -0.5f, -0.5f); + float toolAngle = turtle.getToolRenderAngle( side, f ); + transform.translate( 0.0f, 0.5f, 0.5f ); + transform.multiply( Vector3f.NEGATIVE_X.getDegreesQuaternion( toolAngle ) ); + transform.translate( 0.0f, -0.5f, -0.5f ); - TransformedModel model = upgrade.getModel(turtle.getAccess(), side); - model.push(transform); - TileEntityTurtleRenderer.renderModel(transform, renderer, lightmapCoord, overlayLight, model.getModel(), null); + TransformedModel model = upgrade.getModel( turtle.getAccess(), side ); + model.push( transform ); + TileEntityTurtleRenderer.renderModel( transform, renderer, lightmapCoord, overlayLight, model.getModel(), null ); transform.pop(); transform.pop(); } - public static void renderModel(@Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, - ModelIdentifier modelLocation, int[] tints) { + public static void renderModel( @Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, + ModelIdentifier modelLocation, int[] tints ) + { BakedModelManager modelManager = MinecraftClient.getInstance() - .getItemRenderer() - .getModels() - .getModelManager(); - renderModel(transform, renderer, lightmapCoord, overlayLight, modelManager.getModel(modelLocation), tints); + .getItemRenderer() + .getModels() + .getModelManager(); + renderModel( transform, renderer, lightmapCoord, overlayLight, modelManager.getModel( modelLocation ), tints ); } - public static void renderModel(@Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, BakedModel model, - int[] tints) { + public static void renderModel( @Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, BakedModel model, + int[] tints ) + { Random random = new Random(); - random.setSeed(0); - renderQuads(transform, renderer, lightmapCoord, overlayLight, model.getQuads(null, null, random), tints); - for (Direction facing : DirectionUtil.FACINGS) { - renderQuads(transform, renderer, lightmapCoord, overlayLight, model.getQuads(null, facing, random), tints); + random.setSeed( 0 ); + renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random ), tints ); + for( Direction facing : DirectionUtil.FACINGS ) + { + renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random ), tints ); } } } diff --git a/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java b/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java index 5ff3f23bc..50ae22c5b 100644 --- a/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java +++ b/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java @@ -6,17 +6,10 @@ package dan200.computercraft.client.render; -import java.util.Arrays; -import java.util.Collection; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -import javax.annotation.Nonnull; - import com.mojang.datafixers.util.Pair; import dan200.computercraft.ComputerCraft; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelLoader; @@ -25,70 +18,84 @@ import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.util.Identifier; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; -@Environment (EnvType.CLIENT) -public final class TurtleModelLoader { +@Environment( EnvType.CLIENT ) +public final class TurtleModelLoader +{ public static final TurtleModelLoader INSTANCE = new TurtleModelLoader(); - private static final Identifier NORMAL_TURTLE_MODEL = new Identifier(ComputerCraft.MOD_ID, "block/turtle_normal"); - private static final Identifier ADVANCED_TURTLE_MODEL = new Identifier(ComputerCraft.MOD_ID, "block/turtle_advanced"); - private static final Identifier COLOUR_TURTLE_MODEL = new Identifier(ComputerCraft.MOD_ID, "block/turtle_colour"); + private static final Identifier NORMAL_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_normal" ); + private static final Identifier ADVANCED_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_advanced" ); + private static final Identifier COLOUR_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_colour" ); - private TurtleModelLoader() { + private TurtleModelLoader() + { } - public boolean accepts(@Nonnull Identifier name) { + public boolean accepts( @Nonnull Identifier name ) + { return name.getNamespace() - .equals(ComputerCraft.MOD_ID) && (name.getPath() - .equals("item/turtle_normal") || name.getPath() - .equals("item/turtle_advanced")); + .equals( ComputerCraft.MOD_ID ) && (name.getPath() + .equals( "item/turtle_normal" ) || name.getPath() + .equals( "item/turtle_advanced" )); } @Nonnull - public UnbakedModel loadModel(@Nonnull Identifier name) { - if (name.getNamespace() - .equals(ComputerCraft.MOD_ID)) { - switch (name.getPath()) { - case "item/turtle_normal": - return new TurtleModel(NORMAL_TURTLE_MODEL); - case "item/turtle_advanced": - return new TurtleModel(ADVANCED_TURTLE_MODEL); + public UnbakedModel loadModel( @Nonnull Identifier name ) + { + if( name.getNamespace() + .equals( ComputerCraft.MOD_ID ) ) + { + switch( name.getPath() ) + { + case "item/turtle_normal": + return new TurtleModel( NORMAL_TURTLE_MODEL ); + case "item/turtle_advanced": + return new TurtleModel( ADVANCED_TURTLE_MODEL ); } } - throw new IllegalStateException("Loader does not accept " + name); + throw new IllegalStateException( "Loader does not accept " + name ); } - private static final class TurtleModel implements UnbakedModel { + private static final class TurtleModel implements UnbakedModel + { private final Identifier family; - private TurtleModel(Identifier family) {this.family = family;} + private TurtleModel( Identifier family ) {this.family = family;} @Override - public Collection getTextureDependencies(Function modelGetter, - Set> missingTextureErrors) { + public Collection getTextureDependencies( Function modelGetter, + Set> missingTextureErrors ) + { return this.getModelDependencies() - .stream() - .flatMap(x -> modelGetter.apply(x) - .getTextureDependencies(modelGetter, missingTextureErrors) - .stream()) - .collect(Collectors.toSet()); + .stream() + .flatMap( x -> modelGetter.apply( x ) + .getTextureDependencies( modelGetter, missingTextureErrors ) + .stream() ) + .collect( Collectors.toSet() ); } @Nonnull @Override - public Collection getModelDependencies() { - return Arrays.asList(this.family, COLOUR_TURTLE_MODEL); + public Collection getModelDependencies() + { + return Arrays.asList( this.family, COLOUR_TURTLE_MODEL ); } @Override - public BakedModel bake(@Nonnull ModelLoader loader, @Nonnull Function spriteGetter, @Nonnull ModelBakeSettings state, - Identifier modelId) { - return new TurtleSmartItemModel(loader.getOrLoadModel(this.family) - .bake(loader, spriteGetter, state, modelId), - loader.getOrLoadModel(COLOUR_TURTLE_MODEL) - .bake(loader, spriteGetter, state, modelId)); + public BakedModel bake( @Nonnull ModelLoader loader, @Nonnull Function spriteGetter, @Nonnull ModelBakeSettings state, + Identifier modelId ) + { + return new TurtleSmartItemModel( loader.getOrLoadModel( this.family ) + .bake( loader, spriteGetter, state, modelId ), + loader.getOrLoadModel( COLOUR_TURTLE_MODEL ) + .bake( loader, spriteGetter, state, modelId ) ); } } } diff --git a/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java b/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java index e0b1f1cf7..96da1dcc7 100644 --- a/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java +++ b/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java @@ -6,16 +6,9 @@ package dan200.computercraft.client.render; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.client.TransformedModel; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedQuad; @@ -24,21 +17,23 @@ import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.AffineTransformation; import net.minecraft.util.math.Direction; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; +import java.util.*; -@Environment (EnvType.CLIENT) -public class TurtleMultiModel implements BakedModel { +@Environment( EnvType.CLIENT ) +public class TurtleMultiModel implements BakedModel +{ private final BakedModel m_baseModel; private final BakedModel m_overlayModel; private final AffineTransformation m_generalTransform; private final TransformedModel m_leftUpgradeModel; private final TransformedModel m_rightUpgradeModel; private List m_generalQuads = null; - private Map> m_faceQuads = new EnumMap<>(Direction.class); + private Map> m_faceQuads = new EnumMap<>( Direction.class ); - public TurtleMultiModel(BakedModel baseModel, BakedModel overlayModel, AffineTransformation generalTransform, TransformedModel leftUpgradeModel, - TransformedModel rightUpgradeModel) { + public TurtleMultiModel( BakedModel baseModel, BakedModel overlayModel, AffineTransformation generalTransform, TransformedModel leftUpgradeModel, + TransformedModel rightUpgradeModel ) + { // Get the models this.m_baseModel = baseModel; this.m_overlayModel = overlayModel; @@ -49,81 +44,98 @@ public class TurtleMultiModel implements BakedModel { @Nonnull @Override - public List getQuads(BlockState state, Direction side, @Nonnull Random rand) { - if (side != null) { - if (!this.m_faceQuads.containsKey(side)) { - this.m_faceQuads.put(side, this.buildQuads(state, side, rand)); + public List getQuads( BlockState state, Direction side, @Nonnull Random rand ) + { + if( side != null ) + { + if( !this.m_faceQuads.containsKey( side ) ) + { + this.m_faceQuads.put( side, this.buildQuads( state, side, rand ) ); } - return this.m_faceQuads.get(side); - } else { - if (this.m_generalQuads == null) { - this.m_generalQuads = this.buildQuads(state, side, rand); + return this.m_faceQuads.get( side ); + } + else + { + if( this.m_generalQuads == null ) + { + this.m_generalQuads = this.buildQuads( state, side, rand ); } return this.m_generalQuads; } } - private List buildQuads(BlockState state, Direction side, Random rand) { + private List buildQuads( BlockState state, Direction side, Random rand ) + { ArrayList quads = new ArrayList<>(); - ModelTransformer.transformQuadsTo(quads, this.m_baseModel.getQuads(state, side, rand), this.m_generalTransform.getMatrix()); - if (this.m_overlayModel != null) { - ModelTransformer.transformQuadsTo(quads, this.m_overlayModel.getQuads(state, side, rand), this.m_generalTransform.getMatrix()); + ModelTransformer.transformQuadsTo( quads, this.m_baseModel.getQuads( state, side, rand ), this.m_generalTransform.getMatrix() ); + if( this.m_overlayModel != null ) + { + ModelTransformer.transformQuadsTo( quads, this.m_overlayModel.getQuads( state, side, rand ), this.m_generalTransform.getMatrix() ); } - if (this.m_leftUpgradeModel != null) { - AffineTransformation upgradeTransform = this.m_generalTransform.multiply(this.m_leftUpgradeModel.getMatrix()); - ModelTransformer.transformQuadsTo(quads, this.m_leftUpgradeModel.getModel() - .getQuads(state, side, rand), - upgradeTransform.getMatrix()); + if( this.m_leftUpgradeModel != null ) + { + AffineTransformation upgradeTransform = this.m_generalTransform.multiply( this.m_leftUpgradeModel.getMatrix() ); + ModelTransformer.transformQuadsTo( quads, this.m_leftUpgradeModel.getModel() + .getQuads( state, side, rand ), + upgradeTransform.getMatrix() ); } - if (this.m_rightUpgradeModel != null) { - AffineTransformation upgradeTransform = this.m_generalTransform.multiply(this.m_rightUpgradeModel.getMatrix()); - ModelTransformer.transformQuadsTo(quads, this.m_rightUpgradeModel.getModel() - .getQuads(state, side, rand), - upgradeTransform.getMatrix()); + if( this.m_rightUpgradeModel != null ) + { + AffineTransformation upgradeTransform = this.m_generalTransform.multiply( this.m_rightUpgradeModel.getMatrix() ); + ModelTransformer.transformQuadsTo( quads, this.m_rightUpgradeModel.getModel() + .getQuads( state, side, rand ), + upgradeTransform.getMatrix() ); } quads.trimToSize(); return quads; } @Override - public boolean useAmbientOcclusion() { + public boolean useAmbientOcclusion() + { return this.m_baseModel.useAmbientOcclusion(); } @Override - public boolean hasDepth() { + public boolean hasDepth() + { return this.m_baseModel.hasDepth(); } @Override - public boolean isSideLit() { + public boolean isSideLit() + { return this.m_baseModel.isSideLit(); } @Override - public boolean isBuiltin() { + public boolean isBuiltin() + { return this.m_baseModel.isBuiltin(); } @Nonnull @Override @Deprecated - public Sprite getSprite() { + public Sprite getSprite() + { return this.m_baseModel.getSprite(); } @Nonnull @Override @Deprecated - public net.minecraft.client.render.model.json.ModelTransformation getTransformation() { + public net.minecraft.client.render.model.json.ModelTransformation getTransformation() + { return this.m_baseModel.getTransformation(); } @Nonnull @Override - public ModelOverrideList getOverrides() { + public ModelOverrideList getOverrides() + { return ModelOverrideList.EMPTY; } } diff --git a/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java b/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java index 186b12deb..636cc4b4d 100644 --- a/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/TurtlePlayerRenderer.java @@ -5,35 +5,38 @@ */ package dan200.computercraft.client.render; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.turtle.core.TurtlePlayer; - +import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; +import javax.annotation.Nonnull; -public class TurtlePlayerRenderer extends EntityRenderer { - public TurtlePlayerRenderer(EntityRenderDispatcher renderManager) { - super(renderManager); +public class TurtlePlayerRenderer extends EntityRenderer +{ + public TurtlePlayerRenderer( EntityRenderDispatcher renderManager ) + { + super( renderManager ); } - public TurtlePlayerRenderer(EntityRenderDispatcher entityRenderDispatcher, EntityRendererRegistry.Context context) { - super(entityRenderDispatcher); + public TurtlePlayerRenderer( EntityRenderDispatcher entityRenderDispatcher, EntityRendererRegistry.Context context ) + { + super( entityRenderDispatcher ); } @Override - public void render(@Nonnull TurtlePlayer entityIn, float entityYaw, float partialTicks, @Nonnull MatrixStack transform, - @Nonnull VertexConsumerProvider buffer, int packedLightIn) { + public void render( @Nonnull TurtlePlayer entityIn, float entityYaw, float partialTicks, @Nonnull MatrixStack transform, + @Nonnull VertexConsumerProvider buffer, int packedLightIn ) + { } @Nonnull @Override - public Identifier getTexture(@Nonnull TurtlePlayer entity) { + public Identifier getTexture( @Nonnull TurtlePlayer entity ) + { return ComputerBorderRenderer.BACKGROUND_NORMAL; } } diff --git a/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java b/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java index 7465a5215..dcad3b2db 100644 --- a/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java +++ b/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java @@ -6,23 +6,15 @@ package dan200.computercraft.client.render; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Random; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.base.Objects; import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.turtle.items.ItemTurtle; -import dan200.computercraft.shared.turtle.upgrades.TurtleTool; import dan200.computercraft.shared.util.Holiday; import dan200.computercraft.shared.util.HolidayUtil; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.BakedModel; @@ -40,121 +32,142 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; import net.minecraft.util.math.Direction; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Random; -@Environment (EnvType.CLIENT) -public class TurtleSmartItemModel implements BakedModel { +@Environment( EnvType.CLIENT ) +public class TurtleSmartItemModel implements BakedModel +{ private static final AffineTransformation identity, flip; - static { + static + { MatrixStack stack = new MatrixStack(); - stack.scale(0, -1, 0); - stack.translate(0, 0, 1); + stack.scale( 0, -1, 0 ); + stack.translate( 0, 0, 1 ); identity = AffineTransformation.identity(); - flip = new AffineTransformation(stack.peek() - .getModel()); + flip = new AffineTransformation( stack.peek() + .getModel() ); } private final BakedModel familyModel; private final BakedModel colourModel; private final HashMap m_cachedModels = new HashMap<>(); private final ModelOverrideList m_overrides; - public TurtleSmartItemModel(BakedModel familyModel, BakedModel colourModel) { + + public TurtleSmartItemModel( BakedModel familyModel, BakedModel colourModel ) + { this.familyModel = familyModel; this.colourModel = colourModel; // this actually works I think, trust me - this.m_overrides = new ModelOverrideList(null, null, null, Collections.emptyList()) { + this.m_overrides = new ModelOverrideList( null, null, null, Collections.emptyList() ) + { @Nonnull @Override - public BakedModel apply(@Nonnull BakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientWorld world, - @Nullable LivingEntity entity) { + public BakedModel apply( @Nonnull BakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientWorld world, + @Nullable LivingEntity entity ) + { ItemTurtle turtle = (ItemTurtle) stack.getItem(); - int colour = turtle.getColour(stack); - ITurtleUpgrade leftUpgrade = turtle.getUpgrade(stack, TurtleSide.LEFT); - ITurtleUpgrade rightUpgrade = turtle.getUpgrade(stack, TurtleSide.RIGHT); - Identifier overlay = turtle.getOverlay(stack); + int colour = turtle.getColour( stack ); + ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.LEFT ); + ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.RIGHT ); + Identifier overlay = turtle.getOverlay( stack ); boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS; - String label = turtle.getLabel(stack); + String label = turtle.getLabel( stack ); // TODO make upside down turtle items render properly (currently inivisible) //boolean flip = label != null && (label.equals("Dinnerbone") || label.equals("Grumm")); boolean flip = false; - TurtleModelCombination combo = new TurtleModelCombination(colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip); + TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip ); - BakedModel model = TurtleSmartItemModel.this.m_cachedModels.get(combo); - if (model == null) { - TurtleSmartItemModel.this.m_cachedModels.put(combo, model = TurtleSmartItemModel.this.buildModel(combo)); + BakedModel model = TurtleSmartItemModel.this.m_cachedModels.get( combo ); + if( model == null ) + { + TurtleSmartItemModel.this.m_cachedModels.put( combo, model = TurtleSmartItemModel.this.buildModel( combo ) ); } return model; } }; } - private BakedModel buildModel(TurtleModelCombination combo) { + private BakedModel buildModel( TurtleModelCombination combo ) + { MinecraftClient mc = MinecraftClient.getInstance(); BakedModelManager modelManager = mc.getItemRenderer() - .getModels() - .getModelManager(); - ModelIdentifier overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel(combo.m_overlay, combo.m_christmas); + .getModels() + .getModelManager(); + ModelIdentifier overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas ); BakedModel baseModel = combo.m_colour ? this.colourModel : this.familyModel; - BakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel(overlayModelLocation) : null; + BakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null; AffineTransformation transform = combo.m_flip ? flip : identity; - TransformedModel leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel(null, TurtleSide.LEFT) : null; - TransformedModel rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel(null, TurtleSide.RIGHT) : null; - return new TurtleMultiModel(baseModel, overlayModel, transform, leftModel, rightModel); + TransformedModel leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel( null, TurtleSide.LEFT ) : null; + TransformedModel rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null; + return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel ); } @Nonnull @Override @Deprecated - public List getQuads(BlockState state, Direction facing, @Nonnull Random rand) { - return this.familyModel.getQuads(state, facing, rand); + public List getQuads( BlockState state, Direction facing, @Nonnull Random rand ) + { + return this.familyModel.getQuads( state, facing, rand ); } @Override - public boolean useAmbientOcclusion() { + public boolean useAmbientOcclusion() + { return this.familyModel.useAmbientOcclusion(); } @Override - public boolean hasDepth() { + public boolean hasDepth() + { return this.familyModel.hasDepth(); } @Override - public boolean isSideLit() { + public boolean isSideLit() + { return this.familyModel.isSideLit(); } @Override - public boolean isBuiltin() { + public boolean isBuiltin() + { return this.familyModel.isBuiltin(); } @Nonnull @Override @Deprecated - public Sprite getSprite() { + public Sprite getSprite() + { return this.familyModel.getSprite(); } @Nonnull @Override @Deprecated - public ModelTransformation getTransformation() { + public ModelTransformation getTransformation() + { return this.familyModel.getTransformation(); } @Nonnull @Override - public ModelOverrideList getOverrides() { + public ModelOverrideList getOverrides() + { return this.m_overrides; } - private static class TurtleModelCombination { + private static class TurtleModelCombination + { final boolean m_colour; final ITurtleUpgrade m_leftUpgrade; final ITurtleUpgrade m_rightUpgrade; @@ -162,8 +175,9 @@ public class TurtleSmartItemModel implements BakedModel { final boolean m_christmas; final boolean m_flip; - TurtleModelCombination(boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, Identifier overlay, boolean christmas, - boolean flip) { + TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, Identifier overlay, boolean christmas, + boolean flip ) + { this.m_colour = colour; this.m_leftUpgrade = leftUpgrade; this.m_rightUpgrade = rightUpgrade; @@ -173,7 +187,8 @@ public class TurtleSmartItemModel implements BakedModel { } @Override - public int hashCode() { + public int hashCode() + { final int prime = 31; int result = 0; result = prime * result + (this.m_colour ? 1 : 0); @@ -186,17 +201,20 @@ public class TurtleSmartItemModel implements BakedModel { } @Override - public boolean equals(Object other) { - if (other == this) { + public boolean equals( Object other ) + { + if( other == this ) + { return true; } - if (!(other instanceof TurtleModelCombination)) { + if( !(other instanceof TurtleModelCombination) ) + { return false; } TurtleModelCombination otherCombo = (TurtleModelCombination) other; return otherCombo.m_colour == this.m_colour && otherCombo.m_leftUpgrade == this.m_leftUpgrade && otherCombo.m_rightUpgrade == this.m_rightUpgrade && Objects.equal( - otherCombo.m_overlay, this.m_overlay) && otherCombo.m_christmas == this.m_christmas && otherCombo.m_flip == this.m_flip; + otherCombo.m_overlay, this.m_overlay ) && otherCombo.m_christmas == this.m_christmas && otherCombo.m_flip == this.m_flip; } } diff --git a/src/main/java/dan200/computercraft/core/apis/ApiFactories.java b/src/main/java/dan200/computercraft/core/apis/ApiFactories.java index 4a370d49f..fc4b9eff7 100644 --- a/src/main/java/dan200/computercraft/core/apis/ApiFactories.java +++ b/src/main/java/dan200/computercraft/core/apis/ApiFactories.java @@ -6,27 +6,31 @@ package dan200.computercraft.core.apis; +import dan200.computercraft.api.lua.ILuaAPIFactory; + +import javax.annotation.Nonnull; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Objects; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.lua.ILuaAPIFactory; - -public final class ApiFactories { +public final class ApiFactories +{ private static final Collection factories = new LinkedHashSet<>(); - private static final Collection factoriesView = Collections.unmodifiableCollection(factories); - private ApiFactories() { + private static final Collection factoriesView = Collections.unmodifiableCollection( factories ); + + private ApiFactories() + { } - public static synchronized void register(@Nonnull ILuaAPIFactory factory) { - Objects.requireNonNull(factory, "provider cannot be null"); - factories.add(factory); + public static synchronized void register( @Nonnull ILuaAPIFactory factory ) + { + Objects.requireNonNull( factory, "provider cannot be null" ); + factories.add( factory ); } - public static Iterable getAll() { + public static Iterable getAll() + { return factoriesView; } } diff --git a/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java b/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java index 27c5e504b..c71e9ec7b 100644 --- a/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java +++ b/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java @@ -6,12 +6,6 @@ package dan200.computercraft.core.apis; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.peripheral.IComputerAccess; @@ -19,121 +13,157 @@ import dan200.computercraft.api.peripheral.IWorkMonitor; import dan200.computercraft.core.filesystem.FileSystem; import dan200.computercraft.core.filesystem.FileSystemException; -public abstract class ComputerAccess implements IComputerAccess { +import javax.annotation.Nonnull; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +public abstract class ComputerAccess implements IComputerAccess +{ private final IAPIEnvironment m_environment; private final Set m_mounts = new HashSet<>(); - protected ComputerAccess(IAPIEnvironment environment) { + protected ComputerAccess( IAPIEnvironment environment ) + { this.m_environment = environment; } - public void unmountAll() { + public void unmountAll() + { FileSystem fileSystem = this.m_environment.getFileSystem(); - for (String mount : this.m_mounts) { - fileSystem.unmount(mount); + for( String mount : this.m_mounts ) + { + fileSystem.unmount( mount ); } this.m_mounts.clear(); } @Override - public synchronized String mount(@Nonnull String desiredLoc, @Nonnull IMount mount, @Nonnull String driveName) { - Objects.requireNonNull(desiredLoc, "desiredLocation cannot be null"); - Objects.requireNonNull(mount, "mount cannot be null"); - Objects.requireNonNull(driveName, "driveName cannot be null"); + public synchronized String mount( @Nonnull String desiredLoc, @Nonnull IMount mount, @Nonnull String driveName ) + { + Objects.requireNonNull( desiredLoc, "desiredLocation cannot be null" ); + Objects.requireNonNull( mount, "mount cannot be null" ); + Objects.requireNonNull( driveName, "driveName cannot be null" ); // Mount the location String location; FileSystem fileSystem = this.m_environment.getFileSystem(); - if (fileSystem == null) { - throw new IllegalStateException("File system has not been created"); + if( fileSystem == null ) + { + throw new IllegalStateException( "File system has not been created" ); } - synchronized (fileSystem) { - location = this.findFreeLocation(desiredLoc); - if (location != null) { - try { - fileSystem.mount(driveName, location, mount); - } catch (FileSystemException ignored) { + synchronized( fileSystem ) + { + location = this.findFreeLocation( desiredLoc ); + if( location != null ) + { + try + { + fileSystem.mount( driveName, location, mount ); + } + catch( FileSystemException ignored ) + { } } } - if (location != null) { - this.m_mounts.add(location); + if( location != null ) + { + this.m_mounts.add( location ); } return location; } @Override - public synchronized String mountWritable(@Nonnull String desiredLoc, @Nonnull IWritableMount mount, @Nonnull String driveName) { - Objects.requireNonNull(desiredLoc, "desiredLocation cannot be null"); - Objects.requireNonNull(mount, "mount cannot be null"); - Objects.requireNonNull(driveName, "driveName cannot be null"); + public synchronized String mountWritable( @Nonnull String desiredLoc, @Nonnull IWritableMount mount, @Nonnull String driveName ) + { + Objects.requireNonNull( desiredLoc, "desiredLocation cannot be null" ); + Objects.requireNonNull( mount, "mount cannot be null" ); + Objects.requireNonNull( driveName, "driveName cannot be null" ); // Mount the location String location; FileSystem fileSystem = this.m_environment.getFileSystem(); - if (fileSystem == null) { - throw new IllegalStateException("File system has not been created"); + if( fileSystem == null ) + { + throw new IllegalStateException( "File system has not been created" ); } - synchronized (fileSystem) { - location = this.findFreeLocation(desiredLoc); - if (location != null) { - try { - fileSystem.mountWritable(driveName, location, mount); - } catch (FileSystemException ignored) { + synchronized( fileSystem ) + { + location = this.findFreeLocation( desiredLoc ); + if( location != null ) + { + try + { + fileSystem.mountWritable( driveName, location, mount ); + } + catch( FileSystemException ignored ) + { } } } - if (location != null) { - this.m_mounts.add(location); + if( location != null ) + { + this.m_mounts.add( location ); } return location; } @Override - public void unmount(String location) { - if (location == null) { + public void unmount( String location ) + { + if( location == null ) + { return; } - if (!this.m_mounts.contains(location)) { - throw new IllegalStateException("You didn't mount this location"); + if( !this.m_mounts.contains( location ) ) + { + throw new IllegalStateException( "You didn't mount this location" ); } this.m_environment.getFileSystem() - .unmount(location); - this.m_mounts.remove(location); + .unmount( location ); + this.m_mounts.remove( location ); } @Override - public int getID() { + public int getID() + { return this.m_environment.getComputerID(); } @Override - public void queueEvent(@Nonnull String event, Object... arguments) { - Objects.requireNonNull(event, "event cannot be null"); - this.m_environment.queueEvent(event, arguments); + public void queueEvent( @Nonnull String event, Object... arguments ) + { + Objects.requireNonNull( event, "event cannot be null" ); + this.m_environment.queueEvent( event, arguments ); } @Nonnull @Override - public IWorkMonitor getMainThreadMonitor() { + public IWorkMonitor getMainThreadMonitor() + { return this.m_environment.getMainThreadMonitor(); } - private String findFreeLocation(String desiredLoc) { - try { + private String findFreeLocation( String desiredLoc ) + { + try + { FileSystem fileSystem = this.m_environment.getFileSystem(); - if (!fileSystem.exists(desiredLoc)) { + if( !fileSystem.exists( desiredLoc ) ) + { return desiredLoc; } // We used to check foo2, foo3, foo4, etc here but the disk drive does this itself now return null; - } catch (FileSystemException e) { + } + catch( FileSystemException e ) + { return null; } } diff --git a/src/main/java/dan200/computercraft/core/apis/FSAPI.java b/src/main/java/dan200/computercraft/core/apis/FSAPI.java index c2156a069..fa174c003 100644 --- a/src/main/java/dan200/computercraft/core/apis/FSAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/FSAPI.java @@ -6,18 +6,6 @@ package dan200.computercraft.core.apis; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; -import java.util.HashMap; -import java.util.Map; -import java.util.OptionalLong; -import java.util.function.Function; - - import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.lua.LuaException; @@ -31,31 +19,47 @@ import dan200.computercraft.core.filesystem.FileSystemException; import dan200.computercraft.core.filesystem.FileSystemWrapper; import dan200.computercraft.core.tracking.TrackingField; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.HashMap; +import java.util.Map; +import java.util.OptionalLong; +import java.util.function.Function; + /** * The FS API allows you to manipulate files and the filesystem. * * @cc.module fs */ -public class FSAPI implements ILuaAPI { +public class FSAPI implements ILuaAPI +{ private final IAPIEnvironment environment; private FileSystem fileSystem = null; - public FSAPI(IAPIEnvironment env) { + public FSAPI( IAPIEnvironment env ) + { this.environment = env; } @Override - public String[] getNames() { - return new String[] {"fs"}; + public String[] getNames() + { + return new String[] { "fs" }; } @Override - public void startup() { + public void startup() + { this.fileSystem = this.environment.getFileSystem(); } @Override - public void shutdown() { + public void shutdown() + { this.fileSystem = null; } @@ -67,12 +71,16 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the path doesn't exist. */ @LuaFunction - public final String[] list(String path) throws LuaException { - this.environment.addTrackingChange(TrackingField.FS_OPS); - try { - return this.fileSystem.list(path); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final String[] list( String path ) throws LuaException + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + try + { + return this.fileSystem.list( path ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -82,22 +90,24 @@ public class FSAPI implements ILuaAPI { * * @param arguments The paths to combine. * @return The new path, with separators added between parts as needed. + * @throws LuaException On argument errors. * @cc.tparam string path The first part of the path. For example, a parent directory path. * @cc.tparam string ... Additional parts of the path to combine. - * @throws LuaException On argument errors. */ @LuaFunction - public final String combine( IArguments arguments ) throws LuaException { + public final String combine( IArguments arguments ) throws LuaException + { StringBuilder result = new StringBuilder(); - result.append(FileSystem.sanitizePath(arguments.getString(0), true)); + result.append( FileSystem.sanitizePath( arguments.getString( 0 ), true ) ); - for (int i = 1, n = arguments.count(); i < n; i++) { - String part = FileSystem.sanitizePath(arguments.getString(i), true); - if (result.length() != 0 && !part.isEmpty()) result.append('/'); - result.append(part); + for( int i = 1, n = arguments.count(); i < n; i++ ) + { + String part = FileSystem.sanitizePath( arguments.getString( i ), true ); + if( result.length() != 0 && !part.isEmpty() ) result.append( '/' ); + result.append( part ); } - return FileSystem.sanitizePath(result.toString(), true); + return FileSystem.sanitizePath( result.toString(), true ); } /** @@ -107,8 +117,9 @@ public class FSAPI implements ILuaAPI { * @return The final part of the path (the file name). */ @LuaFunction - public final String getName(String path) { - return FileSystem.getName(path); + public final String getName( String path ) + { + return FileSystem.getName( path ); } /** @@ -118,8 +129,9 @@ public class FSAPI implements ILuaAPI { * @return The path with the final part removed (the parent directory). */ @LuaFunction - public final String getDir(String path) { - return FileSystem.getDirectory(path); + public final String getDir( String path ) + { + return FileSystem.getDirectory( path ); } /** @@ -130,11 +142,15 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the path doesn't exist. */ @LuaFunction - public final long getSize(String path) throws LuaException { - try { - return this.fileSystem.getSize(path); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final long getSize( String path ) throws LuaException + { + try + { + return this.fileSystem.getSize( path ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -145,10 +161,14 @@ public class FSAPI implements ILuaAPI { * @return Whether the path exists. */ @LuaFunction - public final boolean exists(String path) { - try { - return this.fileSystem.exists(path); - } catch (FileSystemException e) { + public final boolean exists( String path ) + { + try + { + return this.fileSystem.exists( path ); + } + catch( FileSystemException e ) + { return false; } } @@ -160,10 +180,14 @@ public class FSAPI implements ILuaAPI { * @return Whether the path is a directory. */ @LuaFunction - public final boolean isDir(String path) { - try { - return this.fileSystem.isDir(path); - } catch (FileSystemException e) { + public final boolean isDir( String path ) + { + try + { + return this.fileSystem.isDir( path ); + } + catch( FileSystemException e ) + { return false; } } @@ -175,10 +199,14 @@ public class FSAPI implements ILuaAPI { * @return Whether the path cannot be written to. */ @LuaFunction - public final boolean isReadOnly(String path) { - try { - return this.fileSystem.isReadOnly(path); - } catch (FileSystemException e) { + public final boolean isReadOnly( String path ) + { + try + { + return this.fileSystem.isReadOnly( path ); + } + catch( FileSystemException e ) + { return false; } } @@ -190,12 +218,16 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the directory couldn't be created. */ @LuaFunction - public final void makeDir(String path) throws LuaException { - try { - this.environment.addTrackingChange(TrackingField.FS_OPS); - this.fileSystem.makeDir(path); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final void makeDir( String path ) throws LuaException + { + try + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + this.fileSystem.makeDir( path ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -209,12 +241,16 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the file or directory couldn't be moved. */ @LuaFunction - public final void move(String path, String dest) throws LuaException { - try { - this.environment.addTrackingChange(TrackingField.FS_OPS); - this.fileSystem.move(path, dest); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final void move( String path, String dest ) throws LuaException + { + try + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + this.fileSystem.move( path, dest ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -228,12 +264,16 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the file or directory couldn't be copied. */ @LuaFunction - public final void copy(String path, String dest) throws LuaException { - try { - this.environment.addTrackingChange(TrackingField.FS_OPS); - this.fileSystem.copy(path, dest); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final void copy( String path, String dest ) throws LuaException + { + try + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + this.fileSystem.copy( path, dest ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -246,12 +286,16 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the file or directory couldn't be deleted. */ @LuaFunction - public final void delete(String path) throws LuaException { - try { - this.environment.addTrackingChange(TrackingField.FS_OPS); - this.fileSystem.delete(path); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final void delete( String path ) throws LuaException + { + try + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + this.fileSystem.delete( path ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -272,44 +316,55 @@ public class FSAPI implements ILuaAPI { * @cc.treturn string|nil A message explaining why the file cannot be opened. */ @LuaFunction - public final Object[] open(String path, String mode) throws LuaException { - this.environment.addTrackingChange(TrackingField.FS_OPS); - try { - switch (mode) { - case "r": { - // Open the file for reading, then create a wrapper around the reader - FileSystemWrapper reader = this.fileSystem.openForRead(path, EncodedReadableHandle::openUtf8); - return new Object[] {new EncodedReadableHandle(reader.get(), reader)}; + public final Object[] open( String path, String mode ) throws LuaException + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + try + { + switch( mode ) + { + case "r": + { + // Open the file for reading, then create a wrapper around the reader + FileSystemWrapper reader = this.fileSystem.openForRead( path, EncodedReadableHandle::openUtf8 ); + return new Object[] { new EncodedReadableHandle( reader.get(), reader ) }; + } + case "w": + { + // Open the file for writing, then create a wrapper around the writer + FileSystemWrapper writer = this.fileSystem.openForWrite( path, false, EncodedWritableHandle::openUtf8 ); + return new Object[] { new EncodedWritableHandle( writer.get(), writer ) }; + } + case "a": + { + // Open the file for appending, then create a wrapper around the writer + FileSystemWrapper writer = this.fileSystem.openForWrite( path, true, EncodedWritableHandle::openUtf8 ); + return new Object[] { new EncodedWritableHandle( writer.get(), writer ) }; + } + case "rb": + { + // Open the file for binary reading, then create a wrapper around the reader + FileSystemWrapper reader = this.fileSystem.openForRead( path, Function.identity() ); + return new Object[] { BinaryReadableHandle.of( reader.get(), reader ) }; + } + case "wb": + { + // Open the file for binary writing, then create a wrapper around the writer + FileSystemWrapper writer = this.fileSystem.openForWrite( path, false, Function.identity() ); + return new Object[] { BinaryWritableHandle.of( writer.get(), writer ) }; + } + case "ab": + { + // Open the file for binary appending, then create a wrapper around the reader + FileSystemWrapper writer = this.fileSystem.openForWrite( path, true, Function.identity() ); + return new Object[] { BinaryWritableHandle.of( writer.get(), writer ) }; + } + default: + throw new LuaException( "Unsupported mode" ); } - case "w": { - // Open the file for writing, then create a wrapper around the writer - FileSystemWrapper writer = this.fileSystem.openForWrite(path, false, EncodedWritableHandle::openUtf8); - return new Object[] {new EncodedWritableHandle(writer.get(), writer)}; - } - case "a": { - // Open the file for appending, then create a wrapper around the writer - FileSystemWrapper writer = this.fileSystem.openForWrite(path, true, EncodedWritableHandle::openUtf8); - return new Object[] {new EncodedWritableHandle(writer.get(), writer)}; - } - case "rb": { - // Open the file for binary reading, then create a wrapper around the reader - FileSystemWrapper reader = this.fileSystem.openForRead(path, Function.identity()); - return new Object[] {BinaryReadableHandle.of(reader.get(), reader)}; - } - case "wb": { - // Open the file for binary writing, then create a wrapper around the writer - FileSystemWrapper writer = this.fileSystem.openForWrite(path, false, Function.identity()); - return new Object[] {BinaryWritableHandle.of(writer.get(), writer)}; - } - case "ab": { - // Open the file for binary appending, then create a wrapper around the reader - FileSystemWrapper writer = this.fileSystem.openForWrite(path, true, Function.identity()); - return new Object[] {BinaryWritableHandle.of(writer.get(), writer)}; - } - default: - throw new LuaException("Unsupported mode"); - } - } catch (FileSystemException e) { + } + catch( FileSystemException e ) + { return new Object[] { null, e.getMessage() @@ -326,11 +381,15 @@ public class FSAPI implements ILuaAPI { * @cc.treturn string The name of the drive that the file is on; e.g. {@code hdd} for local files, or {@code rom} for ROM files. */ @LuaFunction - public final Object[] getDrive(String path) throws LuaException { - try { - return this.fileSystem.exists(path) ? new Object[] {this.fileSystem.getMountLabel(path)} : null; - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final Object[] getDrive( String path ) throws LuaException + { + try + { + return this.fileSystem.exists( path ) ? new Object[] { this.fileSystem.getMountLabel( path ) } : null; + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -343,12 +402,16 @@ public class FSAPI implements ILuaAPI { * @cc.treturn number|"unlimited" The amount of free space available, in bytes, or "unlimited". */ @LuaFunction - public final Object getFreeSpace(String path) throws LuaException { - try { - long freeSpace = this.fileSystem.getFreeSpace(path); + public final Object getFreeSpace( String path ) throws LuaException + { + try + { + long freeSpace = this.fileSystem.getFreeSpace( path ); return freeSpace >= 0 ? freeSpace : "unlimited"; - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -363,12 +426,16 @@ public class FSAPI implements ILuaAPI { * @throws LuaException If the path doesn't exist. */ @LuaFunction - public final String[] find(String path) throws LuaException { - try { - this.environment.addTrackingChange(TrackingField.FS_OPS); - return this.fileSystem.find(path); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + public final String[] find( String path ) throws LuaException + { + try + { + this.environment.addTrackingChange( TrackingField.FS_OPS ); + return this.fileSystem.find( path ); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -384,12 +451,16 @@ public class FSAPI implements ILuaAPI { * @cc.treturn number|nil This drive's capacity. This will be nil for "read-only" drives, such as the ROM or treasure disks. */ @LuaFunction - public final Object getCapacity(String path) throws LuaException { - try { - OptionalLong capacity = this.fileSystem.getCapacity(path); + public final Object getCapacity( String path ) throws LuaException + { + try + { + OptionalLong capacity = this.fileSystem.getCapacity( path ); return capacity.isPresent() ? capacity.getAsLong() : null; - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } @@ -410,9 +481,11 @@ public class FSAPI implements ILuaAPI { * @see #isDir If you only care whether a path is a directory or not. */ @LuaFunction - public final Map attributes(String path) throws LuaException { - try { - BasicFileAttributes attributes = this.fileSystem.getAttributes(path); + public final Map attributes( String path ) throws LuaException + { + try + { + BasicFileAttributes attributes = this.fileSystem.getAttributes( path ); Map result = new HashMap<>(); result.put( "modification", getFileTime( attributes.lastModifiedTime() ) ); result.put( "modified", getFileTime( attributes.lastModifiedTime() ) ); @@ -421,12 +494,15 @@ public class FSAPI implements ILuaAPI { result.put( "isDir", attributes.isDirectory() ); result.put( "isReadOnly", fileSystem.isReadOnly( path ) ); return result; - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); + } + catch( FileSystemException e ) + { + throw new LuaException( e.getMessage() ); } } - private static long getFileTime(FileTime time) { + private static long getFileTime( FileTime time ) + { return time == null ? 0 : time.toMillis(); } } diff --git a/src/main/java/dan200/computercraft/core/apis/FastLuaException.java b/src/main/java/dan200/computercraft/core/apis/FastLuaException.java index cee6aead1..45e4db0b2 100644 --- a/src/main/java/dan200/computercraft/core/apis/FastLuaException.java +++ b/src/main/java/dan200/computercraft/core/apis/FastLuaException.java @@ -5,26 +5,30 @@ */ package dan200.computercraft.core.apis; -import javax.annotation.Nullable; - import dan200.computercraft.api.lua.LuaException; +import javax.annotation.Nullable; + /** * A Lua exception which does not contain its stack trace. */ -public class FastLuaException extends LuaException { +public class FastLuaException extends LuaException +{ private static final long serialVersionUID = 5957864899303561143L; - public FastLuaException(@Nullable String message) { - super(message); + public FastLuaException( @Nullable String message ) + { + super( message ); } - public FastLuaException(@Nullable String message, int level) { - super(message, level); + public FastLuaException( @Nullable String message, int level ) + { + super( message, level ); } @Override - public synchronized Throwable fillInStackTrace() { + public synchronized Throwable fillInStackTrace() + { return this; } } diff --git a/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java b/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java index 698f783b4..396232e92 100644 --- a/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java @@ -156,7 +156,7 @@ public class HTTPAPI implements ILuaAPI @LuaFunction public final Object[] websocket( String address, Optional> headerTbl ) throws LuaException { - if( !ComputerCraft.httpWebsocketEnabled) + if( !ComputerCraft.httpWebsocketEnabled ) { throw new LuaException( "Websocket connections are disabled" ); } @@ -205,4 +205,4 @@ public class HTTPAPI implements ILuaAPI } return headers; } -} \ No newline at end of file +} diff --git a/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java b/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java index ef130fae0..8376b598d 100644 --- a/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java +++ b/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java @@ -6,9 +6,6 @@ package dan200.computercraft.core.apis; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IWorkMonitor; import dan200.computercraft.core.computer.ComputerSide; @@ -17,7 +14,11 @@ import dan200.computercraft.core.filesystem.FileSystem; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.tracking.TrackingField; -public interface IAPIEnvironment { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public interface IAPIEnvironment +{ String TIMER_EVENT = "timer"; int getComputerID(); @@ -37,41 +38,43 @@ public interface IAPIEnvironment { void reboot(); - void queueEvent(String event, Object... args); + void queueEvent( String event, Object... args ); - void setOutput(ComputerSide side, int output); + void setOutput( ComputerSide side, int output ); - int getOutput(ComputerSide side); + int getOutput( ComputerSide side ); - int getInput(ComputerSide side); + int getInput( ComputerSide side ); - void setBundledOutput(ComputerSide side, int output); + void setBundledOutput( ComputerSide side, int output ); - int getBundledOutput(ComputerSide side); + int getBundledOutput( ComputerSide side ); - int getBundledInput(ComputerSide side); + int getBundledInput( ComputerSide side ); - void setPeripheralChangeListener(@Nullable IPeripheralChangeListener listener); + void setPeripheralChangeListener( @Nullable IPeripheralChangeListener listener ); @Nullable - IPeripheral getPeripheral(ComputerSide side); + IPeripheral getPeripheral( ComputerSide side ); String getLabel(); - void setLabel(@Nullable String label); + void setLabel( @Nullable String label ); - int startTimer(long ticks); + int startTimer( long ticks ); - void cancelTimer(int id); + void cancelTimer( int id ); - default void addTrackingChange(@Nonnull TrackingField field) { - this.addTrackingChange(field, 1); + default void addTrackingChange( @Nonnull TrackingField field ) + { + this.addTrackingChange( field, 1 ); } - void addTrackingChange(@Nonnull TrackingField field, long change); + void addTrackingChange( @Nonnull TrackingField field, long change ); @FunctionalInterface - interface IPeripheralChangeListener { - void onPeripheralChanged(ComputerSide side, @Nullable IPeripheral newPeripheral); + interface IPeripheralChangeListener + { + void onPeripheralChanged( ComputerSide side, @Nullable IPeripheral newPeripheral ); } } diff --git a/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java b/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java index 39f307a20..fbb486296 100644 --- a/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java +++ b/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java @@ -6,276 +6,297 @@ package dan200.computercraft.core.apis; +import dan200.computercraft.api.lua.LuaException; + import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatterBuilder; import java.time.format.TextStyle; -import java.time.temporal.ChronoField; -import java.time.temporal.IsoFields; -import java.time.temporal.Temporal; -import java.time.temporal.TemporalAccessor; -import java.time.temporal.TemporalField; -import java.time.temporal.TemporalUnit; -import java.time.temporal.ValueRange; -import java.time.temporal.WeekFields; +import java.time.temporal.*; import java.util.HashMap; import java.util.Map; import java.util.function.LongUnaryOperator; -import dan200.computercraft.api.lua.LuaException; +final class LuaDateTime +{ + private static final TemporalField CENTURY = map( ChronoField.YEAR, ValueRange.of( 0, 6 ), x -> (x / 100) % 100 ); + private static final TemporalField ZERO_WEEK = map( WeekFields.SUNDAY_START.dayOfWeek(), ValueRange.of( 0, 6 ), x -> x - 1 ); -final class LuaDateTime { - private static final TemporalField CENTURY = map(ChronoField.YEAR, ValueRange.of(0, 6), x -> (x / 100) % 100); - private static final TemporalField ZERO_WEEK = map(WeekFields.SUNDAY_START.dayOfWeek(), ValueRange.of(0, 6), x -> x - 1); - - private LuaDateTime() { + private LuaDateTime() + { } - static void format(DateTimeFormatterBuilder formatter, String format, ZoneOffset offset) throws LuaException { - for (int i = 0; i < format.length(); ) { + static void format( DateTimeFormatterBuilder formatter, String format, ZoneOffset offset ) throws LuaException + { + for( int i = 0; i < format.length(); ) + { char c; - switch (c = format.charAt(i++)) { - case '\n': - formatter.appendLiteral('\n'); - break; - default: - formatter.appendLiteral(c); - break; - case '%': - if (i >= format.length()) { + switch( c = format.charAt( i++ ) ) + { + case '\n': + formatter.appendLiteral( '\n' ); break; - } - switch (c = format.charAt(i++)) { default: - throw new LuaException("bad argument #1: invalid conversion specifier '%" + c + "'"); - + formatter.appendLiteral( c ); + break; case '%': - formatter.appendLiteral('%'); - break; - case 'a': - formatter.appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT); - break; - case 'A': - formatter.appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL); - break; - case 'b': - case 'h': - formatter.appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT); - break; - case 'B': - formatter.appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL); - break; - case 'c': - format(formatter, "%a %b %e %H:%M:%S %Y", offset); - break; - case 'C': - formatter.appendValueReduced(CENTURY, 2, 2, 0); - break; - case 'd': - formatter.appendValue(ChronoField.DAY_OF_MONTH, 2); - break; - case 'D': - case 'x': - format(formatter, "%m/%d/%y", offset); - break; - case 'e': - formatter.padNext(2) - .appendValue(ChronoField.DAY_OF_MONTH); - break; - case 'F': - format(formatter, "%Y-%m-%d", offset); - break; - case 'g': - formatter.appendValueReduced(IsoFields.WEEK_BASED_YEAR, 2, 2, 0); - break; - case 'G': - formatter.appendValue(IsoFields.WEEK_BASED_YEAR); - break; - case 'H': - formatter.appendValue(ChronoField.HOUR_OF_DAY, 2); - break; - case 'I': - formatter.appendValue(ChronoField.HOUR_OF_AMPM); - break; - case 'j': - formatter.appendValue(ChronoField.DAY_OF_YEAR, 3); - break; - case 'm': - formatter.appendValue(ChronoField.MONTH_OF_YEAR, 2); - break; - case 'M': - formatter.appendValue(ChronoField.MINUTE_OF_HOUR, 2); - break; - case 'n': - formatter.appendLiteral('\n'); - break; - case 'p': - formatter.appendText(ChronoField.AMPM_OF_DAY); - break; - case 'r': - format(formatter, "%I:%M:%S %p", offset); - break; - case 'R': - format(formatter, "%H:%M", offset); - break; - case 'S': - formatter.appendValue(ChronoField.SECOND_OF_MINUTE, 2); - break; - case 't': - formatter.appendLiteral('\t'); - break; - case 'T': - case 'X': - format(formatter, "%H:%M:%S", offset); - break; - case 'u': - formatter.appendValue(ChronoField.DAY_OF_WEEK); - break; - case 'U': - formatter.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2); - break; - case 'V': - formatter.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2); - break; - case 'w': - formatter.appendValue(ZERO_WEEK); - break; - case 'W': - formatter.appendValue(WeekFields.ISO.weekOfYear(), 2); - break; - case 'y': - formatter.appendValueReduced(ChronoField.YEAR, 2, 2, 0); - break; - case 'Y': - formatter.appendValue(ChronoField.YEAR); - break; - case 'z': - formatter.appendOffset("+HHMM", "+0000"); - break; - case 'Z': - formatter.appendChronologyId(); - break; - } + if( i >= format.length() ) + { + break; + } + switch( c = format.charAt( i++ ) ) + { + default: + throw new LuaException( "bad argument #1: invalid conversion specifier '%" + c + "'" ); + + case '%': + formatter.appendLiteral( '%' ); + break; + case 'a': + formatter.appendText( ChronoField.DAY_OF_WEEK, TextStyle.SHORT ); + break; + case 'A': + formatter.appendText( ChronoField.DAY_OF_WEEK, TextStyle.FULL ); + break; + case 'b': + case 'h': + formatter.appendText( ChronoField.MONTH_OF_YEAR, TextStyle.SHORT ); + break; + case 'B': + formatter.appendText( ChronoField.MONTH_OF_YEAR, TextStyle.FULL ); + break; + case 'c': + format( formatter, "%a %b %e %H:%M:%S %Y", offset ); + break; + case 'C': + formatter.appendValueReduced( CENTURY, 2, 2, 0 ); + break; + case 'd': + formatter.appendValue( ChronoField.DAY_OF_MONTH, 2 ); + break; + case 'D': + case 'x': + format( formatter, "%m/%d/%y", offset ); + break; + case 'e': + formatter.padNext( 2 ) + .appendValue( ChronoField.DAY_OF_MONTH ); + break; + case 'F': + format( formatter, "%Y-%m-%d", offset ); + break; + case 'g': + formatter.appendValueReduced( IsoFields.WEEK_BASED_YEAR, 2, 2, 0 ); + break; + case 'G': + formatter.appendValue( IsoFields.WEEK_BASED_YEAR ); + break; + case 'H': + formatter.appendValue( ChronoField.HOUR_OF_DAY, 2 ); + break; + case 'I': + formatter.appendValue( ChronoField.HOUR_OF_AMPM ); + break; + case 'j': + formatter.appendValue( ChronoField.DAY_OF_YEAR, 3 ); + break; + case 'm': + formatter.appendValue( ChronoField.MONTH_OF_YEAR, 2 ); + break; + case 'M': + formatter.appendValue( ChronoField.MINUTE_OF_HOUR, 2 ); + break; + case 'n': + formatter.appendLiteral( '\n' ); + break; + case 'p': + formatter.appendText( ChronoField.AMPM_OF_DAY ); + break; + case 'r': + format( formatter, "%I:%M:%S %p", offset ); + break; + case 'R': + format( formatter, "%H:%M", offset ); + break; + case 'S': + formatter.appendValue( ChronoField.SECOND_OF_MINUTE, 2 ); + break; + case 't': + formatter.appendLiteral( '\t' ); + break; + case 'T': + case 'X': + format( formatter, "%H:%M:%S", offset ); + break; + case 'u': + formatter.appendValue( ChronoField.DAY_OF_WEEK ); + break; + case 'U': + formatter.appendValue( ChronoField.ALIGNED_WEEK_OF_YEAR, 2 ); + break; + case 'V': + formatter.appendValue( IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2 ); + break; + case 'w': + formatter.appendValue( ZERO_WEEK ); + break; + case 'W': + formatter.appendValue( WeekFields.ISO.weekOfYear(), 2 ); + break; + case 'y': + formatter.appendValueReduced( ChronoField.YEAR, 2, 2, 0 ); + break; + case 'Y': + formatter.appendValue( ChronoField.YEAR ); + break; + case 'z': + formatter.appendOffset( "+HHMM", "+0000" ); + break; + case 'Z': + formatter.appendChronologyId(); + break; + } } } } - static long fromTable(Map table) throws LuaException { - int year = getField(table, "year", -1); - int month = getField(table, "month", -1); - int day = getField(table, "day", -1); - int hour = getField(table, "hour", 12); - int minute = getField(table, "min", 12); - int second = getField(table, "sec", 12); - LocalDateTime time = LocalDateTime.of(year, month, day, hour, minute, second); + static long fromTable( Map table ) throws LuaException + { + int year = getField( table, "year", -1 ); + int month = getField( table, "month", -1 ); + int day = getField( table, "day", -1 ); + int hour = getField( table, "hour", 12 ); + int minute = getField( table, "min", 12 ); + int second = getField( table, "sec", 12 ); + LocalDateTime time = LocalDateTime.of( year, month, day, hour, minute, second ); - Boolean isDst = getBoolField(table, "isdst"); - if (isDst != null) { + Boolean isDst = getBoolField( table, "isdst" ); + if( isDst != null ) + { boolean requireDst = isDst; - for (ZoneOffset possibleOffset : ZoneOffset.systemDefault() - .getRules() - .getValidOffsets(time)) { - Instant instant = time.toInstant(possibleOffset); - if (possibleOffset.getRules() - .getDaylightSavings(instant) - .isZero() == requireDst) { + for( ZoneOffset possibleOffset : ZoneOffset.systemDefault() + .getRules() + .getValidOffsets( time ) ) + { + Instant instant = time.toInstant( possibleOffset ); + if( possibleOffset.getRules() + .getDaylightSavings( instant ) + .isZero() == requireDst ) + { return instant.getEpochSecond(); } } } ZoneOffset offset = ZoneOffset.systemDefault() - .getRules() - .getOffset(time); - return time.toInstant(offset) - .getEpochSecond(); + .getRules() + .getOffset( time ); + return time.toInstant( offset ) + .getEpochSecond(); } - private static int getField(Map table, String field, int def) throws LuaException { - Object value = table.get(field); - if (value instanceof Number) { + private static int getField( Map table, String field, int def ) throws LuaException + { + Object value = table.get( field ); + if( value instanceof Number ) + { return ((Number) value).intValue(); } - if (def < 0) { - throw new LuaException("field \"" + field + "\" missing in date table"); + if( def < 0 ) + { + throw new LuaException( "field \"" + field + "\" missing in date table" ); } return def; } - private static Boolean getBoolField(Map table, String field) throws LuaException { - Object value = table.get(field); - if (value instanceof Boolean || value == null) { + private static Boolean getBoolField( Map table, String field ) throws LuaException + { + Object value = table.get( field ); + if( value instanceof Boolean || value == null ) + { return (Boolean) value; } - throw new LuaException("field \"" + field + "\" missing in date table"); + throw new LuaException( "field \"" + field + "\" missing in date table" ); } - static Map toTable(TemporalAccessor date, ZoneId offset, Instant instant) { - HashMap table = new HashMap<>(9); - table.put("year", date.getLong(ChronoField.YEAR)); - table.put("month", date.getLong(ChronoField.MONTH_OF_YEAR)); - table.put("day", date.getLong(ChronoField.DAY_OF_MONTH)); - table.put("hour", date.getLong(ChronoField.HOUR_OF_DAY)); - table.put("min", date.getLong(ChronoField.MINUTE_OF_HOUR)); - table.put("sec", date.getLong(ChronoField.SECOND_OF_MINUTE)); - table.put("wday", date.getLong(WeekFields.SUNDAY_START.dayOfWeek())); - table.put("yday", date.getLong(ChronoField.DAY_OF_YEAR)); - table.put("isdst", - offset.getRules() - .isDaylightSavings(instant)); + static Map toTable( TemporalAccessor date, ZoneId offset, Instant instant ) + { + HashMap table = new HashMap<>( 9 ); + table.put( "year", date.getLong( ChronoField.YEAR ) ); + table.put( "month", date.getLong( ChronoField.MONTH_OF_YEAR ) ); + table.put( "day", date.getLong( ChronoField.DAY_OF_MONTH ) ); + table.put( "hour", date.getLong( ChronoField.HOUR_OF_DAY ) ); + table.put( "min", date.getLong( ChronoField.MINUTE_OF_HOUR ) ); + table.put( "sec", date.getLong( ChronoField.SECOND_OF_MINUTE ) ); + table.put( "wday", date.getLong( WeekFields.SUNDAY_START.dayOfWeek() ) ); + table.put( "yday", date.getLong( ChronoField.DAY_OF_YEAR ) ); + table.put( "isdst", + offset.getRules() + .isDaylightSavings( instant ) ); return table; } - private static TemporalField map(TemporalField field, ValueRange range, LongUnaryOperator convert) { - return new TemporalField() { - private final ValueRange range = ValueRange.of(0, 99); + private static TemporalField map( TemporalField field, ValueRange range, LongUnaryOperator convert ) + { + return new TemporalField() + { + private final ValueRange range = ValueRange.of( 0, 99 ); @Override - public TemporalUnit getBaseUnit() { + public TemporalUnit getBaseUnit() + { return field.getBaseUnit(); } @Override - public TemporalUnit getRangeUnit() { + public TemporalUnit getRangeUnit() + { return field.getRangeUnit(); } @Override - public ValueRange range() { + public ValueRange range() + { return this.range; } @Override - public boolean isDateBased() { + public boolean isDateBased() + { return field.isDateBased(); } @Override - public boolean isTimeBased() { + public boolean isTimeBased() + { return field.isTimeBased(); } @Override - public boolean isSupportedBy(TemporalAccessor temporal) { - return field.isSupportedBy(temporal); + public boolean isSupportedBy( TemporalAccessor temporal ) + { + return field.isSupportedBy( temporal ); } @Override - public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + public ValueRange rangeRefinedBy( TemporalAccessor temporal ) + { return this.range; } @Override - public long getFrom(TemporalAccessor temporal) { - return convert.applyAsLong(temporal.getLong(field)); + public long getFrom( TemporalAccessor temporal ) + { + return convert.applyAsLong( temporal.getLong( field ) ); } @Override - @SuppressWarnings ("unchecked") - public R adjustInto(R temporal, long newValue) { - return (R) temporal.with(field, newValue); + @SuppressWarnings( "unchecked" ) + public R adjustInto( R temporal, long newValue ) + { + return (R) temporal.with( field, newValue ); } }; } diff --git a/src/main/java/dan200/computercraft/core/apis/OSAPI.java b/src/main/java/dan200/computercraft/core/apis/OSAPI.java index 27da0462d..c34a8ef7d 100644 --- a/src/main/java/dan200/computercraft/core/apis/OSAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/OSAPI.java @@ -6,23 +6,6 @@ package dan200.computercraft.core.apis; -import static dan200.computercraft.api.lua.LuaValues.checkFinite; - -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatterBuilder; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.TimeZone; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.lua.LuaException; @@ -31,12 +14,23 @@ import dan200.computercraft.shared.util.StringUtil; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import javax.annotation.Nonnull; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatterBuilder; +import java.util.*; + +import static dan200.computercraft.api.lua.LuaValues.checkFinite; + /** * The {@link OSAPI} API allows interacting with the current computer. * * @cc.module os */ -public class OSAPI implements ILuaAPI { +public class OSAPI implements ILuaAPI +{ private final IAPIEnvironment apiEnvironment; private final Int2ObjectMap m_alarms = new Int2ObjectOpenHashMap<>(); @@ -46,51 +40,60 @@ public class OSAPI implements ILuaAPI { private int m_nextAlarmToken = 0; - public OSAPI(IAPIEnvironment environment) { + public OSAPI( IAPIEnvironment environment ) + { this.apiEnvironment = environment; } @Override - public String[] getNames() { - return new String[] {"os"}; + public String[] getNames() + { + return new String[] { "os" }; } @Override - public void startup() { + public void startup() + { this.m_time = this.apiEnvironment.getComputerEnvironment() - .getTimeOfDay(); + .getTimeOfDay(); this.m_day = this.apiEnvironment.getComputerEnvironment() - .getDay(); + .getDay(); this.m_clock = 0; - synchronized (this.m_alarms) { + synchronized( this.m_alarms ) + { this.m_alarms.clear(); } } @Override - public void update() { + public void update() + { this.m_clock++; // Wait for all of our alarms - synchronized (this.m_alarms) { + synchronized( this.m_alarms ) + { double previousTime = this.m_time; int previousDay = this.m_day; double time = this.apiEnvironment.getComputerEnvironment() - .getTimeOfDay(); + .getTimeOfDay(); int day = this.apiEnvironment.getComputerEnvironment() - .getDay(); + .getDay(); - if (time > previousTime || day > previousDay) { + if( time > previousTime || day > previousDay ) + { double now = this.m_day * 24.0 + this.m_time; Iterator> it = this.m_alarms.int2ObjectEntrySet() - .iterator(); - while (it.hasNext()) { + .iterator(); + while( it.hasNext() ) + { Int2ObjectMap.Entry entry = it.next(); Alarm alarm = entry.getValue(); double t = alarm.m_day * 24.0 + alarm.m_time; - if (now >= t) { - this.apiEnvironment.queueEvent("alarm", entry.getIntKey()); + if( now >= t ) + { + this.apiEnvironment.queueEvent( "alarm", entry.getIntKey() ); it.remove(); } } @@ -102,8 +105,10 @@ public class OSAPI implements ILuaAPI { } @Override - public void shutdown() { - synchronized (this.m_alarms) { + public void shutdown() + { + synchronized( this.m_alarms ) + { this.m_alarms.clear(); } } @@ -118,10 +123,11 @@ public class OSAPI implements ILuaAPI { * @cc.see os.pullEvent To pull the event queued */ @LuaFunction - public final void queueEvent(String name, IArguments args) { - this.apiEnvironment.queueEvent(name, - args.drop(1) - .getAll()); + public final void queueEvent( String name, IArguments args ) + { + this.apiEnvironment.queueEvent( name, + args.drop( 1 ) + .getAll() ); } /** @@ -133,8 +139,9 @@ public class OSAPI implements ILuaAPI { * @throws LuaException If the time is below zero. */ @LuaFunction - public final int startTimer(double timer) throws LuaException { - return this.apiEnvironment.startTimer(Math.round(checkFinite(0, timer) / 0.05)); + public final int startTimer( double timer ) throws LuaException + { + return this.apiEnvironment.startTimer( Math.round( checkFinite( 0, timer ) / 0.05 ) ); } /** @@ -144,8 +151,9 @@ public class OSAPI implements ILuaAPI { * @see #startTimer To start a timer. */ @LuaFunction - public final void cancelTimer(int token) { - this.apiEnvironment.cancelTimer(token); + public final void cancelTimer( int token ) + { + this.apiEnvironment.cancelTimer( token ); } /** @@ -156,14 +164,17 @@ public class OSAPI implements ILuaAPI { * @throws LuaException If the time is out of range. */ @LuaFunction - public final int setAlarm(double time) throws LuaException { - checkFinite(0, time); - if (time < 0.0 || time >= 24.0) { - throw new LuaException("Number out of range"); + public final int setAlarm( double time ) throws LuaException + { + checkFinite( 0, time ); + if( time < 0.0 || time >= 24.0 ) + { + throw new LuaException( "Number out of range" ); } - synchronized (this.m_alarms) { + synchronized( this.m_alarms ) + { int day = time > this.m_time ? this.m_day : this.m_day + 1; - this.m_alarms.put(this.m_nextAlarmToken, new Alarm(time, day)); + this.m_alarms.put( this.m_nextAlarmToken, new Alarm( time, day ) ); return this.m_nextAlarmToken++; } } @@ -175,25 +186,29 @@ public class OSAPI implements ILuaAPI { * @see #setAlarm To set an alarm. */ @LuaFunction - public final void cancelAlarm(int token) { - synchronized (this.m_alarms) { - this.m_alarms.remove(token); + public final void cancelAlarm( int token ) + { + synchronized( this.m_alarms ) + { + this.m_alarms.remove( token ); } } /** * Shuts down the computer immediately. */ - @LuaFunction ("shutdown") - public final void doShutdown() { + @LuaFunction( "shutdown" ) + public final void doShutdown() + { this.apiEnvironment.shutdown(); } /** * Reboots the computer immediately. */ - @LuaFunction ("reboot") - public final void doReboot() { + @LuaFunction( "reboot" ) + public final void doReboot() + { this.apiEnvironment.reboot(); } @@ -202,11 +217,12 @@ public class OSAPI implements ILuaAPI { * * @return The ID of the computer. */ - @LuaFunction ({ + @LuaFunction( { "getComputerID", "computerID" - }) - public final int getComputerID() { + } ) + public final int getComputerID() + { return this.apiEnvironment.getComputerID(); } @@ -216,13 +232,14 @@ public class OSAPI implements ILuaAPI { * @return The label of the computer. * @cc.treturn string The label of the computer. */ - @LuaFunction ({ + @LuaFunction( { "getComputerLabel", "computerLabel" - }) - public final Object[] getComputerLabel() { + } ) + public final Object[] getComputerLabel() + { String label = this.apiEnvironment.getLabel(); - return label == null ? null : new Object[] {label}; + return label == null ? null : new Object[] { label }; } /** @@ -231,8 +248,9 @@ public class OSAPI implements ILuaAPI { * @param label The new label. May be {@code nil} in order to clear it. */ @LuaFunction - public final void setComputerLabel(Optional label) { - this.apiEnvironment.setLabel(StringUtil.normaliseLabel(label.orElse(null))); + public final void setComputerLabel( Optional label ) + { + this.apiEnvironment.setLabel( StringUtil.normaliseLabel( label.orElse( null ) ) ); } /** @@ -241,7 +259,8 @@ public class OSAPI implements ILuaAPI { * @return The computer's uptime. */ @LuaFunction - public final double clock() { + public final double clock() + { return this.m_clock * 0.05; } @@ -258,33 +277,37 @@ public class OSAPI implements ILuaAPI { * @return The hour of the selected locale, or a UNIX timestamp from the table, depending on the argument passed in. * @throws LuaException If an invalid locale is passed. * @cc.tparam [opt] string|table locale The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code ingame} - * locale if not specified. + * locale if not specified. * @see #date To get a date table that can be converted with this function. */ @LuaFunction - public final Object time(IArguments args) throws LuaException { - Object value = args.get(0); - if (value instanceof Map) { - return LuaDateTime.fromTable((Map) value); + public final Object time( IArguments args ) throws LuaException + { + Object value = args.get( 0 ); + if( value instanceof Map ) + { + return LuaDateTime.fromTable( (Map) value ); } - String param = args.optString(0, "ingame"); - switch (param.toLowerCase(Locale.ROOT)) { - case "utc": // Get Hour of day (UTC) - return getTimeForCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTC"))); - case "local": // Get Hour of day (local time) - return getTimeForCalendar(Calendar.getInstance()); - case "ingame": // Get in-game hour - return this.m_time; - default: - throw new LuaException("Unsupported operation"); + String param = args.optString( 0, "ingame" ); + switch( param.toLowerCase( Locale.ROOT ) ) + { + case "utc": // Get Hour of day (UTC) + return getTimeForCalendar( Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ) ); + case "local": // Get Hour of day (local time) + return getTimeForCalendar( Calendar.getInstance() ); + case "ingame": // Get in-game hour + return this.m_time; + default: + throw new LuaException( "Unsupported operation" ); } } - private static float getTimeForCalendar(Calendar c) { - float time = c.get(Calendar.HOUR_OF_DAY); - time += c.get(Calendar.MINUTE) / 60.0f; - time += c.get(Calendar.SECOND) / (60.0f * 60.0f); + private static float getTimeForCalendar( Calendar c ) + { + float time = c.get( Calendar.HOUR_OF_DAY ); + time += c.get( Calendar.MINUTE ) / 60.0f; + time += c.get( Calendar.SECOND ) / (60.0f * 60.0f); return time; } @@ -300,28 +323,32 @@ public class OSAPI implements ILuaAPI { * @throws LuaException If an invalid locale is passed. */ @LuaFunction - public final int day(Optional args) throws LuaException { - switch (args.orElse("ingame") - .toLowerCase(Locale.ROOT)) { - case "utc": // Get numbers of days since 1970-01-01 (utc) - return getDayForCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTC"))); - case "local": // Get numbers of days since 1970-01-01 (local time) - return getDayForCalendar(Calendar.getInstance()); - case "ingame":// Get game day - return this.m_day; - default: - throw new LuaException("Unsupported operation"); + public final int day( Optional args ) throws LuaException + { + switch( args.orElse( "ingame" ) + .toLowerCase( Locale.ROOT ) ) + { + case "utc": // Get numbers of days since 1970-01-01 (utc) + return getDayForCalendar( Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ) ); + case "local": // Get numbers of days since 1970-01-01 (local time) + return getDayForCalendar( Calendar.getInstance() ); + case "ingame":// Get game day + return this.m_day; + default: + throw new LuaException( "Unsupported operation" ); } } - private static int getDayForCalendar(Calendar c) { + private static int getDayForCalendar( Calendar c ) + { GregorianCalendar g = c instanceof GregorianCalendar ? (GregorianCalendar) c : new GregorianCalendar(); - int year = c.get(Calendar.YEAR); + int year = c.get( Calendar.YEAR ); int day = 0; - for (int y = 1970; y < year; y++) { - day += g.isLeapYear(y) ? 366 : 365; + for( int y = 1970; y < year; y++ ) + { + day += g.isLeapYear( y ) ? 366 : 365; } - day += c.get(Calendar.DAY_OF_YEAR); + day += c.get( Calendar.DAY_OF_YEAR ); return day; } @@ -337,32 +364,38 @@ public class OSAPI implements ILuaAPI { * @throws LuaException If an invalid locale is passed. */ @LuaFunction - public final long epoch(Optional args) throws LuaException { - switch (args.orElse("ingame") - .toLowerCase(Locale.ROOT)) { - case "utc": { - // Get utc epoch - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - return getEpochForCalendar(c); - } - case "local": { - // Get local epoch - Calendar c = Calendar.getInstance(); - return getEpochForCalendar(c); - } - case "ingame": - // Get in-game epoch - synchronized (this.m_alarms) { - return this.m_day * 86400000L + (long) (this.m_time * 3600000.0); + public final long epoch( Optional args ) throws LuaException + { + switch( args.orElse( "ingame" ) + .toLowerCase( Locale.ROOT ) ) + { + case "utc": + { + // Get utc epoch + Calendar c = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); + return getEpochForCalendar( c ); } - default: - throw new LuaException("Unsupported operation"); + case "local": + { + // Get local epoch + Calendar c = Calendar.getInstance(); + return getEpochForCalendar( c ); + } + case "ingame": + // Get in-game epoch + synchronized( this.m_alarms ) + { + return this.m_day * 86400000L + (long) (this.m_time * 3600000.0); + } + default: + throw new LuaException( "Unsupported operation" ); } } - private static long getEpochForCalendar(Calendar c) { + private static long getEpochForCalendar( Calendar c ) + { return c.getTime() - .getTime(); + .getTime(); } /** @@ -376,54 +409,62 @@ public class OSAPI implements ILuaAPI { * UNIX timestamp (days since 1 January 1970) with {@link #date}. * * @param formatA The format of the string to return. This defaults to {@code %c}, which expands to a string similar to "Sat Dec 24 16:58:00 2011". - * @param timeA The time to convert to a string. This defaults to the current time. + * @param timeA The time to convert to a string. This defaults to the current time. * @return The resulting format string. * @throws LuaException If an invalid format is passed. */ @LuaFunction - public final Object date(Optional formatA, Optional timeA) throws LuaException { - String format = formatA.orElse("%c"); - long time = timeA.orElseGet(() -> Instant.now() - .getEpochSecond()); + public final Object date( Optional formatA, Optional timeA ) throws LuaException + { + String format = formatA.orElse( "%c" ); + long time = timeA.orElseGet( () -> Instant.now() + .getEpochSecond() ); - Instant instant = Instant.ofEpochSecond(time); + Instant instant = Instant.ofEpochSecond( time ); ZonedDateTime date; ZoneOffset offset; - if (format.startsWith("!")) { + if( format.startsWith( "!" ) ) + { offset = ZoneOffset.UTC; - date = ZonedDateTime.ofInstant(instant, offset); - format = format.substring(1); - } else { + date = ZonedDateTime.ofInstant( instant, offset ); + format = format.substring( 1 ); + } + else + { ZoneId id = ZoneId.systemDefault(); offset = id.getRules() - .getOffset(instant); - date = ZonedDateTime.ofInstant(instant, id); + .getOffset( instant ); + date = ZonedDateTime.ofInstant( instant, id ); } - if (format.equals("*t")) { - return LuaDateTime.toTable(date, offset, instant); + if( format.equals( "*t" ) ) + { + return LuaDateTime.toTable( date, offset, instant ); } DateTimeFormatterBuilder formatter = new DateTimeFormatterBuilder(); - LuaDateTime.format(formatter, format, offset); - return formatter.toFormatter(Locale.ROOT) - .format(date); + LuaDateTime.format( formatter, format, offset ); + return formatter.toFormatter( Locale.ROOT ) + .format( date ); } - private static class Alarm implements Comparable { + private static class Alarm implements Comparable + { final double m_time; final int m_day; - Alarm(double time, int day) { + Alarm( double time, int day ) + { this.m_time = time; this.m_day = day; } @Override - public int compareTo(@Nonnull Alarm o) { + public int compareTo( @Nonnull Alarm o ) + { double t = this.m_day * 24.0 + this.m_time; double ot = this.m_day * 24.0 + this.m_time; - return Double.compare(t, ot); + return Double.compare( t, ot ); } } diff --git a/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java b/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java index 916aa4541..58c40004e 100644 --- a/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java @@ -6,24 +6,9 @@ package dan200.computercraft.core.apis; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.ILuaAPI; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; -import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.lua.*; import dan200.computercraft.api.peripheral.IDynamicPeripheral; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IWorkMonitor; @@ -34,35 +19,45 @@ import dan200.computercraft.core.asm.PeripheralMethod; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.core.tracking.TrackingField; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; + /** * CC's "native" peripheral API. This is wrapped within CraftOS to provide a version which works with modems. * * @cc.module peripheral * @hidden */ -public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener { +public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener +{ private final IAPIEnvironment environment; private final PeripheralWrapper[] peripherals = new PeripheralWrapper[6]; private boolean running; - public PeripheralAPI(IAPIEnvironment environment) { + + public PeripheralAPI( IAPIEnvironment environment ) + { this.environment = environment; - this.environment.setPeripheralChangeListener(this); + this.environment.setPeripheralChangeListener( this ); this.running = false; } - public static Map getMethods(IPeripheral peripheral) { - String[] dynamicMethods = peripheral instanceof IDynamicPeripheral ? Objects.requireNonNull(((IDynamicPeripheral) peripheral).getMethodNames(), - "Peripheral methods cannot be null") : - LuaMethod.EMPTY_METHODS; + public static Map getMethods( IPeripheral peripheral ) + { + String[] dynamicMethods = peripheral instanceof IDynamicPeripheral ? Objects.requireNonNull( ((IDynamicPeripheral) peripheral).getMethodNames(), + "Peripheral methods cannot be null" ) : + LuaMethod.EMPTY_METHODS; - List> methods = PeripheralMethod.GENERATOR.getMethods(peripheral.getClass()); + List> methods = PeripheralMethod.GENERATOR.getMethods( peripheral.getClass() ); - Map methodMap = new HashMap<>(methods.size() + dynamicMethods.length); - for (int i = 0; i < dynamicMethods.length; i++) { - methodMap.put(dynamicMethods[i], PeripheralMethod.DYNAMIC.get(i)); + Map methodMap = new HashMap<>( methods.size() + dynamicMethods.length ); + for( int i = 0; i < dynamicMethods.length; i++ ) + { + methodMap.put( dynamicMethods[i], PeripheralMethod.DYNAMIC.get( i ) ); } - for (NamedMethod method : methods) { - methodMap.put(method.getName(), method.getMethod()); + for( NamedMethod method : methods ) + { + methodMap.put( method.getName(), method.getMethod() ); } return methodMap; } @@ -70,48 +65,59 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange // IPeripheralChangeListener @Override - public void onPeripheralChanged(ComputerSide side, IPeripheral newPeripheral) { - synchronized (this.peripherals) { + public void onPeripheralChanged( ComputerSide side, IPeripheral newPeripheral ) + { + synchronized( this.peripherals ) + { int index = side.ordinal(); - if (this.peripherals[index] != null) { + if( this.peripherals[index] != null ) + { // Queue a detachment final PeripheralWrapper wrapper = this.peripherals[index]; - if (wrapper.isAttached()) { + if( wrapper.isAttached() ) + { wrapper.detach(); } // Queue a detachment event - this.environment.queueEvent("peripheral_detach", side.getName()); + this.environment.queueEvent( "peripheral_detach", side.getName() ); } // Assign the new peripheral - this.peripherals[index] = newPeripheral == null ? null : new PeripheralWrapper(newPeripheral, side.getName()); + this.peripherals[index] = newPeripheral == null ? null : new PeripheralWrapper( newPeripheral, side.getName() ); - if (this.peripherals[index] != null) { + if( this.peripherals[index] != null ) + { // Queue an attachment final PeripheralWrapper wrapper = this.peripherals[index]; - if (this.running && !wrapper.isAttached()) { + if( this.running && !wrapper.isAttached() ) + { wrapper.attach(); } // Queue an attachment event - this.environment.queueEvent("peripheral", side.getName()); + this.environment.queueEvent( "peripheral", side.getName() ); } } } @Override - public String[] getNames() { - return new String[] {"peripheral"}; + public String[] getNames() + { + return new String[] { "peripheral" }; } @Override - public void startup() { - synchronized (this.peripherals) { + public void startup() + { + synchronized( this.peripherals ) + { this.running = true; - for (int i = 0; i < 6; i++) { + for( int i = 0; i < 6; i++ ) + { PeripheralWrapper wrapper = this.peripherals[i]; - if (wrapper != null && !wrapper.isAttached()) { + if( wrapper != null && !wrapper.isAttached() ) + { wrapper.attach(); } } @@ -119,12 +125,16 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange } @Override - public void shutdown() { - synchronized (this.peripherals) { + public void shutdown() + { + synchronized( this.peripherals ) + { this.running = false; - for (int i = 0; i < 6; i++) { + for( int i = 0; i < 6; i++ ) + { PeripheralWrapper wrapper = this.peripherals[i]; - if (wrapper != null && wrapper.isAttached()) { + if( wrapper != null && wrapper.isAttached() ) + { wrapper.detach(); } } @@ -132,12 +142,16 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange } @LuaFunction - public final boolean isPresent(String sideName) { - ComputerSide side = ComputerSide.valueOfInsensitive(sideName); - if (side != null) { - synchronized (this.peripherals) { + public final boolean isPresent( String sideName ) + { + ComputerSide side = ComputerSide.valueOfInsensitive( sideName ); + if( side != null ) + { + synchronized( this.peripherals ) + { PeripheralWrapper p = this.peripherals[side.ordinal()]; - if (p != null) { + if( p != null ) + { return true; } } @@ -146,69 +160,86 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange } @LuaFunction - public final Object[] getType(String sideName) { - ComputerSide side = ComputerSide.valueOfInsensitive(sideName); - if (side == null) { + public final Object[] getType( String sideName ) + { + ComputerSide side = ComputerSide.valueOfInsensitive( sideName ); + if( side == null ) + { return null; } - synchronized (this.peripherals) { + synchronized( this.peripherals ) + { PeripheralWrapper p = this.peripherals[side.ordinal()]; - if (p != null) { - return new Object[] {p.getType()}; + if( p != null ) + { + return new Object[] { p.getType() }; } } return null; } @LuaFunction - public final Object[] getMethods(String sideName) { - ComputerSide side = ComputerSide.valueOfInsensitive(sideName); - if (side == null) { + public final Object[] getMethods( String sideName ) + { + ComputerSide side = ComputerSide.valueOfInsensitive( sideName ); + if( side == null ) + { return null; } - synchronized (this.peripherals) { + synchronized( this.peripherals ) + { PeripheralWrapper p = this.peripherals[side.ordinal()]; - if (p != null) { - return new Object[] {p.getMethods()}; + if( p != null ) + { + return new Object[] { p.getMethods() }; } } return null; } @LuaFunction - public final MethodResult call(ILuaContext context, IArguments args) throws LuaException { - ComputerSide side = ComputerSide.valueOfInsensitive(args.getString(0)); - String methodName = args.getString(1); - IArguments methodArgs = args.drop(2); + public final MethodResult call( ILuaContext context, IArguments args ) throws LuaException + { + ComputerSide side = ComputerSide.valueOfInsensitive( args.getString( 0 ) ); + String methodName = args.getString( 1 ); + IArguments methodArgs = args.drop( 2 ); - if (side == null) { - throw new LuaException("No peripheral attached"); + if( side == null ) + { + throw new LuaException( "No peripheral attached" ); } PeripheralWrapper p; - synchronized (this.peripherals) { + synchronized( this.peripherals ) + { p = this.peripherals[side.ordinal()]; } - if (p == null) { - throw new LuaException("No peripheral attached"); + if( p == null ) + { + throw new LuaException( "No peripheral attached" ); } - try { - return p.call(context, methodName, methodArgs) - .adjustError(1); - } catch (LuaException e) { + try + { + return p.call( context, methodName, methodArgs ) + .adjustError( 1 ); + } + catch( LuaException e ) + { // We increase the error level by one in order to shift the error level to where peripheral.call was // invoked. It would be possible to do it in Lua code, but would add significantly more overhead. - if (e.getLevel() > 0) { - throw new FastLuaException(e.getMessage(), e.getLevel() + 1); + if( e.getLevel() > 0 ) + { + throw new FastLuaException( e.getMessage(), e.getLevel() + 1 ); } throw e; } } - private class PeripheralWrapper extends ComputerAccess { + private class PeripheralWrapper extends ComputerAccess + { private final String side; private final IPeripheral peripheral; @@ -216,116 +247,144 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange private final Map methodMap; private boolean attached; - PeripheralWrapper(IPeripheral peripheral, String side) { - super(PeripheralAPI.this.environment); + PeripheralWrapper( IPeripheral peripheral, String side ) + { + super( PeripheralAPI.this.environment ); this.side = side; this.peripheral = peripheral; this.attached = false; - this.type = Objects.requireNonNull(peripheral.getType(), "Peripheral type cannot be null"); + this.type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" ); - this.methodMap = PeripheralAPI.getMethods(peripheral); + this.methodMap = PeripheralAPI.getMethods( peripheral ); } - public String getType() { + public String getType() + { return this.type; - } public IPeripheral getPeripheral() { + } + + public IPeripheral getPeripheral() + { return this.peripheral; } - public Collection getMethods() { + public Collection getMethods() + { return this.methodMap.keySet(); } - public synchronized void attach() { + public synchronized void attach() + { this.attached = true; - this.peripheral.attach(this); + this.peripheral.attach( this ); } - public void detach() { + public void detach() + { // Call detach - this.peripheral.detach(this); + this.peripheral.detach( this ); - synchronized (this) { + synchronized( this ) + { // Unmount everything the detach function forgot to do this.unmountAll(); } this.attached = false; - } public synchronized boolean isAttached() { + } + + public synchronized boolean isAttached() + { return this.attached; } - public MethodResult call(ILuaContext context, String methodName, IArguments arguments) throws LuaException { + public MethodResult call( ILuaContext context, String methodName, IArguments arguments ) throws LuaException + { PeripheralMethod method; - synchronized (this) { - method = this.methodMap.get(methodName); + synchronized( this ) + { + method = this.methodMap.get( methodName ); } - if (method == null) { - throw new LuaException("No such method " + methodName); + if( method == null ) + { + throw new LuaException( "No such method " + methodName ); } - PeripheralAPI.this.environment.addTrackingChange(TrackingField.PERIPHERAL_OPS); - return method.apply(this.peripheral, context, this, arguments); + PeripheralAPI.this.environment.addTrackingChange( TrackingField.PERIPHERAL_OPS ); + return method.apply( this.peripheral, context, this, arguments ); } // IComputerAccess implementation @Override - public synchronized String mount(@Nonnull String desiredLoc, @Nonnull IMount mount, @Nonnull String driveName) { - if (!this.attached) { + public synchronized String mount( @Nonnull String desiredLoc, @Nonnull IMount mount, @Nonnull String driveName ) + { + if( !this.attached ) + { throw new NotAttachedException(); } - return super.mount(desiredLoc, mount, driveName); + return super.mount( desiredLoc, mount, driveName ); } @Override - public synchronized String mountWritable(@Nonnull String desiredLoc, @Nonnull IWritableMount mount, @Nonnull String driveName) { - if (!this.attached) { + public synchronized String mountWritable( @Nonnull String desiredLoc, @Nonnull IWritableMount mount, @Nonnull String driveName ) + { + if( !this.attached ) + { throw new NotAttachedException(); } - return super.mountWritable(desiredLoc, mount, driveName); + return super.mountWritable( desiredLoc, mount, driveName ); } @Override - public synchronized void unmount(String location) { - if (!this.attached) { + public synchronized void unmount( String location ) + { + if( !this.attached ) + { throw new NotAttachedException(); } - super.unmount(location); + super.unmount( location ); } @Override - public int getID() { - if (!this.attached) { + public int getID() + { + if( !this.attached ) + { throw new NotAttachedException(); } return super.getID(); } @Override - public void queueEvent(@Nonnull String event, Object... arguments) { - if (!this.attached) { + public void queueEvent( @Nonnull String event, Object... arguments ) + { + if( !this.attached ) + { throw new NotAttachedException(); } - super.queueEvent(event, arguments); + super.queueEvent( event, arguments ); } @Nonnull @Override - public IWorkMonitor getMainThreadMonitor() { - if (!this.attached) { + public IWorkMonitor getMainThreadMonitor() + { + if( !this.attached ) + { throw new NotAttachedException(); } return super.getMainThreadMonitor(); } - @Nonnull @Override - public String getAttachmentName() { - if (!this.attached) { + public String getAttachmentName() + { + if( !this.attached ) + { throw new NotAttachedException(); } return this.side; @@ -333,31 +392,39 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange @Nonnull @Override - public Map getAvailablePeripherals() { - if (!this.attached) { + public Map getAvailablePeripherals() + { + if( !this.attached ) + { throw new NotAttachedException(); } Map peripherals = new HashMap<>(); - for (PeripheralWrapper wrapper : PeripheralAPI.this.peripherals) { - if (wrapper != null && wrapper.isAttached()) { - peripherals.put(wrapper.getAttachmentName(), wrapper.getPeripheral()); + for( PeripheralWrapper wrapper : PeripheralAPI.this.peripherals ) + { + if( wrapper != null && wrapper.isAttached() ) + { + peripherals.put( wrapper.getAttachmentName(), wrapper.getPeripheral() ); } } - return Collections.unmodifiableMap(peripherals); + return Collections.unmodifiableMap( peripherals ); } @Nullable @Override - public IPeripheral getAvailablePeripheral(@Nonnull String name) { - if (!this.attached) { + public IPeripheral getAvailablePeripheral( @Nonnull String name ) + { + if( !this.attached ) + { throw new NotAttachedException(); } - for (PeripheralWrapper wrapper : PeripheralAPI.this.peripherals) { - if (wrapper != null && wrapper.isAttached() && wrapper.getAttachmentName() - .equals(name)) { + for( PeripheralWrapper wrapper : PeripheralAPI.this.peripherals ) + { + if( wrapper != null && wrapper.isAttached() && wrapper.getAttachmentName() + .equals( name ) ) + { return wrapper.getPeripheral(); } } diff --git a/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java b/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java index 9f026729a..90cedcfe7 100644 --- a/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java @@ -26,7 +26,7 @@ import dan200.computercraft.core.computer.ComputerSide; * * @cc.usage Toggle the redstone signal above the computer every 0.5 seconds. * - *
+ * 
  *     while true do
  *       redstone.setOutput("top", not redstone.getOutput("top"))
  *       sleep(0.5)
@@ -34,7 +34,7 @@ import dan200.computercraft.core.computer.ComputerSide;
  *     
* @cc.usage Mimic a redstone comparator in [subtraction mode][comparator]. * - *
+ * 
  *     while true do
  *       local rear = rs.getAnalogueInput("back")
  *       local sides = math.max(rs.getAnalogueInput("left"), rs.getAnalogueInput("right"))
@@ -44,18 +44,21 @@ import dan200.computercraft.core.computer.ComputerSide;
  *     end
  *     
* - * [comparator]: https://minecraft.gamepedia.com/Redstone_Comparator#Subtract_signal_strength "Redstone Comparator on the Minecraft wiki." + * [comparator]: https://minecraft.gamepedia.com/Redstone_Comparator#Subtract_signal_strength "Redstone Comparator on the Minecraft wiki." * @cc.module redstone */ -public class RedstoneAPI implements ILuaAPI { +public class RedstoneAPI implements ILuaAPI +{ private final IAPIEnvironment environment; - public RedstoneAPI(IAPIEnvironment environment) { + public RedstoneAPI( IAPIEnvironment environment ) + { this.environment = environment; } @Override - public String[] getNames() { + public String[] getNames() + { return new String[] { "rs", "redstone" @@ -68,7 +71,8 @@ public class RedstoneAPI implements ILuaAPI { * @return A table of valid sides. */ @LuaFunction - public final String[] getSides() { + public final String[] getSides() + { return ComputerSide.NAMES; } @@ -76,11 +80,12 @@ public class RedstoneAPI implements ILuaAPI { * Turn the redstone signal of a specific side on or off. * * @param side The side to set. - * @param on Whether the redstone signal should be on or off. When on, a signal strength of 15 is emitted. + * @param on Whether the redstone signal should be on or off. When on, a signal strength of 15 is emitted. */ @LuaFunction - public final void setOutput(ComputerSide side, boolean on) { - this.environment.setOutput(side, on ? 15 : 0); + public final void setOutput( ComputerSide side, boolean on ) + { + this.environment.setOutput( side, on ? 15 : 0 ); } /** @@ -91,8 +96,9 @@ public class RedstoneAPI implements ILuaAPI { * @see #setOutput */ @LuaFunction - public final boolean getOutput(ComputerSide side) { - return this.environment.getOutput(side) > 0; + public final boolean getOutput( ComputerSide side ) + { + return this.environment.getOutput( side ) > 0; } /** @@ -102,26 +108,29 @@ public class RedstoneAPI implements ILuaAPI { * @return Whether the redstone input is on or off. */ @LuaFunction - public final boolean getInput(ComputerSide side) { - return this.environment.getInput(side) > 0; + public final boolean getInput( ComputerSide side ) + { + return this.environment.getInput( side ) > 0; } /** * Set the redstone signal strength for a specific side. * - * @param side The side to set. + * @param side The side to set. * @param value The signal strength between 0 and 15. * @throws LuaException If {@code value} is not betwene 0 and 15. */ - @LuaFunction ({ + @LuaFunction( { "setAnalogOutput", "setAnalogueOutput" - }) - public final void setAnalogOutput(ComputerSide side, int value) throws LuaException { - if (value < 0 || value > 15) { - throw new LuaException("Expected number in range 0-15"); + } ) + public final void setAnalogOutput( ComputerSide side, int value ) throws LuaException + { + if( value < 0 || value > 15 ) + { + throw new LuaException( "Expected number in range 0-15" ); } - this.environment.setOutput(side, value); + this.environment.setOutput( side, value ); } /** @@ -131,12 +140,13 @@ public class RedstoneAPI implements ILuaAPI { * @return The output signal strength, between 0 and 15. * @see #setAnalogOutput */ - @LuaFunction ({ + @LuaFunction( { "getAnalogOutput", "getAnalogueOutput" - }) - public final int getAnalogOutput(ComputerSide side) { - return this.environment.getOutput(side); + } ) + public final int getAnalogOutput( ComputerSide side ) + { + return this.environment.getOutput( side ); } /** @@ -145,25 +155,27 @@ public class RedstoneAPI implements ILuaAPI { * @param side The side to get. * @return The input signal strength, between 0 and 15. */ - @LuaFunction ({ + @LuaFunction( { "getAnalogInput", "getAnalogueInput" - }) - public final int getAnalogInput(ComputerSide side) { - return this.environment.getInput(side); + } ) + public final int getAnalogInput( ComputerSide side ) + { + return this.environment.getInput( side ); } /** * Set the bundled cable output for a specific side. * - * @param side The side to set. + * @param side The side to set. * @param output The colour bitmask to set. * @cc.see colors.subtract For removing a colour from the bitmask. * @cc.see colors.combine For adding a color to the bitmask. */ @LuaFunction - public final void setBundledOutput(ComputerSide side, int output) { - this.environment.setBundledOutput(side, output); + public final void setBundledOutput( ComputerSide side, int output ) + { + this.environment.setBundledOutput( side, output ); } /** @@ -173,8 +185,9 @@ public class RedstoneAPI implements ILuaAPI { * @return The bundle cable's output. */ @LuaFunction - public final int getBundledOutput(ComputerSide side) { - return this.environment.getBundledOutput(side); + public final int getBundledOutput( ComputerSide side ) + { + return this.environment.getBundledOutput( side ); } /** @@ -197,14 +210,15 @@ public class RedstoneAPI implements ILuaAPI { * @param mask The mask to test. * @return If the colours are on. * @cc.usage Check if @{colors.white} and @{colors.black} are on above the computer. - *
+     * 
      *     print(redstone.testBundledInput("top", colors.combine(colors.white, colors.black)))
      *     
* @see #getBundledInput */ @LuaFunction - public final boolean testBundledInput(ComputerSide side, int mask) { - int input = this.environment.getBundledInput(side); + public final boolean testBundledInput( ComputerSide side, int mask ) + { + int input = this.environment.getBundledInput( side ); return (input & mask) == mask; } } diff --git a/src/main/java/dan200/computercraft/core/apis/TableHelper.java b/src/main/java/dan200/computercraft/core/apis/TableHelper.java index d3766b337..cb584cd23 100644 --- a/src/main/java/dan200/computercraft/core/apis/TableHelper.java +++ b/src/main/java/dan200/computercraft/core/apis/TableHelper.java @@ -6,150 +6,207 @@ package dan200.computercraft.core.apis; -import static dan200.computercraft.api.lua.LuaValues.getNumericType; - -import java.util.Map; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaValues; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Map; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaValues; +import static dan200.computercraft.api.lua.LuaValues.getNumericType; /** * Various helpers for tables. */ -public final class TableHelper { - private TableHelper() { - throw new IllegalStateException("Cannot instantiate singleton " + this.getClass().getName()); +public final class TableHelper +{ + private TableHelper() + { + throw new IllegalStateException( "Cannot instantiate singleton " + this.getClass().getName() ); } - public static int getIntField(@Nonnull Map table, @Nonnull String key) throws LuaException { - Object value = table.get(key); - if (value instanceof Number) { + public static int getIntField( @Nonnull Map table, @Nonnull String key ) throws LuaException + { + Object value = table.get( key ); + if( value instanceof Number ) + { return (int) ((Number) value).longValue(); - } else { - throw badKey(key, "number", value); + } + else + { + throw badKey( key, "number", value ); } } @Nonnull - public static LuaException badKey(@Nonnull String key, @Nonnull String expected, @Nullable Object actual) { - return badKey(key, expected, LuaValues.getType(actual)); + public static LuaException badKey( @Nonnull String key, @Nonnull String expected, @Nullable Object actual ) + { + return badKey( key, expected, LuaValues.getType( actual ) ); } @Nonnull - public static LuaException badKey(@Nonnull String key, @Nonnull String expected, @Nonnull String actual) { - return new LuaException("bad field '" + key + "' (" + expected + " expected, got " + actual + ")"); + public static LuaException badKey( @Nonnull String key, @Nonnull String expected, @Nonnull String actual ) + { + return new LuaException( "bad field '" + key + "' (" + expected + " expected, got " + actual + ")" ); } - public static double getRealField(@Nonnull Map table, @Nonnull String key) throws LuaException { - return checkReal(key, getNumberField(table, key)); + public static double getRealField( @Nonnull Map table, @Nonnull String key ) throws LuaException + { + return checkReal( key, getNumberField( table, key ) ); } - private static double checkReal(@Nonnull String key, double value) throws LuaException { - if (!Double.isFinite(value)) { - throw badKey(key, "number", getNumericType(value)); + private static double checkReal( @Nonnull String key, double value ) throws LuaException + { + if( !Double.isFinite( value ) ) + { + throw badKey( key, "number", getNumericType( value ) ); } return value; } - public static double getNumberField(@Nonnull Map table, @Nonnull String key) throws LuaException { - Object value = table.get(key); - if (value instanceof Number) { + public static double getNumberField( @Nonnull Map table, @Nonnull String key ) throws LuaException + { + Object value = table.get( key ); + if( value instanceof Number ) + { return ((Number) value).doubleValue(); - } else { - throw badKey(key, "number", value); + } + else + { + throw badKey( key, "number", value ); } } - public static boolean getBooleanField(@Nonnull Map table, @Nonnull String key) throws LuaException { - Object value = table.get(key); - if (value instanceof Boolean) { + public static boolean getBooleanField( @Nonnull Map table, @Nonnull String key ) throws LuaException + { + Object value = table.get( key ); + if( value instanceof Boolean ) + { return (Boolean) value; - } else { - throw badKey(key, "boolean", value); + } + else + { + throw badKey( key, "boolean", value ); } } @Nonnull - public static String getStringField(@Nonnull Map table, @Nonnull String key) throws LuaException { - Object value = table.get(key); - if (value instanceof String) { + public static String getStringField( @Nonnull Map table, @Nonnull String key ) throws LuaException + { + Object value = table.get( key ); + if( value instanceof String ) + { return (String) value; - } else { - throw badKey(key, "string", value); + } + else + { + throw badKey( key, "string", value ); } } - @SuppressWarnings ("unchecked") + @SuppressWarnings( "unchecked" ) @Nonnull - public static Map getTableField(@Nonnull Map table, @Nonnull String key) throws LuaException { - Object value = table.get(key); - if (value instanceof Map) { + public static Map getTableField( @Nonnull Map table, @Nonnull String key ) throws LuaException + { + Object value = table.get( key ); + if( value instanceof Map ) + { return (Map) value; - } else { - throw badKey(key, "table", value); + } + else + { + throw badKey( key, "table", value ); } } - public static int optIntField(@Nonnull Map table, @Nonnull String key, int def) throws LuaException { - Object value = table.get(key); - if (value == null) { + public static int optIntField( @Nonnull Map table, @Nonnull String key, int def ) throws LuaException + { + Object value = table.get( key ); + if( value == null ) + { return def; - } else if (value instanceof Number) { + } + else if( value instanceof Number ) + { return (int) ((Number) value).longValue(); - } else { - throw badKey(key, "number", value); + } + else + { + throw badKey( key, "number", value ); } } - public static double optRealField(@Nonnull Map table, @Nonnull String key, double def) throws LuaException { - return checkReal(key, optNumberField(table, key, def)); + public static double optRealField( @Nonnull Map table, @Nonnull String key, double def ) throws LuaException + { + return checkReal( key, optNumberField( table, key, def ) ); } - public static double optNumberField(@Nonnull Map table, @Nonnull String key, double def) throws LuaException { - Object value = table.get(key); - if (value == null) { + public static double optNumberField( @Nonnull Map table, @Nonnull String key, double def ) throws LuaException + { + Object value = table.get( key ); + if( value == null ) + { return def; - } else if (value instanceof Number) { + } + else if( value instanceof Number ) + { return ((Number) value).doubleValue(); - } else { - throw badKey(key, "number", value); + } + else + { + throw badKey( key, "number", value ); } } - public static boolean optBooleanField(@Nonnull Map table, @Nonnull String key, boolean def) throws LuaException { - Object value = table.get(key); - if (value == null) { + public static boolean optBooleanField( @Nonnull Map table, @Nonnull String key, boolean def ) throws LuaException + { + Object value = table.get( key ); + if( value == null ) + { return def; - } else if (value instanceof Boolean) { + } + else if( value instanceof Boolean ) + { return (Boolean) value; - } else { - throw badKey(key, "boolean", value); + } + else + { + throw badKey( key, "boolean", value ); } } - public static String optStringField(@Nonnull Map table, @Nonnull String key, String def) throws LuaException { - Object value = table.get(key); - if (value == null) { + public static String optStringField( @Nonnull Map table, @Nonnull String key, String def ) throws LuaException + { + Object value = table.get( key ); + if( value == null ) + { return def; - } else if (value instanceof String) { + } + else if( value instanceof String ) + { return (String) value; - } else { - throw badKey(key, "string", value); + } + else + { + throw badKey( key, "string", value ); } } - @SuppressWarnings ("unchecked") - public static Map optTableField(@Nonnull Map table, @Nonnull String key, Map def) throws LuaException { - Object value = table.get(key); - if (value == null) { + @SuppressWarnings( "unchecked" ) + public static Map optTableField( @Nonnull Map table, @Nonnull String key, Map def ) throws LuaException + { + Object value = table.get( key ); + if( value == null ) + { return def; - } else if (value instanceof Map) { + } + else if( value instanceof Map ) + { return (Map) value; - } else { - throw badKey(key, "table", value); + } + else + { + throw badKey( key, "table", value ); } } } diff --git a/src/main/java/dan200/computercraft/core/apis/TermAPI.java b/src/main/java/dan200/computercraft/core/apis/TermAPI.java index 41d7d435e..b081e2ee9 100644 --- a/src/main/java/dan200/computercraft/core/apis/TermAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/TermAPI.java @@ -6,8 +6,6 @@ package dan200.computercraft.core.apis; -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.lua.LuaException; @@ -16,23 +14,28 @@ import dan200.computercraft.core.computer.IComputerEnvironment; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.util.Colour; +import javax.annotation.Nonnull; + /** * The Terminal API provides functions for writing text to the terminal and monitors, and drawing ASCII graphics. * * @cc.module term */ -public class TermAPI extends TermMethods implements ILuaAPI { +public class TermAPI extends TermMethods implements ILuaAPI +{ private final Terminal terminal; private final IComputerEnvironment environment; - public TermAPI(IAPIEnvironment environment) { + public TermAPI( IAPIEnvironment environment ) + { this.terminal = environment.getTerminal(); this.environment = environment.getComputerEnvironment(); } @Override - public String[] getNames() { - return new String[] {"term"}; + public String[] getNames() + { + return new String[] { "term" }; } /** @@ -46,18 +49,20 @@ public class TermAPI extends TermMethods implements ILuaAPI { * @cc.treturn number The blue channel, will be between 0 and 1. * @see TermMethods#setPaletteColour(IArguments) To change the palette colour. */ - @LuaFunction ({ + @LuaFunction( { "nativePaletteColour", "nativePaletteColor" - }) - public final Object[] nativePaletteColour(int colour) throws LuaException { - int actualColour = 15 - parseColour(colour); - Colour c = Colour.fromInt(actualColour); + } ) + public final Object[] nativePaletteColour( int colour ) throws LuaException + { + int actualColour = 15 - parseColour( colour ); + Colour c = Colour.fromInt( actualColour ); float[] rgb = c.getRGB(); Object[] rgbObj = new Object[rgb.length]; - for (int i = 0; i < rgbObj.length; ++i) { + for( int i = 0; i < rgbObj.length; ++i ) + { rgbObj[i] = rgb[i]; } return rgbObj; @@ -65,12 +70,14 @@ public class TermAPI extends TermMethods implements ILuaAPI { @Nonnull @Override - public Terminal getTerminal() { + public Terminal getTerminal() + { return this.terminal; } @Override - public boolean isColour() { + public boolean isColour() + { return this.environment.isColour(); } } diff --git a/src/main/java/dan200/computercraft/core/apis/TermMethods.java b/src/main/java/dan200/computercraft/core/apis/TermMethods.java index da0fd371f..a3d959844 100644 --- a/src/main/java/dan200/computercraft/core/apis/TermMethods.java +++ b/src/main/java/dan200/computercraft/core/apis/TermMethods.java @@ -5,8 +5,6 @@ */ package dan200.computercraft.core.apis; -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; @@ -15,12 +13,15 @@ import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.StringUtil; import org.apache.commons.lang3.ArrayUtils; +import javax.annotation.Nonnull; + /** * A base class for all objects which interact with a terminal. Namely the {@link TermAPI} and monitors. * * @cc.module term.Redirect */ -public abstract class TermMethods { +public abstract class TermMethods +{ /** * Write {@code text} at the current cursor position, moving the cursor to the end of the text. * @@ -31,12 +32,14 @@ public abstract class TermMethods { * @cc.param text The text to write. */ @LuaFunction - public final void write(IArguments arguments) throws LuaException { - String text = StringUtil.toString(arguments.get(0)); + public final void write( IArguments arguments ) throws LuaException + { + String text = StringUtil.toString( arguments.get( 0 ) ); Terminal terminal = this.getTerminal(); - synchronized (terminal) { - terminal.write(text); - terminal.setCursorPos(terminal.getCursorX() + text.length(), terminal.getCursorY()); + synchronized( terminal ) + { + terminal.write( text ); + terminal.setCursorPos( terminal.getCursorX() + text.length(), terminal.getCursorY() ); } } @@ -53,8 +56,9 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. */ @LuaFunction - public final void scroll(int y) throws LuaException { - this.getTerminal().scroll(y); + public final void scroll( int y ) throws LuaException + { + this.getTerminal().scroll( y ); } /** @@ -66,7 +70,8 @@ public abstract class TermMethods { * @cc.treturn number The y position of the cursor. */ @LuaFunction - public final Object[] getCursorPos() throws LuaException { + public final Object[] getCursorPos() throws LuaException + { Terminal terminal = this.getTerminal(); return new Object[] { terminal.getCursorX() + 1, @@ -82,10 +87,12 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. */ @LuaFunction - public final void setCursorPos(int x, int y) throws LuaException { + public final void setCursorPos( int x, int y ) throws LuaException + { Terminal terminal = this.getTerminal(); - synchronized (terminal) { - terminal.setCursorPos(x - 1, y - 1); + synchronized( terminal ) + { + terminal.setCursorPos( x - 1, y - 1 ); } } @@ -96,7 +103,8 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. */ @LuaFunction - public final boolean getCursorBlink() throws LuaException { + public final boolean getCursorBlink() throws LuaException + { return this.getTerminal().getCursorBlink(); } @@ -107,10 +115,12 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. */ @LuaFunction - public final void setCursorBlink(boolean blink) throws LuaException { + public final void setCursorBlink( boolean blink ) throws LuaException + { Terminal terminal = this.getTerminal(); - synchronized (terminal) { - terminal.setCursorBlink(blink); + synchronized( terminal ) + { + terminal.setCursorBlink( blink ); } } @@ -123,7 +133,8 @@ public abstract class TermMethods { * @cc.treturn number The terminal's height. */ @LuaFunction - public final Object[] getSize() throws LuaException { + public final Object[] getSize() throws LuaException + { Terminal terminal = this.getTerminal(); return new Object[] { terminal.getWidth(), @@ -137,7 +148,8 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. */ @LuaFunction - public final void clear() throws LuaException { + public final void clear() throws LuaException + { this.getTerminal().clear(); } @@ -147,7 +159,8 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. */ @LuaFunction - public final void clearLine() throws LuaException { + public final void clearLine() throws LuaException + { this.getTerminal().clearLine(); } @@ -158,12 +171,13 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. * @cc.see colors For a list of colour constants, returned by this function. */ - @LuaFunction ({ + @LuaFunction( { "getTextColour", "getTextColor" - }) - public final int getTextColour() throws LuaException { - return encodeColour(this.getTerminal().getTextColour()); + } ) + public final int getTextColour() throws LuaException + { + return encodeColour( this.getTerminal().getTextColour() ); } /** @@ -173,39 +187,47 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. * @cc.see colors For a list of colour constants. */ - @LuaFunction ({ + @LuaFunction( { "setTextColour", "setTextColor" - }) - public final void setTextColour(int colourArg) throws LuaException { - int colour = parseColour(colourArg); + } ) + public final void setTextColour( int colourArg ) throws LuaException + { + int colour = parseColour( colourArg ); Terminal terminal = this.getTerminal(); - synchronized (terminal) { - terminal.setTextColour(colour); + synchronized( terminal ) + { + terminal.setTextColour( colour ); } } - public static int parseColour(int colour) throws LuaException { - if (colour <= 0) { - throw new LuaException("Colour out of range"); + public static int parseColour( int colour ) throws LuaException + { + if( colour <= 0 ) + { + throw new LuaException( "Colour out of range" ); } - colour = getHighestBit(colour) - 1; - if (colour < 0 || colour > 15) { - throw new LuaException("Colour out of range"); + colour = getHighestBit( colour ) - 1; + if( colour < 0 || colour > 15 ) + { + throw new LuaException( "Colour out of range" ); } return colour; } - private static int getHighestBit(int group) { + private static int getHighestBit( int group ) + { int bit = 0; - while (group > 0) { + while( group > 0 ) + { group >>= 1; bit++; } return bit; } - public static int encodeColour(int colour) { + public static int encodeColour( int colour ) + { return 1 << colour; } @@ -216,12 +238,13 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. * @cc.see colors For a list of colour constants, returned by this function. */ - @LuaFunction ({ + @LuaFunction( { "getBackgroundColour", "getBackgroundColor" - }) - public final int getBackgroundColour() throws LuaException { - return encodeColour(this.getTerminal().getBackgroundColour()); + } ) + public final int getBackgroundColour() throws LuaException + { + return encodeColour( this.getTerminal().getBackgroundColour() ); } /** @@ -231,15 +254,17 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. * @cc.see colors For a list of colour constants. */ - @LuaFunction ({ + @LuaFunction( { "setBackgroundColour", "setBackgroundColor" - }) - public final void setBackgroundColour(int colourArg) throws LuaException { - int colour = parseColour(colourArg); + } ) + public final void setBackgroundColour( int colourArg ) throws LuaException + { + int colour = parseColour( colourArg ); Terminal terminal = this.getTerminal(); - synchronized (terminal) { - terminal.setBackgroundColour(colour); + synchronized( terminal ) + { + terminal.setBackgroundColour( colour ); } } @@ -251,11 +276,12 @@ public abstract class TermMethods { * @return Whether this terminal supports colour. * @throws LuaException (hidden) If the terminal cannot be found. */ - @LuaFunction ({ + @LuaFunction( { "isColour", "isColor" - }) - public final boolean getIsColour() throws LuaException { + } ) + public final boolean getIsColour() throws LuaException + { return this.isColour(); } @@ -269,26 +295,29 @@ public abstract class TermMethods { * {@code textColour} and {@code backgroundColour} must both be strings the same length as {@code text}. All characters represent a single hexadecimal * digit, which is converted to one of CC's colours. For instance, {@code "a"} corresponds to purple. * - * @param text The text to write. - * @param textColour The corresponding text colours. + * @param text The text to write. + * @param textColour The corresponding text colours. * @param backgroundColour The corresponding background colours. * @throws LuaException If the three inputs are not the same length. * @cc.see colors For a list of colour constants, and their hexadecimal values. * @cc.usage Prints "Hello, world!" in rainbow text. - *
{@code
+     * 
{@code
      *     term.blit("Hello, world!","01234456789ab","0000000000000")
      *     }
*/ @LuaFunction - public final void blit(String text, String textColour, String backgroundColour) throws LuaException { - if (textColour.length() != text.length() || backgroundColour.length() != text.length()) { - throw new LuaException("Arguments must be the same length"); + public final void blit( String text, String textColour, String backgroundColour ) throws LuaException + { + if( textColour.length() != text.length() || backgroundColour.length() != text.length() ) + { + throw new LuaException( "Arguments must be the same length" ); } Terminal terminal = this.getTerminal(); - synchronized (terminal) { - terminal.blit(text, textColour, backgroundColour); - terminal.setCursorPos(terminal.getCursorX() + text.length(), terminal.getCursorY()); + synchronized( terminal ) + { + terminal.blit( text, textColour, backgroundColour ); + terminal.setCursorPos( terminal.getCursorX() + text.length(), terminal.getCursorY() ); } } @@ -303,19 +332,19 @@ public abstract class TermMethods { * @throws LuaException (hidden) If the terminal cannot be found. * @cc.tparam [1] number index The colour whose palette should be changed. * @cc.tparam number colour A 24-bit integer representing the RGB value of the colour. For instance the integer `0xFF0000` corresponds to the colour - * #FF0000. + * #FF0000. * @cc.tparam [2] number index The colour whose palette should be changed. * @cc.tparam number r The intensity of the red channel, between 0 and 1. * @cc.tparam number g The intensity of the green channel, between 0 and 1. * @cc.tparam number b The intensity of the blue channel, between 0 and 1. * @cc.usage Change the @{colors.red|red colour} from the default #CC4C4C to #FF0000. - *
{@code
+     * 
{@code
      *     term.setPaletteColour(colors.red, 0xFF0000)
      *     term.setTextColour(colors.red)
      *     print("Hello, world!")
      *     }
* @cc.usage As above, but specifying each colour channel separately. - *
{@code
+     * 
{@code
      *     term.setPaletteColour(colors.red, 1, 0, 0)
      *     term.setTextColour(colors.red)
      *     print("Hello, world!")
@@ -323,27 +352,32 @@ public abstract class TermMethods {
      * @cc.see colors.unpackRGB To convert from the 24-bit format to three separate channels.
      * @cc.see colors.packRGB To convert from three separate channels to the 24-bit format.
      */
-    @LuaFunction ({
+    @LuaFunction( {
         "setPaletteColour",
         "setPaletteColor"
-    })
-    public final void setPaletteColour(IArguments args) throws LuaException {
-        int colour = 15 - parseColour(args.getInt(0));
-        if (args.count() == 2) {
-            int hex = args.getInt(1);
-            double[] rgb = Palette.decodeRGB8(hex);
-            setColour(this.getTerminal(), colour, rgb[0], rgb[1], rgb[2]);
-        } else {
-            double r = args.getFiniteDouble(1);
-            double g = args.getFiniteDouble(2);
-            double b = args.getFiniteDouble(3);
-            setColour(this.getTerminal(), colour, r, g, b);
+    } )
+    public final void setPaletteColour( IArguments args ) throws LuaException
+    {
+        int colour = 15 - parseColour( args.getInt( 0 ) );
+        if( args.count() == 2 )
+        {
+            int hex = args.getInt( 1 );
+            double[] rgb = Palette.decodeRGB8( hex );
+            setColour( this.getTerminal(), colour, rgb[0], rgb[1], rgb[2] );
+        }
+        else
+        {
+            double r = args.getFiniteDouble( 1 );
+            double g = args.getFiniteDouble( 2 );
+            double b = args.getFiniteDouble( 3 );
+            setColour( this.getTerminal(), colour, r, g, b );
         }
     }
 
-    public static void setColour(Terminal terminal, int colour, double r, double g, double b) {
+    public static void setColour( Terminal terminal, int colour, double r, double g, double b )
+    {
         terminal.getPalette()
-                .setColour(colour, r, g, b);
+            .setColour( colour, r, g, b );
         terminal.setChanged();
     }
 
@@ -357,16 +391,18 @@ public abstract class TermMethods {
      * @cc.treturn number The green channel, will be between 0 and 1.
      * @cc.treturn number The blue channel, will be between 0 and 1.
      */
-    @LuaFunction ({
+    @LuaFunction( {
         "getPaletteColour",
         "getPaletteColor"
-    })
-    public final Object[] getPaletteColour(int colourArg) throws LuaException {
-        int colour = 15 - parseColour(colourArg);
+    } )
+    public final Object[] getPaletteColour( int colourArg ) throws LuaException
+    {
+        int colour = 15 - parseColour( colourArg );
         Terminal terminal = this.getTerminal();
-        synchronized (terminal) {
-            return ArrayUtils.toObject(terminal.getPalette()
-                                               .getColour(colour));
+        synchronized( terminal )
+        {
+            return ArrayUtils.toObject( terminal.getPalette()
+                .getColour( colour ) );
         }
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java b/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java
index a2f9bb241..e1c9ddec7 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java
@@ -6,62 +6,74 @@
 
 package dan200.computercraft.core.apis.http;
 
+import dan200.computercraft.core.apis.IAPIEnvironment;
+
 import java.net.InetSocketAddress;
 import java.net.URI;
 import java.util.concurrent.Future;
 
-import dan200.computercraft.core.apis.IAPIEnvironment;
-
 /**
  * Checks a URL using {@link NetworkUtils#getAddress(String, int, boolean)}}
  *
  * This requires a DNS lookup, and so needs to occur off-thread.
  */
-public class CheckUrl extends Resource {
+public class CheckUrl extends Resource
+{
     private static final String EVENT = "http_check";
     private final IAPIEnvironment environment;
     private final String address;
     private final URI uri;
     private Future future;
 
-    public CheckUrl(ResourceGroup limiter, IAPIEnvironment environment, String address, URI uri) {
-        super(limiter);
+    public CheckUrl( ResourceGroup limiter, IAPIEnvironment environment, String address, URI uri )
+    {
+        super( limiter );
         this.environment = environment;
         this.address = address;
         this.uri = uri;
     }
 
-    public void run() {
-        if (this.isClosed()) {
+    public void run()
+    {
+        if( this.isClosed() )
+        {
             return;
         }
-        this.future = NetworkUtils.EXECUTOR.submit(this::doRun);
+        this.future = NetworkUtils.EXECUTOR.submit( this::doRun );
         this.checkClosed();
     }
 
-    private void doRun() {
-        if (this.isClosed()) {
+    private void doRun()
+    {
+        if( this.isClosed() )
+        {
             return;
         }
 
-        try {
+        try
+        {
             boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
             InetSocketAddress netAddress = NetworkUtils.getAddress( uri, ssl );
             NetworkUtils.getOptions( uri.getHost(), netAddress );
 
-            if (this.tryClose()) {
-                this.environment.queueEvent(EVENT, this.address, true);
+            if( this.tryClose() )
+            {
+                this.environment.queueEvent( EVENT, this.address, true );
             }
-        } catch (HTTPRequestException e) {
-            if (this.tryClose()) {
-                this.environment.queueEvent(EVENT, this.address, false, e.getMessage());
+        }
+        catch( HTTPRequestException e )
+        {
+            if( this.tryClose() )
+            {
+                this.environment.queueEvent( EVENT, this.address, false, e.getMessage() );
             }
         }
     }
 
     @Override
-    protected void dispose() {
+    protected void dispose()
+    {
         super.dispose();
-        this.future = closeFuture(this.future);
+        this.future = closeFuture( this.future );
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/HTTPRequestException.java b/src/main/java/dan200/computercraft/core/apis/http/HTTPRequestException.java
index beca1f0c6..ea1864ab6 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/HTTPRequestException.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/HTTPRequestException.java
@@ -6,15 +6,18 @@
 
 package dan200.computercraft.core.apis.http;
 
-public class HTTPRequestException extends Exception {
+public class HTTPRequestException extends Exception
+{
     private static final long serialVersionUID = 7591208619422744652L;
 
-    public HTTPRequestException(String s) {
-        super(s);
+    public HTTPRequestException( String s )
+    {
+        super( s );
     }
 
     @Override
-    public Throwable fillInStackTrace() {
+    public Throwable fillInStackTrace()
+    {
         return this;
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java b/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java
index 76ddc19e8..4e2539aeb 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java
@@ -6,17 +6,6 @@
 
 package dan200.computercraft.core.apis.http;
 
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.security.KeyStore;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.SSLException;
-import javax.net.ssl.TrustManagerFactory;
-
 import dan200.computercraft.ComputerCraft;
 import dan200.computercraft.core.apis.http.options.Action;
 import dan200.computercraft.core.apis.http.options.AddressRule;
@@ -28,67 +17,94 @@ import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.handler.ssl.SslContext;
 import io.netty.handler.ssl.SslContextBuilder;
 
+import javax.net.ssl.SSLException;
+import javax.net.ssl.TrustManagerFactory;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.security.KeyStore;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Just a shared object for executing simple HTTP related tasks.
  */
-public final class NetworkUtils {
-    public static final ExecutorService EXECUTOR = new ThreadPoolExecutor(4,
-                                                                          Integer.MAX_VALUE,
-                                                                          60L,
-                                                                          TimeUnit.SECONDS,
-                                                                          new SynchronousQueue<>(),
-                                                                          ThreadUtils.builder("Network")
-                                                                                     .setPriority(Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2)
-                                                                                     .build());
+public final class NetworkUtils
+{
+    public static final ExecutorService EXECUTOR = new ThreadPoolExecutor( 4,
+        Integer.MAX_VALUE,
+        60L,
+        TimeUnit.SECONDS,
+        new SynchronousQueue<>(),
+        ThreadUtils.builder( "Network" )
+            .setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
+            .build() );
 
-    public static final EventLoopGroup LOOP_GROUP = new NioEventLoopGroup(4,
-                                                                          ThreadUtils.builder("Netty")
-                                                                                     .setPriority(Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2)
-                                                                                     .build());
+    public static final EventLoopGroup LOOP_GROUP = new NioEventLoopGroup( 4,
+        ThreadUtils.builder( "Netty" )
+            .setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
+            .build() );
     private static final Object sslLock = new Object();
     private static TrustManagerFactory trustManager;
     private static SslContext sslContext;
     private static boolean triedSslContext = false;
-    private NetworkUtils() {
+
+    private NetworkUtils()
+    {
     }
 
-    public static SslContext getSslContext() throws HTTPRequestException {
-        if (sslContext != null || triedSslContext) {
+    public static SslContext getSslContext() throws HTTPRequestException
+    {
+        if( sslContext != null || triedSslContext )
+        {
             return sslContext;
         }
-        synchronized (sslLock) {
-            if (sslContext != null || triedSslContext) {
+        synchronized( sslLock )
+        {
+            if( sslContext != null || triedSslContext )
+            {
                 return sslContext;
             }
-            try {
+            try
+            {
                 return sslContext = SslContextBuilder.forClient()
-                                                     .trustManager(getTrustManager())
-                                                     .build();
-            } catch (SSLException e) {
-                ComputerCraft.log.error("Cannot construct SSL context", e);
+                    .trustManager( getTrustManager() )
+                    .build();
+            }
+            catch( SSLException e )
+            {
+                ComputerCraft.log.error( "Cannot construct SSL context", e );
                 triedSslContext = true;
                 sslContext = null;
 
-                throw new HTTPRequestException("Cannot create a secure connection");
+                throw new HTTPRequestException( "Cannot create a secure connection" );
             }
         }
     }
 
-    private static TrustManagerFactory getTrustManager() {
-        if (trustManager != null) {
+    private static TrustManagerFactory getTrustManager()
+    {
+        if( trustManager != null )
+        {
             return trustManager;
         }
-        synchronized (sslLock) {
-            if (trustManager != null) {
+        synchronized( sslLock )
+        {
+            if( trustManager != null )
+            {
                 return trustManager;
             }
 
             TrustManagerFactory tmf = null;
-            try {
-                tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                tmf.init((KeyStore) null);
-            } catch (Exception e) {
-                ComputerCraft.log.error("Cannot setup trust manager", e);
+            try
+            {
+                tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
+                tmf.init( (KeyStore) null );
+            }
+            catch( Exception e )
+            {
+                ComputerCraft.log.error( "Cannot setup trust manager", e );
             }
 
             return trustManager = tmf;
@@ -117,17 +133,20 @@ public final class NetworkUtils {
      *
      * @param host The host to resolve.
      * @param port The port, or -1 if not defined.
-     * @param ssl Whether to connect with SSL. This is used to find the default port if not otherwise specified.
+     * @param ssl  Whether to connect with SSL. This is used to find the default port if not otherwise specified.
      * @return The resolved address.
      * @throws HTTPRequestException If the host is not malformed.
      */
-    public static InetSocketAddress getAddress(String host, int port, boolean ssl) throws HTTPRequestException {
-        if (port < 0) {
+    public static InetSocketAddress getAddress( String host, int port, boolean ssl ) throws HTTPRequestException
+    {
+        if( port < 0 )
+        {
             port = ssl ? 443 : 80;
         }
-        InetSocketAddress socketAddress = new InetSocketAddress(host, port);
-        if (socketAddress.isUnresolved()) {
-            throw new HTTPRequestException("Unknown host");
+        InetSocketAddress socketAddress = new InetSocketAddress( host, port );
+        if( socketAddress.isUnresolved() )
+        {
+            throw new HTTPRequestException( "Unknown host" );
         }
         return socketAddress;
     }
@@ -135,15 +154,17 @@ public final class NetworkUtils {
     /**
      * Get options for a specific domain.
      *
-     * @param host The host to resolve.
+     * @param host    The host to resolve.
      * @param address The address, resolved by {@link #getAddress(String, int, boolean)}.
      * @return The options for this host.
      * @throws HTTPRequestException If the host is not permitted
      */
-    public static Options getOptions(String host, InetSocketAddress address) throws HTTPRequestException {
+    public static Options getOptions( String host, InetSocketAddress address ) throws HTTPRequestException
+    {
         Options options = AddressRule.apply( ComputerCraft.httpRules, host, address );
-        if (options.action == Action.DENY) {
-            throw new HTTPRequestException("Domain not permitted");
+        if( options.action == Action.DENY )
+        {
+            throw new HTTPRequestException( "Domain not permitted" );
         }
         return options;
     }
@@ -154,9 +175,10 @@ public final class NetworkUtils {
      * @param buffer The buffer to read.
      * @return The resulting bytes.
      */
-    public static byte[] toBytes(ByteBuf buffer) {
+    public static byte[] toBytes( ByteBuf buffer )
+    {
         byte[] bytes = new byte[buffer.readableBytes()];
-        buffer.readBytes(bytes);
+        buffer.readBytes( bytes );
         return bytes;
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/Resource.java b/src/main/java/dan200/computercraft/core/apis/http/Resource.java
index cc2981402..1c16cc050 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/Resource.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/Resource.java
@@ -6,6 +6,10 @@
 
 package dan200.computercraft.core.apis.http;
 
+import dan200.computercraft.shared.util.IoUtil;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+
 import java.io.Closeable;
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
@@ -14,34 +18,36 @@ import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 
-import dan200.computercraft.shared.util.IoUtil;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-
 /**
  * A holder for one or more resources, with a lifetime.
  *
  * @param  The type of this resource. Should be the class extending from {@link Resource}.
  */
-public abstract class Resource> implements Closeable {
+public abstract class Resource> implements Closeable
+{
     private static final ReferenceQueue QUEUE = new ReferenceQueue<>();
-    private final AtomicBoolean closed = new AtomicBoolean(false);
+    private final AtomicBoolean closed = new AtomicBoolean( false );
     private final ResourceGroup limiter;
 
-    protected Resource(ResourceGroup limiter) {
+    protected Resource( ResourceGroup limiter )
+    {
         this.limiter = limiter;
     }
 
-    protected static  T closeCloseable(T closeable) {
-        IoUtil.closeQuietly(closeable);
+    protected static  T closeCloseable( T closeable )
+    {
+        IoUtil.closeQuietly( closeable );
         return null;
     }
 
-    protected static ChannelFuture closeChannel(ChannelFuture future) {
-        if (future != null) {
-            future.cancel(false);
+    protected static ChannelFuture closeChannel( ChannelFuture future )
+    {
+        if( future != null )
+        {
+            future.cancel( false );
             Channel channel = future.channel();
-            if (channel != null && channel.isOpen()) {
+            if( channel != null && channel.isOpen() )
+            {
                 channel.close();
             }
         }
@@ -49,22 +55,27 @@ public abstract class Resource> implements Closeable {
         return null;
     }
 
-    protected static > T closeFuture(T future) {
-        if (future != null) {
-            future.cancel(true);
+    protected static > T closeFuture( T future )
+    {
+        if( future != null )
+        {
+            future.cancel( true );
         }
         return null;
     }
 
-    public static void cleanup() {
+    public static void cleanup()
+    {
         Reference reference;
-        while ((reference = QUEUE.poll()) != null) {
+        while( (reference = QUEUE.poll()) != null )
+        {
             ((CloseReference) reference).resource.close();
         }
     }
 
     @Override
-    public final void close() {
+    public final void close()
+    {
         this.tryClose();
     }
 
@@ -73,8 +84,10 @@ public abstract class Resource> implements Closeable {
      *
      * @return Whether this was successfully closed, or {@code false} if it has already been closed.
      */
-    protected final boolean tryClose() {
-        if (this.closed.getAndSet(true)) {
+    protected final boolean tryClose()
+    {
+        if( this.closed.getAndSet( true ) )
+        {
             return false;
         }
         this.dispose();
@@ -86,7 +99,8 @@ public abstract class Resource> implements Closeable {
      *
      * @return Whether this resource is closed.
      */
-    public final boolean isClosed() {
+    public final boolean isClosed()
+    {
         return this.closed.get();
     }
 
@@ -95,8 +109,10 @@ public abstract class Resource> implements Closeable {
      *
      * @return Whether this resource has been closed.
      */
-    public final boolean checkClosed() {
-        if (!this.closed.get()) {
+    public final boolean checkClosed()
+    {
+        if( !this.closed.get() )
+        {
             return false;
         }
         this.dispose();
@@ -108,34 +124,39 @@ public abstract class Resource> implements Closeable {
      *
      * Note, this may be called multiple times, and so should be thread-safe and avoid any major side effects.
      */
-    protected void dispose() {
-        @SuppressWarnings ("unchecked")
+    protected void dispose()
+    {
+        @SuppressWarnings( "unchecked" )
         T thisT = (T) this;
-        this.limiter.release(thisT);
+        this.limiter.release( thisT );
     }
 
     /**
      * Create a {@link WeakReference} which will close {@code this} when collected.
      *
-     * @param  The object we are wrapping in a reference.
+     * @param     The object we are wrapping in a reference.
      * @param object The object to reference to
      * @return The weak reference.
      */
-    protected  WeakReference createOwnerReference(R object) {
-        return new CloseReference<>(this, object);
+    protected  WeakReference createOwnerReference( R object )
+    {
+        return new CloseReference<>( this, object );
     }
 
-    public boolean queue(Consumer task) {
-        @SuppressWarnings ("unchecked")
+    public boolean queue( Consumer task )
+    {
+        @SuppressWarnings( "unchecked" )
         T thisT = (T) this;
-        return this.limiter.queue(thisT, () -> task.accept(thisT));
+        return this.limiter.queue( thisT, () -> task.accept( thisT ) );
     }
 
-    private static class CloseReference extends WeakReference {
+    private static class CloseReference extends WeakReference
+    {
         final Resource resource;
 
-        CloseReference(Resource resource, T referent) {
-            super(referent, QUEUE);
+        CloseReference( Resource resource, T referent )
+        {
+            super( referent, QUEUE );
             this.resource = resource;
         }
     }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/ResourceGroup.java b/src/main/java/dan200/computercraft/core/apis/http/ResourceGroup.java
index 4510a6e98..058c9875f 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/ResourceGroup.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/ResourceGroup.java
@@ -17,29 +17,35 @@ import java.util.function.Supplier;
  *
  * @param  The type of the resource this group manages.
  */
-public class ResourceGroup> {
+public class ResourceGroup>
+{
     private static final IntSupplier ZERO = () -> 0;
 
     final IntSupplier limit;
-    final Set resources = Collections.newSetFromMap(new ConcurrentHashMap<>());
+    final Set resources = Collections.newSetFromMap( new ConcurrentHashMap<>() );
     boolean active = false;
 
-    public ResourceGroup(IntSupplier limit) {
+    public ResourceGroup( IntSupplier limit )
+    {
         this.limit = limit;
     }
 
-    public ResourceGroup() {
+    public ResourceGroup()
+    {
         this.limit = ZERO;
     }
 
-    public void startup() {
+    public void startup()
+    {
         this.active = true;
     }
 
-    public synchronized void shutdown() {
+    public synchronized void shutdown()
+    {
         this.active = false;
 
-        for (T resource : this.resources) {
+        for( T resource : this.resources )
+        {
             resource.close();
         }
         this.resources.clear();
@@ -48,29 +54,34 @@ public class ResourceGroup> {
     }
 
 
-    public final boolean queue(T resource, Runnable setup) {
-        return this.queue(() -> {
+    public final boolean queue( T resource, Runnable setup )
+    {
+        return this.queue( () -> {
             setup.run();
             return resource;
-        });
+        } );
     }
 
-    public synchronized boolean queue(Supplier resource) {
+    public synchronized boolean queue( Supplier resource )
+    {
         Resource.cleanup();
-        if (!this.active) {
+        if( !this.active )
+        {
             return false;
         }
 
         int limit = this.limit.getAsInt();
-        if (limit <= 0 || this.resources.size() < limit) {
-            this.resources.add(resource.get());
+        if( limit <= 0 || this.resources.size() < limit )
+        {
+            this.resources.add( resource.get() );
             return true;
         }
 
         return false;
     }
 
-    public synchronized void release(T resource) {
-        this.resources.remove(resource);
+    public synchronized void release( T resource )
+    {
+        this.resources.remove( resource );
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/ResourceQueue.java b/src/main/java/dan200/computercraft/core/apis/http/ResourceQueue.java
index 080a3a54a..74c79ce53 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/ResourceQueue.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/ResourceQueue.java
@@ -15,47 +15,58 @@ import java.util.function.Supplier;
  *
  * @param  The type of the resource this queue manages.
  */
-public class ResourceQueue> extends ResourceGroup {
+public class ResourceQueue> extends ResourceGroup
+{
     private final ArrayDeque> pending = new ArrayDeque<>();
 
-    public ResourceQueue(IntSupplier limit) {
-        super(limit);
+    public ResourceQueue( IntSupplier limit )
+    {
+        super( limit );
     }
 
-    public ResourceQueue() {
+    public ResourceQueue()
+    {
     }
 
     @Override
-    public synchronized void shutdown() {
+    public synchronized void shutdown()
+    {
         super.shutdown();
         this.pending.clear();
     }
 
     @Override
-    public synchronized boolean queue(Supplier resource) {
-        if (!this.active) {
+    public synchronized boolean queue( Supplier resource )
+    {
+        if( !this.active )
+        {
             return false;
         }
 
-        if (!super.queue(resource)) {
-            this.pending.add(resource);
+        if( !super.queue( resource ) )
+        {
+            this.pending.add( resource );
         }
         return true;
     }
 
     @Override
-    public synchronized void release(T resource) {
-        super.release(resource);
+    public synchronized void release( T resource )
+    {
+        super.release( resource );
 
-        if (!this.active) {
+        if( !this.active )
+        {
             return;
         }
 
         int limit = this.limit.getAsInt();
-        if (limit <= 0 || this.resources.size() < limit) {
+        if( limit <= 0 || this.resources.size() < limit )
+        {
             Supplier next = this.pending.poll();
-            if (next != null) {
-                this.resources.add(next.get());
+            if( next != null )
+            {
+                this.resources.add( next.get() );
             }
         }
     }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/options/Action.java b/src/main/java/dan200/computercraft/core/apis/http/options/Action.java
index 6410fc2d9..df8641a2f 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/options/Action.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/options/Action.java
@@ -7,13 +7,15 @@ package dan200.computercraft.core.apis.http.options;
 
 import javax.annotation.Nonnull;
 
-public enum Action {
+public enum Action
+{
     ALLOW, DENY;
 
-    private final PartialOptions partial = new PartialOptions(this, null, null, null, null);
+    private final PartialOptions partial = new PartialOptions( this, null, null, null, null );
 
     @Nonnull
-    public PartialOptions toPartial() {
+    public PartialOptions toPartial()
+    {
         return this.partial;
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java b/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java
index e9b1b1d8f..912e8e057 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java
@@ -6,25 +6,24 @@
 
 package dan200.computercraft.core.apis.http.options;
 
+import com.google.common.net.InetAddresses;
+import dan200.computercraft.core.apis.http.options.AddressPredicate.DomainPattern;
+import dan200.computercraft.core.apis.http.options.AddressPredicate.HostRange;
+import dan200.computercraft.core.apis.http.options.AddressPredicate.PrivatePattern;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.regex.Pattern;
 
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import com.google.common.net.InetAddresses;
-
-import dan200.computercraft.core.apis.http.options.AddressPredicate.DomainPattern;
-import dan200.computercraft.core.apis.http.options.AddressPredicate.HostRange;
-import dan200.computercraft.core.apis.http.options.AddressPredicate.PrivatePattern;
-
 /**
  * A pattern which matches an address, and controls whether it is accessible or not.
  */
-public final class AddressRule {
+public final class AddressRule
+{
     public static final long MAX_DOWNLOAD = 16 * 1024 * 1024;
     public static final long MAX_UPLOAD = 4 * 1024 * 1024;
     public static final int TIMEOUT = 30_000;
@@ -33,31 +32,38 @@ public final class AddressRule {
     private final AddressPredicate predicate;
     private final Integer port;
     private final PartialOptions partial;
-    private AddressRule( @Nonnull AddressPredicate predicate, @Nullable Integer port, @Nonnull PartialOptions partial ) {
+
+    private AddressRule( @Nonnull AddressPredicate predicate, @Nullable Integer port, @Nonnull PartialOptions partial )
+    {
         this.predicate = predicate;
         this.partial = partial;
-		this.port = port;
+        this.port = port;
     }
 
     @Nullable
-    public static AddressRule parse( String filter, @Nullable Integer port, @Nonnull PartialOptions partial ) {
-        int cidr = filter.indexOf('/');
-        if (cidr >= 0) {
-            String addressStr = filter.substring(0, cidr);
-            String prefixSizeStr = filter.substring(cidr + 1);
+    public static AddressRule parse( String filter, @Nullable Integer port, @Nonnull PartialOptions partial )
+    {
+        int cidr = filter.indexOf( '/' );
+        if( cidr >= 0 )
+        {
+            String addressStr = filter.substring( 0, cidr );
+            String prefixSizeStr = filter.substring( cidr + 1 );
             HostRange range = HostRange.parse( addressStr, prefixSizeStr );
             return range == null ? null : new AddressRule( range, port, partial );
         }
         else if( filter.equalsIgnoreCase( "$private" ) )
         {
             return new AddressRule( PrivatePattern.INSTANCE, port, partial );
-        } else {
+        }
+        else
+        {
             Pattern pattern = Pattern.compile( "^\\Q" + filter.replaceAll( "\\*", "\\\\E.*\\\\Q" ) + "\\E$", Pattern.CASE_INSENSITIVE );
             return new AddressRule( new DomainPattern( pattern ), port, partial );
         }
     }
 
-    public static Options apply( Iterable rules, String domain, InetSocketAddress socketAddress ) {
+    public static Options apply( Iterable rules, String domain, InetSocketAddress socketAddress )
+    {
         PartialOptions options = null;
         boolean hasMany = false;
 
@@ -66,19 +72,24 @@ public final class AddressRule {
         Inet4Address ipv4Address = address instanceof Inet6Address && InetAddresses.is6to4Address( (Inet6Address) address )
             ? InetAddresses.get6to4IPv4Address( (Inet6Address) address ) : null;
 
-        for (AddressRule rule : rules) {
+        for( AddressRule rule : rules )
+        {
             if( !rule.matches( domain, port, address, ipv4Address ) ) continue;
 
-            if (options == null) {
+            if( options == null )
+            {
                 options = rule.partial;
-            } else {
+            }
+            else
+            {
 
-                if (!hasMany) {
+                if( !hasMany )
+                {
                     options = options.copy();
                     hasMany = true;
                 }
 
-                options.merge(rule.partial);
+                options.merge( rule.partial );
             }
         }
 
@@ -94,8 +105,9 @@ public final class AddressRule {
      * @param ipv4Address An ipv4 version of the address, if the original was an ipv6 address.
      * @return Whether it matches any of these patterns.
      */
-    private boolean matches(String domain, int port, InetAddress address, Inet4Address ipv4Address) {
-		if( this.port != null && this.port != port ) return false;
+    private boolean matches( String domain, int port, InetAddress address, Inet4Address ipv4Address )
+    {
+        if( this.port != null && this.port != port ) return false;
         return predicate.matches( domain )
             || predicate.matches( address )
             || (ipv4Address != null && predicate.matches( ipv4Address ));
diff --git a/src/main/java/dan200/computercraft/core/apis/http/options/AddressRuleConfig.java b/src/main/java/dan200/computercraft/core/apis/http/options/AddressRuleConfig.java
index 660acfb18..3fb2c6e6f 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/options/AddressRuleConfig.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/options/AddressRuleConfig.java
@@ -17,116 +17,117 @@ import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 
 
-public class AddressRuleConfig {
+public class AddressRuleConfig
+{
 
-        public static UnmodifiableConfig makeRule( String host, Action action )
+    public static UnmodifiableConfig makeRule( String host, Action action )
+    {
+        CommentedConfig config = InMemoryCommentedFormat.defaultInstance().createConfig( ConcurrentHashMap::new );
+        config.add( "host", host );
+        config.add( "action", action.name().toLowerCase( Locale.ROOT ) );
+
+        if( host.equals( "*" ) && action == Action.ALLOW )
         {
-            CommentedConfig config = InMemoryCommentedFormat.defaultInstance().createConfig( ConcurrentHashMap::new );
-            config.add( "host", host );
-            config.add( "action", action.name().toLowerCase( Locale.ROOT ) );
+            config.setComment( "timeout", "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." );
+            config.add( "timeout", AddressRule.TIMEOUT );
 
-            if( host.equals( "*" ) && action == Action.ALLOW )
-            {
-                config.setComment( "timeout", "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." );
-                config.add( "timeout", AddressRule.TIMEOUT );
+            config.setComment( "max_download", "The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client." );
+            config.set( "max_download", AddressRule.MAX_DOWNLOAD );
 
-                config.setComment( "max_download", "The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client." );
-                config.set( "max_download", AddressRule.MAX_DOWNLOAD );
+            config.setComment( "max_upload", "The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text." );
+            config.set( "max_upload", AddressRule.MAX_UPLOAD );
 
-                config.setComment( "max_upload", "The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text." );
-                config.set( "max_upload", AddressRule.MAX_UPLOAD );
-
-                config.setComment( "max_websocket_message", "The maximum size (in bytes) that a computer can send or receive in one websocket packet." );
-                config.set( "max_websocket_message", AddressRule.WEBSOCKET_MESSAGE );
-            }
-
-            return config;
+            config.setComment( "max_websocket_message", "The maximum size (in bytes) that a computer can send or receive in one websocket packet." );
+            config.set( "max_websocket_message", AddressRule.WEBSOCKET_MESSAGE );
         }
 
-        public static boolean checkRule( UnmodifiableConfig builder )
+        return config;
+    }
+
+    public static boolean checkRule( UnmodifiableConfig builder )
+    {
+        String hostObj = get( builder, "host", String.class ).orElse( null );
+        Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
+        return hostObj != null && checkEnum( builder, "action", Action.class )
+            && check( builder, "port", Number.class )
+            && check( builder, "timeout", Number.class )
+            && check( builder, "max_upload", Number.class )
+            && check( builder, "max_download", Number.class )
+            && check( builder, "websocket_message", Number.class )
+            && AddressRule.parse( hostObj, port, PartialOptions.DEFAULT ) != null;
+    }
+
+    @Nullable
+    public static AddressRule parseRule( UnmodifiableConfig builder )
+    {
+        String hostObj = get( builder, "host", String.class ).orElse( null );
+        Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
+        if( hostObj == null ) return null;
+
+        Action action = getEnum( builder, "action", Action.class ).orElse( null );
+        Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
+        Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
+        Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
+        Integer websocketMessage = get( builder, "websocket_message", Number.class ).map( Number::intValue ).orElse( null );
+
+        PartialOptions options = new PartialOptions(
+            action,
+            maxUpload,
+            maxDownload,
+            timeout,
+            websocketMessage
+        );
+
+        return AddressRule.parse( hostObj, port, options );
+    }
+
+    private static  boolean check( UnmodifiableConfig config, String field, Class klass )
+    {
+        Object value = config.get( field );
+        if( value == null || klass.isInstance( value ) ) return true;
+
+        ComputerCraft.log.warn( "HTTP rule's {} is not a {}.", field, klass.getSimpleName() );
+        return false;
+    }
+
+    private static > boolean checkEnum( UnmodifiableConfig config, String field, Class klass )
+    {
+        Object value = config.get( field );
+        if( value == null ) return true;
+
+        if( !(value instanceof String) )
         {
-            String hostObj = get( builder, "host", String.class ).orElse( null );
-            Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
-            return hostObj != null && checkEnum( builder, "action", Action.class )
-                && check( builder, "port", Number.class )
-                && check( builder, "timeout", Number.class )
-                && check( builder, "max_upload", Number.class )
-                && check( builder, "max_download", Number.class )
-                && check( builder, "websocket_message", Number.class )
-                && AddressRule.parse( hostObj, port, PartialOptions.DEFAULT ) != null;
-        }
-
-        @Nullable
-        public static AddressRule parseRule( UnmodifiableConfig builder )
-        {
-            String hostObj = get( builder, "host", String.class ).orElse( null );
-            Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
-            if( hostObj == null ) return null;
-
-            Action action = getEnum( builder, "action", Action.class ).orElse( null );
-            Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
-            Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
-            Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
-            Integer websocketMessage = get( builder, "websocket_message", Number.class ).map( Number::intValue ).orElse( null );
-
-            PartialOptions options = new PartialOptions(
-                action,
-                maxUpload,
-                maxDownload,
-                timeout,
-                websocketMessage
-            );
-
-            return AddressRule.parse( hostObj, port, options );
-        }
-
-        private static  boolean check( UnmodifiableConfig config, String field, Class klass )
-        {
-            Object value = config.get( field );
-            if( value == null || klass.isInstance( value ) ) return true;
-
-            ComputerCraft.log.warn( "HTTP rule's {} is not a {}.", field, klass.getSimpleName() );
+            ComputerCraft.log.warn( "HTTP rule's {} is not a string", field );
             return false;
         }
 
-        private static > boolean checkEnum( UnmodifiableConfig config, String field, Class klass )
+        if( parseEnum( klass, (String) value ) == null )
         {
-            Object value = config.get( field );
-            if( value == null ) return true;
-
-            if( !(value instanceof String) )
-            {
-                ComputerCraft.log.warn( "HTTP rule's {} is not a string", field );
-                return false;
-            }
-
-            if( parseEnum( klass, (String) value ) == null )
-            {
-                ComputerCraft.log.warn( "HTTP rule's {} is not a known option", field );
-                return false;
-            }
-
-            return true;
+            ComputerCraft.log.warn( "HTTP rule's {} is not a known option", field );
+            return false;
         }
 
-        private static  Optional get( UnmodifiableConfig config, String field, Class klass )
-        {
-            Object value = config.get( field );
-            return klass.isInstance( value ) ? Optional.of( klass.cast( value ) ) : Optional.empty();
-        }
+        return true;
+    }
 
-        private static > Optional getEnum( UnmodifiableConfig config, String field, Class klass )
-        {
-            return get( config, field, String.class ).map( x -> parseEnum( klass, x ) );
-        }
+    private static  Optional get( UnmodifiableConfig config, String field, Class klass )
+    {
+        Object value = config.get( field );
+        return klass.isInstance( value ) ? Optional.of( klass.cast( value ) ) : Optional.empty();
+    }
 
-        @Nullable
-        private static > T parseEnum( Class klass, String x )
+    private static > Optional getEnum( UnmodifiableConfig config, String field, Class klass )
+    {
+        return get( config, field, String.class ).map( x -> parseEnum( klass, x ) );
+    }
+
+    @Nullable
+    private static > T parseEnum( Class klass, String x )
+    {
+        for( T value : klass.getEnumConstants() )
         {
-            for( T value : klass.getEnumConstants() )
-            {
-                if( value.name().equalsIgnoreCase( x ) ) return value;
-            }
-            return null;
+            if( value.name().equalsIgnoreCase( x ) ) return value;
         }
+        return null;
+    }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/options/Options.java b/src/main/java/dan200/computercraft/core/apis/http/options/Options.java
index d4fde11f6..d6074a9a4 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/options/Options.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/options/Options.java
@@ -10,14 +10,17 @@ import javax.annotation.Nonnull;
 /**
  * Options about a specific domain.
  */
-public final class Options {
-    @Nonnull public final Action action;
+public final class Options
+{
+    @Nonnull
+    public final Action action;
     public final long maxUpload;
     public final long maxDownload;
     public final int timeout;
     public final int websocketMessage;
 
-    Options(@Nonnull Action action, long maxUpload, long maxDownload, int timeout, int websocketMessage) {
+    Options( @Nonnull Action action, long maxUpload, long maxDownload, int timeout, int websocketMessage )
+    {
         this.action = action;
         this.maxUpload = maxUpload;
         this.maxDownload = maxDownload;
diff --git a/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java b/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java
index 9835f461b..76699aa30 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java
@@ -7,8 +7,9 @@ package dan200.computercraft.core.apis.http.options;
 
 import javax.annotation.Nonnull;
 
-public final class PartialOptions {
-    static final PartialOptions DEFAULT = new PartialOptions(null, null, null, null, null);
+public final class PartialOptions
+{
+    static final PartialOptions DEFAULT = new PartialOptions( null, null, null, null, null );
 
     Action action;
     Long maxUpload;
@@ -18,7 +19,8 @@ public final class PartialOptions {
 
     Options options;
 
-    PartialOptions(Action action, Long maxUpload, Long maxDownload, Integer timeout, Integer websocketMessage) {
+    PartialOptions( Action action, Long maxUpload, Long maxDownload, Integer timeout, Integer websocketMessage )
+    {
         this.action = action;
         this.maxUpload = maxUpload;
         this.maxDownload = maxDownload;
@@ -27,36 +29,45 @@ public final class PartialOptions {
     }
 
     @Nonnull
-    Options toOptions() {
-        if (this.options != null) {
+    Options toOptions()
+    {
+        if( this.options != null )
+        {
             return this.options;
         }
 
-        return this.options = new Options(this.action == null ? Action.DENY : this.action,
-                                     this.maxUpload == null ? AddressRule.MAX_UPLOAD : this.maxUpload,
-                                     this.maxDownload == null ? AddressRule.MAX_DOWNLOAD : this.maxDownload,
-                                     this.timeout == null ? AddressRule.TIMEOUT : this.timeout, this.websocketMessage == null ? AddressRule.WEBSOCKET_MESSAGE : this.websocketMessage);
+        return this.options = new Options( this.action == null ? Action.DENY : this.action,
+            this.maxUpload == null ? AddressRule.MAX_UPLOAD : this.maxUpload,
+            this.maxDownload == null ? AddressRule.MAX_DOWNLOAD : this.maxDownload,
+            this.timeout == null ? AddressRule.TIMEOUT : this.timeout, this.websocketMessage == null ? AddressRule.WEBSOCKET_MESSAGE : this.websocketMessage );
     }
 
-    void merge(@Nonnull PartialOptions other) {
-        if (this.action == null && other.action != null) {
+    void merge( @Nonnull PartialOptions other )
+    {
+        if( this.action == null && other.action != null )
+        {
             this.action = other.action;
         }
-        if (this.maxUpload == null && other.maxUpload != null) {
+        if( this.maxUpload == null && other.maxUpload != null )
+        {
             this.maxUpload = other.maxUpload;
         }
-        if (this.maxDownload == null && other.maxDownload != null) {
+        if( this.maxDownload == null && other.maxDownload != null )
+        {
             this.maxDownload = other.maxDownload;
         }
-        if (this.timeout == null && other.timeout != null) {
+        if( this.timeout == null && other.timeout != null )
+        {
             this.timeout = other.timeout;
         }
-        if (this.websocketMessage == null && other.websocketMessage != null) {
+        if( this.websocketMessage == null && other.websocketMessage != null )
+        {
             this.websocketMessage = other.websocketMessage;
         }
     }
 
-    PartialOptions copy() {
-        return new PartialOptions(this.action, this.maxUpload, this.maxDownload, this.timeout, this.websocketMessage);
+    PartialOptions copy()
+    {
+        return new PartialOptions( this.action, this.maxUpload, this.maxDownload, this.timeout, this.websocketMessage );
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java b/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java
index dba5b0e7b..b6ba95a21 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java
@@ -6,16 +6,6 @@
 
 package dan200.computercraft.core.apis.http.request;
 
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-import java.util.Map;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
 import dan200.computercraft.ComputerCraft;
 import dan200.computercraft.core.apis.IAPIEnvironment;
 import dan200.computercraft.core.apis.http.HTTPRequestException;
@@ -34,19 +24,26 @@ import io.netty.channel.ConnectTimeoutException;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioSocketChannel;
 import io.netty.handler.codec.TooLongFrameException;
-import io.netty.handler.codec.http.HttpClientCodec;
-import io.netty.handler.codec.http.HttpContentDecompressor;
-import io.netty.handler.codec.http.HttpHeaderNames;
-import io.netty.handler.codec.http.HttpHeaders;
-import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.*;
 import io.netty.handler.ssl.SslContext;
 import io.netty.handler.timeout.ReadTimeoutException;
 import io.netty.handler.timeout.ReadTimeoutHandler;
 
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * Represents an in-progress HTTP request.
  */
-public class HttpRequest extends Resource {
+public class HttpRequest extends Resource
+{
     private static final String SUCCESS_EVENT = "http_success";
     private static final String FAILURE_EVENT = "http_failure";
 
@@ -61,201 +58,252 @@ public class HttpRequest extends Resource {
     private ChannelFuture connectFuture;
     private HttpRequestHandler currentRequest;
 
-    public HttpRequest(ResourceGroup limiter, IAPIEnvironment environment, String address, String postText, HttpHeaders headers,
-                       boolean binary, boolean followRedirects) {
-        super(limiter);
+    public HttpRequest( ResourceGroup limiter, IAPIEnvironment environment, String address, String postText, HttpHeaders headers,
+                        boolean binary, boolean followRedirects )
+    {
+        super( limiter );
         this.environment = environment;
         this.address = address;
-        this.postBuffer = postText != null ? Unpooled.wrappedBuffer(postText.getBytes(StandardCharsets.UTF_8)) : Unpooled.buffer(0);
+        this.postBuffer = postText != null ? Unpooled.wrappedBuffer( postText.getBytes( StandardCharsets.UTF_8 ) ) : Unpooled.buffer( 0 );
         this.headers = headers;
         this.binary = binary;
-        this.redirects = new AtomicInteger(followRedirects ? MAX_REDIRECTS : 0);
+        this.redirects = new AtomicInteger( followRedirects ? MAX_REDIRECTS : 0 );
 
-        if (postText != null) {
-            if (!headers.contains(HttpHeaderNames.CONTENT_TYPE)) {
-                headers.set(HttpHeaderNames.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=utf-8");
+        if( postText != null )
+        {
+            if( !headers.contains( HttpHeaderNames.CONTENT_TYPE ) )
+            {
+                headers.set( HttpHeaderNames.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=utf-8" );
             }
 
-            if (!headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
-                headers.set(HttpHeaderNames.CONTENT_LENGTH, this.postBuffer.readableBytes());
+            if( !headers.contains( HttpHeaderNames.CONTENT_LENGTH ) )
+            {
+                headers.set( HttpHeaderNames.CONTENT_LENGTH, this.postBuffer.readableBytes() );
             }
         }
     }
 
-    public static URI checkUri(String address) throws HTTPRequestException {
+    public static URI checkUri( String address ) throws HTTPRequestException
+    {
         URI url;
-        try {
-            url = new URI(address);
-        } catch (URISyntaxException e) {
-            throw new HTTPRequestException("URL malformed");
+        try
+        {
+            url = new URI( address );
+        }
+        catch( URISyntaxException e )
+        {
+            throw new HTTPRequestException( "URL malformed" );
         }
 
-        checkUri(url);
+        checkUri( url );
         return url;
     }
 
-    public static void checkUri(URI url) throws HTTPRequestException {
+    public static void checkUri( URI url ) throws HTTPRequestException
+    {
         // Validate the URL
-        if (url.getScheme() == null) {
-            throw new HTTPRequestException("Must specify http or https");
+        if( url.getScheme() == null )
+        {
+            throw new HTTPRequestException( "Must specify http or https" );
         }
-        if (url.getHost() == null) {
-            throw new HTTPRequestException("URL malformed");
+        if( url.getHost() == null )
+        {
+            throw new HTTPRequestException( "URL malformed" );
         }
 
         String scheme = url.getScheme()
-                           .toLowerCase(Locale.ROOT);
-        if (!scheme.equalsIgnoreCase("http") && !scheme.equalsIgnoreCase("https")) {
-            throw new HTTPRequestException("Invalid protocol '" + scheme + "'");
+            .toLowerCase( Locale.ROOT );
+        if( !scheme.equalsIgnoreCase( "http" ) && !scheme.equalsIgnoreCase( "https" ) )
+        {
+            throw new HTTPRequestException( "Invalid protocol '" + scheme + "'" );
         }
     }
 
-    public IAPIEnvironment environment() {
+    public IAPIEnvironment environment()
+    {
         return this.environment;
     }
 
-    public void request(URI uri, HttpMethod method) {
-        if (this.isClosed()) {
+    public void request( URI uri, HttpMethod method )
+    {
+        if( this.isClosed() )
+        {
             return;
         }
-        this.executorFuture = NetworkUtils.EXECUTOR.submit(() -> this.doRequest(uri, method));
+        this.executorFuture = NetworkUtils.EXECUTOR.submit( () -> this.doRequest( uri, method ) );
         this.checkClosed();
     }
 
-    private void doRequest(URI uri, HttpMethod method) {
+    private void doRequest( URI uri, HttpMethod method )
+    {
         // If we're cancelled, abort.
-        if (this.isClosed()) {
+        if( this.isClosed() )
+        {
             return;
         }
 
-        try {
+        try
+        {
             boolean ssl = uri.getScheme()
-                             .equalsIgnoreCase("https");
-            InetSocketAddress socketAddress = NetworkUtils.getAddress(uri, ssl);
-            Options options = NetworkUtils.getOptions(uri.getHost(), socketAddress);
+                .equalsIgnoreCase( "https" );
+            InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
+            Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
             SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
 
             // getAddress may have a slight delay, so let's perform another cancellation check.
-            if (this.isClosed()) {
+            if( this.isClosed() )
+            {
                 return;
             }
 
-            long requestBody = getHeaderSize(this.headers) + this.postBuffer.capacity();
-            if (options.maxUpload != 0 && requestBody > options.maxUpload) {
-                this.failure("Request body is too large");
+            long requestBody = getHeaderSize( this.headers ) + this.postBuffer.capacity();
+            if( options.maxUpload != 0 && requestBody > options.maxUpload )
+            {
+                this.failure( "Request body is too large" );
                 return;
             }
 
             // Add request size to the tracker before opening the connection
-            this.environment.addTrackingChange(TrackingField.HTTP_REQUESTS, 1);
-            this.environment.addTrackingChange(TrackingField.HTTP_UPLOAD, requestBody);
+            this.environment.addTrackingChange( TrackingField.HTTP_REQUESTS, 1 );
+            this.environment.addTrackingChange( TrackingField.HTTP_UPLOAD, requestBody );
 
-            HttpRequestHandler handler = this.currentRequest = new HttpRequestHandler(this, uri, method, options);
-            this.connectFuture = new Bootstrap().group(NetworkUtils.LOOP_GROUP)
-                                                .channelFactory(NioSocketChannel::new)
-                                                .handler(new ChannelInitializer() {
-                                               @Override
-                                               protected void initChannel(SocketChannel ch) {
+            HttpRequestHandler handler = this.currentRequest = new HttpRequestHandler( this, uri, method, options );
+            this.connectFuture = new Bootstrap().group( NetworkUtils.LOOP_GROUP )
+                .channelFactory( NioSocketChannel::new )
+                .handler( new ChannelInitializer()
+                {
+                    @Override
+                    protected void initChannel( SocketChannel ch )
+                    {
 
-                                                   if (options.timeout > 0) {
-                                                       ch.config()
-                                                         .setConnectTimeoutMillis(options.timeout);
-                                                   }
+                        if( options.timeout > 0 )
+                        {
+                            ch.config()
+                                .setConnectTimeoutMillis( options.timeout );
+                        }
 
-                                                   ChannelPipeline p = ch.pipeline();
-                                                   if (sslContext != null) {
-                                                       p.addLast(sslContext.newHandler(ch.alloc(), uri.getHost(), socketAddress.getPort()));
-                                                   }
+                        ChannelPipeline p = ch.pipeline();
+                        if( sslContext != null )
+                        {
+                            p.addLast( sslContext.newHandler( ch.alloc(), uri.getHost(), socketAddress.getPort() ) );
+                        }
 
-                                                   if (options.timeout > 0) {
-                                                       p.addLast(new ReadTimeoutHandler(options.timeout, TimeUnit.MILLISECONDS));
-                                                   }
+                        if( options.timeout > 0 )
+                        {
+                            p.addLast( new ReadTimeoutHandler( options.timeout, TimeUnit.MILLISECONDS ) );
+                        }
 
-                                                   p.addLast(new HttpClientCodec(), new HttpContentDecompressor(), handler);
-                                               }
-                                           })
-                                                .remoteAddress(socketAddress)
-                                                .connect()
-                                                .addListener(c -> {
-                                               if (!c.isSuccess()) {
-                                                   this.failure(c.cause());
-                                               }
-                                           });
+                        p.addLast( new HttpClientCodec(), new HttpContentDecompressor(), handler );
+                    }
+                } )
+                .remoteAddress( socketAddress )
+                .connect()
+                .addListener( c -> {
+                    if( !c.isSuccess() )
+                    {
+                        this.failure( c.cause() );
+                    }
+                } );
 
             // Do an additional check for cancellation
             this.checkClosed();
-        } catch (HTTPRequestException e) {
-            this.failure(e.getMessage());
-        } catch (Exception e) {
-            this.failure("Could not connect");
-            if (ComputerCraft.logComputerErrors) {
-                ComputerCraft.log.error("Error in HTTP request", e);
+        }
+        catch( HTTPRequestException e )
+        {
+            this.failure( e.getMessage() );
+        }
+        catch( Exception e )
+        {
+            this.failure( "Could not connect" );
+            if( ComputerCraft.logComputerErrors )
+            {
+                ComputerCraft.log.error( "Error in HTTP request", e );
             }
         }
     }
 
-    public static long getHeaderSize(HttpHeaders headers) {
+    public static long getHeaderSize( HttpHeaders headers )
+    {
         long size = 0;
-        for (Map.Entry header : headers) {
+        for( Map.Entry header : headers )
+        {
             size += header.getKey() == null ? 0 : header.getKey()
-                                                        .length();
+                .length();
             size += header.getValue() == null ? 0 : header.getValue()
-                                                          .length() + 1;
+                .length() + 1;
         }
         return size;
     }
 
-    void failure(String message) {
-        if (this.tryClose()) {
-            this.environment.queueEvent(FAILURE_EVENT, this.address, message);
+    void failure( String message )
+    {
+        if( this.tryClose() )
+        {
+            this.environment.queueEvent( FAILURE_EVENT, this.address, message );
         }
     }
 
-    void failure(Throwable cause) {
+    void failure( Throwable cause )
+    {
         String message;
-        if (cause instanceof HTTPRequestException) {
+        if( cause instanceof HTTPRequestException )
+        {
             message = cause.getMessage();
-        } else if (cause instanceof TooLongFrameException) {
+        }
+        else if( cause instanceof TooLongFrameException )
+        {
             message = "Response is too large";
-        } else if (cause instanceof ReadTimeoutException || cause instanceof ConnectTimeoutException) {
+        }
+        else if( cause instanceof ReadTimeoutException || cause instanceof ConnectTimeoutException )
+        {
             message = "Timed out";
-        } else {
+        }
+        else
+        {
             message = "Could not connect";
         }
 
-        this.failure(message);
+        this.failure( message );
     }
 
-    void failure(String message, HttpResponseHandle object) {
-        if (this.tryClose()) {
-            this.environment.queueEvent(FAILURE_EVENT, this.address, message, object);
+    void failure( String message, HttpResponseHandle object )
+    {
+        if( this.tryClose() )
+        {
+            this.environment.queueEvent( FAILURE_EVENT, this.address, message, object );
         }
     }
 
-    void success(HttpResponseHandle object) {
-        if (this.tryClose()) {
-            this.environment.queueEvent(SUCCESS_EVENT, this.address, object);
+    void success( HttpResponseHandle object )
+    {
+        if( this.tryClose() )
+        {
+            this.environment.queueEvent( SUCCESS_EVENT, this.address, object );
         }
     }
 
     @Override
-    protected void dispose() {
+    protected void dispose()
+    {
         super.dispose();
 
-        this.executorFuture = closeFuture(this.executorFuture);
-        this.connectFuture = closeChannel(this.connectFuture);
-        this.currentRequest = closeCloseable(this.currentRequest);
+        this.executorFuture = closeFuture( this.executorFuture );
+        this.connectFuture = closeChannel( this.connectFuture );
+        this.currentRequest = closeCloseable( this.currentRequest );
     }
 
-    public ByteBuf body() {
+    public ByteBuf body()
+    {
         return this.postBuffer;
     }
 
-    public HttpHeaders headers() {
+    public HttpHeaders headers()
+    {
         return this.headers;
     }
 
-    public boolean isBinary() {
+    public boolean isBinary()
+    {
         return this.binary;
     }
 }
diff --git a/src/main/java/dan200/computercraft/core/apis/http/request/HttpResponseHandle.java b/src/main/java/dan200/computercraft/core/apis/http/request/HttpResponseHandle.java
index 14cf8cfd7..55436a634 100644
--- a/src/main/java/dan200/computercraft/core/apis/http/request/HttpResponseHandle.java
+++ b/src/main/java/dan200/computercraft/core/apis/http/request/HttpResponseHandle.java
@@ -6,11 +6,6 @@
 
 package dan200.computercraft.core.apis.http.request;
 
-import java.util.Collections;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-
 import dan200.computercraft.api.lua.IArguments;
 import dan200.computercraft.api.lua.LuaFunction;
 import dan200.computercraft.core.apis.HTTPAPI;
@@ -19,6 +14,10 @@ import dan200.computercraft.core.apis.handles.EncodedReadableHandle;
 import dan200.computercraft.core.apis.handles.HandleGeneric;
 import dan200.computercraft.core.asm.ObjectSource;
 
+import javax.annotation.Nonnull;
+import java.util.Collections;
+import java.util.Map;
+
 /**
  * A http response. This provides the same methods as a {@link EncodedReadableHandle file} (or {@link BinaryReadableHandle binary file} if the request used
  * binary mode), though provides several request specific methods.
@@ -26,13 +25,15 @@ import dan200.computercraft.core.asm.ObjectSource;
  * @cc.module http.Response
  * @see HTTPAPI#request(IArguments)  On how to make a http request.
  */
-public class HttpResponseHandle implements ObjectSource {
+public class HttpResponseHandle implements ObjectSource
+{
     private final Object reader;
     private final int responseCode;
     private final String responseStatus;
     private final Map responseHeaders;
 
-    public HttpResponseHandle(@Nonnull HandleGeneric reader, int responseCode, String responseStatus, @Nonnull Map responseHeaders) {
+    public HttpResponseHandle( @Nonnull HandleGeneric reader, int responseCode, String responseStatus, @Nonnull Map responseHeaders )
+    {
         this.reader = reader;
         this.responseCode = responseCode;
         this.responseStatus = responseStatus;
@@ -47,7 +48,8 @@ public class HttpResponseHandle implements ObjectSource {
      * @cc.treturn string The response message (i.e. "OK")
      */
     @LuaFunction
-    public final Object[] getResponseCode() {
+    public final Object[] getResponseCode()
+    {
         return new Object[] {
             this.responseCode,
             this.responseStatus
@@ -60,7 +62,7 @@ public class HttpResponseHandle implements ObjectSource {
      *
      * @return The response's headers.
      * @cc.usage Make a request to [example.computercraft.cc](https://example.computercraft.cc), and print the returned headers.
-     *     
{@code
+     * 
{@code
      *     local request = http.get("https://example.computercraft.cc")
      *     print(textutils.serialize(request.getResponseHeaders()))
      *     -- => {
@@ -72,12 +74,14 @@ public class HttpResponseHandle implements ObjectSource {
      *     }
*/ @LuaFunction - public final Map getResponseHeaders() { + public final Map getResponseHeaders() + { return this.responseHeaders; } @Override - public Iterable getExtra() { - return Collections.singletonList(this.reader); + public Iterable getExtra() + { + return Collections.singletonList( this.reader ); } } diff --git a/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java b/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java index e72647cc0..d559fc193 100644 --- a/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java +++ b/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java @@ -6,12 +6,6 @@ package dan200.computercraft.core.apis.http.websocket; -import java.lang.ref.WeakReference; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.concurrent.Future; - import com.google.common.base.Strings; import dan200.computercraft.ComputerCraft; import dan200.computercraft.core.apis.IAPIEnvironment; @@ -37,10 +31,17 @@ import io.netty.handler.codec.http.websocketx.WebSocketVersion; import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler; import io.netty.handler.ssl.SslContext; +import java.lang.ref.WeakReference; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.Future; + /** * Provides functionality to verify and connect to a remote websocket. */ -public class Websocket extends Resource { +public class Websocket extends Resource +{ /** * We declare the maximum size to be 2^30 bytes. While messages can be much longer, we set an arbitrary limit as working with larger messages * (especially within a Lua VM) is absurd. @@ -59,159 +60,199 @@ public class Websocket extends Resource { private ChannelFuture connectFuture; private WeakReference websocketHandle; - public Websocket(ResourceGroup limiter, IAPIEnvironment environment, URI uri, String address, HttpHeaders headers) { - super(limiter); + public Websocket( ResourceGroup limiter, IAPIEnvironment environment, URI uri, String address, HttpHeaders headers ) + { + super( limiter ); this.environment = environment; this.uri = uri; this.address = address; this.headers = headers; } - public static URI checkUri(String address) throws HTTPRequestException { + public static URI checkUri( String address ) throws HTTPRequestException + { URI uri = null; - try { - uri = new URI(address); - } catch (URISyntaxException ignored) { + try + { + uri = new URI( address ); + } + catch( URISyntaxException ignored ) + { } - if (uri == null || uri.getHost() == null) { - try { - uri = new URI("ws://" + address); - } catch (URISyntaxException ignored) { + if( uri == null || uri.getHost() == null ) + { + try + { + uri = new URI( "ws://" + address ); + } + catch( URISyntaxException ignored ) + { } } - if (uri == null || uri.getHost() == null) { - throw new HTTPRequestException("URL malformed"); + if( uri == null || uri.getHost() == null ) + { + throw new HTTPRequestException( "URL malformed" ); } String scheme = uri.getScheme(); - if (scheme == null) { - try { - uri = new URI("ws://" + uri); - } catch (URISyntaxException e) { - throw new HTTPRequestException("URL malformed"); + if( scheme == null ) + { + try + { + uri = new URI( "ws://" + uri ); } - } else if (!scheme.equalsIgnoreCase("wss") && !scheme.equalsIgnoreCase("ws")) { - throw new HTTPRequestException("Invalid scheme '" + scheme + "'"); + catch( URISyntaxException e ) + { + throw new HTTPRequestException( "URL malformed" ); + } + } + else if( !scheme.equalsIgnoreCase( "wss" ) && !scheme.equalsIgnoreCase( "ws" ) ) + { + throw new HTTPRequestException( "Invalid scheme '" + scheme + "'" ); } return uri; } - public void connect() { - if (this.isClosed()) { + public void connect() + { + if( this.isClosed() ) + { return; } - this.executorFuture = NetworkUtils.EXECUTOR.submit(this::doConnect); + this.executorFuture = NetworkUtils.EXECUTOR.submit( this::doConnect ); this.checkClosed(); } - private void doConnect() { + private void doConnect() + { // If we're cancelled, abort. - if (this.isClosed()) { + if( this.isClosed() ) + { return; } - try { + try + { boolean ssl = this.uri.getScheme() - .equalsIgnoreCase("wss"); + .equalsIgnoreCase( "wss" ); - InetSocketAddress socketAddress = NetworkUtils.getAddress(uri, ssl); - Options options = NetworkUtils.getOptions(this.uri.getHost(), socketAddress); + InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl ); + Options options = NetworkUtils.getOptions( this.uri.getHost(), socketAddress ); SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null; // getAddress may have a slight delay, so let's perform another cancellation check. - if (this.isClosed()) { + if( this.isClosed() ) + { return; } - this.connectFuture = new Bootstrap().group(NetworkUtils.LOOP_GROUP) - .channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - if (sslContext != null) { - p.addLast(sslContext.newHandler(ch.alloc(), Websocket.this.uri.getHost(), socketAddress.getPort())); - } + this.connectFuture = new Bootstrap().group( NetworkUtils.LOOP_GROUP ) + .channel( NioSocketChannel.class ) + .handler( new ChannelInitializer() + { + @Override + protected void initChannel( SocketChannel ch ) + { + ChannelPipeline p = ch.pipeline(); + if( sslContext != null ) + { + p.addLast( sslContext.newHandler( ch.alloc(), Websocket.this.uri.getHost(), socketAddress.getPort() ) ); + } - WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(Websocket.this.uri, - WebSocketVersion.V13, - null, - true, - Websocket.this.headers, - options.websocketMessage <= 0 ? MAX_MESSAGE_SIZE : options.websocketMessage); + WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker( Websocket.this.uri, + WebSocketVersion.V13, + null, + true, + Websocket.this.headers, + options.websocketMessage <= 0 ? MAX_MESSAGE_SIZE : options.websocketMessage ); - p.addLast(new HttpClientCodec(), - new HttpObjectAggregator(8192), - WebSocketClientCompressionHandler.INSTANCE, - new WebsocketHandler(Websocket.this, handshaker, options)); - } - }) - .remoteAddress(socketAddress) - .connect() - .addListener(c -> { - if (!c.isSuccess()) { - this.failure(c.cause() - .getMessage()); - } - }); + p.addLast( new HttpClientCodec(), + new HttpObjectAggregator( 8192 ), + WebSocketClientCompressionHandler.INSTANCE, + new WebsocketHandler( Websocket.this, handshaker, options ) ); + } + } ) + .remoteAddress( socketAddress ) + .connect() + .addListener( c -> { + if( !c.isSuccess() ) + { + this.failure( c.cause() + .getMessage() ); + } + } ); // Do an additional check for cancellation this.checkClosed(); - } catch (HTTPRequestException e) { - this.failure(e.getMessage()); - } catch (Exception e) { - this.failure("Could not connect"); - if (ComputerCraft.logComputerErrors) { - ComputerCraft.log.error("Error in websocket", e); + } + catch( HTTPRequestException e ) + { + this.failure( e.getMessage() ); + } + catch( Exception e ) + { + this.failure( "Could not connect" ); + if( ComputerCraft.logComputerErrors ) + { + ComputerCraft.log.error( "Error in websocket", e ); } } } - void failure(String message) { - if (this.tryClose()) { - this.environment.queueEvent(FAILURE_EVENT, this.address, message); + void failure( String message ) + { + if( this.tryClose() ) + { + this.environment.queueEvent( FAILURE_EVENT, this.address, message ); } } - void success(Channel channel, Options options) { - if (this.isClosed()) { + void success( Channel channel, Options options ) + { + if( this.isClosed() ) + { return; } - WebsocketHandle handle = new WebsocketHandle(this, options, channel); - this.environment().queueEvent(SUCCESS_EVENT, this.address, handle); - this.websocketHandle = this.createOwnerReference(handle); + WebsocketHandle handle = new WebsocketHandle( this, options, channel ); + this.environment().queueEvent( SUCCESS_EVENT, this.address, handle ); + this.websocketHandle = this.createOwnerReference( handle ); this.checkClosed(); } - public IAPIEnvironment environment() { + public IAPIEnvironment environment() + { return this.environment; } - void close(int status, String reason) { - if (this.tryClose()) { - this.environment.queueEvent(CLOSE_EVENT, this.address, Strings.isNullOrEmpty(reason) ? null : reason, status < 0 ? null : status); + void close( int status, String reason ) + { + if( this.tryClose() ) + { + this.environment.queueEvent( CLOSE_EVENT, this.address, Strings.isNullOrEmpty( reason ) ? null : reason, status < 0 ? null : status ); } } @Override - protected void dispose() { + protected void dispose() + { super.dispose(); - this.executorFuture = closeFuture(this.executorFuture); - this.connectFuture = closeChannel(this.connectFuture); + this.executorFuture = closeFuture( this.executorFuture ); + this.connectFuture = closeChannel( this.connectFuture ); WeakReference websocketHandleRef = this.websocketHandle; WebsocketHandle websocketHandle = websocketHandleRef == null ? null : websocketHandleRef.get(); - IoUtil.closeQuietly(websocketHandle); + IoUtil.closeQuietly( websocketHandle ); this.websocketHandle = null; } - public String address() { + public String address() + { return this.address; } } diff --git a/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java b/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java index c31c5dd70..4931d2d63 100644 --- a/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java +++ b/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java @@ -6,23 +6,8 @@ package dan200.computercraft.core.apis.http.websocket; -import static dan200.computercraft.api.lua.LuaValues.checkFinite; -import static dan200.computercraft.core.apis.IAPIEnvironment.TIMER_EVENT; -import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT; -import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT; - -import java.io.Closeable; -import java.util.Arrays; -import java.util.Optional; - -import javax.annotation.Nonnull; - import com.google.common.base.Objects; -import dan200.computercraft.api.lua.ILuaCallback; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; -import dan200.computercraft.api.lua.LuaValues; -import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.lua.*; import dan200.computercraft.core.apis.http.options.Options; import dan200.computercraft.core.tracking.TrackingField; import dan200.computercraft.shared.util.StringUtil; @@ -31,20 +16,32 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; +import javax.annotation.Nonnull; +import java.io.Closeable; +import java.util.Arrays; +import java.util.Optional; + +import static dan200.computercraft.api.lua.LuaValues.checkFinite; +import static dan200.computercraft.core.apis.IAPIEnvironment.TIMER_EVENT; +import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT; +import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT; + /** * A websocket, which can be used to send an receive messages with a web server. * * @cc.module http.Websocket * @see dan200.computercraft.core.apis.HTTPAPI#websocket On how to open a websocket. */ -public class WebsocketHandle implements Closeable { +public class WebsocketHandle implements Closeable +{ private final Websocket websocket; private final Options options; private boolean closed = false; private Channel channel; - public WebsocketHandle(Websocket websocket, Options options, Channel channel) { + public WebsocketHandle( Websocket websocket, Options options, Channel channel ) + { this.websocket = websocket; this.options = options; this.channel = channel; @@ -61,17 +58,20 @@ public class WebsocketHandle implements Closeable { * @cc.treturn [2] nil If the websocket was closed while waiting, or if we timed out. */ @LuaFunction - public final MethodResult receive(Optional timeout) throws LuaException { + public final MethodResult receive( Optional timeout ) throws LuaException + { this.checkOpen(); int timeoutId = timeout.isPresent() ? this.websocket.environment() - .startTimer(Math.round(checkFinite(0, timeout.get()) / 0.05)) : -1; + .startTimer( Math.round( checkFinite( 0, timeout.get() ) / 0.05 ) ) : -1; - return new ReceiveCallback(timeoutId).pull; + return new ReceiveCallback( timeoutId ).pull; } - private void checkOpen() throws LuaException { - if (this.closed) { - throw new LuaException("attempt to use a closed file"); + private void checkOpen() throws LuaException + { + if( this.closed ) + { + throw new LuaException( "attempt to use a closed file" ); } } @@ -79,67 +79,81 @@ public class WebsocketHandle implements Closeable { * Send a websocket message to the connected server. * * @param message The message to send. - * @param binary Whether this message should be treated as a + * @param binary Whether this message should be treated as a * @throws LuaException If the message is too large. * @throws LuaException If the websocket has been closed. */ @LuaFunction - public final void send(Object message, Optional binary) throws LuaException { + public final void send( Object message, Optional binary ) throws LuaException + { this.checkOpen(); - String text = StringUtil.toString(message); - if (this.options.websocketMessage != 0 && text.length() > this.options.websocketMessage) { - throw new LuaException("Message is too large"); + String text = StringUtil.toString( message ); + if( this.options.websocketMessage != 0 && text.length() > this.options.websocketMessage ) + { + throw new LuaException( "Message is too large" ); } this.websocket.environment() - .addTrackingChange(TrackingField.WEBSOCKET_OUTGOING, text.length()); + .addTrackingChange( TrackingField.WEBSOCKET_OUTGOING, text.length() ); Channel channel = this.channel; - if (channel != null) { - channel.writeAndFlush(binary.orElse(false) ? new BinaryWebSocketFrame(Unpooled.wrappedBuffer(LuaValues.encode(text))) : new TextWebSocketFrame( - text)); + if( channel != null ) + { + channel.writeAndFlush( binary.orElse( false ) ? new BinaryWebSocketFrame( Unpooled.wrappedBuffer( LuaValues.encode( text ) ) ) : new TextWebSocketFrame( + text ) ); } } /** * Close this websocket. This will terminate the connection, meaning messages can no longer be sent or received along it. */ - @LuaFunction ("close") - public final void doClose() { + @LuaFunction( "close" ) + public final void doClose() + { this.close(); this.websocket.close(); } @Override - public void close() { + public void close() + { this.closed = true; Channel channel = this.channel; - if (channel != null) { + if( channel != null ) + { channel.close(); this.channel = null; } } - private final class ReceiveCallback implements ILuaCallback { - final MethodResult pull = MethodResult.pullEvent(null, this); + private final class ReceiveCallback implements ILuaCallback + { + final MethodResult pull = MethodResult.pullEvent( null, this ); private final int timeoutId; - ReceiveCallback(int timeoutId) { + ReceiveCallback( int timeoutId ) + { this.timeoutId = timeoutId; } @Nonnull @Override - public MethodResult resume(Object[] event) { - if (event.length >= 3 && Objects.equal(event[0], MESSAGE_EVENT) && Objects.equal(event[1], WebsocketHandle.this.websocket.address())) { - return MethodResult.of(Arrays.copyOfRange(event, 2, event.length)); - } else if (event.length >= 2 && Objects.equal(event[0], CLOSE_EVENT) && Objects.equal(event[1], WebsocketHandle.this.websocket.address()) && WebsocketHandle.this.closed) { + public MethodResult resume( Object[] event ) + { + if( event.length >= 3 && Objects.equal( event[0], MESSAGE_EVENT ) && Objects.equal( event[1], WebsocketHandle.this.websocket.address() ) ) + { + return MethodResult.of( Arrays.copyOfRange( event, 2, event.length ) ); + } + else if( event.length >= 2 && Objects.equal( event[0], CLOSE_EVENT ) && Objects.equal( event[1], WebsocketHandle.this.websocket.address() ) && WebsocketHandle.this.closed ) + { // If the socket is closed abort. return MethodResult.of(); - } else if (event.length >= 2 && this.timeoutId != -1 && Objects.equal(event[0], - TIMER_EVENT) && event[1] instanceof Number && ((Number) event[1]).intValue() == this.timeoutId) { + } + else if( event.length >= 2 && this.timeoutId != -1 && Objects.equal( event[0], + TIMER_EVENT ) && event[1] instanceof Number && ((Number) event[1]).intValue() == this.timeoutId ) + { // If we received a matching timer event then abort. return MethodResult.of(); } diff --git a/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandler.java b/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandler.java index 600db3b31..7aa2fdd30 100644 --- a/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandler.java +++ b/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandler.java @@ -6,8 +6,6 @@ package dan200.computercraft.core.apis.http.websocket; -import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT; - import dan200.computercraft.core.apis.http.HTTPRequestException; import dan200.computercraft.core.apis.http.NetworkUtils; import dan200.computercraft.core.apis.http.options.Options; @@ -17,103 +15,124 @@ import io.netty.channel.ConnectTimeoutException; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.TooLongFrameException; import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; -import io.netty.handler.codec.http.websocketx.PingWebSocketFrame; -import io.netty.handler.codec.http.websocketx.PongWebSocketFrame; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException; +import io.netty.handler.codec.http.websocketx.*; import io.netty.handler.timeout.ReadTimeoutException; import io.netty.util.CharsetUtil; -public class WebsocketHandler extends SimpleChannelInboundHandler { +import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT; + +public class WebsocketHandler extends SimpleChannelInboundHandler +{ private final Websocket websocket; private final WebSocketClientHandshaker handshaker; private final Options options; - public WebsocketHandler(Websocket websocket, WebSocketClientHandshaker handshaker, Options options) { + public WebsocketHandler( Websocket websocket, WebSocketClientHandshaker handshaker, Options options ) + { this.handshaker = handshaker; this.websocket = websocket; this.options = options; } @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - this.handshaker.handshake(ctx.channel()); - super.channelActive(ctx); + public void channelActive( ChannelHandlerContext ctx ) throws Exception + { + this.handshaker.handshake( ctx.channel() ); + super.channelActive( ctx ); } @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - this.websocket.close(-1, "Websocket is inactive"); - super.channelInactive(ctx); + public void channelInactive( ChannelHandlerContext ctx ) throws Exception + { + this.websocket.close( -1, "Websocket is inactive" ); + super.channelInactive( ctx ); } @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + public void exceptionCaught( ChannelHandlerContext ctx, Throwable cause ) + { ctx.close(); String message; - if (cause instanceof WebSocketHandshakeException || cause instanceof HTTPRequestException) { + if( cause instanceof WebSocketHandshakeException || cause instanceof HTTPRequestException ) + { message = cause.getMessage(); - } else if (cause instanceof TooLongFrameException) { + } + else if( cause instanceof TooLongFrameException ) + { message = "Message is too large"; - } else if (cause instanceof ReadTimeoutException || cause instanceof ConnectTimeoutException) { + } + else if( cause instanceof ReadTimeoutException || cause instanceof ConnectTimeoutException ) + { message = "Timed out"; - } else { + } + else + { message = "Could not connect"; } - if (this.handshaker.isHandshakeComplete()) { - this.websocket.close(-1, message); - } else { - this.websocket.failure(message); + if( this.handshaker.isHandshakeComplete() ) + { + this.websocket.close( -1, message ); + } + else + { + this.websocket.failure( message ); } } @Override - public void channelRead0(ChannelHandlerContext ctx, Object msg) { - if (this.websocket.isClosed()) { + public void channelRead0( ChannelHandlerContext ctx, Object msg ) + { + if( this.websocket.isClosed() ) + { return; } - if (!this.handshaker.isHandshakeComplete()) { - this.handshaker.finishHandshake(ctx.channel(), (FullHttpResponse) msg); - this.websocket.success(ctx.channel(), this.options); + if( !this.handshaker.isHandshakeComplete() ) + { + this.handshaker.finishHandshake( ctx.channel(), (FullHttpResponse) msg ); + this.websocket.success( ctx.channel(), this.options ); return; } - if (msg instanceof FullHttpResponse) { + if( msg instanceof FullHttpResponse ) + { FullHttpResponse response = (FullHttpResponse) msg; - throw new IllegalStateException("Unexpected FullHttpResponse (getStatus=" + response.status() + ", content=" + response.content() - .toString(CharsetUtil.UTF_8) + ')'); + throw new IllegalStateException( "Unexpected FullHttpResponse (getStatus=" + response.status() + ", content=" + response.content() + .toString( CharsetUtil.UTF_8 ) + ')' ); } WebSocketFrame frame = (WebSocketFrame) msg; - if (frame instanceof TextWebSocketFrame) { + if( frame instanceof TextWebSocketFrame ) + { String data = ((TextWebSocketFrame) frame).text(); this.websocket.environment() - .addTrackingChange(TrackingField.WEBSOCKET_INCOMING, data.length()); + .addTrackingChange( TrackingField.WEBSOCKET_INCOMING, data.length() ); this.websocket.environment() - .queueEvent(MESSAGE_EVENT, this.websocket.address(), data, false); - } else if (frame instanceof BinaryWebSocketFrame) { - byte[] converted = NetworkUtils.toBytes(frame.content()); + .queueEvent( MESSAGE_EVENT, this.websocket.address(), data, false ); + } + else if( frame instanceof BinaryWebSocketFrame ) + { + byte[] converted = NetworkUtils.toBytes( frame.content() ); this.websocket.environment() - .addTrackingChange(TrackingField.WEBSOCKET_INCOMING, converted.length); + .addTrackingChange( TrackingField.WEBSOCKET_INCOMING, converted.length ); this.websocket.environment() - .queueEvent(MESSAGE_EVENT, this.websocket.address(), converted, true); - } else if (frame instanceof CloseWebSocketFrame) { + .queueEvent( MESSAGE_EVENT, this.websocket.address(), converted, true ); + } + else if( frame instanceof CloseWebSocketFrame ) + { CloseWebSocketFrame closeFrame = (CloseWebSocketFrame) frame; - this.websocket.close(closeFrame.statusCode(), closeFrame.reasonText()); - } else if (frame instanceof PingWebSocketFrame) { + this.websocket.close( closeFrame.statusCode(), closeFrame.reasonText() ); + } + else if( frame instanceof PingWebSocketFrame ) + { frame.content() - .retain(); + .retain(); ctx.channel() - .writeAndFlush(new PongWebSocketFrame(frame.content())); + .writeAndFlush( new PongWebSocketFrame( frame.content() ) ); } } } diff --git a/src/main/java/dan200/computercraft/core/asm/DeclaringClassLoader.java b/src/main/java/dan200/computercraft/core/asm/DeclaringClassLoader.java index 4d9ea0e9d..404c02715 100644 --- a/src/main/java/dan200/computercraft/core/asm/DeclaringClassLoader.java +++ b/src/main/java/dan200/computercraft/core/asm/DeclaringClassLoader.java @@ -7,14 +7,17 @@ package dan200.computercraft.core.asm; import java.security.ProtectionDomain; -final class DeclaringClassLoader extends ClassLoader { +final class DeclaringClassLoader extends ClassLoader +{ static final DeclaringClassLoader INSTANCE = new DeclaringClassLoader(); - private DeclaringClassLoader() { - super(DeclaringClassLoader.class.getClassLoader()); + private DeclaringClassLoader() + { + super( DeclaringClassLoader.class.getClassLoader() ); } - Class define(String name, byte[] bytes, ProtectionDomain protectionDomain) throws ClassFormatError { - return this.defineClass(name, bytes, 0, bytes.length, protectionDomain); + Class define( String name, byte[] bytes, ProtectionDomain protectionDomain ) throws ClassFormatError + { + return this.defineClass( name, bytes, 0, bytes.length, protectionDomain ); } } diff --git a/src/main/java/dan200/computercraft/core/asm/Generator.java b/src/main/java/dan200/computercraft/core/asm/Generator.java index a3c028076..4da5a1b70 100644 --- a/src/main/java/dan200/computercraft/core/asm/Generator.java +++ b/src/main/java/dan200/computercraft/core/asm/Generator.java @@ -5,18 +5,22 @@ */ package dan200.computercraft.core.asm; -import static org.objectweb.asm.Opcodes.ACC_FINAL; -import static org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static org.objectweb.asm.Opcodes.ALOAD; -import static org.objectweb.asm.Opcodes.ARETURN; -import static org.objectweb.asm.Opcodes.CHECKCAST; -import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; -import static org.objectweb.asm.Opcodes.INVOKESPECIAL; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; -import static org.objectweb.asm.Opcodes.RETURN; -import static org.objectweb.asm.Opcodes.V1_8; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.primitives.Primitives; +import com.google.common.reflect.TypeToken; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.lua.IArguments; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.MethodResult; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Type; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -27,31 +31,20 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import static org.objectweb.asm.Opcodes.*; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.primitives.Primitives; -import com.google.common.reflect.TypeToken; -import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.lua.*; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; - -public final class Generator { +public final class Generator +{ private static final AtomicInteger METHOD_ID = new AtomicInteger(); private static final String METHOD_NAME = "apply"; - private static final String[] EXCEPTIONS = new String[] {Type.getInternalName(LuaException.class)}; + private static final String[] EXCEPTIONS = new String[] { Type.getInternalName( LuaException.class ) }; - private static final String INTERNAL_METHOD_RESULT = Type.getInternalName(MethodResult.class); - private static final String DESC_METHOD_RESULT = Type.getDescriptor(MethodResult.class); + private static final String INTERNAL_METHOD_RESULT = Type.getInternalName( MethodResult.class ); + private static final String DESC_METHOD_RESULT = Type.getDescriptor( MethodResult.class ); - private static final String INTERNAL_ARGUMENTS = Type.getInternalName(IArguments.class); - private static final String DESC_ARGUMENTS = Type.getDescriptor(IArguments.class); + private static final String INTERNAL_ARGUMENTS = Type.getInternalName( IArguments.class ); + private static final String DESC_ARGUMENTS = Type.getDescriptor( IArguments.class ); private final Class base; private final List> context; @@ -61,229 +54,273 @@ public final class Generator { private final Function wrap; private final LoadingCache> methodCache = CacheBuilder.newBuilder() - .build(CacheLoader.from(catching(this::build, Optional.empty()))); + .build( CacheLoader.from( catching( this::build, Optional.empty() ) ) ); private final LoadingCache, List>> classCache = CacheBuilder.newBuilder() - .build(CacheLoader.from(catching(this::build, Collections.emptyList()))); + .build( CacheLoader.from( catching( this::build, Collections.emptyList() ) ) ); - Generator(Class base, List> context, Function wrap) { + Generator( Class base, List> context, Function wrap ) + { this.base = base; this.context = context; - this.interfaces = new String[] {Type.getInternalName(base)}; + this.interfaces = new String[] { Type.getInternalName( base ) }; this.wrap = wrap; - StringBuilder methodDesc = new StringBuilder().append("(Ljava/lang/Object;"); - for (Class klass : context) { - methodDesc.append(Type.getDescriptor(klass)); + StringBuilder methodDesc = new StringBuilder().append( "(Ljava/lang/Object;" ); + for( Class klass : context ) + { + methodDesc.append( Type.getDescriptor( klass ) ); } - methodDesc.append(DESC_ARGUMENTS) - .append(")") - .append(DESC_METHOD_RESULT); + methodDesc.append( DESC_ARGUMENTS ) + .append( ")" ) + .append( DESC_METHOD_RESULT ); this.methodDesc = methodDesc.toString(); } @Nonnull - public List> getMethods(@Nonnull Class klass) { - try { - return this.classCache.get(klass); - } catch (ExecutionException e) { - ComputerCraft.log.error("Error getting methods for {}.", klass.getName(), e.getCause()); + public List> getMethods( @Nonnull Class klass ) + { + try + { + return this.classCache.get( klass ); + } + catch( ExecutionException e ) + { + ComputerCraft.log.error( "Error getting methods for {}.", klass.getName(), e.getCause() ); return Collections.emptyList(); } } @Nonnull - private List> build(Class klass) { + private List> build( Class klass ) + { ArrayList> methods = null; - for (Method method : klass.getMethods()) { - LuaFunction annotation = method.getAnnotation(LuaFunction.class); - if (annotation == null) { + for( Method method : klass.getMethods() ) + { + LuaFunction annotation = method.getAnnotation( LuaFunction.class ); + if( annotation == null ) + { continue; } - if (Modifier.isStatic(method.getModifiers())) { - ComputerCraft.log.warn("LuaFunction method {}.{} should be an instance method.", method.getDeclaringClass(), method.getName()); + if( Modifier.isStatic( method.getModifiers() ) ) + { + ComputerCraft.log.warn( "LuaFunction method {}.{} should be an instance method.", method.getDeclaringClass(), method.getName() ); continue; } - T instance = this.methodCache.getUnchecked(method) - .orElse(null); - if (instance == null) { + T instance = this.methodCache.getUnchecked( method ) + .orElse( null ); + if( instance == null ) + { continue; } - if (methods == null) { + if( methods == null ) + { methods = new ArrayList<>(); } - this.addMethod(methods, method, annotation, instance); + this.addMethod( methods, method, annotation, instance ); } for( GenericMethod method : GenericMethod.all() ) { if( !method.target.isAssignableFrom( klass ) ) continue; - T instance = this.methodCache.getUnchecked(method.method) - .orElse(null); - if (instance == null) { + T instance = this.methodCache.getUnchecked( method.method ) + .orElse( null ); + if( instance == null ) + { continue; } - if (methods == null) { + if( methods == null ) + { methods = new ArrayList<>(); } - this.addMethod(methods, method.method, method.annotation, instance); + this.addMethod( methods, method.method, method.annotation, instance ); } - if (methods == null) { + if( methods == null ) + { return Collections.emptyList(); } methods.trimToSize(); - return Collections.unmodifiableList(methods); + return Collections.unmodifiableList( methods ); } - private void addMethod(List> methods, Method method, LuaFunction annotation, T instance) { - if (annotation.mainThread()) { - instance = this.wrap.apply(instance); + private void addMethod( List> methods, Method method, LuaFunction annotation, T instance ) + { + if( annotation.mainThread() ) + { + instance = this.wrap.apply( instance ); } String[] names = annotation.value(); boolean isSimple = method.getReturnType() != MethodResult.class && !annotation.mainThread(); - if (names.length == 0) { - methods.add(new NamedMethod<>(method.getName(), instance, isSimple)); - } else { - for (String name : names) { - methods.add(new NamedMethod<>(name, instance, isSimple)); + if( names.length == 0 ) + { + methods.add( new NamedMethod<>( method.getName(), instance, isSimple ) ); + } + else + { + for( String name : names ) + { + methods.add( new NamedMethod<>( name, instance, isSimple ) ); } } } @Nonnull - private Optional build(Method method) { + private Optional build( Method method ) + { String name = method.getDeclaringClass() - .getName() + "." + method.getName(); + .getName() + "." + method.getName(); int modifiers = method.getModifiers(); // Instance methods must be final - this prevents them being overridden and potentially exposed twice. - if (!Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) { - ComputerCraft.log.warn("Lua Method {} should be final.", name); + if( !Modifier.isStatic( modifiers ) && !Modifier.isFinal( modifiers ) ) + { + ComputerCraft.log.warn( "Lua Method {} should be final.", name ); } - if (!Modifier.isPublic(modifiers)) { - ComputerCraft.log.error("Lua Method {} should be a public method.", name); + if( !Modifier.isPublic( modifiers ) ) + { + ComputerCraft.log.error( "Lua Method {} should be a public method.", name ); return Optional.empty(); } - if (!Modifier.isPublic(method.getDeclaringClass() - .getModifiers())) { - ComputerCraft.log.error("Lua Method {} should be on a public class.", name); + if( !Modifier.isPublic( method.getDeclaringClass() + .getModifiers() ) ) + { + ComputerCraft.log.error( "Lua Method {} should be on a public class.", name ); return Optional.empty(); } - ComputerCraft.log.debug("Generating method wrapper for {}.", name); + ComputerCraft.log.debug( "Generating method wrapper for {}.", name ); Class[] exceptions = method.getExceptionTypes(); - for (Class exception : exceptions) { - if (exception != LuaException.class) { - ComputerCraft.log.error("Lua Method {} cannot throw {}.", name, exception.getName()); + for( Class exception : exceptions ) + { + if( exception != LuaException.class ) + { + ComputerCraft.log.error( "Lua Method {} cannot throw {}.", name, exception.getName() ); return Optional.empty(); } } // We have some rather ugly handling of static methods in both here and the main generate function. Static methods // only come from generic sources, so this should be safe. - Class target = Modifier.isStatic(modifiers) ? method.getParameterTypes()[0] : method.getDeclaringClass(); + Class target = Modifier.isStatic( modifiers ) ? method.getParameterTypes()[0] : method.getDeclaringClass(); - try { + try + { String className = method.getDeclaringClass() - .getName() + "$cc$" + method.getName() + METHOD_ID.getAndIncrement(); - byte[] bytes = this.generate(className, target, method); - if (bytes == null) { + .getName() + "$cc$" + method.getName() + METHOD_ID.getAndIncrement(); + byte[] bytes = this.generate( className, target, method ); + if( bytes == null ) + { return Optional.empty(); } - Class klass = DeclaringClassLoader.INSTANCE.define(className, - bytes, - method.getDeclaringClass() - .getProtectionDomain()); - return Optional.of(klass.asSubclass(this.base) - .getDeclaredConstructor() - .newInstance()); - } catch (ReflectiveOperationException | ClassFormatError | RuntimeException e) { - ComputerCraft.log.error("Error generating wrapper for {}.", name, e); + Class klass = DeclaringClassLoader.INSTANCE.define( className, + bytes, + method.getDeclaringClass() + .getProtectionDomain() ); + return Optional.of( klass.asSubclass( this.base ) + .getDeclaredConstructor() + .newInstance() ); + } + catch( ReflectiveOperationException | ClassFormatError | RuntimeException e ) + { + ComputerCraft.log.error( "Error generating wrapper for {}.", name, e ); return Optional.empty(); } } @Nullable - private byte[] generate(String className, Class target, Method method) { - String internalName = className.replace(".", "/"); + private byte[] generate( String className, Class target, Method method ) + { + String internalName = className.replace( ".", "/" ); // Construct a public final class which extends Object and implements MethodInstance.Delegate - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - cw.visit(V1_8, ACC_PUBLIC | ACC_FINAL, internalName, null, "java/lang/Object", this.interfaces); - cw.visitSource("CC generated method", null); + ClassWriter cw = new ClassWriter( ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS ); + cw.visit( V1_8, ACC_PUBLIC | ACC_FINAL, internalName, null, "java/lang/Object", this.interfaces ); + cw.visitSource( "CC generated method", null ); { // Constructor just invokes super. - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + MethodVisitor mw = cw.visitMethod( ACC_PUBLIC, "", "()V", null, null ); mw.visitCode(); - mw.visitVarInsn(ALOAD, 0); - mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mw.visitInsn(RETURN); - mw.visitMaxs(0, 0); + mw.visitVarInsn( ALOAD, 0 ); + mw.visitMethodInsn( INVOKESPECIAL, "java/lang/Object", "", "()V", false ); + mw.visitInsn( RETURN ); + mw.visitMaxs( 0, 0 ); mw.visitEnd(); } { - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, METHOD_NAME, this.methodDesc, null, EXCEPTIONS); + MethodVisitor mw = cw.visitMethod( ACC_PUBLIC, METHOD_NAME, this.methodDesc, null, EXCEPTIONS ); mw.visitCode(); // If we're an instance method, load the this parameter. - if (!Modifier.isStatic(method.getModifiers())) { - mw.visitVarInsn(ALOAD, 1); - mw.visitTypeInsn(CHECKCAST, Type.getInternalName(target)); + if( !Modifier.isStatic( method.getModifiers() ) ) + { + mw.visitVarInsn( ALOAD, 1 ); + mw.visitTypeInsn( CHECKCAST, Type.getInternalName( target ) ); } int argIndex = 0; - for (java.lang.reflect.Type genericArg : method.getGenericParameterTypes()) { - Boolean loadedArg = this.loadArg(mw, target, method, genericArg, argIndex); - if (loadedArg == null) { + for( java.lang.reflect.Type genericArg : method.getGenericParameterTypes() ) + { + Boolean loadedArg = this.loadArg( mw, target, method, genericArg, argIndex ); + if( loadedArg == null ) + { return null; } - if (loadedArg) { + if( loadedArg ) + { argIndex++; } } - mw.visitMethodInsn(Modifier.isStatic(method.getModifiers()) ? INVOKESTATIC : INVOKEVIRTUAL, - Type.getInternalName(method.getDeclaringClass()), - method.getName(), - Type.getMethodDescriptor(method), - false); + mw.visitMethodInsn( Modifier.isStatic( method.getModifiers() ) ? INVOKESTATIC : INVOKEVIRTUAL, + Type.getInternalName( method.getDeclaringClass() ), + method.getName(), + Type.getMethodDescriptor( method ), + false ); // We allow a reasonable amount of flexibility on the return value's type. Alongside the obvious MethodResult, // we convert basic types into an immediate result. Class ret = method.getReturnType(); - if (ret != MethodResult.class) { - if (ret == void.class) { - mw.visitMethodInsn(INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "()" + DESC_METHOD_RESULT, false); - } else if (ret.isPrimitive()) { - Class boxed = Primitives.wrap(ret); - mw.visitMethodInsn(INVOKESTATIC, - Type.getInternalName(boxed), - "valueOf", - "(" + Type.getDescriptor(ret) + ")" + Type.getDescriptor(boxed), - false); - mw.visitMethodInsn(INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "(Ljava/lang/Object;)" + DESC_METHOD_RESULT, false); - } else if (ret == Object[].class) { - mw.visitMethodInsn(INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "([Ljava/lang/Object;)" + DESC_METHOD_RESULT, false); - } else { - mw.visitMethodInsn(INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "(Ljava/lang/Object;)" + DESC_METHOD_RESULT, false); + if( ret != MethodResult.class ) + { + if( ret == void.class ) + { + mw.visitMethodInsn( INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "()" + DESC_METHOD_RESULT, false ); + } + else if( ret.isPrimitive() ) + { + Class boxed = Primitives.wrap( ret ); + mw.visitMethodInsn( INVOKESTATIC, + Type.getInternalName( boxed ), + "valueOf", + "(" + Type.getDescriptor( ret ) + ")" + Type.getDescriptor( boxed ), + false ); + mw.visitMethodInsn( INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "(Ljava/lang/Object;)" + DESC_METHOD_RESULT, false ); + } + else if( ret == Object[].class ) + { + mw.visitMethodInsn( INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "([Ljava/lang/Object;)" + DESC_METHOD_RESULT, false ); + } + else + { + mw.visitMethodInsn( INVOKESTATIC, INTERNAL_METHOD_RESULT, "of", "(Ljava/lang/Object;)" + DESC_METHOD_RESULT, false ); } } - mw.visitInsn(ARETURN); + mw.visitInsn( ARETURN ); - mw.visitMaxs(0, 0); + mw.visitMaxs( 0, 0 ); mw.visitEnd(); } @@ -292,82 +329,94 @@ public final class Generator { return cw.toByteArray(); } - private Boolean loadArg(MethodVisitor mw, Class target, Method method, java.lang.reflect.Type genericArg, int argIndex) { - if (genericArg == target) { - mw.visitVarInsn(ALOAD, 1); - mw.visitTypeInsn(CHECKCAST, Type.getInternalName(target)); + private Boolean loadArg( MethodVisitor mw, Class target, Method method, java.lang.reflect.Type genericArg, int argIndex ) + { + if( genericArg == target ) + { + mw.visitVarInsn( ALOAD, 1 ); + mw.visitTypeInsn( CHECKCAST, Type.getInternalName( target ) ); return false; } - Class arg = Reflect.getRawType(method, genericArg, true); - if (arg == null) { + Class arg = Reflect.getRawType( method, genericArg, true ); + if( arg == null ) + { return null; } - if (arg == IArguments.class) { - mw.visitVarInsn(ALOAD, 2 + this.context.size()); + if( arg == IArguments.class ) + { + mw.visitVarInsn( ALOAD, 2 + this.context.size() ); return false; } - int idx = this.context.indexOf(arg); - if (idx >= 0) { - mw.visitVarInsn(ALOAD, 2 + idx); + int idx = this.context.indexOf( arg ); + if( idx >= 0 ) + { + mw.visitVarInsn( ALOAD, 2 + idx ); return false; } - if (arg == Optional.class) { - Class klass = Reflect.getRawType(method, - TypeToken.of(genericArg) - .resolveType(Reflect.OPTIONAL_IN) - .getType(), - false); - if (klass == null) { + if( arg == Optional.class ) + { + Class klass = Reflect.getRawType( method, + TypeToken.of( genericArg ) + .resolveType( Reflect.OPTIONAL_IN ) + .getType(), + false ); + if( klass == null ) + { return null; } - if (Enum.class.isAssignableFrom(klass) && klass != Enum.class) { - mw.visitVarInsn(ALOAD, 2 + this.context.size()); - Reflect.loadInt(mw, argIndex); - mw.visitLdcInsn(Type.getType(klass)); - mw.visitMethodInsn(INVOKEINTERFACE, INTERNAL_ARGUMENTS, "optEnum", "(ILjava/lang/Class;)Ljava/util/Optional;", true); + if( Enum.class.isAssignableFrom( klass ) && klass != Enum.class ) + { + mw.visitVarInsn( ALOAD, 2 + this.context.size() ); + Reflect.loadInt( mw, argIndex ); + mw.visitLdcInsn( Type.getType( klass ) ); + mw.visitMethodInsn( INVOKEINTERFACE, INTERNAL_ARGUMENTS, "optEnum", "(ILjava/lang/Class;)Ljava/util/Optional;", true ); return true; } - String name = Reflect.getLuaName(Primitives.unwrap(klass)); - if (name != null) { - mw.visitVarInsn(ALOAD, 2 + this.context.size()); - Reflect.loadInt(mw, argIndex); - mw.visitMethodInsn(INVOKEINTERFACE, INTERNAL_ARGUMENTS, "opt" + name, "(I)Ljava/util/Optional;", true); + String name = Reflect.getLuaName( Primitives.unwrap( klass ) ); + if( name != null ) + { + mw.visitVarInsn( ALOAD, 2 + this.context.size() ); + Reflect.loadInt( mw, argIndex ); + mw.visitMethodInsn( INVOKEINTERFACE, INTERNAL_ARGUMENTS, "opt" + name, "(I)Ljava/util/Optional;", true ); return true; } } - if (Enum.class.isAssignableFrom(arg) && arg != Enum.class) { - mw.visitVarInsn(ALOAD, 2 + this.context.size()); - Reflect.loadInt(mw, argIndex); - mw.visitLdcInsn(Type.getType(arg)); - mw.visitMethodInsn(INVOKEINTERFACE, INTERNAL_ARGUMENTS, "getEnum", "(ILjava/lang/Class;)Ljava/lang/Enum;", true); - mw.visitTypeInsn(CHECKCAST, Type.getInternalName(arg)); + if( Enum.class.isAssignableFrom( arg ) && arg != Enum.class ) + { + mw.visitVarInsn( ALOAD, 2 + this.context.size() ); + Reflect.loadInt( mw, argIndex ); + mw.visitLdcInsn( Type.getType( arg ) ); + mw.visitMethodInsn( INVOKEINTERFACE, INTERNAL_ARGUMENTS, "getEnum", "(ILjava/lang/Class;)Ljava/lang/Enum;", true ); + mw.visitTypeInsn( CHECKCAST, Type.getInternalName( arg ) ); return true; } - String name = arg == Object.class ? "" : Reflect.getLuaName(arg); - if (name != null) { - if (Reflect.getRawType(method, genericArg, false) == null) { + String name = arg == Object.class ? "" : Reflect.getLuaName( arg ); + if( name != null ) + { + if( Reflect.getRawType( method, genericArg, false ) == null ) + { return null; } - mw.visitVarInsn(ALOAD, 2 + this.context.size()); - Reflect.loadInt(mw, argIndex); - mw.visitMethodInsn(INVOKEINTERFACE, INTERNAL_ARGUMENTS, "get" + name, "(I)" + Type.getDescriptor(arg), true); + mw.visitVarInsn( ALOAD, 2 + this.context.size() ); + Reflect.loadInt( mw, argIndex ); + mw.visitMethodInsn( INVOKEINTERFACE, INTERNAL_ARGUMENTS, "get" + name, "(I)" + Type.getDescriptor( arg ), true ); return true; } - ComputerCraft.log.error("Unknown parameter type {} for method {}.{}.", - arg.getName(), - method.getDeclaringClass() - .getName(), - method.getName()); + ComputerCraft.log.error( "Unknown parameter type {} for method {}.{}.", + arg.getName(), + method.getDeclaringClass() + .getName(), + method.getName() ); return null; } diff --git a/src/main/java/dan200/computercraft/core/asm/IntCache.java b/src/main/java/dan200/computercraft/core/asm/IntCache.java index de56d79ae..cb1056dee 100644 --- a/src/main/java/dan200/computercraft/core/asm/IntCache.java +++ b/src/main/java/dan200/computercraft/core/asm/IntCache.java @@ -8,34 +8,43 @@ package dan200.computercraft.core.asm; import java.util.Arrays; import java.util.function.IntFunction; -public final class IntCache { +public final class IntCache +{ private final IntFunction factory; private volatile Object[] cache = new Object[16]; - IntCache(IntFunction factory) { + IntCache( IntFunction factory ) + { this.factory = factory; } - @SuppressWarnings ("unchecked") - public T get(int index) { - if (index < 0) { - throw new IllegalArgumentException("index < 0"); + @SuppressWarnings( "unchecked" ) + public T get( int index ) + { + if( index < 0 ) + { + throw new IllegalArgumentException( "index < 0" ); } - if (index < this.cache.length) { + if( index < this.cache.length ) + { T current = (T) this.cache[index]; - if (current != null) { + if( current != null ) + { return current; } } - synchronized (this) { - if (index >= this.cache.length) { - this.cache = Arrays.copyOf(this.cache, Math.max(this.cache.length * 2, index + 1)); + synchronized( this ) + { + if( index >= this.cache.length ) + { + this.cache = Arrays.copyOf( this.cache, Math.max( this.cache.length * 2, index + 1 ) ); } T current = (T) this.cache[index]; - if (current == null) { - this.cache[index] = current = this.factory.apply(index); + if( current == null ) + { + this.cache[index] = current = this.factory.apply( index ); } return current; } diff --git a/src/main/java/dan200/computercraft/core/asm/LuaMethod.java b/src/main/java/dan200/computercraft/core/asm/LuaMethod.java index b0bb19b54..87c454878 100644 --- a/src/main/java/dan200/computercraft/core/asm/LuaMethod.java +++ b/src/main/java/dan200/computercraft/core/asm/LuaMethod.java @@ -5,28 +5,24 @@ */ package dan200.computercraft.core.asm; -import java.util.Collections; +import dan200.computercraft.api.lua.*; import javax.annotation.Nonnull; +import java.util.Collections; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.IDynamicLuaObject; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.MethodResult; +public interface LuaMethod +{ + Generator GENERATOR = new Generator<>( LuaMethod.class, + Collections.singletonList( ILuaContext.class ), + m -> ( target, context, args ) -> TaskCallback.make( context, + () -> TaskCallback.checkUnwrap( m.apply( target, + context, + args ) ) ) ); -public interface LuaMethod { - Generator GENERATOR = new Generator<>(LuaMethod.class, - Collections.singletonList(ILuaContext.class), - m -> (target, context, args) -> TaskCallback.make(context, - () -> TaskCallback.checkUnwrap(m.apply(target, - context, - args)))); - - IntCache DYNAMIC = new IntCache<>(method -> (instance, context, args) -> ((IDynamicLuaObject) instance).callMethod(context, method, args)); + IntCache DYNAMIC = new IntCache<>( method -> ( instance, context, args ) -> ((IDynamicLuaObject) instance).callMethod( context, method, args ) ); String[] EMPTY_METHODS = new String[0]; @Nonnull - MethodResult apply(@Nonnull Object target, @Nonnull ILuaContext context, @Nonnull IArguments args) throws LuaException; + MethodResult apply( @Nonnull Object target, @Nonnull ILuaContext context, @Nonnull IArguments args ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/core/asm/NamedMethod.java b/src/main/java/dan200/computercraft/core/asm/NamedMethod.java index 7edd17f05..ffb6e0b8b 100644 --- a/src/main/java/dan200/computercraft/core/asm/NamedMethod.java +++ b/src/main/java/dan200/computercraft/core/asm/NamedMethod.java @@ -7,28 +7,33 @@ package dan200.computercraft.core.asm; import javax.annotation.Nonnull; -public final class NamedMethod { +public final class NamedMethod +{ private final String name; private final T method; private final boolean nonYielding; - NamedMethod(String name, T method, boolean nonYielding) { + NamedMethod( String name, T method, boolean nonYielding ) + { this.name = name; this.method = method; this.nonYielding = nonYielding; } @Nonnull - public String getName() { + public String getName() + { return this.name; } @Nonnull - public T getMethod() { + public T getMethod() + { return this.method; } - public boolean nonYielding() { + public boolean nonYielding() + { return this.nonYielding; } } diff --git a/src/main/java/dan200/computercraft/core/asm/ObjectSource.java b/src/main/java/dan200/computercraft/core/asm/ObjectSource.java index b696867b9..9ea11f60d 100644 --- a/src/main/java/dan200/computercraft/core/asm/ObjectSource.java +++ b/src/main/java/dan200/computercraft/core/asm/ObjectSource.java @@ -13,16 +13,22 @@ import java.util.function.BiConsumer; * This can be used to merge multiple objects together into one. Ideally this'd be part of the API, but I'm not entirely happy with the interface - * something I'd like to think about first. */ -public interface ObjectSource { - static void allMethods(Generator generator, Object object, BiConsumer> accept) { - for (NamedMethod method : generator.getMethods(object.getClass())) { - accept.accept(object, method); +public interface ObjectSource +{ + static void allMethods( Generator generator, Object object, BiConsumer> accept ) + { + for( NamedMethod method : generator.getMethods( object.getClass() ) ) + { + accept.accept( object, method ); } - if (object instanceof ObjectSource) { - for (Object extra : ((ObjectSource) object).getExtra()) { - for (NamedMethod method : generator.getMethods(extra.getClass())) { - accept.accept(extra, method); + if( object instanceof ObjectSource ) + { + for( Object extra : ((ObjectSource) object).getExtra() ) + { + for( NamedMethod method : generator.getMethods( extra.getClass() ) ) + { + accept.accept( extra, method ); } } } diff --git a/src/main/java/dan200/computercraft/core/asm/PeripheralMethod.java b/src/main/java/dan200/computercraft/core/asm/PeripheralMethod.java index 07f0c1913..959fbb5d5 100644 --- a/src/main/java/dan200/computercraft/core/asm/PeripheralMethod.java +++ b/src/main/java/dan200/computercraft/core/asm/PeripheralMethod.java @@ -5,10 +5,6 @@ */ package dan200.computercraft.core.asm; -import java.util.Arrays; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; @@ -16,21 +12,25 @@ import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IDynamicPeripheral; -public interface PeripheralMethod { - Generator GENERATOR = new Generator<>(PeripheralMethod.class, - Arrays.asList(ILuaContext.class, IComputerAccess.class), - m -> (target, context, computer, args) -> TaskCallback.make(context, - () -> TaskCallback.checkUnwrap(m.apply( - target, - context, - computer, - args)))); +import javax.annotation.Nonnull; +import java.util.Arrays; - IntCache DYNAMIC = new IntCache<>(method -> (instance, context, computer, args) -> ((IDynamicPeripheral) instance).callMethod(computer, - context, - method, - args)); +public interface PeripheralMethod +{ + Generator GENERATOR = new Generator<>( PeripheralMethod.class, + Arrays.asList( ILuaContext.class, IComputerAccess.class ), + m -> ( target, context, computer, args ) -> TaskCallback.make( context, + () -> TaskCallback.checkUnwrap( m.apply( + target, + context, + computer, + args ) ) ) ); + + IntCache DYNAMIC = new IntCache<>( method -> ( instance, context, computer, args ) -> ((IDynamicPeripheral) instance).callMethod( computer, + context, + method, + args ) ); @Nonnull - MethodResult apply(@Nonnull Object target, @Nonnull ILuaContext context, @Nonnull IComputerAccess computer, @Nonnull IArguments args) throws LuaException; + MethodResult apply( @Nonnull Object target, @Nonnull ILuaContext context, @Nonnull IComputerAccess computer, @Nonnull IArguments args ) throws LuaException; } diff --git a/src/main/java/dan200/computercraft/core/asm/Reflect.java b/src/main/java/dan200/computercraft/core/asm/Reflect.java index adac4de3d..15e016215 100644 --- a/src/main/java/dan200/computercraft/core/asm/Reflect.java +++ b/src/main/java/dan200/computercraft/core/asm/Reflect.java @@ -5,51 +5,59 @@ */ package dan200.computercraft.core.asm; -import static org.objectweb.asm.Opcodes.ICONST_0; +import dan200.computercraft.ComputerCraft; +import org.objectweb.asm.MethodVisitor; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; +import javax.annotation.Nullable; +import java.lang.reflect.*; import java.nio.ByteBuffer; import java.util.Map; import java.util.Optional; -import javax.annotation.Nullable; +import static org.objectweb.asm.Opcodes.ICONST_0; -import dan200.computercraft.ComputerCraft; -import org.objectweb.asm.MethodVisitor; - -final class Reflect { +final class Reflect +{ static final java.lang.reflect.Type OPTIONAL_IN = Optional.class.getTypeParameters()[0]; - private Reflect() { + private Reflect() + { } @Nullable - static String getLuaName(Class klass) { - if (klass.isPrimitive()) { - if (klass == int.class) { + static String getLuaName( Class klass ) + { + if( klass.isPrimitive() ) + { + if( klass == int.class ) + { return "Int"; } - if (klass == boolean.class) { + if( klass == boolean.class ) + { return "Boolean"; } - if (klass == double.class) { + if( klass == double.class ) + { return "Double"; } - if (klass == long.class) { + if( klass == long.class ) + { return "Long"; } - } else { - if (klass == Map.class) { + } + else + { + if( klass == Map.class ) + { return "Table"; } - if (klass == String.class) { + if( klass == String.class ) + { return "String"; } - if (klass == ByteBuffer.class) { + if( klass == ByteBuffer.class ) + { return "Bytes"; } } @@ -58,30 +66,38 @@ final class Reflect { } @Nullable - static Class getRawType(Method method, Type root, boolean allowParameter) { + static Class getRawType( Method method, Type root, boolean allowParameter ) + { Type underlying = root; - while (true) { - if (underlying instanceof Class) { + while( true ) + { + if( underlying instanceof Class ) + { return (Class) underlying; } - if (underlying instanceof ParameterizedType) { + if( underlying instanceof ParameterizedType ) + { ParameterizedType type = (ParameterizedType) underlying; - if (!allowParameter) { - for (java.lang.reflect.Type arg : type.getActualTypeArguments()) { - if (arg instanceof WildcardType) { + if( !allowParameter ) + { + for( java.lang.reflect.Type arg : type.getActualTypeArguments() ) + { + if( arg instanceof WildcardType ) + { continue; } - if (arg instanceof TypeVariable && ((TypeVariable) arg).getName() - .startsWith("capture#")) { + if( arg instanceof TypeVariable && ((TypeVariable) arg).getName() + .startsWith( "capture#" ) ) + { continue; } - ComputerCraft.log.error("Method {}.{} has generic type {} with non-wildcard argument {}.", - method.getDeclaringClass(), - method.getName(), - root, - arg); + ComputerCraft.log.error( "Method {}.{} has generic type {} with non-wildcard argument {}.", + method.getDeclaringClass(), + method.getName(), + root, + arg ); return null; } } @@ -91,16 +107,20 @@ final class Reflect { continue; } - ComputerCraft.log.error("Method {}.{} has unknown generic type {}.", method.getDeclaringClass(), method.getName(), root); + ComputerCraft.log.error( "Method {}.{} has unknown generic type {}.", method.getDeclaringClass(), method.getName(), root ); return null; } } - static void loadInt(MethodVisitor visitor, int value) { - if (value >= -1 && value <= 5) { - visitor.visitInsn(ICONST_0 + value); - } else { - visitor.visitLdcInsn(value); + static void loadInt( MethodVisitor visitor, int value ) + { + if( value >= -1 && value <= 5 ) + { + visitor.visitInsn( ICONST_0 + value ); + } + else + { + visitor.visitLdcInsn( value ); } } } diff --git a/src/main/java/dan200/computercraft/core/asm/TaskCallback.java b/src/main/java/dan200/computercraft/core/asm/TaskCallback.java index 918710e11..b5c208a29 100644 --- a/src/main/java/dan200/computercraft/core/asm/TaskCallback.java +++ b/src/main/java/dan200/computercraft/core/asm/TaskCallback.java @@ -5,58 +5,66 @@ */ package dan200.computercraft.core.asm; -import java.util.Arrays; +import dan200.computercraft.api.lua.*; import javax.annotation.Nonnull; +import java.util.Arrays; -import dan200.computercraft.api.lua.ILuaCallback; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.ILuaTask; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.MethodResult; - -public final class TaskCallback implements ILuaCallback { - private final MethodResult pull = MethodResult.pullEvent("task_complete", this); +public final class TaskCallback implements ILuaCallback +{ + private final MethodResult pull = MethodResult.pullEvent( "task_complete", this ); private final long task; - private TaskCallback(long task) { + private TaskCallback( long task ) + { this.task = task; } - static Object[] checkUnwrap(MethodResult result) { - if (result.getCallback() != null) { + static Object[] checkUnwrap( MethodResult result ) + { + if( result.getCallback() != null ) + { // Due to how tasks are implemented, we can't currently return a MethodResult. This is an // entirely artificial limitation - we can remove it if it ever becomes an issue. - throw new IllegalStateException("Cannot return MethodResult for mainThread task."); + throw new IllegalStateException( "Cannot return MethodResult for mainThread task." ); } return result.getResult(); } - public static MethodResult make(ILuaContext context, ILuaTask func) throws LuaException { - long task = context.issueMainThreadTask(func); - return new TaskCallback(task).pull; + public static MethodResult make( ILuaContext context, ILuaTask func ) throws LuaException + { + long task = context.issueMainThreadTask( func ); + return new TaskCallback( task ).pull; } @Nonnull @Override - public MethodResult resume(Object[] response) throws LuaException { - if (response.length < 3 || !(response[1] instanceof Number) || !(response[2] instanceof Boolean)) { + public MethodResult resume( Object[] response ) throws LuaException + { + if( response.length < 3 || !(response[1] instanceof Number) || !(response[2] instanceof Boolean) ) + { return this.pull; } - if (((Number) response[1]).longValue() != this.task) { + if( ((Number) response[1]).longValue() != this.task ) + { return this.pull; } - if ((Boolean) response[2]) { + if( (Boolean) response[2] ) + { // Extract the return values from the event and return them - return MethodResult.of(Arrays.copyOfRange(response, 3, response.length)); - } else if (response.length >= 4 && response[3] instanceof String) { + return MethodResult.of( Arrays.copyOfRange( response, 3, response.length ) ); + } + else if( response.length >= 4 && response[3] instanceof String ) + { // Extract the error message from the event and raise it - throw new LuaException((String) response[3]); - } else { - throw new LuaException("error"); + throw new LuaException( (String) response[3] ); + } + else + { + throw new LuaException( "error" ); } } } diff --git a/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java b/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java index 3a75d7428..bea5b44c8 100644 --- a/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java +++ b/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java @@ -11,37 +11,44 @@ import dan200.computercraft.api.lua.ILuaAPI; /** * A wrapper for {@link ILuaAPI}s which cleans up after a {@link ComputerSystem} when the computer is shutdown. */ -final class ApiWrapper implements ILuaAPI { +final class ApiWrapper implements ILuaAPI +{ private final ILuaAPI delegate; private final ComputerSystem system; - ApiWrapper(ILuaAPI delegate, ComputerSystem system) { + ApiWrapper( ILuaAPI delegate, ComputerSystem system ) + { this.delegate = delegate; this.system = system; } @Override - public String[] getNames() { + public String[] getNames() + { return this.delegate.getNames(); } @Override - public void startup() { + public void startup() + { this.delegate.startup(); } @Override - public void update() { + public void update() + { this.delegate.update(); } @Override - public void shutdown() { + public void shutdown() + { this.delegate.shutdown(); this.system.unmountAll(); } - public ILuaAPI getDelegate() { + public ILuaAPI getDelegate() + { return this.delegate; } } diff --git a/src/main/java/dan200/computercraft/core/computer/Computer.java b/src/main/java/dan200/computercraft/core/computer/Computer.java index 534f97596..db70b2e88 100644 --- a/src/main/java/dan200/computercraft/core/computer/Computer.java +++ b/src/main/java/dan200/computercraft/core/computer/Computer.java @@ -6,8 +6,6 @@ package dan200.computercraft.core.computer; -import java.util.concurrent.atomic.AtomicBoolean; - import com.google.common.base.Objects; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.peripheral.IWorkMonitor; @@ -15,6 +13,8 @@ import dan200.computercraft.core.apis.IAPIEnvironment; import dan200.computercraft.core.filesystem.FileSystem; import dan200.computercraft.core.terminal.Terminal; +import java.util.concurrent.atomic.AtomicBoolean; + /** * Represents a computer which may exist in-world or elsewhere. * @@ -28,14 +28,15 @@ import dan200.computercraft.core.terminal.Terminal; *
  • Passes main thread tasks to the {@link MainThreadExecutor}.
  • * */ -public class Computer { +public class Computer +{ private static final int START_DELAY = 50; // Read-only fields about the computer private final IComputerEnvironment m_environment; private final Terminal m_terminal; private final ComputerExecutor executor; private final MainThreadExecutor serverExecutor; - private final Environment internalEnvironment = new Environment(this); + private final Environment internalEnvironment = new Environment( this ); private final AtomicBoolean externalOutputChanged = new AtomicBoolean(); // Various properties of the computer private int m_id; @@ -45,53 +46,64 @@ public class Computer { private boolean startRequested; private int m_ticksSinceStart = -1; - public Computer(IComputerEnvironment environment, Terminal terminal, int id) { + public Computer( IComputerEnvironment environment, Terminal terminal, int id ) + { this.m_id = id; this.m_environment = environment; this.m_terminal = terminal; - this.executor = new ComputerExecutor(this); - this.serverExecutor = new MainThreadExecutor(this); + this.executor = new ComputerExecutor( this ); + this.serverExecutor = new MainThreadExecutor( this ); } - IComputerEnvironment getComputerEnvironment() { + IComputerEnvironment getComputerEnvironment() + { return this.m_environment; } - FileSystem getFileSystem() { + FileSystem getFileSystem() + { return this.executor.getFileSystem(); } - Terminal getTerminal() { + Terminal getTerminal() + { return this.m_terminal; } - public Environment getEnvironment() { + public Environment getEnvironment() + { return this.internalEnvironment; } - public IAPIEnvironment getAPIEnvironment() { + public IAPIEnvironment getAPIEnvironment() + { return this.internalEnvironment; } - public void turnOn() { + public void turnOn() + { this.startRequested = true; } - public void shutdown() { - this.executor.queueStop(false, false); + public void shutdown() + { + this.executor.queueStop( false, false ); } - public void reboot() { - this.executor.queueStop(true, false); + public void reboot() + { + this.executor.queueStop( true, false ); } - public void unload() { - this.executor.queueStop(false, true); + public void unload() + { + this.executor.queueStop( false, true ); } - public void queueEvent(String event, Object[] args) { - this.executor.queueEvent(event, args); + public void queueEvent( String event, Object[] args ) + { + this.executor.queueEvent( event, args ); } /** @@ -100,49 +112,62 @@ public class Computer { * @param runnable The task to run * @return If the task was successfully queued (namely, whether there is space on it). */ - public boolean queueMainThread(Runnable runnable) { - return this.serverExecutor.enqueue(runnable); + public boolean queueMainThread( Runnable runnable ) + { + return this.serverExecutor.enqueue( runnable ); } - public IWorkMonitor getMainThreadMonitor() { + public IWorkMonitor getMainThreadMonitor() + { return this.serverExecutor; } - public int getID() { + public int getID() + { return this.m_id; } - public void setID(int id) { + public void setID( int id ) + { this.m_id = id; } - public int assignID() { - if (this.m_id < 0) { + public int assignID() + { + if( this.m_id < 0 ) + { this.m_id = this.m_environment.assignNewID(); } return this.m_id; } - public String getLabel() { + public String getLabel() + { return this.m_label; } - public void setLabel(String label) { - if (!Objects.equal(label, this.m_label)) { + public void setLabel( String label ) + { + if( !Objects.equal( label, this.m_label ) ) + { this.m_label = label; - this.externalOutputChanged.set(true); + this.externalOutputChanged.set( true ); } } - public void tick() { + public void tick() + { // We keep track of the number of ticks since the last start, only - if (this.m_ticksSinceStart >= 0 && this.m_ticksSinceStart <= START_DELAY) { + if( this.m_ticksSinceStart >= 0 && this.m_ticksSinceStart <= START_DELAY ) + { this.m_ticksSinceStart++; } - if (this.startRequested && (this.m_ticksSinceStart < 0 || this.m_ticksSinceStart > START_DELAY)) { + if( this.startRequested && (this.m_ticksSinceStart < 0 || this.m_ticksSinceStart > START_DELAY) ) + { this.startRequested = false; - if (!this.executor.isOn()) { + if( !this.executor.isOn() ) + { this.m_ticksSinceStart = 0; this.executor.queueStart(); } @@ -154,35 +179,42 @@ public class Computer { this.internalEnvironment.tick(); // Propagate the environment's output to the world. - if (this.internalEnvironment.updateOutput()) { - this.externalOutputChanged.set(true); + if( this.internalEnvironment.updateOutput() ) + { + this.externalOutputChanged.set( true ); } // Set output changed if the terminal has changed from blinking to not boolean blinking = this.m_terminal.getCursorBlink() && this.m_terminal.getCursorX() >= 0 && this.m_terminal.getCursorX() < this.m_terminal.getWidth() && this.m_terminal.getCursorY() >= 0 && this.m_terminal.getCursorY() < this.m_terminal.getHeight(); - if (blinking != this.m_blinking) { + if( blinking != this.m_blinking ) + { this.m_blinking = blinking; - this.externalOutputChanged.set(true); + this.externalOutputChanged.set( true ); } } - void markChanged() { - this.externalOutputChanged.set(true); + void markChanged() + { + this.externalOutputChanged.set( true ); } - public boolean pollAndResetChanged() { - return this.externalOutputChanged.getAndSet(false); + public boolean pollAndResetChanged() + { + return this.externalOutputChanged.getAndSet( false ); } - public boolean isBlinking() { + public boolean isBlinking() + { return this.isOn() && this.m_blinking; } - public boolean isOn() { + public boolean isOn() + { return this.executor.isOn(); } - public void addApi(ILuaAPI api) { - this.executor.addApi(api); + public void addApi( ILuaAPI api ) + { + this.executor.addApi( api ); } } diff --git a/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java b/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java index 6d4f8fe97..bb3b6681e 100644 --- a/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java +++ b/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java @@ -6,29 +6,12 @@ package dan200.computercraft.core.computer; -import java.io.InputStream; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.List; -import java.util.Queue; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.ReentrantLock; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.lua.ILuaAPIFactory; -import dan200.computercraft.core.apis.ApiFactories; -import dan200.computercraft.core.apis.FSAPI; -import dan200.computercraft.core.apis.HTTPAPI; -import dan200.computercraft.core.apis.OSAPI; -import dan200.computercraft.core.apis.PeripheralAPI; -import dan200.computercraft.core.apis.RedstoneAPI; -import dan200.computercraft.core.apis.TermAPI; +import dan200.computercraft.core.apis.*; import dan200.computercraft.core.filesystem.FileSystem; import dan200.computercraft.core.filesystem.FileSystemException; import dan200.computercraft.core.lua.CobaltLuaMachine; @@ -39,6 +22,16 @@ import dan200.computercraft.core.tracking.Tracking; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.IoUtil; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.InputStream; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantLock; + /** * The main task queue and executor for a single computer. This handles turning on and off a computer, as well as running events. * @@ -55,7 +48,8 @@ import dan200.computercraft.shared.util.IoUtil; * One final responsibility for the executor is calling {@link ILuaAPI#update()} every tick, via the {@link #tick()} method. This should only be called when * the computer is actually on ({@link #isOn}). */ -final class ComputerExecutor { +final class ComputerExecutor +{ private static final int QUEUE_LIMIT = 256; final TimeoutState timeout = new TimeoutState(); /** @@ -88,7 +82,7 @@ final class ComputerExecutor { * * Note, this should be empty if this computer is off - it is cleared on shutdown and when turning on again. */ - private final Queue eventQueue = new ArrayDeque<>(4); + private final Queue eventQueue = new ArrayDeque<>( 4 ); /** * Determines if this executor is present within {@link ComputerThread}. * @@ -143,7 +137,8 @@ final class ComputerExecutor { private boolean closed; private IWritableMount rootMount; - ComputerExecutor(Computer computer) { + ComputerExecutor( Computer computer ) + { // Ensure the computer thread is running as required. ComputerThread.start(); @@ -152,44 +147,53 @@ final class ComputerExecutor { Environment environment = computer.getEnvironment(); // Add all default APIs to the loaded list. - this.apis.add(new TermAPI(environment)); - this.apis.add(new RedstoneAPI(environment)); - this.apis.add(new FSAPI(environment)); - this.apis.add(new PeripheralAPI(environment)); - this.apis.add(new OSAPI(environment)); - if (ComputerCraft.httpEnabled) { - this.apis.add(new HTTPAPI(environment)); + this.apis.add( new TermAPI( environment ) ); + this.apis.add( new RedstoneAPI( environment ) ); + this.apis.add( new FSAPI( environment ) ); + this.apis.add( new PeripheralAPI( environment ) ); + this.apis.add( new OSAPI( environment ) ); + if( ComputerCraft.httpEnabled ) + { + this.apis.add( new HTTPAPI( environment ) ); } // Load in the externally registered APIs. - for (ILuaAPIFactory factory : ApiFactories.getAll()) { - ComputerSystem system = new ComputerSystem(environment); - ILuaAPI api = factory.create(system); - if (api != null) { - this.apis.add(new ApiWrapper(api, system)); + for( ILuaAPIFactory factory : ApiFactories.getAll() ) + { + ComputerSystem system = new ComputerSystem( environment ); + ILuaAPI api = factory.create( system ); + if( api != null ) + { + this.apis.add( new ApiWrapper( api, system ) ); } } } - boolean isOn() { + boolean isOn() + { return this.isOn; } - FileSystem getFileSystem() { + FileSystem getFileSystem() + { return this.fileSystem; } - void addApi(ILuaAPI api) { - this.apis.add(api); + void addApi( ILuaAPI api ) + { + this.apis.add( api ); } /** * Schedule this computer to be started if not already on. */ - void queueStart() { - synchronized (this.queueLock) { + void queueStart() + { + synchronized( this.queueLock ) + { // We should only schedule a start if we're not currently on and there's turn on. - if (this.closed || this.isOn || this.command != null) { + if( this.closed || this.isOn || this.command != null ) + { return; } @@ -201,10 +205,13 @@ final class ComputerExecutor { /** * Add this executor to the {@link ComputerThread} if not already there. */ - private void enqueue() { - synchronized (this.queueLock) { - if (!this.onComputerQueue) { - ComputerThread.queue(this); + private void enqueue() + { + synchronized( this.queueLock ) + { + if( !this.onComputerQueue ) + { + ComputerThread.queue( this ); } } } @@ -213,12 +220,15 @@ final class ComputerExecutor { * Schedule this computer to be stopped if not already on. * * @param reboot Reboot the computer after stopping - * @param close Close the computer after stopping. + * @param close Close the computer after stopping. * @see #closed */ - void queueStop(boolean reboot, boolean close) { - synchronized (this.queueLock) { - if (this.closed) { + void queueStop( boolean reboot, boolean close ) + { + synchronized( this.queueLock ) + { + if( this.closed ) + { return; } this.closed = close; @@ -226,9 +236,11 @@ final class ComputerExecutor { StateCommand newCommand = reboot ? StateCommand.REBOOT : StateCommand.SHUTDOWN; // We should only schedule a stop if we're currently on and there's no shutdown pending. - if (!this.isOn || this.command != null) { + if( !this.isOn || this.command != null ) + { // If we're closing, set the command just in case. - if (close) { + if( close ) + { this.command = newCommand; } return; @@ -242,18 +254,23 @@ final class ComputerExecutor { /** * Abort this whole computer due to a timeout. This will immediately destroy the Lua machine, and then schedule a shutdown. */ - void abort() { + void abort() + { ILuaMachine machine = this.machine; - if (machine != null) { + if( machine != null ) + { machine.close(); } - synchronized (this.queueLock) { - if (this.closed) { + synchronized( this.queueLock ) + { + if( this.closed ) + { return; } this.command = StateCommand.ABORT; - if (this.isOn) { + if( this.isOn ) + { this.enqueue(); } } @@ -263,23 +280,27 @@ final class ComputerExecutor { * Queue an event if the computer is on. * * @param event The event's name - * @param args The event's arguments + * @param args The event's arguments */ - void queueEvent(@Nonnull String event, @Nullable Object[] args) { + void queueEvent( @Nonnull String event, @Nullable Object[] args ) + { // Events should be skipped if we're not on. - if (!this.isOn) { + if( !this.isOn ) + { return; } - synchronized (this.queueLock) { + synchronized( this.queueLock ) + { // And if we've got some command in the pipeline, then don't queue events - they'll // probably be disposed of anyway. // We also limit the number of events which can be queued. - if (this.closed || this.command != null || this.eventQueue.size() >= QUEUE_LIMIT) { + if( this.closed || this.command != null || this.eventQueue.size() >= QUEUE_LIMIT ) + { return; } - this.eventQueue.offer(new Event(event, args)); + this.eventQueue.offer( new Event( event, args ) ); this.enqueue(); } } @@ -287,20 +308,27 @@ final class ComputerExecutor { /** * Update the internals of the executor. */ - void tick() { - if (this.isOn && this.isOnLock.tryLock()) { + void tick() + { + if( this.isOn && this.isOnLock.tryLock() ) + { // This horrific structure means we don't try to update APIs while the state is being changed // (and so they may be running startup/shutdown). // We use tryLock here, as it has minimal delay, and it doesn't matter if we miss an advance at the // beginning or end of a computer's lifetime. - try { - if (this.isOn) { + try + { + if( this.isOn ) + { // Advance our APIs. - for (ILuaAPI api : this.apis) { + for( ILuaAPI api : this.apis ) + { api.update(); } } - } finally { + } + finally + { this.isOnLock.unlock(); } } @@ -309,7 +337,8 @@ final class ComputerExecutor { /** * Called before calling {@link #work()}, setting up any important state. */ - void beforeWork() { + void beforeWork() + { this.vRuntimeStart = System.nanoTime(); this.timeout.startTimer(); } @@ -319,28 +348,36 @@ final class ComputerExecutor { * * @return If we have more work to do. */ - boolean afterWork() { - if (this.interruptedEvent) { + boolean afterWork() + { + if( this.interruptedEvent ) + { this.timeout.pauseTimer(); - } else { + } + else + { this.timeout.stopTimer(); } - Tracking.addTaskTiming(this.getComputer(), this.timeout.nanoCurrent()); + Tracking.addTaskTiming( this.getComputer(), this.timeout.nanoCurrent() ); - if (this.interruptedEvent) { + if( this.interruptedEvent ) + { return true; } - synchronized (this.queueLock) { - if (this.eventQueue.isEmpty() && this.command == null) { + synchronized( this.queueLock ) + { + if( this.eventQueue.isEmpty() && this.command == null ) + { return this.onComputerQueue = false; } return true; } } - Computer getComputer() { + Computer getComputer() + { return this.computer; } @@ -353,24 +390,30 @@ final class ComputerExecutor { * @see #command * @see #eventQueue */ - void work() throws InterruptedException { - if (this.interruptedEvent) { + void work() throws InterruptedException + { + if( this.interruptedEvent ) + { this.interruptedEvent = false; - if (this.machine != null) { - this.resumeMachine(null, null); + if( this.machine != null ) + { + this.resumeMachine( null, null ); return; } } StateCommand command; Event event = null; - synchronized (this.queueLock) { + synchronized( this.queueLock ) + { command = this.command; this.command = null; // If we've no command, pull something from the event queue instead. - if (command == null) { - if (!this.isOn) { + if( command == null ) + { + if( !this.isOn ) + { // We're not on and had no command, but we had work queued. This should never happen, so clear // the event queue just in case. this.eventQueue.clear(); @@ -381,86 +424,102 @@ final class ComputerExecutor { } } - if (command != null) { - switch (command) { - case TURN_ON: - if (this.isOn) { - return; - } - this.turnOn(); - break; + if( command != null ) + { + switch( command ) + { + case TURN_ON: + if( this.isOn ) + { + return; + } + this.turnOn(); + break; - case SHUTDOWN: + case SHUTDOWN: - if (!this.isOn) { - return; - } - this.computer.getTerminal() - .reset(); - this.shutdown(); - break; + if( !this.isOn ) + { + return; + } + this.computer.getTerminal() + .reset(); + this.shutdown(); + break; - case REBOOT: - if (!this.isOn) { - return; - } - this.computer.getTerminal() - .reset(); - this.shutdown(); + case REBOOT: + if( !this.isOn ) + { + return; + } + this.computer.getTerminal() + .reset(); + this.shutdown(); - this.computer.turnOn(); - break; + this.computer.turnOn(); + break; - case ABORT: - if (!this.isOn) { - return; - } - this.displayFailure("Error running computer", TimeoutState.ABORT_MESSAGE); - this.shutdown(); - break; + case ABORT: + if( !this.isOn ) + { + return; + } + this.displayFailure( "Error running computer", TimeoutState.ABORT_MESSAGE ); + this.shutdown(); + break; } - } else if (event != null) { - this.resumeMachine(event.name, event.args); + } + else if( event != null ) + { + this.resumeMachine( event.name, event.args ); } } - private void resumeMachine(String event, Object[] args) throws InterruptedException { - MachineResult result = this.machine.handleEvent(event, args); + private void resumeMachine( String event, Object[] args ) throws InterruptedException + { + MachineResult result = this.machine.handleEvent( event, args ); this.interruptedEvent = result.isPause(); - if (!result.isError()) { + if( !result.isError() ) + { return; } - this.displayFailure("Error running computer", result.getMessage()); + this.displayFailure( "Error running computer", result.getMessage() ); this.shutdown(); } - private void turnOn() throws InterruptedException { + private void turnOn() throws InterruptedException + { this.isOnLock.lockInterruptibly(); - try { + try + { // Reset the terminal and event queue this.computer.getTerminal() - .reset(); + .reset(); this.interruptedEvent = false; - synchronized (this.queueLock) { + synchronized( this.queueLock ) + { this.eventQueue.clear(); } // Init filesystem - if ((this.fileSystem = this.createFileSystem()) == null) { + if( (this.fileSystem = this.createFileSystem()) == null ) + { this.shutdown(); return; } // Init APIs this.computer.getEnvironment() - .reset(); - for (ILuaAPI api : this.apis) { + .reset(); + for( ILuaAPI api : this.apis ) + { api.startup(); } // Init lua - if ((this.machine = this.createLuaMachine()) == null) { + if( (this.machine = this.createLuaMachine()) == null ) + { this.shutdown(); return; } @@ -468,159 +527,192 @@ final class ComputerExecutor { // Initialisation has finished, so let's mark ourselves as on. this.isOn = true; this.computer.markChanged(); - } finally { + } + finally + { this.isOnLock.unlock(); } // Now actually start the computer, now that everything is set up. - this.resumeMachine(null, null); + this.resumeMachine( null, null ); } - private void shutdown() throws InterruptedException { + private void shutdown() throws InterruptedException + { this.isOnLock.lockInterruptibly(); - try { + try + { this.isOn = false; this.interruptedEvent = false; - synchronized (this.queueLock) { + synchronized( this.queueLock ) + { this.eventQueue.clear(); } // Shutdown Lua machine - if (this.machine != null) { + if( this.machine != null ) + { this.machine.close(); this.machine = null; } // Shutdown our APIs - for (ILuaAPI api : this.apis) { + for( ILuaAPI api : this.apis ) + { api.shutdown(); } this.computer.getEnvironment() - .reset(); + .reset(); // Unload filesystem - if (this.fileSystem != null) { + if( this.fileSystem != null ) + { this.fileSystem.close(); this.fileSystem = null; } this.computer.getEnvironment() - .resetOutput(); + .resetOutput(); this.computer.markChanged(); - } finally { + } + finally + { this.isOnLock.unlock(); } } - private void displayFailure(String message, String extra) { + private void displayFailure( String message, String extra ) + { Terminal terminal = this.computer.getTerminal(); boolean colour = this.computer.getComputerEnvironment() - .isColour(); + .isColour(); terminal.reset(); // Display our primary error message - if (colour) { - terminal.setTextColour(15 - Colour.RED.ordinal()); + if( colour ) + { + terminal.setTextColour( 15 - Colour.RED.ordinal() ); } - terminal.write(message); + terminal.write( message ); - if (extra != null) { + if( extra != null ) + { // Display any additional information. This generally comes from the Lua Machine, such as compilation or // runtime errors. - terminal.setCursorPos(0, terminal.getCursorY() + 1); - terminal.write(extra); + terminal.setCursorPos( 0, terminal.getCursorY() + 1 ); + terminal.write( extra ); } // And display our generic "CC may be installed incorrectly" message. - terminal.setCursorPos(0, terminal.getCursorY() + 1); - if (colour) { - terminal.setTextColour(15 - Colour.WHITE.ordinal()); + terminal.setCursorPos( 0, terminal.getCursorY() + 1 ); + if( colour ) + { + terminal.setTextColour( 15 - Colour.WHITE.ordinal() ); } - terminal.write("ComputerCraft may be installed incorrectly"); + terminal.write( "ComputerCraft may be installed incorrectly" ); } - private FileSystem createFileSystem() { + private FileSystem createFileSystem() + { FileSystem filesystem = null; - try { - filesystem = new FileSystem("hdd", this.getRootMount()); + try + { + filesystem = new FileSystem( "hdd", this.getRootMount() ); IMount romMount = this.getRomMount(); - if (romMount == null) { - this.displayFailure("Cannot mount ROM", null); + if( romMount == null ) + { + this.displayFailure( "Cannot mount ROM", null ); return null; } - filesystem.mount("rom", "rom", romMount); + filesystem.mount( "rom", "rom", romMount ); return filesystem; - } catch (FileSystemException e) { - if (filesystem != null) { + } + catch( FileSystemException e ) + { + if( filesystem != null ) + { filesystem.close(); } - ComputerCraft.log.error("Cannot mount computer filesystem", e); + ComputerCraft.log.error( "Cannot mount computer filesystem", e ); - this.displayFailure("Cannot mount computer system", null); + this.displayFailure( "Cannot mount computer system", null ); return null; } } - private ILuaMachine createLuaMachine() { + private ILuaMachine createLuaMachine() + { // Load the bios resource InputStream biosStream = null; - try { + try + { biosStream = this.computer.getComputerEnvironment() - .createResourceFile("computercraft", "lua/bios.lua"); - } catch (Exception ignored) { + .createResourceFile( "computercraft", "lua/bios.lua" ); + } + catch( Exception ignored ) + { } - if (biosStream == null) { - this.displayFailure("Error loading bios.lua", null); + if( biosStream == null ) + { + this.displayFailure( "Error loading bios.lua", null ); return null; } // Create the lua machine - ILuaMachine machine = new CobaltLuaMachine(this.computer, this.timeout); + ILuaMachine machine = new CobaltLuaMachine( this.computer, this.timeout ); // Add the APIs. We unwrap them (yes, this is horrible) to get access to the underlying object. - for (ILuaAPI api : this.apis) { - machine.addAPI(api instanceof ApiWrapper ? ((ApiWrapper) api).getDelegate() : api); + for( ILuaAPI api : this.apis ) + { + machine.addAPI( api instanceof ApiWrapper ? ((ApiWrapper) api).getDelegate() : api ); } // Start the machine running the bios resource - MachineResult result = machine.loadBios(biosStream); - IoUtil.closeQuietly(biosStream); + MachineResult result = machine.loadBios( biosStream ); + IoUtil.closeQuietly( biosStream ); - if (result.isError()) { + if( result.isError() ) + { machine.close(); - this.displayFailure("Error loading bios.lua", result.getMessage()); + this.displayFailure( "Error loading bios.lua", result.getMessage() ); return null; } return machine; } - private IWritableMount getRootMount() { - if (this.rootMount == null) { + private IWritableMount getRootMount() + { + if( this.rootMount == null ) + { this.rootMount = this.computer.getComputerEnvironment() - .createSaveDirMount("computer/" + this.computer.assignID(), this.computer.getComputerEnvironment() - .getComputerSpaceLimit()); + .createSaveDirMount( "computer/" + this.computer.assignID(), this.computer.getComputerEnvironment() + .getComputerSpaceLimit() ); } return this.rootMount; } - private IMount getRomMount() { + private IMount getRomMount() + { return this.computer.getComputerEnvironment() - .createResourceMount("computercraft", "lua/rom"); + .createResourceMount( "computercraft", "lua/rom" ); } - private enum StateCommand { + private enum StateCommand + { TURN_ON, SHUTDOWN, REBOOT, ABORT, } - private static final class Event { + private static final class Event + { final String name; final Object[] args; - private Event(String name, Object[] args) { + private Event( String name, Object[] args ) + { this.name = name; this.args = args; } diff --git a/src/main/java/dan200/computercraft/core/computer/ComputerSide.java b/src/main/java/dan200/computercraft/core/computer/ComputerSide.java index ea80874d5..fbc4b054e 100644 --- a/src/main/java/dan200/computercraft/core/computer/ComputerSide.java +++ b/src/main/java/dan200/computercraft/core/computer/ComputerSide.java @@ -12,8 +12,9 @@ import javax.annotation.Nullable; /** * A side on a computer. Unlike {@link Direction}, this is relative to the direction the computer is facing.. */ -public enum ComputerSide { - BOTTOM("bottom"), TOP("top"), BACK("back"), FRONT("front"), RIGHT("right"), LEFT("left"); +public enum ComputerSide +{ + BOTTOM( "bottom" ), TOP( "top" ), BACK( "back" ), FRONT( "front" ), RIGHT( "right" ), LEFT( "left" ); public static final String[] NAMES = new String[] { "bottom", @@ -30,19 +31,24 @@ public enum ComputerSide { private final String name; - ComputerSide(String name) { + ComputerSide( String name ) + { this.name = name; } @Nonnull - public static ComputerSide valueOf(int side) { + public static ComputerSide valueOf( int side ) + { return VALUES[side]; } @Nullable - public static ComputerSide valueOfInsensitive(@Nonnull String name) { - for (ComputerSide side : VALUES) { - if (side.name.equalsIgnoreCase(name)) { + public static ComputerSide valueOfInsensitive( @Nonnull String name ) + { + for( ComputerSide side : VALUES ) + { + if( side.name.equalsIgnoreCase( name ) ) + { return side; } } @@ -50,7 +56,8 @@ public enum ComputerSide { return null; } - public String getName() { + public String getName() + { return this.name; } } diff --git a/src/main/java/dan200/computercraft/core/computer/ComputerSystem.java b/src/main/java/dan200/computercraft/core/computer/ComputerSystem.java index 5773e5b07..bdff606db 100644 --- a/src/main/java/dan200/computercraft/core/computer/ComputerSystem.java +++ b/src/main/java/dan200/computercraft/core/computer/ComputerSystem.java @@ -6,12 +6,6 @@ package dan200.computercraft.core.computer; -import java.util.Collections; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IFileSystem; import dan200.computercraft.api.lua.IComputerSystem; import dan200.computercraft.api.lua.ILuaAPIFactory; @@ -21,6 +15,11 @@ import dan200.computercraft.core.apis.ComputerAccess; import dan200.computercraft.core.apis.IAPIEnvironment; import dan200.computercraft.core.filesystem.FileSystem; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.Map; + /** * Implementation of {@link IComputerAccess}/{@link IComputerSystem} for usage by externally registered APIs. * @@ -28,43 +27,50 @@ import dan200.computercraft.core.filesystem.FileSystem; * @see ILuaAPIFactory * @see ApiWrapper */ -public class ComputerSystem extends ComputerAccess implements IComputerSystem { +public class ComputerSystem extends ComputerAccess implements IComputerSystem +{ private final IAPIEnvironment environment; - ComputerSystem(IAPIEnvironment environment) { - super(environment); + ComputerSystem( IAPIEnvironment environment ) + { + super( environment ); this.environment = environment; } @Nonnull @Override - public String getAttachmentName() { + public String getAttachmentName() + { return "computer"; } @Nonnull @Override - public Map getAvailablePeripherals() { + public Map getAvailablePeripherals() + { // TODO: Should this return peripherals on the current computer? return Collections.emptyMap(); } @Nullable @Override - public IPeripheral getAvailablePeripheral(@Nonnull String name) { + public IPeripheral getAvailablePeripheral( @Nonnull String name ) + { return null; } @Nullable @Override - public IFileSystem getFileSystem() { + public IFileSystem getFileSystem() + { FileSystem fs = this.environment.getFileSystem(); return fs == null ? null : fs.getMountWrapper(); } @Nullable @Override - public String getLabel() { + public String getLabel() + { return this.environment.getLabel(); } } diff --git a/src/main/java/dan200/computercraft/core/computer/ComputerThread.java b/src/main/java/dan200/computercraft/core/computer/ComputerThread.java index ccebc9e2c..135efd9b0 100644 --- a/src/main/java/dan200/computercraft/core/computer/ComputerThread.java +++ b/src/main/java/dan200/computercraft/core/computer/ComputerThread.java @@ -6,9 +6,11 @@ package dan200.computercraft.core.computer; -import static dan200.computercraft.core.computer.TimeoutState.ABORT_TIMEOUT; -import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.shared.util.ThreadUtils; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.TreeSet; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; @@ -17,11 +19,8 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import dan200.computercraft.ComputerCraft; -import dan200.computercraft.shared.util.ThreadUtils; +import static dan200.computercraft.core.computer.TimeoutState.ABORT_TIMEOUT; +import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT; /** * Responsible for running all tasks from a {@link Computer}. @@ -44,7 +43,8 @@ import dan200.computercraft.shared.util.ThreadUtils; * @see TimeoutState For how hard timeouts are handled. * @see ComputerExecutor For how computers actually do execution. */ -public final class ComputerThread { +public final class ComputerThread +{ /** * How often the computer thread monitor should run, in milliseconds. * @@ -57,7 +57,7 @@ public final class ComputerThread { * * An average tick takes 50ms, and so we ideally need to have handled a couple of events within that window in order to have a perceived low latency. */ - private static final long DEFAULT_LATENCY = TimeUnit.MILLISECONDS.toNanos(50); + private static final long DEFAULT_LATENCY = TimeUnit.MILLISECONDS.toNanos( 50 ); /** * The minimum value that {@link #DEFAULT_LATENCY} can have when scaled. @@ -65,7 +65,7 @@ public final class ComputerThread { * From statistics gathered on SwitchCraft, almost all machines will execute under 15ms, 75% under 1.5ms, with the mean being about 3ms. Most computers * shouldn't be too impacted with having such a short period to execute in. */ - private static final long DEFAULT_MIN_PERIOD = TimeUnit.MILLISECONDS.toNanos(5); + private static final long DEFAULT_MIN_PERIOD = TimeUnit.MILLISECONDS.toNanos( 5 ); /** * The maximum number of tasks before we have to start scaling latency linearly. @@ -81,19 +81,21 @@ public final class ComputerThread { /** * Active queues to execute. */ - private static final TreeSet computerQueue = new TreeSet<>((a, b) -> { - if (a == b) { + private static final TreeSet computerQueue = new TreeSet<>( ( a, b ) -> { + if( a == b ) + { return 0; // Should never happen, but let's be consistent here } long at = a.virtualRuntime, bt = b.virtualRuntime; - if (at == bt) { - return Integer.compare(a.hashCode(), b.hashCode()); + if( at == bt ) + { + return Integer.compare( a.hashCode(), b.hashCode() ); } return at < bt ? -1 : 1; - }); - private static final ThreadFactory monitorFactory = ThreadUtils.factory("Computer-Monitor"); - private static final ThreadFactory runnerFactory = ThreadUtils.factory("Computer-Runner"); + } ); + private static final ThreadFactory monitorFactory = ThreadUtils.factory( "Computer-Monitor" ); + private static final ThreadFactory runnerFactory = ThreadUtils.factory( "Computer-Runner" ); /** * Whether the computer thread system is currently running. */ @@ -118,36 +120,43 @@ public final class ComputerThread { /** * Start the computer thread. */ - static void start() { - synchronized (threadLock) { + static void start() + { + synchronized( threadLock ) + { running = true; - if (runners == null) { + if( runners == null ) + { // TODO: Change the runners length on config reloads runners = new TaskRunner[ComputerCraft.computerThreads]; // latency and minPeriod are scaled by 1 + floor(log2(threads)). We can afford to execute tasks for // longer when executing on more than one thread. - long factor = 64 - Long.numberOfLeadingZeros(runners.length); + long factor = 64 - Long.numberOfLeadingZeros( runners.length ); latency = DEFAULT_LATENCY * factor; minPeriod = DEFAULT_MIN_PERIOD * factor; } - for (int i = 0; i < runners.length; i++) { + for( int i = 0; i < runners.length; i++ ) + { TaskRunner runner = runners[i]; - if (runner == null || runner.owner == null || !runner.owner.isAlive()) { + if( runner == null || runner.owner == null || !runner.owner.isAlive() ) + { // Mark the old runner as dead, just in case. - if (runner != null) { + if( runner != null ) + { runner.running = false; } // And start a new runner - runnerFactory.newThread(runners[i] = new TaskRunner()) - .start(); + runnerFactory.newThread( runners[i] = new TaskRunner() ) + .start(); } } - if (monitor == null || !monitor.isAlive()) { - (monitor = monitorFactory.newThread(new Monitor())).start(); + if( monitor == null || !monitor.isAlive() ) + { + (monitor = monitorFactory.newThread( new Monitor() )).start(); } } } @@ -155,17 +164,23 @@ public final class ComputerThread { /** * Attempt to stop the computer thread. This interrupts each runner, and clears the task queue. */ - public static void stop() { - synchronized (threadLock) { + public static void stop() + { + synchronized( threadLock ) + { running = false; - if (runners != null) { - for (TaskRunner runner : runners) { - if (runner == null) { + if( runners != null ) + { + for( TaskRunner runner : runners ) + { + if( runner == null ) + { continue; } runner.running = false; - if (runner.owner != null) { + if( runner.owner != null ) + { runner.owner.interrupt(); } } @@ -173,9 +188,12 @@ public final class ComputerThread { } computerLock.lock(); - try { + try + { computerQueue.clear(); - } finally { + } + finally + { computerLock.unlock(); } } @@ -187,34 +205,42 @@ public final class ComputerThread { * * @param executor The computer to execute work on. */ - static void queue(@Nonnull ComputerExecutor executor) { + static void queue( @Nonnull ComputerExecutor executor ) + { computerLock.lock(); - try { - if (executor.onComputerQueue) { - throw new IllegalStateException("Cannot queue already queued executor"); + try + { + if( executor.onComputerQueue ) + { + throw new IllegalStateException( "Cannot queue already queued executor" ); } executor.onComputerQueue = true; - updateRuntimes(null); + updateRuntimes( null ); // We're not currently on the queue, so update its current execution time to // ensure its at least as high as the minimum. long newRuntime = minimumVirtualRuntime; - if (executor.virtualRuntime == 0) { + if( executor.virtualRuntime == 0 ) + { // Slow down new computers a little bit. newRuntime += scaledPeriod(); - } else { + } + else + { // Give a small boost to computers which have slept a little. newRuntime -= latency / 2; } - executor.virtualRuntime = Math.max(newRuntime, executor.virtualRuntime); + executor.virtualRuntime = Math.max( newRuntime, executor.virtualRuntime ); // Add to the queue, and signal the workers. - computerQueue.add(executor); + computerQueue.add( executor ); hasWork.signal(); - } finally { + } + finally + { computerLock.unlock(); } } @@ -228,11 +254,13 @@ public final class ComputerThread { * * @param current The machine which we updating runtimes from. */ - private static void updateRuntimes(@Nullable ComputerExecutor current) { + private static void updateRuntimes( @Nullable ComputerExecutor current ) + { long minRuntime = Long.MAX_VALUE; // If we've a task on the queue, use that as our base time. - if (!computerQueue.isEmpty()) { + if( !computerQueue.isEmpty() ) + { minRuntime = computerQueue.first().virtualRuntime; } @@ -240,29 +268,35 @@ public final class ComputerThread { long now = System.nanoTime(); int tasks = 1 + computerQueue.size(); TaskRunner[] currentRunners = runners; - if (currentRunners != null) { - for (TaskRunner runner : currentRunners) { - if (runner == null) { + if( currentRunners != null ) + { + for( TaskRunner runner : currentRunners ) + { + if( runner == null ) + { continue; } ComputerExecutor executor = runner.currentExecutor.get(); - if (executor == null) { + if( executor == null ) + { continue; } // We do two things here: first we update the task's virtual runtime based on when we // last checked, and then we check the minimum. - minRuntime = Math.min(minRuntime, executor.virtualRuntime += (now - executor.vRuntimeStart) / tasks); + minRuntime = Math.min( minRuntime, executor.virtualRuntime += (now - executor.vRuntimeStart) / tasks ); executor.vRuntimeStart = now; } } // And update the most recently executed one (if set). - if (current != null) { - minRuntime = Math.min(minRuntime, current.virtualRuntime += (now - current.vRuntimeStart) / tasks); + if( current != null ) + { + minRuntime = Math.min( minRuntime, current.virtualRuntime += (now - current.vRuntimeStart) / tasks ); } - if (minRuntime > minimumVirtualRuntime && minRuntime < Long.MAX_VALUE) { + if( minRuntime > minimumVirtualRuntime && minRuntime < Long.MAX_VALUE ) + { minimumVirtualRuntime = minRuntime; } } @@ -275,7 +309,8 @@ public final class ComputerThread { * @see #DEFAULT_MIN_PERIOD * @see #LATENCY_MAX_TASKS */ - static long scaledPeriod() { + static long scaledPeriod() + { // +1 to include the current task int count = 1 + computerQueue.size(); return count < LATENCY_MAX_TASKS ? latency / count : minPeriod; @@ -284,34 +319,40 @@ public final class ComputerThread { /** * Ensure the "currently working" state of the executor is reset, the timings are updated, and then requeue the executor if needed. * - * @param runner The runner this task was on. + * @param runner The runner this task was on. * @param executor The executor to requeue */ - private static void afterWork(TaskRunner runner, ComputerExecutor executor) { + private static void afterWork( TaskRunner runner, ComputerExecutor executor ) + { // Clear the executor's thread. - Thread currentThread = executor.executingThread.getAndSet(null); - if (currentThread != runner.owner) { + Thread currentThread = executor.executingThread.getAndSet( null ); + if( currentThread != runner.owner ) + { ComputerCraft.log.error( "Expected computer #{} to be running on {}, but already running on {}. This is a SERIOUS bug, please report with your debug.log.", executor.getComputer() - .getID(), + .getID(), runner.owner.getName(), - currentThread == null ? "nothing" : currentThread.getName()); + currentThread == null ? "nothing" : currentThread.getName() ); } computerLock.lock(); - try { - updateRuntimes(executor); + try + { + updateRuntimes( executor ); // If we've no more tasks, just return. - if (!executor.afterWork()) { + if( !executor.afterWork() ) + { return; } // Otherwise, add to the queue, and signal any waiting workers. - computerQueue.add(executor); + computerQueue.add( executor ); hasWork.signal(); - } finally { + } + finally + { computerLock.unlock(); } } @@ -321,36 +362,41 @@ public final class ComputerThread { * * @return If we have work queued up. */ - static boolean hasPendingWork() { + static boolean hasPendingWork() + { return !computerQueue.isEmpty(); } - private static void timeoutTask(ComputerExecutor executor, Thread thread, long time) { - if (!ComputerCraft.logComputerErrors) { + private static void timeoutTask( ComputerExecutor executor, Thread thread, long time ) + { + if( !ComputerCraft.logComputerErrors ) + { return; } - StringBuilder builder = new StringBuilder().append("Terminating computer #") - .append(executor.getComputer() - .getID()) - .append(" due to timeout (running for ") - .append(time * 1e-9) - .append(" seconds). This is NOT a bug, but may mean a computer is misbehaving. ") - .append(thread.getName()) - .append(" is currently ") - .append(thread.getState()); - Object blocking = LockSupport.getBlocker(thread); - if (blocking != null) { - builder.append("\n on ") - .append(blocking); + StringBuilder builder = new StringBuilder().append( "Terminating computer #" ) + .append( executor.getComputer() + .getID() ) + .append( " due to timeout (running for " ) + .append( time * 1e-9 ) + .append( " seconds). This is NOT a bug, but may mean a computer is misbehaving. " ) + .append( thread.getName() ) + .append( " is currently " ) + .append( thread.getState() ); + Object blocking = LockSupport.getBlocker( thread ); + if( blocking != null ) + { + builder.append( "\n on " ) + .append( blocking ); } - for (StackTraceElement element : thread.getStackTrace()) { - builder.append("\n at ") - .append(element); + for( StackTraceElement element : thread.getStackTrace() ) + { + builder.append( "\n at " ) + .append( element ); } - ComputerCraft.log.warn(builder.toString()); + ComputerCraft.log.warn( builder.toString() ); } /** @@ -358,36 +404,46 @@ public final class ComputerThread { * * @see TimeoutState */ - private static final class Monitor implements Runnable { + private static final class Monitor implements Runnable + { @Override - public void run() { - try { - while (true) { - Thread.sleep(MONITOR_WAKEUP); + public void run() + { + try + { + while( true ) + { + Thread.sleep( MONITOR_WAKEUP ); TaskRunner[] currentRunners = ComputerThread.runners; - if (currentRunners != null) { - for (int i = 0; i < currentRunners.length; i++) { + if( currentRunners != null ) + { + for( int i = 0; i < currentRunners.length; i++ ) + { TaskRunner runner = currentRunners[i]; // If we've no runner, skip. - if (runner == null || runner.owner == null || !runner.owner.isAlive()) { - if (!running) { + if( runner == null || runner.owner == null || !runner.owner.isAlive() ) + { + if( !running ) + { continue; } // Mark the old runner as dead and start a new one. - ComputerCraft.log.warn("Previous runner ({}) has crashed, restarting!", - runner != null && runner.owner != null ? runner.owner.getName() : runner); - if (runner != null) { + ComputerCraft.log.warn( "Previous runner ({}) has crashed, restarting!", + runner != null && runner.owner != null ? runner.owner.getName() : runner ); + if( runner != null ) + { runner.running = false; } - runnerFactory.newThread(runners[i] = new TaskRunner()) - .start(); + runnerFactory.newThread( runners[i] = new TaskRunner() ) + .start(); } // If the runner has no work, skip ComputerExecutor executor = runner.currentExecutor.get(); - if (executor == null) { + if( executor == null ) + { continue; } @@ -395,7 +451,8 @@ public final class ComputerThread { // then we can let the Lua machine do its work. long afterStart = executor.timeout.nanoCumulative(); long afterHardAbort = afterStart - TIMEOUT - ABORT_TIMEOUT; - if (afterHardAbort < 0) { + if( afterHardAbort < 0 ) + { continue; } @@ -403,34 +460,42 @@ public final class ComputerThread { executor.timeout.hardAbort(); executor.abort(); - if (afterHardAbort >= ABORT_TIMEOUT * 2) { + if( afterHardAbort >= ABORT_TIMEOUT * 2 ) + { // If we've hard aborted and interrupted, and we're still not dead, then mark the runner // as dead, finish off the task, and spawn a new runner. - timeoutTask(executor, runner.owner, afterStart); + timeoutTask( executor, runner.owner, afterStart ); runner.running = false; runner.owner.interrupt(); - ComputerExecutor thisExecutor = runner.currentExecutor.getAndSet(null); - if (thisExecutor != null) { - afterWork(runner, executor); + ComputerExecutor thisExecutor = runner.currentExecutor.getAndSet( null ); + if( thisExecutor != null ) + { + afterWork( runner, executor ); } - synchronized (threadLock) { - if (running && runners.length > i && runners[i] == runner) { - runnerFactory.newThread(currentRunners[i] = new TaskRunner()) - .start(); + synchronized( threadLock ) + { + if( running && runners.length > i && runners[i] == runner ) + { + runnerFactory.newThread( currentRunners[i] = new TaskRunner() ) + .start(); } } - } else if (afterHardAbort >= ABORT_TIMEOUT) { + } + else if( afterHardAbort >= ABORT_TIMEOUT ) + { // If we've hard aborted but we're still not dead, dump the stack trace and interrupt // the task. - timeoutTask(executor, runner.owner, afterStart); + timeoutTask( executor, runner.owner, afterStart ); runner.owner.interrupt(); } } } } - } catch (InterruptedException ignored) { + } + catch( InterruptedException ignored ) + { } } } @@ -441,31 +506,41 @@ public final class ComputerThread { * This is responsible for running the {@link ComputerExecutor#work()}, {@link ComputerExecutor#beforeWork()} and {@link ComputerExecutor#afterWork()} * functions. Everything else is either handled by the executor, timeout state or monitor. */ - private static final class TaskRunner implements Runnable { + private static final class TaskRunner implements Runnable + { final AtomicReference currentExecutor = new AtomicReference<>(); Thread owner; volatile boolean running = true; @Override - public void run() { + public void run() + { this.owner = Thread.currentThread(); tasks: - while (this.running && ComputerThread.running) { + while( this.running && ComputerThread.running ) + { // Wait for an active queue to execute ComputerExecutor executor; - try { + try + { computerLock.lockInterruptibly(); - try { - while (computerQueue.isEmpty()) { + try + { + while( computerQueue.isEmpty() ) + { hasWork.await(); } executor = computerQueue.pollFirst(); assert executor != null : "hasWork should ensure we never receive null work"; - } finally { + } + finally + { computerLock.unlock(); } - } catch (InterruptedException ignored) { + } + catch( InterruptedException ignored ) + { // If we've been interrupted, our running flag has probably been reset, so we'll // just jump into the next iteration. continue; @@ -473,14 +548,16 @@ public final class ComputerThread { // If we're trying to executing some task on this computer while someone else is doing work, something // is seriously wrong. - while (!executor.executingThread.compareAndSet(null, this.owner)) { + while( !executor.executingThread.compareAndSet( null, this.owner ) ) + { Thread existing = executor.executingThread.get(); - if (existing != null) { + if( existing != null ) + { ComputerCraft.log.error( "Trying to run computer #{} on thread {}, but already running on {}. This is a SERIOUS bug, please report with your debug.log.", executor.getComputer() - .getID(), this.owner.getName(), - existing.getName()); + .getID(), this.owner.getName(), + existing.getName() ); continue tasks; } } @@ -490,18 +567,24 @@ public final class ComputerThread { // And then set the current executor. It's important to do it afterwards, as otherwise we introduce // race conditions with the monitor. - this.currentExecutor.set(executor); + this.currentExecutor.set( executor ); // Execute the task - try { + try + { executor.work(); - } catch (Exception | LinkageError | VirtualMachineError e) { - ComputerCraft.log.error("Error running task on computer #" + executor.getComputer() - .getID(), e); - } finally { - ComputerExecutor thisExecutor = this.currentExecutor.getAndSet(null); - if (thisExecutor != null) { - afterWork(this, executor); + } + catch( Exception | LinkageError | VirtualMachineError e ) + { + ComputerCraft.log.error( "Error running task on computer #" + executor.getComputer() + .getID(), e ); + } + finally + { + ComputerExecutor thisExecutor = this.currentExecutor.getAndSet( null ); + if( thisExecutor != null ) + { + afterWork( this, executor ); } } } diff --git a/src/main/java/dan200/computercraft/core/computer/Environment.java b/src/main/java/dan200/computercraft/core/computer/Environment.java index 454333717..31b21539c 100644 --- a/src/main/java/dan200/computercraft/core/computer/Environment.java +++ b/src/main/java/dan200/computercraft/core/computer/Environment.java @@ -6,11 +6,6 @@ package dan200.computercraft.core.computer; -import java.util.Arrays; -import java.util.Iterator; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IWorkMonitor; @@ -22,6 +17,10 @@ import dan200.computercraft.core.tracking.TrackingField; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.Iterator; + /** * Represents the "environment" that a {@link Computer} exists in. * @@ -41,7 +40,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; *

    Peripheral

    * We also keep track of peripherals. These are read on both threads, and only written on the main thread. */ -public final class Environment implements IAPIEnvironment { +public final class Environment implements IAPIEnvironment +{ private final Computer computer; private final int[] internalOutput = new int[ComputerSide.COUNT]; private final int[] internalBundledOutput = new int[ComputerSide.COUNT]; @@ -56,58 +56,70 @@ public final class Environment implements IAPIEnvironment { private IPeripheralChangeListener peripheralListener = null; private int nextTimerToken = 0; - Environment(Computer computer) { + Environment( Computer computer ) + { this.computer = computer; } @Override - public int getComputerID() { + public int getComputerID() + { return this.computer.assignID(); } @Nonnull @Override - public IComputerEnvironment getComputerEnvironment() { + public IComputerEnvironment getComputerEnvironment() + { return this.computer.getComputerEnvironment(); } @Nonnull @Override - public IWorkMonitor getMainThreadMonitor() { + public IWorkMonitor getMainThreadMonitor() + { return this.computer.getMainThreadMonitor(); } @Nonnull @Override - public Terminal getTerminal() { + public Terminal getTerminal() + { return this.computer.getTerminal(); } @Override - public FileSystem getFileSystem() { + public FileSystem getFileSystem() + { return this.computer.getFileSystem(); } @Override - public void shutdown() { + public void shutdown() + { this.computer.shutdown(); } @Override - public void reboot() { + public void reboot() + { this.computer.reboot(); } @Override - public void queueEvent(String event, Object... args) { - this.computer.queueEvent(event, args); + public void queueEvent( String event, Object... args ) + { + this.computer.queueEvent( event, args ); } @Override - public void setOutput(ComputerSide side, int output) { + public void setOutput( ComputerSide side, int output ) + { int index = side.ordinal(); - synchronized (this.internalOutput) { - if (this.internalOutput[index] != output) { + synchronized( this.internalOutput ) + { + if( this.internalOutput[index] != output ) + { this.internalOutput[index] = output; this.internalOutputChanged = true; } @@ -115,22 +127,28 @@ public final class Environment implements IAPIEnvironment { } @Override - public int getOutput(ComputerSide side) { - synchronized (this.internalOutput) { + public int getOutput( ComputerSide side ) + { + synchronized( this.internalOutput ) + { return this.computer.isOn() ? this.internalOutput[side.ordinal()] : 0; } } @Override - public int getInput(ComputerSide side) { + public int getInput( ComputerSide side ) + { return this.input[side.ordinal()]; } @Override - public void setBundledOutput(ComputerSide side, int output) { + public void setBundledOutput( ComputerSide side, int output ) + { int index = side.ordinal(); - synchronized (this.internalOutput) { - if (this.internalBundledOutput[index] != output) { + synchronized( this.internalOutput ) + { + if( this.internalBundledOutput[index] != output ) + { this.internalBundledOutput[index] = output; this.internalOutputChanged = true; } @@ -138,80 +156,100 @@ public final class Environment implements IAPIEnvironment { } @Override - public int getBundledOutput(ComputerSide side) { - synchronized (this.internalOutput) { + public int getBundledOutput( ComputerSide side ) + { + synchronized( this.internalOutput ) + { return this.computer.isOn() ? this.internalBundledOutput[side.ordinal()] : 0; } } @Override - public int getBundledInput(ComputerSide side) { + public int getBundledInput( ComputerSide side ) + { return this.bundledInput[side.ordinal()]; } @Override - public void setPeripheralChangeListener(IPeripheralChangeListener listener) { - synchronized (this.peripherals) { + public void setPeripheralChangeListener( IPeripheralChangeListener listener ) + { + synchronized( this.peripherals ) + { this.peripheralListener = listener; } } @Override - public IPeripheral getPeripheral(ComputerSide side) { - synchronized (this.peripherals) { + public IPeripheral getPeripheral( ComputerSide side ) + { + synchronized( this.peripherals ) + { return this.peripherals[side.ordinal()]; } } @Override - public String getLabel() { + public String getLabel() + { return this.computer.getLabel(); } @Override - public void setLabel(String label) { - this.computer.setLabel(label); + public void setLabel( String label ) + { + this.computer.setLabel( label ); } @Override - public int startTimer(long ticks) { - synchronized (this.timers) { - this.timers.put(this.nextTimerToken, new Timer(ticks)); + public int startTimer( long ticks ) + { + synchronized( this.timers ) + { + this.timers.put( this.nextTimerToken, new Timer( ticks ) ); return this.nextTimerToken++; } } @Override - public void cancelTimer(int id) { - synchronized (this.timers) { - this.timers.remove(id); + public void cancelTimer( int id ) + { + synchronized( this.timers ) + { + this.timers.remove( id ); } } @Override - public void addTrackingChange(@Nonnull TrackingField field, long change) { - Tracking.addValue(this.computer, field, change); + public void addTrackingChange( @Nonnull TrackingField field, long change ) + { + Tracking.addValue( this.computer, field, change ); } - public int getExternalRedstoneOutput(ComputerSide side) { + public int getExternalRedstoneOutput( ComputerSide side ) + { return this.computer.isOn() ? this.externalOutput[side.ordinal()] : 0; } - public int getExternalBundledRedstoneOutput(ComputerSide side) { + public int getExternalBundledRedstoneOutput( ComputerSide side ) + { return this.computer.isOn() ? this.externalBundledOutput[side.ordinal()] : 0; } - public void setRedstoneInput(ComputerSide side, int level) { + public void setRedstoneInput( ComputerSide side, int level ) + { int index = side.ordinal(); - if (this.input[index] != level) { + if( this.input[index] != level ) + { this.input[index] = level; this.inputChanged = true; } } - public void setBundledRedstoneInput(ComputerSide side, int combination) { + public void setBundledRedstoneInput( ComputerSide side, int combination ) + { int index = side.ordinal(); - if (this.bundledInput[index] != combination) { + if( this.bundledInput[index] != combination ) + { this.bundledInput[index] = combination; this.inputChanged = true; } @@ -223,8 +261,10 @@ public final class Environment implements IAPIEnvironment { * @see ILuaAPI#startup() * @see ILuaAPI#shutdown() */ - void reset() { - synchronized (this.timers) { + void reset() + { + synchronized( this.timers ) + { this.timers.clear(); } } @@ -232,23 +272,28 @@ public final class Environment implements IAPIEnvironment { /** * Called on the main thread to update the internal state of the computer. */ - void tick() { - if (this.inputChanged) { + void tick() + { + if( this.inputChanged ) + { this.inputChanged = false; - this.queueEvent("redstone"); + this.queueEvent( "redstone" ); } - synchronized (this.timers) { + synchronized( this.timers ) + { // Countdown all of our active timers Iterator> it = this.timers.int2ObjectEntrySet() - .iterator(); - while (it.hasNext()) { + .iterator(); + while( it.hasNext() ) + { Int2ObjectMap.Entry entry = it.next(); Timer timer = entry.getValue(); timer.ticksLeft--; - if (timer.ticksLeft <= 0) { + if( timer.ticksLeft <= 0 ) + { // Queue the "timer" event - this.queueEvent(TIMER_EVENT, entry.getIntKey()); + this.queueEvent( TIMER_EVENT, entry.getIntKey() ); it.remove(); } } @@ -260,22 +305,28 @@ public final class Environment implements IAPIEnvironment { * * @return If the outputs have changed. */ - boolean updateOutput() { + boolean updateOutput() + { // Mark output as changed if the internal redstone has changed - synchronized (this.internalOutput) { - if (!this.internalOutputChanged) { + synchronized( this.internalOutput ) + { + if( !this.internalOutputChanged ) + { return false; } boolean changed = false; - for (int i = 0; i < ComputerSide.COUNT; i++) { - if (this.externalOutput[i] != this.internalOutput[i]) { + for( int i = 0; i < ComputerSide.COUNT; i++ ) + { + if( this.externalOutput[i] != this.internalOutput[i] ) + { this.externalOutput[i] = this.internalOutput[i]; changed = true; } - if (this.externalBundledOutput[i] != this.internalBundledOutput[i]) { + if( this.externalBundledOutput[i] != this.internalBundledOutput[i] ) + { this.externalBundledOutput[i] = this.internalBundledOutput[i]; changed = true; } @@ -287,32 +338,40 @@ public final class Environment implements IAPIEnvironment { } } - void resetOutput() { + void resetOutput() + { // Reset redstone output - synchronized (this.internalOutput) { - Arrays.fill(this.internalOutput, 0); - Arrays.fill(this.internalBundledOutput, 0); + synchronized( this.internalOutput ) + { + Arrays.fill( this.internalOutput, 0 ); + Arrays.fill( this.internalBundledOutput, 0 ); this.internalOutputChanged = true; } } - public void setPeripheral(ComputerSide side, IPeripheral peripheral) { - synchronized (this.peripherals) { + public void setPeripheral( ComputerSide side, IPeripheral peripheral ) + { + synchronized( this.peripherals ) + { int index = side.ordinal(); IPeripheral existing = this.peripherals[index]; - if ((existing == null && peripheral != null) || (existing != null && peripheral == null) || (existing != null && !existing.equals(peripheral))) { + if( (existing == null && peripheral != null) || (existing != null && peripheral == null) || (existing != null && !existing.equals( peripheral )) ) + { this.peripherals[index] = peripheral; - if (this.peripheralListener != null) { - this.peripheralListener.onPeripheralChanged(side, peripheral); + if( this.peripheralListener != null ) + { + this.peripheralListener.onPeripheralChanged( side, peripheral ); } } } } - private static class Timer { + private static class Timer + { long ticksLeft; - Timer(long ticksLeft) { + Timer( long ticksLeft ) + { this.ticksLeft = ticksLeft; } } diff --git a/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java b/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java index de87cf8dd..66487c42b 100644 --- a/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java +++ b/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java @@ -6,15 +6,15 @@ package dan200.computercraft.core.computer; -import java.io.InputStream; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; -public interface IComputerEnvironment { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.InputStream; + +public interface IComputerEnvironment +{ int getDay(); double getTimeOfDay(); @@ -32,11 +32,11 @@ public interface IComputerEnvironment { int assignNewID(); @Nullable - IWritableMount createSaveDirMount(String subPath, long capacity); + IWritableMount createSaveDirMount( String subPath, long capacity ); @Nullable - IMount createResourceMount(String domain, String subPath); + IMount createResourceMount( String domain, String subPath ); @Nullable - InputStream createResourceFile(String domain, String subPath); + InputStream createResourceFile( String domain, String subPath ); } diff --git a/src/main/java/dan200/computercraft/core/computer/MainThread.java b/src/main/java/dan200/computercraft/core/computer/MainThread.java index 1072b5c24..0187ff2db 100644 --- a/src/main/java/dan200/computercraft/core/computer/MainThread.java +++ b/src/main/java/dan200/computercraft/core/computer/MainThread.java @@ -6,15 +6,14 @@ package dan200.computercraft.core.computer; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.lua.ILuaTask; + +import javax.annotation.Nonnull; import java.util.HashSet; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicLong; -import javax.annotation.Nonnull; - -import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.lua.ILuaTask; - /** * Runs tasks on the main (server) thread, ticks {@link MainThreadExecutor}s, and limits how much time is used this tick. * @@ -27,7 +26,8 @@ import dan200.computercraft.api.lua.ILuaTask; * Next tick, we put {@link ComputerCraft#maxMainGlobalTime} into our budget (and clamp it to that value to). If we're still over budget, then we should not * execute any work (either as part of {@link MainThread} or externally). */ -public final class MainThread { +public final class MainThread +{ /** * An internal counter for {@link ILuaTask} ids. * @@ -39,17 +39,19 @@ public final class MainThread { /** * The queue of {@link MainThreadExecutor}s with tasks to perform. */ - private static final TreeSet executors = new TreeSet<>((a, b) -> { - if (a == b) { + private static final TreeSet executors = new TreeSet<>( ( a, b ) -> { + if( a == b ) + { return 0; // Should never happen, but let's be consistent here } long at = a.virtualTime, bt = b.virtualTime; - if (at == bt) { - return Integer.compare(a.hashCode(), b.hashCode()); + if( at == bt ) + { + return Integer.compare( a.hashCode(), b.hashCode() ); } return at < bt ? -1 : 1; - }); + } ); /** * The set of executors which went over budget in a previous tick, and are waiting for their time to run down. @@ -82,14 +84,18 @@ public final class MainThread { private MainThread() {} - public static long getUniqueTaskID() { + public static long getUniqueTaskID() + { return lastTaskId.incrementAndGet(); } - static void queue(@Nonnull MainThreadExecutor executor, boolean sleeper) { - synchronized (executors) { - if (executor.onQueue) { - throw new IllegalStateException("Cannot queue already queued executor"); + static void queue( @Nonnull MainThreadExecutor executor, boolean sleeper ) + { + synchronized( executors ) + { + if( executor.onQueue ) + { + throw new IllegalStateException( "Cannot queue already queued executor" ); } executor.onQueue = true; executor.updateTime(); @@ -99,54 +105,63 @@ public final class MainThread { long newRuntime = minimumTime; // Slow down new computers a little bit. - if (executor.virtualTime == 0) { + if( executor.virtualTime == 0 ) + { newRuntime += ComputerCraft.maxMainComputerTime; } - executor.virtualTime = Math.max(newRuntime, executor.virtualTime); + executor.virtualTime = Math.max( newRuntime, executor.virtualTime ); - executors.add(executor); + executors.add( executor ); } } - static void cooling(@Nonnull MainThreadExecutor executor) { - cooling.add(executor); + static void cooling( @Nonnull MainThreadExecutor executor ) + { + cooling.add( executor ); } - static boolean canExecute() { + static boolean canExecute() + { return canExecute; } - static int currentTick() { + static int currentTick() + { return currentTick; } - public static void executePendingTasks() { + public static void executePendingTasks() + { // Move onto the next tick and cool down the global executor. We're allowed to execute if we have _any_ time // allocated for this tick. This means we'll stick much closer to doing MAX_TICK_TIME work every tick. // // Of course, we'll go over the MAX_TICK_TIME most of the time, but eventually that overrun will accumulate // and we'll skip a whole tick - bringing the average back down again. currentTick++; - budget = Math.min(budget + ComputerCraft.maxMainGlobalTime, ComputerCraft.maxMainGlobalTime); + budget = Math.min( budget + ComputerCraft.maxMainGlobalTime, ComputerCraft.maxMainGlobalTime ); canExecute = budget > 0; // Cool down any warm computers. - cooling.removeIf(MainThreadExecutor::tickCooling); + cooling.removeIf( MainThreadExecutor::tickCooling ); - if (!canExecute) { + if( !canExecute ) + { return; } // Run until we meet the deadline. long start = System.nanoTime(); long deadline = start + budget; - while (true) { + while( true ) + { MainThreadExecutor executor; - synchronized (executors) { + synchronized( executors ) + { executor = executors.pollFirst(); } - if (executor == null) { + if( executor == null ) + { break; } @@ -154,43 +169,51 @@ public final class MainThread { executor.execute(); long taskStop = System.nanoTime(); - synchronized (executors) { - if (executor.afterExecute(taskStop - taskStart)) { - executors.add(executor); + synchronized( executors ) + { + if( executor.afterExecute( taskStop - taskStart ) ) + { + executors.add( executor ); } // Compute the new minimum time (including the next task on the queue too). Note that this may also include // time spent in external tasks. long newMinimum = executor.virtualTime; - if (!executors.isEmpty()) { + if( !executors.isEmpty() ) + { MainThreadExecutor next = executors.first(); - if (next.virtualTime < newMinimum) { + if( next.virtualTime < newMinimum ) + { newMinimum = next.virtualTime; } } - minimumTime = Math.max(minimumTime, newMinimum); + minimumTime = Math.max( minimumTime, newMinimum ); } - if (taskStop >= deadline) { + if( taskStop >= deadline ) + { break; } } - consumeTime(System.nanoTime() - start); + consumeTime( System.nanoTime() - start ); } - static void consumeTime(long time) { + static void consumeTime( long time ) + { budget -= time; } - public static void reset() { + public static void reset() + { currentTick = 0; budget = 0; canExecute = true; minimumTime = 0; - lastTaskId.set(0); + lastTaskId.set( 0 ); cooling.clear(); - synchronized (executors) { + synchronized( executors ) + { executors.clear(); } } diff --git a/src/main/java/dan200/computercraft/core/computer/MainThreadExecutor.java b/src/main/java/dan200/computercraft/core/computer/MainThreadExecutor.java index 5f9538dfd..74be06df7 100644 --- a/src/main/java/dan200/computercraft/core/computer/MainThreadExecutor.java +++ b/src/main/java/dan200/computercraft/core/computer/MainThreadExecutor.java @@ -6,17 +6,16 @@ package dan200.computercraft.core.computer; -import java.util.ArrayDeque; -import java.util.Queue; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.peripheral.IWorkMonitor; import dan200.computercraft.core.tracking.Tracking; import dan200.computercraft.shared.turtle.core.TurtleBrain; +import javax.annotation.Nonnull; +import java.util.ArrayDeque; +import java.util.Queue; +import java.util.concurrent.TimeUnit; + /** * Keeps track of tasks that a {@link Computer} should run on the main thread and how long that has been spent executing them. * @@ -46,7 +45,8 @@ import dan200.computercraft.shared.turtle.core.TurtleBrain; * @see Computer#getMainThreadMonitor() * @see Computer#queueMainThread(Runnable) */ -final class MainThreadExecutor implements IWorkMonitor { +final class MainThreadExecutor implements IWorkMonitor +{ /** * The maximum number of {@link MainThread} tasks allowed on the queue. */ @@ -65,7 +65,7 @@ final class MainThreadExecutor implements IWorkMonitor { * * @see #queueLock */ - private final Queue tasks = new ArrayDeque<>(4); + private final Queue tasks = new ArrayDeque<>( 4 ); /** * Determines if this executor is currently present on the queue. @@ -100,7 +100,8 @@ final class MainThreadExecutor implements IWorkMonitor { private State state = State.COOL; private long pendingTime; - MainThreadExecutor(Computer computer) { + MainThreadExecutor( Computer computer ) + { this.computer = computer; } @@ -110,29 +111,37 @@ final class MainThreadExecutor implements IWorkMonitor { * @param runnable The task to run on the main thread. * @return Whether this task was enqueued (namely, was there space). */ - boolean enqueue(Runnable runnable) { - synchronized (this.queueLock) { - if (this.tasks.size() >= MAX_TASKS || !this.tasks.offer(runnable)) { + boolean enqueue( Runnable runnable ) + { + synchronized( this.queueLock ) + { + if( this.tasks.size() >= MAX_TASKS || !this.tasks.offer( runnable ) ) + { return false; } - if (!this.onQueue && this.state == State.COOL) { - MainThread.queue(this, true); + if( !this.onQueue && this.state == State.COOL ) + { + MainThread.queue( this, true ); } return true; } } - void execute() { - if (this.state != State.COOL) { + void execute() + { + if( this.state != State.COOL ) + { return; } Runnable task; - synchronized (this.queueLock) { + synchronized( this.queueLock ) + { task = this.tasks.poll(); } - if (task != null) { + if( task != null ) + { task.run(); } } @@ -143,25 +152,30 @@ final class MainThreadExecutor implements IWorkMonitor { * @param time The time some task took to run. * @return Whether this should be added back to the queue. */ - boolean afterExecute(long time) { - this.consumeTime(time); + boolean afterExecute( long time ) + { + this.consumeTime( time ); - synchronized (this.queueLock) { + synchronized( this.queueLock ) + { this.virtualTime += time; this.updateTime(); - if (this.state != State.COOL || this.tasks.isEmpty()) { + if( this.state != State.COOL || this.tasks.isEmpty() ) + { return this.onQueue = false; } return true; } } - private void consumeTime(long time) { - Tracking.addServerTiming(this.computer, time); + private void consumeTime( long time ) + { + Tracking.addServerTiming( this.computer, time ); // Reset the budget if moving onto a new tick. We know this is safe, as this will only have happened if // #tickCooling() isn't called, and so we didn't overrun the previous tick. - if (this.currentTick != MainThread.currentTick()) { + if( this.currentTick != MainThread.currentTick() ) + { this.currentTick = MainThread.currentTick(); this.budget = ComputerCraft.maxMainComputerTime; } @@ -169,19 +183,22 @@ final class MainThreadExecutor implements IWorkMonitor { this.budget -= time; // If we've gone over our limit, mark us as having to cool down. - if (this.budget < 0 && this.state == State.COOL) { + if( this.budget < 0 && this.state == State.COOL ) + { this.state = State.HOT; - MainThread.cooling(this); + MainThread.cooling( this ); } } - void updateTime() { + void updateTime() + { this.virtualTime += this.pendingTime; this.pendingTime = 0; } @Override - public boolean shouldWork() { + public boolean shouldWork() + { return this.state == State.COOL && MainThread.canExecute(); } @@ -191,19 +208,22 @@ final class MainThreadExecutor implements IWorkMonitor { * @return Whether we can execute external tasks. */ @Override - public boolean canWork() { + public boolean canWork() + { return this.state != State.COOLING && MainThread.canExecute(); } @Override - public void trackWork(long time, @Nonnull TimeUnit unit) { - long nanoTime = unit.toNanos(time); - synchronized (this.queueLock) { + public void trackWork( long time, @Nonnull TimeUnit unit ) + { + long nanoTime = unit.toNanos( time ); + synchronized( this.queueLock ) + { this.pendingTime += nanoTime; } - this.consumeTime(nanoTime); - MainThread.consumeTime(nanoTime); + this.consumeTime( nanoTime ); + MainThread.consumeTime( nanoTime ); } /** @@ -211,24 +231,29 @@ final class MainThreadExecutor implements IWorkMonitor { * * @return Whether this executor has cooled down, and so is safe to run again. */ - boolean tickCooling() { + boolean tickCooling() + { this.state = State.COOLING; this.currentTick = MainThread.currentTick(); - this.budget = Math.min(this.budget + ComputerCraft.maxMainComputerTime, ComputerCraft.maxMainComputerTime); - if (this.budget < ComputerCraft.maxMainComputerTime) { + this.budget = Math.min( this.budget + ComputerCraft.maxMainComputerTime, ComputerCraft.maxMainComputerTime ); + if( this.budget < ComputerCraft.maxMainComputerTime ) + { return false; } this.state = State.COOL; - synchronized (this.queueLock) { - if (!this.tasks.isEmpty() && !this.onQueue) { - MainThread.queue(this, false); + synchronized( this.queueLock ) + { + if( !this.tasks.isEmpty() && !this.onQueue ) + { + MainThread.queue( this, false ); } } return true; } - private enum State { + private enum State + { COOL, HOT, COOLING, } } diff --git a/src/main/java/dan200/computercraft/core/computer/TimeoutState.java b/src/main/java/dan200/computercraft/core/computer/TimeoutState.java index 02d6bf064..550bc59fc 100644 --- a/src/main/java/dan200/computercraft/core/computer/TimeoutState.java +++ b/src/main/java/dan200/computercraft/core/computer/TimeoutState.java @@ -6,11 +6,11 @@ package dan200.computercraft.core.computer; -import java.util.concurrent.TimeUnit; - import dan200.computercraft.core.lua.ILuaMachine; import dan200.computercraft.core.lua.MachineResult; +import java.util.concurrent.TimeUnit; + /** * Used to measure how long a computer has executed for, and thus the relevant timeout states. * @@ -31,7 +31,8 @@ import dan200.computercraft.core.lua.MachineResult; * @see ILuaMachine * @see MachineResult#isPause() */ -public final class TimeoutState { +public final class TimeoutState +{ /** * The error message to display when we trigger an abort. */ @@ -39,11 +40,11 @@ public final class TimeoutState { /** * The total time a task is allowed to run before aborting in nanoseconds. */ - static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos(7000); + static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 7000 ); /** * The time the task is allowed to run after each abort in nanoseconds. */ - static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos(1500); + static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 1500 ); private boolean paused; private boolean softAbort; private volatile boolean hardAbort; @@ -68,25 +69,30 @@ public final class TimeoutState { */ private long currentDeadline; - long nanoCumulative() { + long nanoCumulative() + { return System.nanoTime() - this.cumulativeStart; } - long nanoCurrent() { + long nanoCurrent() + { return System.nanoTime() - this.currentStart; } /** * Recompute the {@link #isSoftAborted()} and {@link #isPaused()} flags. */ - public void refresh() { + public void refresh() + { // Important: The weird arithmetic here is important, as nanoTime may return negative values, and so we // need to handle overflow. long now = System.nanoTime(); - if (!this.paused) { + if( !this.paused ) + { this.paused = this.currentDeadline - now <= 0 && ComputerThread.hasPendingWork(); // now >= currentDeadline } - if (!this.softAbort) { + if( !this.softAbort ) + { this.softAbort = now - this.cumulativeStart - TIMEOUT >= 0; // now - cumulativeStart >= TIMEOUT } } @@ -98,7 +104,8 @@ public final class TimeoutState { * * @return Whether we should pause execution. */ - public boolean isPaused() { + public boolean isPaused() + { return this.paused; } @@ -107,7 +114,8 @@ public final class TimeoutState { * * @return {@code true} if we should throw a timeout error. */ - public boolean isSoftAborted() { + public boolean isSoftAborted() + { return this.softAbort; } @@ -116,21 +124,24 @@ public final class TimeoutState { * * @return {@code true} if the machine should be forcibly shut down. */ - public boolean isHardAborted() { + public boolean isHardAborted() + { return this.hardAbort; } /** * If the machine should be forcibly aborted. */ - void hardAbort() { + void hardAbort() + { this.softAbort = this.hardAbort = true; } /** * Start the current and cumulative timers again. */ - void startTimer() { + void startTimer() + { long now = System.nanoTime(); this.currentStart = now; this.currentDeadline = now + ComputerThread.scaledPeriod(); @@ -143,7 +154,8 @@ public final class TimeoutState { * * @see #nanoCumulative() */ - void pauseTimer() { + void pauseTimer() + { // We set the cumulative time to difference between current time and "nominal start time". this.cumulativeElapsed = System.nanoTime() - this.cumulativeStart; this.paused = false; @@ -152,7 +164,8 @@ public final class TimeoutState { /** * Resets the cumulative time and resets the abort flags. */ - void stopTimer() { + void stopTimer() + { this.cumulativeElapsed = 0; this.paused = this.softAbort = this.hardAbort = false; } diff --git a/src/main/java/dan200/computercraft/core/filesystem/ComboMount.java b/src/main/java/dan200/computercraft/core/filesystem/ComboMount.java index 43f4472e1..65f4c1250 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/ComboMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/ComboMount.java @@ -6,6 +6,10 @@ package dan200.computercraft.core.filesystem; +import dan200.computercraft.api.filesystem.FileOperationException; +import dan200.computercraft.api.filesystem.IMount; + +import javax.annotation.Nonnull; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.nio.file.attribute.BasicFileAttributes; @@ -14,81 +18,98 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.filesystem.FileOperationException; -import dan200.computercraft.api.filesystem.IMount; - -public class ComboMount implements IMount { +public class ComboMount implements IMount +{ private IMount[] m_parts; - public ComboMount(IMount[] parts) { + public ComboMount( IMount[] parts ) + { this.m_parts = parts; } // IMount implementation @Override - public void list(@Nonnull String path, @Nonnull List contents) throws IOException { + public void list( @Nonnull String path, @Nonnull List contents ) throws IOException + { // Combine the lists from all the mounts List foundFiles = null; int foundDirs = 0; - for (int i = this.m_parts.length - 1; i >= 0; --i) { + for( int i = this.m_parts.length - 1; i >= 0; --i ) + { IMount part = this.m_parts[i]; - if (part.exists(path) && part.isDirectory(path)) { - if (foundFiles == null) { + if( part.exists( path ) && part.isDirectory( path ) ) + { + if( foundFiles == null ) + { foundFiles = new ArrayList<>(); } - part.list(path, foundFiles); + part.list( path, foundFiles ); foundDirs++; } } - if (foundDirs == 1) { + if( foundDirs == 1 ) + { // We found one directory, so we know it already doesn't contain duplicates - contents.addAll(foundFiles); - } else if (foundDirs > 1) { + contents.addAll( foundFiles ); + } + else if( foundDirs > 1 ) + { // We found multiple directories, so filter for duplicates Set seen = new HashSet<>(); - for (String file : foundFiles) { - if (seen.add(file)) { - contents.add(file); + for( String file : foundFiles ) + { + if( seen.add( file ) ) + { + contents.add( file ); } } - } else { - throw new FileOperationException(path, "Not a directory"); + } + else + { + throw new FileOperationException( path, "Not a directory" ); } } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - for (int i = this.m_parts.length - 1; i >= 0; --i) { + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + for( int i = this.m_parts.length - 1; i >= 0; --i ) + { IMount part = this.m_parts[i]; - if (part.exists(path) && !part.isDirectory(path)) { - return part.openForRead(path); + if( part.exists( path ) && !part.isDirectory( path ) ) + { + return part.openForRead( path ); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } @Nonnull @Override - public BasicFileAttributes getAttributes(@Nonnull String path) throws IOException { - for (int i = this.m_parts.length - 1; i >= 0; --i) { + public BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException + { + for( int i = this.m_parts.length - 1; i >= 0; --i ) + { IMount part = this.m_parts[i]; - if (part.exists(path) && !part.isDirectory(path)) { - return part.getAttributes(path); + if( part.exists( path ) && !part.isDirectory( path ) ) + { + return part.getAttributes( path ); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } @Override - public boolean exists(@Nonnull String path) throws IOException { - for (int i = this.m_parts.length - 1; i >= 0; --i) { + public boolean exists( @Nonnull String path ) throws IOException + { + for( int i = this.m_parts.length - 1; i >= 0; --i ) + { IMount part = this.m_parts[i]; - if (part.exists(path)) { + if( part.exists( path ) ) + { return true; } } @@ -96,10 +117,13 @@ public class ComboMount implements IMount { } @Override - public boolean isDirectory(@Nonnull String path) throws IOException { - for (int i = this.m_parts.length - 1; i >= 0; --i) { + public boolean isDirectory( @Nonnull String path ) throws IOException + { + for( int i = this.m_parts.length - 1; i >= 0; --i ) + { IMount part = this.m_parts[i]; - if (part.isDirectory(path)) { + if( part.isDirectory( path ) ) + { return true; } } @@ -107,13 +131,16 @@ public class ComboMount implements IMount { } @Override - public long getSize(@Nonnull String path) throws IOException { - for (int i = this.m_parts.length - 1; i >= 0; --i) { + public long getSize( @Nonnull String path ) throws IOException + { + for( int i = this.m_parts.length - 1; i >= 0; --i ) + { IMount part = this.m_parts[i]; - if (part.exists(path)) { - return part.getSize(path); + if( part.exists( path ) ) + { + return part.getSize( path ); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/EmptyMount.java b/src/main/java/dan200/computercraft/core/filesystem/EmptyMount.java index 5597fa1e1..2b3050fe5 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/EmptyMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/EmptyMount.java @@ -6,38 +6,43 @@ package dan200.computercraft.core.filesystem; +import dan200.computercraft.api.filesystem.FileOperationException; +import dan200.computercraft.api.filesystem.IMount; + +import javax.annotation.Nonnull; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.util.List; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.filesystem.FileOperationException; -import dan200.computercraft.api.filesystem.IMount; - -public class EmptyMount implements IMount { +public class EmptyMount implements IMount +{ @Override - public void list(@Nonnull String path, @Nonnull List contents) { + public void list( @Nonnull String path, @Nonnull List contents ) + { } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - throw new FileOperationException(path, "No such file"); + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + throw new FileOperationException( path, "No such file" ); } @Override - public boolean exists(@Nonnull String path) { + public boolean exists( @Nonnull String path ) + { return path.isEmpty(); } @Override - public boolean isDirectory(@Nonnull String path) { + public boolean isDirectory( @Nonnull String path ) + { return path.isEmpty(); } @Override - public long getSize(@Nonnull String path) { + public long getSize( @Nonnull String path ) + { return 0; } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileMount.java b/src/main/java/dan200/computercraft/core/filesystem/FileMount.java index 48049e05d..37627333d 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileMount.java @@ -6,65 +6,63 @@ package dan200.computercraft.core.filesystem; +import com.google.common.collect.Sets; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.filesystem.FileOperationException; +import dan200.computercraft.api.filesystem.IWritableMount; + +import javax.annotation.Nonnull; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.FileChannel; -import java.nio.channels.NonReadableChannelException; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.OpenOption; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardOpenOption; +import java.nio.channels.*; +import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; import java.util.List; import java.util.OptionalLong; import java.util.Set; -import javax.annotation.Nonnull; - -import com.google.common.collect.Sets; -import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.filesystem.FileOperationException; -import dan200.computercraft.api.filesystem.IWritableMount; - -public class FileMount implements IWritableMount { +public class FileMount implements IWritableMount +{ private static final int MINIMUM_FILE_SIZE = 500; - private static final Set READ_OPTIONS = Collections.singleton(StandardOpenOption.READ); - private static final Set WRITE_OPTIONS = Sets.newHashSet(StandardOpenOption.WRITE, - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING); - private static final Set APPEND_OPTIONS = Sets.newHashSet(StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.APPEND); + private static final Set READ_OPTIONS = Collections.singleton( StandardOpenOption.READ ); + private static final Set WRITE_OPTIONS = Sets.newHashSet( StandardOpenOption.WRITE, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING ); + private static final Set APPEND_OPTIONS = Sets.newHashSet( StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.APPEND ); private File m_rootPath; private long m_capacity; private long m_usedSpace; - public FileMount(File rootPath, long capacity) { + + public FileMount( File rootPath, long capacity ) + { this.m_rootPath = rootPath; this.m_capacity = capacity + MINIMUM_FILE_SIZE; - this.m_usedSpace = this.created() ? measureUsedSpace(this.m_rootPath) : MINIMUM_FILE_SIZE; + this.m_usedSpace = this.created() ? measureUsedSpace( this.m_rootPath ) : MINIMUM_FILE_SIZE; } - private boolean created() { + private boolean created() + { return this.m_rootPath.exists(); } - private static long measureUsedSpace(File file) { - if (!file.exists()) { + private static long measureUsedSpace( File file ) + { + if( !file.exists() ) + { return 0; } - try { + try + { Visitor visitor = new Visitor(); - Files.walkFileTree(file.toPath(), visitor); + Files.walkFileTree( file.toPath(), visitor ); return visitor.size; - } catch (IOException e) { - ComputerCraft.log.error("Error computing file size for {}", file, e); + } + catch( IOException e ) + { + ComputerCraft.log.error( "Error computing file size for {}", file, e ); return 0; } } @@ -72,326 +70,406 @@ public class FileMount implements IWritableMount { // IMount implementation @Override - public void list(@Nonnull String path, @Nonnull List contents) throws IOException { - if (!this.created()) { - if (!path.isEmpty()) { - throw new FileOperationException(path, "Not a directory"); + public void list( @Nonnull String path, @Nonnull List contents ) throws IOException + { + if( !this.created() ) + { + if( !path.isEmpty() ) + { + throw new FileOperationException( path, "Not a directory" ); } return; } - File file = this.getRealPath(path); - if (!file.exists() || !file.isDirectory()) { - throw new FileOperationException(path, "Not a directory"); + File file = this.getRealPath( path ); + if( !file.exists() || !file.isDirectory() ) + { + throw new FileOperationException( path, "Not a directory" ); } String[] paths = file.list(); - for (String subPath : paths) { - if (new File(file, subPath).exists()) { - contents.add(subPath); + for( String subPath : paths ) + { + if( new File( file, subPath ).exists() ) + { + contents.add( subPath ); } } } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - if (this.created()) { - File file = this.getRealPath(path); - if (file.exists() && !file.isDirectory()) { - return FileChannel.open(file.toPath(), READ_OPTIONS); + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + if( this.created() ) + { + File file = this.getRealPath( path ); + if( file.exists() && !file.isDirectory() ) + { + return FileChannel.open( file.toPath(), READ_OPTIONS ); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } @Nonnull @Override - public BasicFileAttributes getAttributes(@Nonnull String path) throws IOException { - if (this.created()) { - File file = this.getRealPath(path); - if (file.exists()) { - return Files.readAttributes(file.toPath(), BasicFileAttributes.class); + public BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException + { + if( this.created() ) + { + File file = this.getRealPath( path ); + if( file.exists() ) + { + return Files.readAttributes( file.toPath(), BasicFileAttributes.class ); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } @Override - public boolean exists(@Nonnull String path) { - if (!this.created()) { + public boolean exists( @Nonnull String path ) + { + if( !this.created() ) + { return path.isEmpty(); } - File file = this.getRealPath(path); + File file = this.getRealPath( path ); return file.exists(); } @Override - public boolean isDirectory(@Nonnull String path) { - if (!this.created()) { + public boolean isDirectory( @Nonnull String path ) + { + if( !this.created() ) + { return path.isEmpty(); } - File file = this.getRealPath(path); + File file = this.getRealPath( path ); return file.exists() && file.isDirectory(); } @Override - public long getSize(@Nonnull String path) throws IOException { - if (!this.created()) { - if (path.isEmpty()) { + public long getSize( @Nonnull String path ) throws IOException + { + if( !this.created() ) + { + if( path.isEmpty() ) + { return 0; } - } else { - File file = this.getRealPath(path); - if (file.exists()) { + } + else + { + File file = this.getRealPath( path ); + if( file.exists() ) + { return file.isDirectory() ? 0 : file.length(); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } // IWritableMount implementation - private File getRealPath(String path) { - return new File(this.m_rootPath, path); + private File getRealPath( String path ) + { + return new File( this.m_rootPath, path ); } @Override - public void makeDirectory(@Nonnull String path) throws IOException { + public void makeDirectory( @Nonnull String path ) throws IOException + { this.create(); - File file = this.getRealPath(path); - if (file.exists()) { - if (!file.isDirectory()) { - throw new FileOperationException(path, "File exists"); + File file = this.getRealPath( path ); + if( file.exists() ) + { + if( !file.isDirectory() ) + { + throw new FileOperationException( path, "File exists" ); } return; } int dirsToCreate = 1; File parent = file.getParentFile(); - while (!parent.exists()) { + while( !parent.exists() ) + { ++dirsToCreate; parent = parent.getParentFile(); } - if (this.getRemainingSpace() < dirsToCreate * MINIMUM_FILE_SIZE) { - throw new FileOperationException(path, "Out of space"); + if( this.getRemainingSpace() < dirsToCreate * MINIMUM_FILE_SIZE ) + { + throw new FileOperationException( path, "Out of space" ); } - if (file.mkdirs()) { + if( file.mkdirs() ) + { this.m_usedSpace += dirsToCreate * MINIMUM_FILE_SIZE; - } else { - throw new FileOperationException(path, "Access denied"); + } + else + { + throw new FileOperationException( path, "Access denied" ); } } @Override - public void delete(@Nonnull String path) throws IOException { - if (path.isEmpty()) { - throw new FileOperationException(path, "Access denied"); + public void delete( @Nonnull String path ) throws IOException + { + if( path.isEmpty() ) + { + throw new FileOperationException( path, "Access denied" ); } - if (this.created()) { - File file = this.getRealPath(path); - if (file.exists()) { - this.deleteRecursively(file); + if( this.created() ) + { + File file = this.getRealPath( path ); + if( file.exists() ) + { + this.deleteRecursively( file ); } } } @Nonnull @Override - public WritableByteChannel openForWrite(@Nonnull String path) throws IOException { + public WritableByteChannel openForWrite( @Nonnull String path ) throws IOException + { this.create(); - File file = this.getRealPath(path); - if (file.exists() && file.isDirectory()) { - throw new FileOperationException(path, "Cannot write to directory"); + File file = this.getRealPath( path ); + if( file.exists() && file.isDirectory() ) + { + throw new FileOperationException( path, "Cannot write to directory" ); } - if (file.exists()) { - this.m_usedSpace -= Math.max(file.length(), MINIMUM_FILE_SIZE); - } else if (this.getRemainingSpace() < MINIMUM_FILE_SIZE) { - throw new FileOperationException(path, "Out of space"); + if( file.exists() ) + { + this.m_usedSpace -= Math.max( file.length(), MINIMUM_FILE_SIZE ); + } + else if( this.getRemainingSpace() < MINIMUM_FILE_SIZE ) + { + throw new FileOperationException( path, "Out of space" ); } this.m_usedSpace += MINIMUM_FILE_SIZE; - return new SeekableCountingChannel(Files.newByteChannel(file.toPath(), WRITE_OPTIONS), MINIMUM_FILE_SIZE); + return new SeekableCountingChannel( Files.newByteChannel( file.toPath(), WRITE_OPTIONS ), MINIMUM_FILE_SIZE ); } @Nonnull @Override - public WritableByteChannel openForAppend(@Nonnull String path) throws IOException { - if (!this.created()) { - throw new FileOperationException(path, "No such file"); + public WritableByteChannel openForAppend( @Nonnull String path ) throws IOException + { + if( !this.created() ) + { + throw new FileOperationException( path, "No such file" ); } - File file = this.getRealPath(path); - if (!file.exists()) { - throw new FileOperationException(path, "No such file"); + File file = this.getRealPath( path ); + if( !file.exists() ) + { + throw new FileOperationException( path, "No such file" ); } - if (file.isDirectory()) { - throw new FileOperationException(path, "Cannot write to directory"); + if( file.isDirectory() ) + { + throw new FileOperationException( path, "Cannot write to directory" ); } // Allowing seeking when appending is not recommended, so we use a separate channel. - return new WritableCountingChannel(Files.newByteChannel(file.toPath(), APPEND_OPTIONS), Math.max(MINIMUM_FILE_SIZE - file.length(), 0)); + return new WritableCountingChannel( Files.newByteChannel( file.toPath(), APPEND_OPTIONS ), Math.max( MINIMUM_FILE_SIZE - file.length(), 0 ) ); } @Override - public long getRemainingSpace() { - return Math.max(this.m_capacity - this.m_usedSpace, 0); + public long getRemainingSpace() + { + return Math.max( this.m_capacity - this.m_usedSpace, 0 ); } @Nonnull @Override - public OptionalLong getCapacity() { - return OptionalLong.of(this.m_capacity - MINIMUM_FILE_SIZE); + public OptionalLong getCapacity() + { + return OptionalLong.of( this.m_capacity - MINIMUM_FILE_SIZE ); } - private void create() throws IOException { - if (!this.m_rootPath.exists()) { + private void create() throws IOException + { + if( !this.m_rootPath.exists() ) + { boolean success = this.m_rootPath.mkdirs(); - if (!success) { - throw new IOException("Access denied"); + if( !success ) + { + throw new IOException( "Access denied" ); } } } - private void deleteRecursively(File file) throws IOException { + private void deleteRecursively( File file ) throws IOException + { // Empty directories first - if (file.isDirectory()) { + if( file.isDirectory() ) + { String[] children = file.list(); - for (String aChildren : children) { - this.deleteRecursively(new File(file, aChildren)); + for( String aChildren : children ) + { + this.deleteRecursively( new File( file, aChildren ) ); } } // Then delete long fileSize = file.isDirectory() ? 0 : file.length(); boolean success = file.delete(); - if (success) { - this.m_usedSpace -= Math.max(MINIMUM_FILE_SIZE, fileSize); - } else { - throw new IOException("Access denied"); + if( success ) + { + this.m_usedSpace -= Math.max( MINIMUM_FILE_SIZE, fileSize ); + } + else + { + throw new IOException( "Access denied" ); } } - private static class Visitor extends SimpleFileVisitor { + private static class Visitor extends SimpleFileVisitor + { long size; @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + public FileVisitResult preVisitDirectory( Path dir, BasicFileAttributes attrs ) + { this.size += MINIMUM_FILE_SIZE; return FileVisitResult.CONTINUE; } @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - this.size += Math.max(attrs.size(), MINIMUM_FILE_SIZE); + public FileVisitResult visitFile( Path file, BasicFileAttributes attrs ) + { + this.size += Math.max( attrs.size(), MINIMUM_FILE_SIZE ); return FileVisitResult.CONTINUE; } @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) { - ComputerCraft.log.error("Error computing file size for {}", file, exc); + public FileVisitResult visitFileFailed( Path file, IOException exc ) + { + ComputerCraft.log.error( "Error computing file size for {}", file, exc ); return FileVisitResult.CONTINUE; } } - private class WritableCountingChannel implements WritableByteChannel { + private class WritableCountingChannel implements WritableByteChannel + { private final WritableByteChannel m_inner; long m_ignoredBytesLeft; - WritableCountingChannel(WritableByteChannel inner, long bytesToIgnore) { + WritableCountingChannel( WritableByteChannel inner, long bytesToIgnore ) + { this.m_inner = inner; this.m_ignoredBytesLeft = bytesToIgnore; } @Override - public int write(@Nonnull ByteBuffer b) throws IOException { - this.count(b.remaining()); - return this.m_inner.write(b); + public int write( @Nonnull ByteBuffer b ) throws IOException + { + this.count( b.remaining() ); + return this.m_inner.write( b ); } - void count(long n) throws IOException { + void count( long n ) throws IOException + { this.m_ignoredBytesLeft -= n; - if (this.m_ignoredBytesLeft < 0) { + if( this.m_ignoredBytesLeft < 0 ) + { long newBytes = -this.m_ignoredBytesLeft; this.m_ignoredBytesLeft = 0; long bytesLeft = FileMount.this.m_capacity - FileMount.this.m_usedSpace; - if (newBytes > bytesLeft) { - throw new IOException("Out of space"); + if( newBytes > bytesLeft ) + { + throw new IOException( "Out of space" ); } FileMount.this.m_usedSpace += newBytes; } } @Override - public boolean isOpen() { + public boolean isOpen() + { return this.m_inner.isOpen(); } @Override - public void close() throws IOException { + public void close() throws IOException + { this.m_inner.close(); } } - private class SeekableCountingChannel extends WritableCountingChannel implements SeekableByteChannel { + private class SeekableCountingChannel extends WritableCountingChannel implements SeekableByteChannel + { private final SeekableByteChannel m_inner; - SeekableCountingChannel(SeekableByteChannel inner, long bytesToIgnore) { - super(inner, bytesToIgnore); + SeekableCountingChannel( SeekableByteChannel inner, long bytesToIgnore ) + { + super( inner, bytesToIgnore ); this.m_inner = inner; } @Override - public int read(ByteBuffer dst) throws ClosedChannelException { - if (!this.m_inner.isOpen()) { + public int read( ByteBuffer dst ) throws ClosedChannelException + { + if( !this.m_inner.isOpen() ) + { throw new ClosedChannelException(); } throw new NonReadableChannelException(); } @Override - public long position() throws IOException { + public long position() throws IOException + { return this.m_inner.position(); } @Override - public SeekableByteChannel position(long newPosition) throws IOException { - if (!this.isOpen()) { + public SeekableByteChannel position( long newPosition ) throws IOException + { + if( !this.isOpen() ) + { throw new ClosedChannelException(); } - if (newPosition < 0) { - throw new IllegalArgumentException("Cannot seek before the beginning of the stream"); + if( newPosition < 0 ) + { + throw new IllegalArgumentException( "Cannot seek before the beginning of the stream" ); } long delta = newPosition - this.m_inner.position(); - if (delta < 0) { + if( delta < 0 ) + { this.m_ignoredBytesLeft -= delta; - } else { - this.count(delta); + } + else + { + this.count( delta ); } - return this.m_inner.position(newPosition); + return this.m_inner.position( newPosition ); } @Override - public long size() throws IOException { + public long size() throws IOException + { return this.m_inner.size(); } @Override - public SeekableByteChannel truncate(long size) throws IOException { - throw new IOException("Not yet implemented"); + public SeekableByteChannel truncate( long size ) throws IOException + { + throw new IOException( "Not yet implemented" ); } } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileSystemException.java b/src/main/java/dan200/computercraft/core/filesystem/FileSystemException.java index f63e3e615..8756e0ea8 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileSystemException.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileSystemException.java @@ -6,10 +6,12 @@ package dan200.computercraft.core.filesystem; -public class FileSystemException extends Exception { +public class FileSystemException extends Exception +{ private static final long serialVersionUID = -2500631644868104029L; - FileSystemException(String s) { - super(s); + FileSystemException( String s ) + { + super( s ); } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileSystemWrapperMount.java b/src/main/java/dan200/computercraft/core/filesystem/FileSystemWrapperMount.java index 87e44fd8b..dfa3324af 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileSystemWrapperMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileSystemWrapperMount.java @@ -6,6 +6,9 @@ package dan200.computercraft.core.filesystem; +import dan200.computercraft.api.filesystem.IFileSystem; + +import javax.annotation.Nonnull; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; @@ -13,134 +16,181 @@ import java.util.Collections; import java.util.List; import java.util.function.Function; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.filesystem.IFileSystem; - -public class FileSystemWrapperMount implements IFileSystem { +public class FileSystemWrapperMount implements IFileSystem +{ private final FileSystem m_filesystem; - public FileSystemWrapperMount(FileSystem filesystem) { + public FileSystemWrapperMount( FileSystem filesystem ) + { this.m_filesystem = filesystem; } @Override - public void makeDirectory(@Nonnull String path) throws IOException { - try { - this.m_filesystem.makeDir(path); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public void makeDirectory( @Nonnull String path ) throws IOException + { + try + { + this.m_filesystem.makeDir( path ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public void delete(@Nonnull String path) throws IOException { - try { - this.m_filesystem.delete(path); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public void delete( @Nonnull String path ) throws IOException + { + try + { + this.m_filesystem.delete( path ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Nonnull @Override - public WritableByteChannel openForWrite(@Nonnull String path) throws IOException { - try { - return this.m_filesystem.openForWrite(path, false, Function.identity()) - .get(); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public WritableByteChannel openForWrite( @Nonnull String path ) throws IOException + { + try + { + return this.m_filesystem.openForWrite( path, false, Function.identity() ) + .get(); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Nonnull @Override - public WritableByteChannel openForAppend(@Nonnull String path) throws IOException { - try { - return this.m_filesystem.openForWrite(path, true, Function.identity()) - .get(); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public WritableByteChannel openForAppend( @Nonnull String path ) throws IOException + { + try + { + return this.m_filesystem.openForWrite( path, true, Function.identity() ) + .get(); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public long getRemainingSpace() throws IOException { - try { - return this.m_filesystem.getFreeSpace("/"); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public long getRemainingSpace() throws IOException + { + try + { + return this.m_filesystem.getFreeSpace( "/" ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public void list(@Nonnull String path, @Nonnull List contents) throws IOException { - try { - Collections.addAll(contents, this.m_filesystem.list(path)); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public void list( @Nonnull String path, @Nonnull List contents ) throws IOException + { + try + { + Collections.addAll( contents, this.m_filesystem.list( path ) ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - try { + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + try + { // FIXME: Think of a better way of implementing this, so closing this will close on the computer. - return this.m_filesystem.openForRead(path, Function.identity()) - .get(); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + return this.m_filesystem.openForRead( path, Function.identity() ) + .get(); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public boolean exists(@Nonnull String path) throws IOException { - try { - return this.m_filesystem.exists(path); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public boolean exists( @Nonnull String path ) throws IOException + { + try + { + return this.m_filesystem.exists( path ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public boolean isDirectory(@Nonnull String path) throws IOException { - try { - return this.m_filesystem.isDir(path); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public boolean isDirectory( @Nonnull String path ) throws IOException + { + try + { + return this.m_filesystem.isDir( path ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public long getSize(@Nonnull String path) throws IOException { - try { - return this.m_filesystem.getSize(path); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public long getSize( @Nonnull String path ) throws IOException + { + try + { + return this.m_filesystem.getSize( path ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public String combine(String path, String child) { - return this.m_filesystem.combine(path, child); + public String combine( String path, String child ) + { + return this.m_filesystem.combine( path, child ); } @Override - public void copy(String from, String to) throws IOException { - try { - this.m_filesystem.copy(from, to); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public void copy( String from, String to ) throws IOException + { + try + { + this.m_filesystem.copy( from, to ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } @Override - public void move(String from, String to) throws IOException { - try { - this.m_filesystem.move(from, to); - } catch (FileSystemException e) { - throw new IOException(e.getMessage()); + public void move( String from, String to ) throws IOException + { + try + { + this.m_filesystem.move( from, to ); + } + catch( FileSystemException e ) + { + throw new IOException( e.getMessage() ); } } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/JarMount.java b/src/main/java/dan200/computercraft/core/filesystem/JarMount.java index f272700d3..e22a7bf9b 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/JarMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/JarMount.java @@ -6,6 +6,15 @@ package dan200.computercraft.core.filesystem; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.io.ByteStreams; +import dan200.computercraft.api.filesystem.FileOperationException; +import dan200.computercraft.api.filesystem.IMount; +import dan200.computercraft.core.apis.handles.ArrayByteChannel; +import dan200.computercraft.shared.util.IoUtil; + +import javax.annotation.Nonnull; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -26,17 +35,8 @@ import java.util.concurrent.TimeUnit; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import javax.annotation.Nonnull; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.io.ByteStreams; -import dan200.computercraft.api.filesystem.FileOperationException; -import dan200.computercraft.api.filesystem.IMount; -import dan200.computercraft.core.apis.handles.ArrayByteChannel; -import dan200.computercraft.shared.util.IoUtil; - -public class JarMount implements IMount { +public class JarMount implements IMount +{ /** * Only cache files smaller than 1MiB. */ @@ -52,10 +52,10 @@ public class JarMount implements IMount { * access disk for computer startup. */ private static final Cache CONTENTS_CACHE = CacheBuilder.newBuilder() - .concurrencyLevel(4) - .expireAfterAccess(60, TimeUnit.SECONDS) - .maximumWeight(MAX_CACHE_SIZE) - .weakKeys().weigher((k, v) -> v.length).build(); + .concurrencyLevel( 4 ) + .expireAfterAccess( 60, TimeUnit.SECONDS ) + .maximumWeight( MAX_CACHE_SIZE ) + .weakKeys().weigher( ( k, v ) -> v.length ).build(); /** * We have a {@link ReferenceQueue} of all mounts, a long with their corresponding {@link ZipFile}. If the mount has been destroyed, we clean up after @@ -66,151 +66,184 @@ public class JarMount implements IMount { private final ZipFile zip; private final FileEntry root; - public JarMount(File jarFile, String subPath) throws IOException { + public JarMount( File jarFile, String subPath ) throws IOException + { // Cleanup any old mounts. It's unlikely that there will be any, but it's best to be safe. cleanup(); - if (!jarFile.exists() || jarFile.isDirectory()) { - throw new FileNotFoundException("Cannot find " + jarFile); + if( !jarFile.exists() || jarFile.isDirectory() ) + { + throw new FileNotFoundException( "Cannot find " + jarFile ); } // Open the zip file - try { - this.zip = new ZipFile(jarFile); - } catch (IOException e) { - throw new IOException("Error loading zip file", e); + try + { + this.zip = new ZipFile( jarFile ); + } + catch( IOException e ) + { + throw new IOException( "Error loading zip file", e ); } // Ensure the root entry exists. - if (this.zip.getEntry(subPath) == null) { + if( this.zip.getEntry( subPath ) == null ) + { this.zip.close(); - throw new FileNotFoundException("Zip does not contain path"); + throw new FileNotFoundException( "Zip does not contain path" ); } // We now create a weak reference to this mount. This is automatically added to the appropriate queue. - new MountReference(this); + new MountReference( this ); // Read in all the entries this.root = new FileEntry(); Enumeration zipEntries = this.zip.entries(); - while (zipEntries.hasMoreElements()) { + while( zipEntries.hasMoreElements() ) + { ZipEntry entry = zipEntries.nextElement(); String entryPath = entry.getName(); - if (!entryPath.startsWith(subPath)) { + if( !entryPath.startsWith( subPath ) ) + { continue; } - String localPath = FileSystem.toLocal(entryPath, subPath); - this.create(entry, localPath); + String localPath = FileSystem.toLocal( entryPath, subPath ); + this.create( entry, localPath ); } } - private static void cleanup() { + private static void cleanup() + { Reference next; - while ((next = MOUNT_QUEUE.poll()) != null) { - IoUtil.closeQuietly(((MountReference) next).file); + while( (next = MOUNT_QUEUE.poll()) != null ) + { + IoUtil.closeQuietly( ((MountReference) next).file ); } } - private void create(ZipEntry entry, String localPath) { + private void create( ZipEntry entry, String localPath ) + { FileEntry lastEntry = this.root; int lastIndex = 0; - while (lastIndex < localPath.length()) { - int nextIndex = localPath.indexOf('/', lastIndex); - if (nextIndex < 0) { + while( lastIndex < localPath.length() ) + { + int nextIndex = localPath.indexOf( '/', lastIndex ); + if( nextIndex < 0 ) + { nextIndex = localPath.length(); } - String part = localPath.substring(lastIndex, nextIndex); - if (lastEntry.children == null) { - lastEntry.children = new HashMap<>(0); + String part = localPath.substring( lastIndex, nextIndex ); + if( lastEntry.children == null ) + { + lastEntry.children = new HashMap<>( 0 ); } - FileEntry nextEntry = lastEntry.children.get(part); - if (nextEntry == null || !nextEntry.isDirectory()) { - lastEntry.children.put(part, nextEntry = new FileEntry()); + FileEntry nextEntry = lastEntry.children.get( part ); + if( nextEntry == null || !nextEntry.isDirectory() ) + { + lastEntry.children.put( part, nextEntry = new FileEntry() ); } lastEntry = nextEntry; lastIndex = nextIndex + 1; } - lastEntry.setup(entry); + lastEntry.setup( entry ); } @Override - public void list(@Nonnull String path, @Nonnull List contents) throws IOException { - FileEntry file = this.get(path); - if (file == null || !file.isDirectory()) { - throw new FileOperationException(path, "Not a directory"); + public void list( @Nonnull String path, @Nonnull List contents ) throws IOException + { + FileEntry file = this.get( path ); + if( file == null || !file.isDirectory() ) + { + throw new FileOperationException( path, "Not a directory" ); } - file.list(contents); + file.list( contents ); } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - FileEntry file = this.get(path); - if (file != null && !file.isDirectory()) { - byte[] contents = CONTENTS_CACHE.getIfPresent(file); - if (contents != null) { - return new ArrayByteChannel(contents); + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + FileEntry file = this.get( path ); + if( file != null && !file.isDirectory() ) + { + byte[] contents = CONTENTS_CACHE.getIfPresent( file ); + if( contents != null ) + { + return new ArrayByteChannel( contents ); } - try { - ZipEntry entry = this.zip.getEntry(file.path); - if (entry != null) { - try (InputStream stream = this.zip.getInputStream(entry)) { - if (stream.available() > MAX_CACHED_SIZE) { - return Channels.newChannel(stream); + try + { + ZipEntry entry = this.zip.getEntry( file.path ); + if( entry != null ) + { + try( InputStream stream = this.zip.getInputStream( entry ) ) + { + if( stream.available() > MAX_CACHED_SIZE ) + { + return Channels.newChannel( stream ); } - contents = ByteStreams.toByteArray(stream); - CONTENTS_CACHE.put(file, contents); - return new ArrayByteChannel(contents); + contents = ByteStreams.toByteArray( stream ); + CONTENTS_CACHE.put( file, contents ); + return new ArrayByteChannel( contents ); } } - } catch (IOException e) { + } + catch( IOException e ) + { // Treat errors as non-existence of file } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } @Nonnull @Override - public BasicFileAttributes getAttributes(@Nonnull String path) throws IOException { - FileEntry file = this.get(path); - if (file != null) { - ZipEntry entry = this.zip.getEntry(file.path); - if (entry != null) { - return new ZipEntryAttributes(entry); + public BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException + { + FileEntry file = this.get( path ); + if( file != null ) + { + ZipEntry entry = this.zip.getEntry( file.path ); + if( entry != null ) + { + return new ZipEntryAttributes( entry ); } } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } @Override - public boolean exists(@Nonnull String path) { - return this.get(path) != null; + public boolean exists( @Nonnull String path ) + { + return this.get( path ) != null; } - private FileEntry get(String path) { + private FileEntry get( String path ) + { FileEntry lastEntry = this.root; int lastIndex = 0; - while (lastEntry != null && lastIndex < path.length()) { - int nextIndex = path.indexOf('/', lastIndex); - if (nextIndex < 0) { + while( lastEntry != null && lastIndex < path.length() ) + { + int nextIndex = path.indexOf( '/', lastIndex ); + if( nextIndex < 0 ) + { nextIndex = path.length(); } - lastEntry = lastEntry.children == null ? null : lastEntry.children.get(path.substring(lastIndex, nextIndex)); + lastEntry = lastEntry.children == null ? null : lastEntry.children.get( path.substring( lastIndex, nextIndex ) ); lastIndex = nextIndex + 1; } @@ -218,108 +251,132 @@ public class JarMount implements IMount { } @Override - public boolean isDirectory(@Nonnull String path) { - FileEntry file = this.get(path); + public boolean isDirectory( @Nonnull String path ) + { + FileEntry file = this.get( path ); return file != null && file.isDirectory(); } @Override - public long getSize(@Nonnull String path) throws IOException { - FileEntry file = this.get(path); - if (file != null) { + public long getSize( @Nonnull String path ) throws IOException + { + FileEntry file = this.get( path ); + if( file != null ) + { return file.size; } - throw new FileOperationException(path, "No such file"); + throw new FileOperationException( path, "No such file" ); } - private static class FileEntry { + private static class FileEntry + { String path; long size; Map children; - void setup(ZipEntry entry) { + void setup( ZipEntry entry ) + { this.path = entry.getName(); this.size = entry.getSize(); - if (this.children == null && entry.isDirectory()) { - this.children = new HashMap<>(0); + if( this.children == null && entry.isDirectory() ) + { + this.children = new HashMap<>( 0 ); } } - boolean isDirectory() { + boolean isDirectory() + { return this.children != null; } - void list(List contents) { - if (this.children != null) { - contents.addAll(this.children.keySet()); + void list( List contents ) + { + if( this.children != null ) + { + contents.addAll( this.children.keySet() ); } } } - private static class MountReference extends WeakReference { + private static class MountReference extends WeakReference + { final ZipFile file; - MountReference(JarMount file) { - super(file, MOUNT_QUEUE); + MountReference( JarMount file ) + { + super( file, MOUNT_QUEUE ); this.file = file.zip; } } - private static class ZipEntryAttributes implements BasicFileAttributes { - private static final FileTime EPOCH = FileTime.from(Instant.EPOCH); + private static class ZipEntryAttributes implements BasicFileAttributes + { + private static final FileTime EPOCH = FileTime.from( Instant.EPOCH ); private final ZipEntry entry; - ZipEntryAttributes(ZipEntry entry) { + ZipEntryAttributes( ZipEntry entry ) + { this.entry = entry; - } @Override - public FileTime lastModifiedTime() { - return orEpoch(this.entry.getLastModifiedTime()); } @Override - public FileTime lastAccessTime() { - return orEpoch(this.entry.getLastAccessTime()); + public FileTime lastModifiedTime() + { + return orEpoch( this.entry.getLastModifiedTime() ); } @Override - public FileTime creationTime() { + public FileTime lastAccessTime() + { + return orEpoch( this.entry.getLastAccessTime() ); + } + + @Override + public FileTime creationTime() + { FileTime time = this.entry.getCreationTime(); return time == null ? this.lastModifiedTime() : time; } @Override - public boolean isRegularFile() { + public boolean isRegularFile() + { return !this.entry.isDirectory(); } @Override - public boolean isDirectory() { + public boolean isDirectory() + { return this.entry.isDirectory(); } @Override - public boolean isSymbolicLink() { + public boolean isSymbolicLink() + { return false; } @Override - public boolean isOther() { + public boolean isOther() + { return false; } @Override - public long size() { + public long size() + { return this.entry.getSize(); } @Override - public Object fileKey() { + public Object fileKey() + { return null; } - - private static FileTime orEpoch(FileTime time) { + private static FileTime orEpoch( FileTime time ) + { return time == null ? EPOCH : time; } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java b/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java index ee77f8035..5800a421b 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java +++ b/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java @@ -6,6 +6,12 @@ package dan200.computercraft.core.filesystem; +import dan200.computercraft.api.filesystem.FileOperationException; +import dan200.computercraft.api.filesystem.IMount; +import dan200.computercraft.api.filesystem.IWritableMount; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; @@ -14,250 +20,336 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.List; import java.util.OptionalLong; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import dan200.computercraft.api.filesystem.FileOperationException; -import dan200.computercraft.api.filesystem.IMount; -import dan200.computercraft.api.filesystem.IWritableMount; - -class MountWrapper { +class MountWrapper +{ private final String label; private final String location; private final IMount mount; private final IWritableMount writableMount; - MountWrapper(String label, String location, IMount mount) { + MountWrapper( String label, String location, IMount mount ) + { this.label = label; this.location = location; this.mount = mount; this.writableMount = null; } - MountWrapper(String label, String location, IWritableMount mount) { + MountWrapper( String label, String location, IWritableMount mount ) + { this.label = label; this.location = location; this.mount = mount; this.writableMount = mount; } - public String getLabel() { + public String getLabel() + { return this.label; } - public String getLocation() { + public String getLocation() + { return this.location; } - public long getFreeSpace() { - if (this.writableMount == null) { + public long getFreeSpace() + { + if( this.writableMount == null ) + { return 0; } - try { + try + { return this.writableMount.getRemainingSpace(); - } catch (IOException e) { + } + catch( IOException e ) + { return 0; } } - public OptionalLong getCapacity() { + public OptionalLong getCapacity() + { return this.writableMount == null ? OptionalLong.empty() : this.writableMount.getCapacity(); } - public boolean isReadOnly(String path) { + public boolean isReadOnly( String path ) + { return this.writableMount == null; } - public boolean exists(String path) throws FileSystemException { - path = this.toLocal(path); - try { - return this.mount.exists(path); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + public boolean exists( String path ) throws FileSystemException + { + path = this.toLocal( path ); + try + { + return this.mount.exists( path ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - private String toLocal(String path) { - return FileSystem.toLocal(path, this.location); + private String toLocal( String path ) + { + return FileSystem.toLocal( path, this.location ); } - private FileSystemException localExceptionOf(@Nullable String localPath, @Nonnull IOException e) { - if (!this.location.isEmpty() && e instanceof FileOperationException) { + private FileSystemException localExceptionOf( @Nullable String localPath, @Nonnull IOException e ) + { + if( !this.location.isEmpty() && e instanceof FileOperationException ) + { FileOperationException ex = (FileOperationException) e; - if (ex.getFilename() != null) { - return this.localExceptionOf(ex.getFilename(), ex.getMessage()); + if( ex.getFilename() != null ) + { + return this.localExceptionOf( ex.getFilename(), ex.getMessage() ); } } - if (e instanceof java.nio.file.FileSystemException) { + if( e instanceof java.nio.file.FileSystemException ) + { // This error will contain the absolute path, leaking information about where MC is installed. We drop that, // just taking the reason. We assume that the error refers to the input path. String message = ((java.nio.file.FileSystemException) e).getReason() - .trim(); - return localPath == null ? new FileSystemException(message) : this.localExceptionOf(localPath, message); + .trim(); + return localPath == null ? new FileSystemException( message ) : this.localExceptionOf( localPath, message ); } - return new FileSystemException(e.getMessage()); + return new FileSystemException( e.getMessage() ); } - private FileSystemException localExceptionOf(String path, String message) { - if (!this.location.isEmpty()) { + private FileSystemException localExceptionOf( String path, String message ) + { + if( !this.location.isEmpty() ) + { path = path.isEmpty() ? this.location : this.location + "/" + path; } - return exceptionOf(path, message); + return exceptionOf( path, message ); } - private static FileSystemException exceptionOf(String path, String message) { - return new FileSystemException("/" + path + ": " + message); + private static FileSystemException exceptionOf( String path, String message ) + { + return new FileSystemException( "/" + path + ": " + message ); } - public boolean isDirectory(String path) throws FileSystemException { - path = this.toLocal(path); - try { - return this.mount.exists(path) && this.mount.isDirectory(path); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + public boolean isDirectory( String path ) throws FileSystemException + { + path = this.toLocal( path ); + try + { + return this.mount.exists( path ) && this.mount.isDirectory( path ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public void list(String path, List contents) throws FileSystemException { - path = this.toLocal(path); - try { - if (!this.mount.exists(path) || !this.mount.isDirectory(path)) { - throw this.localExceptionOf(path, "Not a directory"); + public void list( String path, List contents ) throws FileSystemException + { + path = this.toLocal( path ); + try + { + if( !this.mount.exists( path ) || !this.mount.isDirectory( path ) ) + { + throw this.localExceptionOf( path, "Not a directory" ); } - this.mount.list(path, contents); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + this.mount.list( path, contents ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public long getSize(String path) throws FileSystemException { - path = this.toLocal(path); - try { - if (!this.mount.exists(path)) { - throw this.localExceptionOf(path, "No such file"); + public long getSize( String path ) throws FileSystemException + { + path = this.toLocal( path ); + try + { + if( !this.mount.exists( path ) ) + { + throw this.localExceptionOf( path, "No such file" ); } - return this.mount.isDirectory(path) ? 0 : this.mount.getSize(path); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + return this.mount.isDirectory( path ) ? 0 : this.mount.getSize( path ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } @Nonnull - public BasicFileAttributes getAttributes(String path) throws FileSystemException { - path = this.toLocal(path); - try { - if (!this.mount.exists(path)) { - throw this.localExceptionOf(path, "No such file"); + public BasicFileAttributes getAttributes( String path ) throws FileSystemException + { + path = this.toLocal( path ); + try + { + if( !this.mount.exists( path ) ) + { + throw this.localExceptionOf( path, "No such file" ); } - return this.mount.getAttributes(path); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + return this.mount.getAttributes( path ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public ReadableByteChannel openForRead(String path) throws FileSystemException { - path = this.toLocal(path); - try { - if (this.mount.exists(path) && !this.mount.isDirectory(path)) { - return this.mount.openForRead(path); - } else { - throw this.localExceptionOf(path, "No such file"); + public ReadableByteChannel openForRead( String path ) throws FileSystemException + { + path = this.toLocal( path ); + try + { + if( this.mount.exists( path ) && !this.mount.isDirectory( path ) ) + { + return this.mount.openForRead( path ); } - } catch (IOException e) { - throw this.localExceptionOf(path, e); + else + { + throw this.localExceptionOf( path, "No such file" ); + } + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public void makeDirectory(String path) throws FileSystemException { - if (this.writableMount == null) { - throw exceptionOf(path, "Access denied"); + public void makeDirectory( String path ) throws FileSystemException + { + if( this.writableMount == null ) + { + throw exceptionOf( path, "Access denied" ); } - path = this.toLocal(path); - try { - if (this.mount.exists(path)) { - if (!this.mount.isDirectory(path)) { - throw this.localExceptionOf(path, "File exists"); + path = this.toLocal( path ); + try + { + if( this.mount.exists( path ) ) + { + if( !this.mount.isDirectory( path ) ) + { + throw this.localExceptionOf( path, "File exists" ); } - } else { - this.writableMount.makeDirectory(path); } - } catch (IOException e) { - throw this.localExceptionOf(path, e); + else + { + this.writableMount.makeDirectory( path ); + } + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public void delete(String path) throws FileSystemException { - if (this.writableMount == null) { - throw exceptionOf(path, "Access denied"); + public void delete( String path ) throws FileSystemException + { + if( this.writableMount == null ) + { + throw exceptionOf( path, "Access denied" ); } - path = this.toLocal(path); - try { - if (this.mount.exists(path)) { - this.writableMount.delete(path); + path = this.toLocal( path ); + try + { + if( this.mount.exists( path ) ) + { + this.writableMount.delete( path ); } - } catch (AccessDeniedException e) { - throw new FileSystemException("Access denied"); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + } + catch( AccessDeniedException e ) + { + throw new FileSystemException( "Access denied" ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public WritableByteChannel openForWrite(String path) throws FileSystemException { - if (this.writableMount == null) { - throw exceptionOf(path, "Access denied"); + public WritableByteChannel openForWrite( String path ) throws FileSystemException + { + if( this.writableMount == null ) + { + throw exceptionOf( path, "Access denied" ); } - path = this.toLocal(path); - try { - if (this.mount.exists(path) && this.mount.isDirectory(path)) { - throw this.localExceptionOf(path, "Cannot write to directory"); - } else { - if (!path.isEmpty()) { - String dir = FileSystem.getDirectory(path); - if (!dir.isEmpty() && !this.mount.exists(path)) { - this.writableMount.makeDirectory(dir); + path = this.toLocal( path ); + try + { + if( this.mount.exists( path ) && this.mount.isDirectory( path ) ) + { + throw this.localExceptionOf( path, "Cannot write to directory" ); + } + else + { + if( !path.isEmpty() ) + { + String dir = FileSystem.getDirectory( path ); + if( !dir.isEmpty() && !this.mount.exists( path ) ) + { + this.writableMount.makeDirectory( dir ); } } - return this.writableMount.openForWrite(path); + return this.writableMount.openForWrite( path ); } - } catch (AccessDeniedException e) { - throw new FileSystemException("Access denied"); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + } + catch( AccessDeniedException e ) + { + throw new FileSystemException( "Access denied" ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } - public WritableByteChannel openForAppend(String path) throws FileSystemException { - if (this.writableMount == null) { - throw exceptionOf(path, "Access denied"); + public WritableByteChannel openForAppend( String path ) throws FileSystemException + { + if( this.writableMount == null ) + { + throw exceptionOf( path, "Access denied" ); } - path = this.toLocal(path); - try { - if (!this.mount.exists(path)) { - if (!path.isEmpty()) { - String dir = FileSystem.getDirectory(path); - if (!dir.isEmpty() && !this.mount.exists(path)) { - this.writableMount.makeDirectory(dir); + path = this.toLocal( path ); + try + { + if( !this.mount.exists( path ) ) + { + if( !path.isEmpty() ) + { + String dir = FileSystem.getDirectory( path ); + if( !dir.isEmpty() && !this.mount.exists( path ) ) + { + this.writableMount.makeDirectory( dir ); } } - return this.writableMount.openForWrite(path); - } else if (this.mount.isDirectory(path)) { - throw this.localExceptionOf(path, "Cannot write to directory"); - } else { - return this.writableMount.openForAppend(path); + return this.writableMount.openForWrite( path ); } - } catch (AccessDeniedException e) { - throw new FileSystemException("Access denied"); - } catch (IOException e) { - throw this.localExceptionOf(path, e); + else if( this.mount.isDirectory( path ) ) + { + throw this.localExceptionOf( path, "Cannot write to directory" ); + } + else + { + return this.writableMount.openForAppend( path ); + } + } + catch( AccessDeniedException e ) + { + throw new FileSystemException( "Access denied" ); + } + catch( IOException e ) + { + throw this.localExceptionOf( path, e ); } } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/ResourceMount.java b/src/main/java/dan200/computercraft/core/filesystem/ResourceMount.java index 1ae391738..d60dd8ff2 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/ResourceMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/ResourceMount.java @@ -6,24 +6,6 @@ package dan200.computercraft.core.filesystem; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.MapMaker; @@ -40,7 +22,20 @@ import net.minecraft.util.Identifier; import net.minecraft.util.InvalidIdentifierException; import net.minecraft.util.profiler.Profiler; -public final class ResourceMount implements IMount { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; + +public final class ResourceMount implements IMount +{ /** * Only cache files smaller than 1MiB. */ @@ -58,37 +53,41 @@ public final class ResourceMount implements IMount { * access disk for computer startup. */ private static final Cache CONTENTS_CACHE = CacheBuilder.newBuilder() - .concurrencyLevel(4) - .expireAfterAccess(60, TimeUnit.SECONDS) - .maximumWeight(MAX_CACHE_SIZE) - .weakKeys().weigher((k, v) -> v.length).build(); + .concurrencyLevel( 4 ) + .expireAfterAccess( 60, TimeUnit.SECONDS ) + .maximumWeight( MAX_CACHE_SIZE ) + .weakKeys().weigher( ( k, v ) -> v.length ).build(); private static final MapMaker CACHE_TEMPLATE = new MapMaker().weakValues() - .concurrencyLevel(1); + .concurrencyLevel( 1 ); /** * Maintain a cache of currently loaded resource mounts. This cache is invalidated when currentManager changes. */ - private static final Map> MOUNT_CACHE = new WeakHashMap<>(2); + private static final Map> MOUNT_CACHE = new WeakHashMap<>( 2 ); private final String namespace; private final String subPath; private final ReloadableResourceManager manager; - @Nullable private FileEntry root; + @Nullable + private FileEntry root; - private ResourceMount(String namespace, String subPath, ReloadableResourceManager manager) { + private ResourceMount( String namespace, String subPath, ReloadableResourceManager manager ) + { this.namespace = namespace; this.subPath = subPath; this.manager = manager; - Listener.INSTANCE.add(manager, this); - if (this.root == null) { + Listener.INSTANCE.add( manager, this ); + if( this.root == null ) + { this.load(); } } - private void load() { + private void load() + { boolean hasAny = false; String existingNamespace = null; @@ -99,8 +98,8 @@ public final class ResourceMount implements IMount { if( !file.getNamespace().equals( namespace ) ) continue; - String localPath = FileSystem.toLocal(file.getPath(), this.subPath); - this.create(newRoot, localPath); + String localPath = FileSystem.toLocal( file.getPath(), this.subPath ); + this.create( newRoot, localPath ); hasAny = true; } @@ -111,34 +110,42 @@ public final class ResourceMount implements IMount { ComputerCraft.log.warn( "Cannot find any files under /data/{}/{} for resource mount.", namespace, subPath ); if( existingNamespace != null ) { - ComputerCraft.log.warn("There are files under /data/{}/{} though. Did you get the wrong namespace?", existingNamespace, subPath); + ComputerCraft.log.warn( "There are files under /data/{}/{} though. Did you get the wrong namespace?", existingNamespace, subPath ); } } } - private void create(FileEntry lastEntry, String path) { + private void create( FileEntry lastEntry, String path ) + { int lastIndex = 0; - while (lastIndex < path.length()) { - int nextIndex = path.indexOf('/', lastIndex); - if (nextIndex < 0) { + while( lastIndex < path.length() ) + { + int nextIndex = path.indexOf( '/', lastIndex ); + if( nextIndex < 0 ) + { nextIndex = path.length(); } - String part = path.substring(lastIndex, nextIndex); - if (lastEntry.children == null) { + String part = path.substring( lastIndex, nextIndex ); + if( lastEntry.children == null ) + { lastEntry.children = new HashMap<>(); } - FileEntry nextEntry = lastEntry.children.get(part); - if (nextEntry == null) { + FileEntry nextEntry = lastEntry.children.get( part ); + if( nextEntry == null ) + { Identifier childPath; - try { - childPath = new Identifier(this.namespace, this.subPath + "/" + path); - } catch (InvalidIdentifierException e) { - ComputerCraft.log.warn("Cannot create resource location for {} ({})", part, e.getMessage()); + try + { + childPath = new Identifier( this.namespace, this.subPath + "/" + path ); + } + catch( InvalidIdentifierException e ) + { + ComputerCraft.log.warn( "Cannot create resource location for {} ({})", part, e.getMessage() ); return; } - lastEntry.children.put(part, nextEntry = new FileEntry(childPath)); + lastEntry.children.put( part, nextEntry = new FileEntry( childPath ) ); } lastEntry = nextEntry; @@ -146,44 +153,54 @@ public final class ResourceMount implements IMount { } } - public static ResourceMount get(String namespace, String subPath, ReloadableResourceManager manager) { + public static ResourceMount get( String namespace, String subPath, ReloadableResourceManager manager ) + { Map cache; - synchronized (MOUNT_CACHE) { - cache = MOUNT_CACHE.get(manager); - if (cache == null) { - MOUNT_CACHE.put(manager, cache = CACHE_TEMPLATE.makeMap()); + synchronized( MOUNT_CACHE ) + { + cache = MOUNT_CACHE.get( manager ); + if( cache == null ) + { + MOUNT_CACHE.put( manager, cache = CACHE_TEMPLATE.makeMap() ); } } - Identifier path = new Identifier(namespace, subPath); - synchronized (cache) { - ResourceMount mount = cache.get(path); - if (mount == null) { - cache.put(path, mount = new ResourceMount(namespace, subPath, manager)); + Identifier path = new Identifier( namespace, subPath ); + synchronized( cache ) + { + ResourceMount mount = cache.get( path ); + if( mount == null ) + { + cache.put( path, mount = new ResourceMount( namespace, subPath, manager ) ); } return mount; } } @Override - public void list(@Nonnull String path, @Nonnull List contents) throws IOException { - FileEntry file = this.get(path); - if (file == null || !file.isDirectory()) { - throw new IOException("/" + path + ": Not a directory"); + public void list( @Nonnull String path, @Nonnull List contents ) throws IOException + { + FileEntry file = this.get( path ); + if( file == null || !file.isDirectory() ) + { + throw new IOException( "/" + path + ": Not a directory" ); } - file.list(contents); + file.list( contents ); } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - FileEntry file = this.get(path); - if (file != null && !file.isDirectory()) { - byte[] contents = CONTENTS_CACHE.getIfPresent(file); - if (contents != null) { - return new ArrayByteChannel(contents); + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + FileEntry file = this.get( path ); + if( file != null && !file.isDirectory() ) + { + byte[] contents = CONTENTS_CACHE.getIfPresent( file ); + if( contents != null ) + { + return new ArrayByteChannel( contents ); } try @@ -199,31 +216,37 @@ public final class ResourceMount implements IMount { { IoUtil.closeQuietly( stream ); } - CONTENTS_CACHE.put(file, contents); - return new ArrayByteChannel(contents); - } catch (FileNotFoundException ignored) { + CONTENTS_CACHE.put( file, contents ); + return new ArrayByteChannel( contents ); + } + catch( FileNotFoundException ignored ) + { } } - throw new IOException("/" + path + ": No such file"); + throw new IOException( "/" + path + ": No such file" ); } @Override - public boolean exists(@Nonnull String path) { - return this.get(path) != null; + public boolean exists( @Nonnull String path ) + { + return this.get( path ) != null; } - private FileEntry get(String path) { + private FileEntry get( String path ) + { FileEntry lastEntry = this.root; int lastIndex = 0; - while (lastEntry != null && lastIndex < path.length()) { - int nextIndex = path.indexOf('/', lastIndex); - if (nextIndex < 0) { + while( lastEntry != null && lastIndex < path.length() ) + { + int nextIndex = path.indexOf( '/', lastIndex ); + if( nextIndex < 0 ) + { nextIndex = path.length(); } - lastEntry = lastEntry.children == null ? null : lastEntry.children.get(path.substring(lastIndex, nextIndex)); + lastEntry = lastEntry.children == null ? null : lastEntry.children.get( path.substring( lastIndex, nextIndex ) ); lastIndex = nextIndex + 1; } @@ -231,61 +254,76 @@ public final class ResourceMount implements IMount { } @Override - public boolean isDirectory(@Nonnull String path) { - FileEntry file = this.get(path); + public boolean isDirectory( @Nonnull String path ) + { + FileEntry file = this.get( path ); return file != null && file.isDirectory(); } @Override - public long getSize(@Nonnull String path) throws IOException { - FileEntry file = this.get(path); - if (file != null) { - if (file.size != -1) { + public long getSize( @Nonnull String path ) throws IOException + { + FileEntry file = this.get( path ); + if( file != null ) + { + if( file.size != -1 ) + { return file.size; } - if (file.isDirectory()) { + if( file.isDirectory() ) + { return file.size = 0; } - byte[] contents = CONTENTS_CACHE.getIfPresent(file); - if (contents != null) { + byte[] contents = CONTENTS_CACHE.getIfPresent( file ); + if( contents != null ) + { return file.size = contents.length; } - try { - Resource resource = this.manager.getResource(file.identifier); + try + { + Resource resource = this.manager.getResource( file.identifier ); InputStream s = resource.getInputStream(); int total = 0, read = 0; - do { + do + { total += read; - read = s.read(TEMP_BUFFER); - } while (read > 0); + read = s.read( TEMP_BUFFER ); + } while( read > 0 ); return file.size = total; - } catch (IOException e) { + } + catch( IOException e ) + { return file.size = 0; } } - throw new IOException("/" + path + ": No such file"); + throw new IOException( "/" + path + ": No such file" ); } - private static class FileEntry { + private static class FileEntry + { final Identifier identifier; Map children; long size = -1; - FileEntry(Identifier identifier) { + FileEntry( Identifier identifier ) + { this.identifier = identifier; } - boolean isDirectory() { + boolean isDirectory() + { return this.children != null; } - void list(List contents) { - if (this.children != null) { - contents.addAll(this.children.keySet()); + void list( List contents ) + { + if( this.children != null ) + { + contents.addAll( this.children.keySet() ); } } } @@ -294,32 +332,40 @@ public final class ResourceMount implements IMount { * While people should really be keeping a permanent reference to this, some people construct it every method call, so let's make this as small as * possible. */ - static class Listener implements ResourceReloadListener { + static class Listener implements ResourceReloadListener + { private static final Listener INSTANCE = new Listener(); - private final Set mounts = Collections.newSetFromMap(new WeakHashMap<>()); - private final Set managers = Collections.newSetFromMap(new WeakHashMap<>()); + private final Set mounts = Collections.newSetFromMap( new WeakHashMap<>() ); + private final Set managers = Collections.newSetFromMap( new WeakHashMap<>() ); @Override - public CompletableFuture reload(Synchronizer synchronizer, ResourceManager resourceManager, Profiler profiler, Profiler profiler1, - Executor executor, Executor executor1) { - return CompletableFuture.runAsync(() -> { - profiler.push("Mount reloading"); - try { - for (ResourceMount mount : this.mounts) { + public CompletableFuture reload( Synchronizer synchronizer, ResourceManager resourceManager, Profiler profiler, Profiler profiler1, + Executor executor, Executor executor1 ) + { + return CompletableFuture.runAsync( () -> { + profiler.push( "Mount reloading" ); + try + { + for( ResourceMount mount : this.mounts ) + { mount.load(); } - } finally { + } + finally + { profiler.pop(); } - }, executor); + }, executor ); } - synchronized void add(ReloadableResourceManager manager, ResourceMount mount) { - if (this.managers.add(manager)) { - manager.registerListener(this); + synchronized void add( ReloadableResourceManager manager, ResourceMount mount ) + { + if( this.managers.add( manager ) ) + { + manager.registerListener( this ); } - this.mounts.add(mount); + this.mounts.add( mount ); } } } diff --git a/src/main/java/dan200/computercraft/core/filesystem/SubMount.java b/src/main/java/dan200/computercraft/core/filesystem/SubMount.java index 4bba07366..1eb05f841 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/SubMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/SubMount.java @@ -6,57 +6,65 @@ package dan200.computercraft.core.filesystem; +import dan200.computercraft.api.filesystem.IMount; + +import javax.annotation.Nonnull; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.nio.file.attribute.BasicFileAttributes; import java.util.List; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.filesystem.IMount; - -public class SubMount implements IMount { +public class SubMount implements IMount +{ private IMount parent; private String subPath; - public SubMount(IMount parent, String subPath) { + public SubMount( IMount parent, String subPath ) + { this.parent = parent; this.subPath = subPath; } @Override - public void list(@Nonnull String path, @Nonnull List contents) throws IOException { - this.parent.list(this.getFullPath(path), contents); + public void list( @Nonnull String path, @Nonnull List contents ) throws IOException + { + this.parent.list( this.getFullPath( path ), contents ); } @Nonnull @Override - public ReadableByteChannel openForRead(@Nonnull String path) throws IOException { - return this.parent.openForRead(this.getFullPath(path)); + public ReadableByteChannel openForRead( @Nonnull String path ) throws IOException + { + return this.parent.openForRead( this.getFullPath( path ) ); } @Nonnull @Override - public BasicFileAttributes getAttributes(@Nonnull String path) throws IOException { - return this.parent.getAttributes(this.getFullPath(path)); + public BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException + { + return this.parent.getAttributes( this.getFullPath( path ) ); } @Override - public boolean exists(@Nonnull String path) throws IOException { - return this.parent.exists(this.getFullPath(path)); + public boolean exists( @Nonnull String path ) throws IOException + { + return this.parent.exists( this.getFullPath( path ) ); } @Override - public boolean isDirectory(@Nonnull String path) throws IOException { - return this.parent.isDirectory(this.getFullPath(path)); + public boolean isDirectory( @Nonnull String path ) throws IOException + { + return this.parent.isDirectory( this.getFullPath( path ) ); } @Override - public long getSize(@Nonnull String path) throws IOException { - return this.parent.getSize(this.getFullPath(path)); + public long getSize( @Nonnull String path ) throws IOException + { + return this.parent.getSize( this.getFullPath( path ) ); } - private String getFullPath(String path) { + private String getFullPath( String path ) + { return path.isEmpty() ? this.subPath : this.subPath + "/" + path; } } diff --git a/src/main/java/dan200/computercraft/core/lua/BasicFunction.java b/src/main/java/dan200/computercraft/core/lua/BasicFunction.java index 6b2dd4d4b..edb8f695d 100644 --- a/src/main/java/dan200/computercraft/core/lua/BasicFunction.java +++ b/src/main/java/dan200/computercraft/core/lua/BasicFunction.java @@ -21,14 +21,16 @@ import org.squiddev.cobalt.function.VarArgFunction; * * As we never yield, we do not need to push a function to the stack, which removes a small amount of overhead. */ -class BasicFunction extends VarArgFunction { +class BasicFunction extends VarArgFunction +{ private final CobaltLuaMachine machine; private final LuaMethod method; private final Object instance; private final ILuaContext context; private final String name; - BasicFunction(CobaltLuaMachine machine, LuaMethod method, Object instance, ILuaContext context, String name) { + BasicFunction( CobaltLuaMachine machine, LuaMethod method, Object instance, ILuaContext context, String name ) + { this.machine = machine; this.method = method; this.instance = instance; @@ -37,27 +39,36 @@ class BasicFunction extends VarArgFunction { } @Override - public Varargs invoke(LuaState luaState, Varargs args) throws LuaError { - IArguments arguments = CobaltLuaMachine.toArguments(args); + public Varargs invoke( LuaState luaState, Varargs args ) throws LuaError + { + IArguments arguments = CobaltLuaMachine.toArguments( args ); MethodResult results; - try { - results = this.method.apply(this.instance, this.context, arguments); - } catch (LuaException e) { - throw wrap(e); - } catch (Throwable t) { - if (ComputerCraft.logComputerErrors) { - ComputerCraft.log.error("Error calling " + this.name + " on " + this.instance, t); + try + { + results = this.method.apply( this.instance, this.context, arguments ); + } + catch( LuaException e ) + { + throw wrap( e ); + } + catch( Throwable t ) + { + if( ComputerCraft.logComputerErrors ) + { + ComputerCraft.log.error( "Error calling " + this.name + " on " + this.instance, t ); } - throw new LuaError("Java Exception Thrown: " + t, 0); + throw new LuaError( "Java Exception Thrown: " + t, 0 ); } - if (results.getCallback() != null) { - throw new IllegalStateException("Cannot have a yielding non-yielding function"); + if( results.getCallback() != null ) + { + throw new IllegalStateException( "Cannot have a yielding non-yielding function" ); } - return this.machine.toValues(results.getResult()); + return this.machine.toValues( results.getResult() ); } - public static LuaError wrap(LuaException exception) { - return exception.hasLevel() ? new LuaError(exception.getMessage()) : new LuaError(exception.getMessage(), exception.getLevel()); + public static LuaError wrap( LuaException exception ) + { + return exception.hasLevel() ? new LuaError( exception.getMessage() ) : new LuaError( exception.getMessage(), exception.getLevel() ); } } diff --git a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java index 486a59244..93d6b3737 100644 --- a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java +++ b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java @@ -6,34 +6,8 @@ package dan200.computercraft.core.lua; -import static org.squiddev.cobalt.ValueFactory.valueOf; -import static org.squiddev.cobalt.ValueFactory.varargsOf; -import static org.squiddev.cobalt.debug.DebugFrame.FLAG_HOOKED; -import static org.squiddev.cobalt.debug.DebugFrame.FLAG_HOOKYIELD; - -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.IDynamicLuaObject; -import dan200.computercraft.api.lua.ILuaAPI; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.ILuaFunction; -import dan200.computercraft.api.lua.ILuaTask; -import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.*; import dan200.computercraft.core.asm.LuaMethod; import dan200.computercraft.core.asm.ObjectSource; import dan200.computercraft.core.computer.Computer; @@ -42,39 +16,40 @@ import dan200.computercraft.core.computer.TimeoutState; import dan200.computercraft.core.tracking.Tracking; import dan200.computercraft.core.tracking.TrackingField; import dan200.computercraft.shared.util.ThreadUtils; -import org.squiddev.cobalt.Constants; -import org.squiddev.cobalt.LuaError; -import org.squiddev.cobalt.LuaState; -import org.squiddev.cobalt.LuaTable; -import org.squiddev.cobalt.LuaThread; -import org.squiddev.cobalt.LuaValue; -import org.squiddev.cobalt.UnwindThrowable; -import org.squiddev.cobalt.Varargs; +import org.squiddev.cobalt.*; import org.squiddev.cobalt.compiler.CompileException; import org.squiddev.cobalt.compiler.LoadState; import org.squiddev.cobalt.debug.DebugFrame; import org.squiddev.cobalt.debug.DebugHandler; import org.squiddev.cobalt.debug.DebugState; import org.squiddev.cobalt.function.LuaFunction; -import org.squiddev.cobalt.lib.BaseLib; -import org.squiddev.cobalt.lib.Bit32Lib; -import org.squiddev.cobalt.lib.CoroutineLib; -import org.squiddev.cobalt.lib.DebugLib; -import org.squiddev.cobalt.lib.MathLib; -import org.squiddev.cobalt.lib.StringLib; -import org.squiddev.cobalt.lib.TableLib; -import org.squiddev.cobalt.lib.Utf8Lib; +import org.squiddev.cobalt.lib.*; import org.squiddev.cobalt.lib.platform.VoidResourceManipulator; -public class CobaltLuaMachine implements ILuaMachine { - private static final ThreadPoolExecutor COROUTINES = new ThreadPoolExecutor(0, - Integer.MAX_VALUE, - 5L, - TimeUnit.MINUTES, - new SynchronousQueue<>(), - ThreadUtils.factory("Coroutine")); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; - private static final LuaMethod FUNCTION_METHOD = (target, context, args) -> ((ILuaFunction) target).call(args); +import static org.squiddev.cobalt.ValueFactory.valueOf; +import static org.squiddev.cobalt.ValueFactory.varargsOf; +import static org.squiddev.cobalt.debug.DebugFrame.FLAG_HOOKED; +import static org.squiddev.cobalt.debug.DebugFrame.FLAG_HOOKYIELD; + +public class CobaltLuaMachine implements ILuaMachine +{ + private static final ThreadPoolExecutor COROUTINES = new ThreadPoolExecutor( 0, + Integer.MAX_VALUE, + 5L, + TimeUnit.MINUTES, + new SynchronousQueue<>(), + ThreadUtils.factory( "Coroutine" ) ); + + private static final LuaMethod FUNCTION_METHOD = ( target, context, args ) -> ((ILuaFunction) target).call( args ); private final Computer m_computer; private final TimeoutState timeout; @@ -87,225 +62,275 @@ public class CobaltLuaMachine implements ILuaMachine { private LuaThread m_mainRoutine = null; private String m_eventFilter = null; - public CobaltLuaMachine(Computer computer, TimeoutState timeout) { + public CobaltLuaMachine( Computer computer, TimeoutState timeout ) + { this.m_computer = computer; this.timeout = timeout; this.debug = new TimeoutDebugHandler(); // Create an environment to run in LuaState state = this.m_state = LuaState.builder() - .resourceManipulator(new VoidResourceManipulator()) - .debug(this.debug) - .coroutineExecutor(command -> { - Tracking.addValue(this.m_computer, TrackingField.COROUTINES_CREATED, 1); - COROUTINES.execute(() -> { - try { - command.run(); - } finally { - Tracking.addValue(this.m_computer, TrackingField.COROUTINES_DISPOSED, 1); - } - }); - }) - .build(); + .resourceManipulator( new VoidResourceManipulator() ) + .debug( this.debug ) + .coroutineExecutor( command -> { + Tracking.addValue( this.m_computer, TrackingField.COROUTINES_CREATED, 1 ); + COROUTINES.execute( () -> { + try + { + command.run(); + } + finally + { + Tracking.addValue( this.m_computer, TrackingField.COROUTINES_DISPOSED, 1 ); + } + } ); + } ) + .build(); this.m_globals = new LuaTable(); - state.setupThread(this.m_globals); + state.setupThread( this.m_globals ); // Add basic libraries - this.m_globals.load(state, new BaseLib()); - this.m_globals.load(state, new TableLib()); - this.m_globals.load(state, new StringLib()); - this.m_globals.load(state, new MathLib()); - this.m_globals.load(state, new CoroutineLib()); - this.m_globals.load(state, new Bit32Lib()); - this.m_globals.load(state, new Utf8Lib()); - if (ComputerCraft.debugEnable) { - this.m_globals.load(state, new DebugLib()); + this.m_globals.load( state, new BaseLib() ); + this.m_globals.load( state, new TableLib() ); + this.m_globals.load( state, new StringLib() ); + this.m_globals.load( state, new MathLib() ); + this.m_globals.load( state, new CoroutineLib() ); + this.m_globals.load( state, new Bit32Lib() ); + this.m_globals.load( state, new Utf8Lib() ); + if( ComputerCraft.debugEnable ) + { + this.m_globals.load( state, new DebugLib() ); } // Remove globals we don't want to expose - this.m_globals.rawset("collectgarbage", Constants.NIL); - this.m_globals.rawset("dofile", Constants.NIL); - this.m_globals.rawset("loadfile", Constants.NIL); - this.m_globals.rawset("print", Constants.NIL); + this.m_globals.rawset( "collectgarbage", Constants.NIL ); + this.m_globals.rawset( "dofile", Constants.NIL ); + this.m_globals.rawset( "loadfile", Constants.NIL ); + this.m_globals.rawset( "print", Constants.NIL ); // Add version globals - this.m_globals.rawset("_VERSION", valueOf("Lua 5.1")); - this.m_globals.rawset("_HOST", - valueOf(computer.getAPIEnvironment() - .getComputerEnvironment() - .getHostString())); - this.m_globals.rawset("_CC_DEFAULT_SETTINGS", valueOf(ComputerCraft.defaultComputerSettings)); - if (ComputerCraft.disableLua51Features) { - this.m_globals.rawset("_CC_DISABLE_LUA51_FEATURES", Constants.TRUE); + this.m_globals.rawset( "_VERSION", valueOf( "Lua 5.1" ) ); + this.m_globals.rawset( "_HOST", + valueOf( computer.getAPIEnvironment() + .getComputerEnvironment() + .getHostString() ) ); + this.m_globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.defaultComputerSettings ) ); + if( ComputerCraft.disableLua51Features ) + { + this.m_globals.rawset( "_CC_DISABLE_LUA51_FEATURES", Constants.TRUE ); } } - static Object toObject(LuaValue value, Map objects) { - switch (value.type()) { - case Constants.TNIL: - case Constants.TNONE: - return null; - case Constants.TINT: - case Constants.TNUMBER: - return value.toDouble(); - case Constants.TBOOLEAN: - return value.toBoolean(); - case Constants.TSTRING: - return value.toString(); - case Constants.TTABLE: { - // Table: - // Start remembering stuff - if (objects == null) { - objects = new IdentityHashMap<>(1); - } else { - Object existing = objects.get(value); - if (existing != null) { - return existing; + static Object toObject( LuaValue value, Map objects ) + { + switch( value.type() ) + { + case Constants.TNIL: + case Constants.TNONE: + return null; + case Constants.TINT: + case Constants.TNUMBER: + return value.toDouble(); + case Constants.TBOOLEAN: + return value.toBoolean(); + case Constants.TSTRING: + return value.toString(); + case Constants.TTABLE: + { + // Table: + // Start remembering stuff + if( objects == null ) + { + objects = new IdentityHashMap<>( 1 ); } + else + { + Object existing = objects.get( value ); + if( existing != null ) + { + return existing; + } + } + Map table = new HashMap<>(); + objects.put( value, table ); + + LuaTable luaTable = (LuaTable) value; + + // Convert all keys + LuaValue k = Constants.NIL; + while( true ) + { + Varargs keyValue; + try + { + keyValue = luaTable.next( k ); + } + catch( LuaError luaError ) + { + break; + } + k = keyValue.first(); + if( k.isNil() ) + { + break; + } + + LuaValue v = keyValue.arg( 2 ); + Object keyObject = toObject( k, objects ); + Object valueObject = toObject( v, objects ); + if( keyObject != null && valueObject != null ) + { + table.put( keyObject, valueObject ); + } + } + return table; } - Map table = new HashMap<>(); - objects.put(value, table); - - LuaTable luaTable = (LuaTable) value; - - // Convert all keys - LuaValue k = Constants.NIL; - while (true) { - Varargs keyValue; - try { - keyValue = luaTable.next(k); - } catch (LuaError luaError) { - break; - } - k = keyValue.first(); - if (k.isNil()) { - break; - } - - LuaValue v = keyValue.arg(2); - Object keyObject = toObject(k, objects); - Object valueObject = toObject(v, objects); - if (keyObject != null && valueObject != null) { - table.put(keyObject, valueObject); - } - } - return table; - } - default: - return null; + default: + return null; } } - static Object[] toObjects(Varargs values) { + static Object[] toObjects( Varargs values ) + { int count = values.count(); Object[] objects = new Object[count]; - for (int i = 0; i < count; i++) { - objects[i] = toObject(values.arg(i + 1), null); + for( int i = 0; i < count; i++ ) + { + objects[i] = toObject( values.arg( i + 1 ), null ); } return objects; } - static IArguments toArguments(Varargs values) { - return values == Constants.NONE ? VarargArguments.EMPTY : new VarargArguments(values); + static IArguments toArguments( Varargs values ) + { + return values == Constants.NONE ? VarargArguments.EMPTY : new VarargArguments( values ); } @Override - public void addAPI(@Nonnull ILuaAPI api) { + public void addAPI( @Nonnull ILuaAPI api ) + { // Add the methods of an API to the global table - LuaTable table = this.wrapLuaObject(api); - if (table == null) { - ComputerCraft.log.warn("API {} does not provide any methods", api); + LuaTable table = this.wrapLuaObject( api ); + if( table == null ) + { + ComputerCraft.log.warn( "API {} does not provide any methods", api ); table = new LuaTable(); } String[] names = api.getNames(); - for (String name : names) { - this.m_globals.rawset(name, table); + for( String name : names ) + { + this.m_globals.rawset( name, table ); } } @Override - public MachineResult loadBios(@Nonnull InputStream bios) { + public MachineResult loadBios( @Nonnull InputStream bios ) + { // Begin executing a file (ie, the bios) - if (this.m_mainRoutine != null) { + if( this.m_mainRoutine != null ) + { return MachineResult.OK; } - try { - LuaFunction value = LoadState.load(this.m_state, bios, "@bios.lua", this.m_globals); - this.m_mainRoutine = new LuaThread(this.m_state, value, this.m_globals); + try + { + LuaFunction value = LoadState.load( this.m_state, bios, "@bios.lua", this.m_globals ); + this.m_mainRoutine = new LuaThread( this.m_state, value, this.m_globals ); return MachineResult.OK; - } catch (CompileException e) { + } + catch( CompileException e ) + { this.close(); - return MachineResult.error(e); - } catch (Exception e) { - ComputerCraft.log.warn("Could not load bios.lua", e); + return MachineResult.error( e ); + } + catch( Exception e ) + { + ComputerCraft.log.warn( "Could not load bios.lua", e ); this.close(); return MachineResult.GENERIC_ERROR; } } @Override - public MachineResult handleEvent(String eventName, Object[] arguments) { - if (this.m_mainRoutine == null) { + public MachineResult handleEvent( String eventName, Object[] arguments ) + { + if( this.m_mainRoutine == null ) + { return MachineResult.OK; } - if (this.m_eventFilter != null && eventName != null && !eventName.equals(this.m_eventFilter) && !eventName.equals("terminate")) { + if( this.m_eventFilter != null && eventName != null && !eventName.equals( this.m_eventFilter ) && !eventName.equals( "terminate" ) ) + { return MachineResult.OK; } // If the soft abort has been cleared then we can reset our flag. this.timeout.refresh(); - if (!this.timeout.isSoftAborted()) { + if( !this.timeout.isSoftAborted() ) + { this.debug.thrownSoftAbort = false; } - try { + try + { Varargs resumeArgs = Constants.NONE; - if (eventName != null) { - resumeArgs = varargsOf(valueOf(eventName), this.toValues(arguments)); + if( eventName != null ) + { + resumeArgs = varargsOf( valueOf( eventName ), this.toValues( arguments ) ); } // Resume the current thread, or the main one when first starting off. LuaThread thread = this.m_state.getCurrentThread(); - if (thread == null || thread == this.m_state.getMainThread()) { + if( thread == null || thread == this.m_state.getMainThread() ) + { thread = this.m_mainRoutine; } - Varargs results = LuaThread.run(thread, resumeArgs); - if (this.timeout.isHardAborted()) { + Varargs results = LuaThread.run( thread, resumeArgs ); + if( this.timeout.isHardAborted() ) + { throw HardAbortError.INSTANCE; } - if (results == null) { + if( results == null ) + { return MachineResult.PAUSE; } LuaValue filter = results.first(); this.m_eventFilter = filter.isString() ? filter.toString() : null; - if (this.m_mainRoutine.getStatus() - .equals("dead")) { + if( this.m_mainRoutine.getStatus() + .equals( "dead" ) ) + { this.close(); return MachineResult.GENERIC_ERROR; - } else { + } + else + { return MachineResult.OK; } - } catch (HardAbortError | InterruptedException e) { + } + catch( HardAbortError | InterruptedException e ) + { this.close(); return MachineResult.TIMEOUT; - } catch (LuaError e) { + } + catch( LuaError e ) + { this.close(); - ComputerCraft.log.warn("Top level coroutine errored", e); - return MachineResult.error(e); + ComputerCraft.log.warn( "Top level coroutine errored", e ); + return MachineResult.error( e ); } } @Override - public void close() { + public void close() + { LuaState state = this.m_state; - if (state == null) { + if( state == null ) + { return; } @@ -316,164 +341,198 @@ public class CobaltLuaMachine implements ILuaMachine { } @Nullable - private LuaTable wrapLuaObject(Object object) { - String[] dynamicMethods = object instanceof IDynamicLuaObject ? Objects.requireNonNull(((IDynamicLuaObject) object).getMethodNames(), - "Methods cannot be null") : LuaMethod.EMPTY_METHODS; + private LuaTable wrapLuaObject( Object object ) + { + String[] dynamicMethods = object instanceof IDynamicLuaObject ? Objects.requireNonNull( ((IDynamicLuaObject) object).getMethodNames(), + "Methods cannot be null" ) : LuaMethod.EMPTY_METHODS; LuaTable table = new LuaTable(); - for (int i = 0; i < dynamicMethods.length; i++) { + for( int i = 0; i < dynamicMethods.length; i++ ) + { String method = dynamicMethods[i]; - table.rawset(method, new ResultInterpreterFunction(this, LuaMethod.DYNAMIC.get(i), object, this.context, method)); + table.rawset( method, new ResultInterpreterFunction( this, LuaMethod.DYNAMIC.get( i ), object, this.context, method ) ); } - ObjectSource.allMethods(LuaMethod.GENERATOR, - object, - (instance, method) -> table.rawset(method.getName(), - method.nonYielding() ? new BasicFunction(this, - (LuaMethod) method.getMethod(), - instance, this.context, - method.getName()) : - new ResultInterpreterFunction( - this, - (LuaMethod) method.getMethod(), - instance, this.context, - method.getName()))); + ObjectSource.allMethods( LuaMethod.GENERATOR, + object, + ( instance, method ) -> table.rawset( method.getName(), + method.nonYielding() ? new BasicFunction( this, + (LuaMethod) method.getMethod(), + instance, this.context, + method.getName() ) : + new ResultInterpreterFunction( + this, + (LuaMethod) method.getMethod(), + instance, this.context, + method.getName() ) ) ); - try { - if (table.keyCount() == 0) { + try + { + if( table.keyCount() == 0 ) + { return null; } - } catch (LuaError ignored) { + } + catch( LuaError ignored ) + { } return table; } @Nonnull - private LuaValue toValue(@Nullable Object object, @Nullable Map values) { - if (object == null) { + private LuaValue toValue( @Nullable Object object, @Nullable Map values ) + { + if( object == null ) + { return Constants.NIL; } - if (object instanceof Number) { - return valueOf(((Number) object).doubleValue()); + if( object instanceof Number ) + { + return valueOf( ((Number) object).doubleValue() ); } - if (object instanceof Boolean) { - return valueOf((Boolean) object); + if( object instanceof Boolean ) + { + return valueOf( (Boolean) object ); } - if (object instanceof String) { - return valueOf(object.toString()); + if( object instanceof String ) + { + return valueOf( object.toString() ); } - if (object instanceof byte[]) { + if( object instanceof byte[] ) + { byte[] b = (byte[]) object; - return valueOf(Arrays.copyOf(b, b.length)); + return valueOf( Arrays.copyOf( b, b.length ) ); } - if (object instanceof ByteBuffer) { + if( object instanceof ByteBuffer ) + { ByteBuffer b = (ByteBuffer) object; byte[] bytes = new byte[b.remaining()]; - b.get(bytes); - return valueOf(bytes); + b.get( bytes ); + return valueOf( bytes ); } - if (values == null) { - values = new IdentityHashMap<>(1); + if( values == null ) + { + values = new IdentityHashMap<>( 1 ); } - LuaValue result = values.get(object); - if (result != null) { + LuaValue result = values.get( object ); + if( result != null ) + { return result; } - if (object instanceof ILuaFunction) { - return new ResultInterpreterFunction(this, FUNCTION_METHOD, object, this.context, object.toString()); + if( object instanceof ILuaFunction ) + { + return new ResultInterpreterFunction( this, FUNCTION_METHOD, object, this.context, object.toString() ); } - if (object instanceof IDynamicLuaObject) { - LuaValue wrapped = this.wrapLuaObject(object); - if (wrapped == null) { + if( object instanceof IDynamicLuaObject ) + { + LuaValue wrapped = this.wrapLuaObject( object ); + if( wrapped == null ) + { wrapped = new LuaTable(); } - values.put(object, wrapped); + values.put( object, wrapped ); return wrapped; } - if (object instanceof Map) { + if( object instanceof Map ) + { LuaTable table = new LuaTable(); - values.put(object, table); + values.put( object, table ); - for (Map.Entry pair : ((Map) object).entrySet()) { - LuaValue key = this.toValue(pair.getKey(), values); - LuaValue value = this.toValue(pair.getValue(), values); - if (!key.isNil() && !value.isNil()) { - table.rawset(key, value); + for( Map.Entry pair : ((Map) object).entrySet() ) + { + LuaValue key = this.toValue( pair.getKey(), values ); + LuaValue value = this.toValue( pair.getValue(), values ); + if( !key.isNil() && !value.isNil() ) + { + table.rawset( key, value ); } } return table; } - if (object instanceof Collection) { + if( object instanceof Collection ) + { Collection objects = (Collection) object; - LuaTable table = new LuaTable(objects.size(), 0); - values.put(object, table); + LuaTable table = new LuaTable( objects.size(), 0 ); + values.put( object, table ); int i = 0; - for (Object child : objects) { - table.rawset(++i, this.toValue(child, values)); + for( Object child : objects ) + { + table.rawset( ++i, this.toValue( child, values ) ); } return table; } - if (object instanceof Object[]) { + if( object instanceof Object[] ) + { Object[] objects = (Object[]) object; - LuaTable table = new LuaTable(objects.length, 0); - values.put(object, table); - for (int i = 0; i < objects.length; i++) { - table.rawset(i + 1, this.toValue(objects[i], values)); + LuaTable table = new LuaTable( objects.length, 0 ); + values.put( object, table ); + for( int i = 0; i < objects.length; i++ ) + { + table.rawset( i + 1, this.toValue( objects[i], values ) ); } return table; } - LuaTable wrapped = this.wrapLuaObject(object); - if (wrapped != null) { - values.put(object, wrapped); + LuaTable wrapped = this.wrapLuaObject( object ); + if( wrapped != null ) + { + values.put( object, wrapped ); return wrapped; } - if (ComputerCraft.logComputerErrors) { - ComputerCraft.log.warn("Received unknown type '{}', returning nil.", - object.getClass() - .getName()); + if( ComputerCraft.logComputerErrors ) + { + ComputerCraft.log.warn( "Received unknown type '{}', returning nil.", + object.getClass() + .getName() ); } return Constants.NIL; } - Varargs toValues(Object[] objects) { - if (objects == null || objects.length == 0) { + Varargs toValues( Object[] objects ) + { + if( objects == null || objects.length == 0 ) + { return Constants.NONE; } - if (objects.length == 1) { - return this.toValue(objects[0], null); + if( objects.length == 1 ) + { + return this.toValue( objects[0], null ); } - Map result = new IdentityHashMap<>(0); + Map result = new IdentityHashMap<>( 0 ); LuaValue[] values = new LuaValue[objects.length]; - for (int i = 0; i < values.length; i++) { + for( int i = 0; i < values.length; i++ ) + { Object object = objects[i]; - values[i] = this.toValue(object, result); + values[i] = this.toValue( object, result ); } - return varargsOf(values); + return varargsOf( values ); } - private static final class HardAbortError extends Error { + private static final class HardAbortError extends Error + { static final HardAbortError INSTANCE = new HardAbortError(); private static final long serialVersionUID = 7954092008586367501L; - private HardAbortError() { - super("Hard Abort", null, true, false); + private HardAbortError() + { + super( "Hard Abort", null, true, false ); } } /** * A {@link DebugHandler} which observes the {@link TimeoutState} and responds accordingly. */ - private class TimeoutDebugHandler extends DebugHandler { + private class TimeoutDebugHandler extends DebugHandler + { private final TimeoutState timeout; boolean thrownSoftAbort; private int count = 0; @@ -481,27 +540,33 @@ public class CobaltLuaMachine implements ILuaMachine { private int oldFlags; private boolean oldInHook; - TimeoutDebugHandler() { + TimeoutDebugHandler() + { this.timeout = CobaltLuaMachine.this.timeout; } @Override - public void onInstruction(DebugState ds, DebugFrame di, int pc) throws LuaError, UnwindThrowable { + public void onInstruction( DebugState ds, DebugFrame di, int pc ) throws LuaError, UnwindThrowable + { di.pc = pc; - if (this.isPaused) { - this.resetPaused(ds, di); + if( this.isPaused ) + { + this.resetPaused( ds, di ); } // We check our current pause/abort state every 128 instructions. - if ((this.count = (this.count + 1) & 127) == 0) { + if( (this.count = (this.count + 1) & 127) == 0 ) + { // If we've been hard aborted or closed then abort. - if (this.timeout.isHardAborted() || CobaltLuaMachine.this.m_state == null) { + if( this.timeout.isHardAborted() || CobaltLuaMachine.this.m_state == null ) + { throw HardAbortError.INSTANCE; } this.timeout.refresh(); - if (this.timeout.isPaused()) { + if( this.timeout.isPaused() ) + { // Preserve the current state this.isPaused = true; this.oldInHook = ds.inhook; @@ -509,92 +574,112 @@ public class CobaltLuaMachine implements ILuaMachine { // Suspend the state. This will probably throw, but we need to handle the case where it won't. di.flags |= FLAG_HOOKYIELD | FLAG_HOOKED; - LuaThread.suspend(ds.getLuaState()); - this.resetPaused(ds, di); + LuaThread.suspend( ds.getLuaState() ); + this.resetPaused( ds, di ); } this.handleSoftAbort(); } - super.onInstruction(ds, di, pc); + super.onInstruction( ds, di, pc ); } @Override - public void poll() throws LuaError { + public void poll() throws LuaError + { // If we've been hard aborted or closed then abort. LuaState state = CobaltLuaMachine.this.m_state; - if (this.timeout.isHardAborted() || state == null) { + if( this.timeout.isHardAborted() || state == null ) + { throw HardAbortError.INSTANCE; } this.timeout.refresh(); - if (this.timeout.isPaused()) { - LuaThread.suspendBlocking(state); + if( this.timeout.isPaused() ) + { + LuaThread.suspendBlocking( state ); } this.handleSoftAbort(); } - private void resetPaused(DebugState ds, DebugFrame di) { + private void resetPaused( DebugState ds, DebugFrame di ) + { // Restore the previous paused state this.isPaused = false; ds.inhook = this.oldInHook; di.flags = this.oldFlags; } - private void handleSoftAbort() throws LuaError { + private void handleSoftAbort() throws LuaError + { // If we already thrown our soft abort error then don't do it again. - if (!this.timeout.isSoftAborted() || this.thrownSoftAbort) { + if( !this.timeout.isSoftAborted() || this.thrownSoftAbort ) + { return; } this.thrownSoftAbort = true; - throw new LuaError(TimeoutState.ABORT_MESSAGE); + throw new LuaError( TimeoutState.ABORT_MESSAGE ); } } - private class CobaltLuaContext implements ILuaContext { + private class CobaltLuaContext implements ILuaContext + { @Override - public long issueMainThreadTask(@Nonnull final ILuaTask task) throws LuaException { + public long issueMainThreadTask( @Nonnull final ILuaTask task ) throws LuaException + { // Issue command final long taskID = MainThread.getUniqueTaskID(); final Runnable iTask = () -> { - try { + try + { Object[] results = task.execute(); - if (results != null) { + if( results != null ) + { Object[] eventArguments = new Object[results.length + 2]; eventArguments[0] = taskID; eventArguments[1] = true; - System.arraycopy(results, 0, eventArguments, 2, results.length); - CobaltLuaMachine.this.m_computer.queueEvent("task_complete", eventArguments); - } else { - CobaltLuaMachine.this.m_computer.queueEvent("task_complete", - new Object[] { - taskID, - true - }); + System.arraycopy( results, 0, eventArguments, 2, results.length ); + CobaltLuaMachine.this.m_computer.queueEvent( "task_complete", eventArguments ); } - } catch (LuaException e) { - CobaltLuaMachine.this.m_computer.queueEvent("task_complete", - new Object[] { - taskID, - false, - e.getMessage() - }); - } catch (Throwable t) { - if (ComputerCraft.logComputerErrors) { - ComputerCraft.log.error("Error running task", t); + else + { + CobaltLuaMachine.this.m_computer.queueEvent( "task_complete", + new Object[] { + taskID, + true + } ); } - CobaltLuaMachine.this.m_computer.queueEvent("task_complete", new Object[] { + } + catch( LuaException e ) + { + CobaltLuaMachine.this.m_computer.queueEvent( "task_complete", + new Object[] { + taskID, + false, + e.getMessage() + } ); + } + catch( Throwable t ) + { + if( ComputerCraft.logComputerErrors ) + { + ComputerCraft.log.error( "Error running task", t ); + } + CobaltLuaMachine.this.m_computer.queueEvent( "task_complete", new Object[] { taskID, false, "Java Exception Thrown: " + t, - }); + } ); } }; - if (CobaltLuaMachine.this.m_computer.queueMainThread(iTask)) { + if( CobaltLuaMachine.this.m_computer.queueMainThread( iTask ) ) + { return taskID; - } else { - throw new LuaException("Task limit exceeded"); + } + else + { + throw new LuaException( "Task limit exceeded" ); } } } diff --git a/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java b/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java index 4008b626d..272a8d3ee 100644 --- a/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java +++ b/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java @@ -6,13 +6,12 @@ package dan200.computercraft.core.lua; -import java.io.InputStream; +import dan200.computercraft.api.lua.IDynamicLuaObject; +import dan200.computercraft.api.lua.ILuaAPI; import javax.annotation.Nonnull; import javax.annotation.Nullable; - -import dan200.computercraft.api.lua.IDynamicLuaObject; -import dan200.computercraft.api.lua.ILuaAPI; +import java.io.InputStream; /** * Represents a machine which will execute Lua code. Technically this API is flexible enough to support many languages, but you'd need a way to provide @@ -24,7 +23,8 @@ import dan200.computercraft.api.lua.ILuaAPI; * This should provide implementations of {@link dan200.computercraft.api.lua.ILuaContext}, and the ability to convert {@link IDynamicLuaObject}s into * something the VM understands, as well as handling method calls. */ -public interface ILuaMachine { +public interface ILuaMachine +{ /** * Inject an API into the global environment of this machine. This should construct an object, as it would for any {@link IDynamicLuaObject} and set it * to all names in {@link ILuaAPI#getNames()}. @@ -33,7 +33,7 @@ public interface ILuaMachine { * * @param api The API to register. */ - void addAPI(@Nonnull ILuaAPI api); + void addAPI( @Nonnull ILuaAPI api ); /** * Create a function from the provided program, and set it up to run when {@link #handleEvent(String, Object[])} is called. @@ -43,7 +43,7 @@ public interface ILuaMachine { * @param bios The stream containing the boot program. * @return The result of loading this machine. Will either be OK, or the error message when loading the bios. */ - MachineResult loadBios(@Nonnull InputStream bios); + MachineResult loadBios( @Nonnull InputStream bios ); /** * Resume the machine, either starting or resuming the coroutine. @@ -51,11 +51,11 @@ public interface ILuaMachine { * This should destroy the machine if it failed to execute successfully. * * @param eventName The name of the event. This is {@code null} when first starting the machine. Note, this may do nothing if it does not match the - * event filter. + * event filter. * @param arguments The arguments for this event. * @return The result of loading this machine. Will either be OK, or the error message that occurred when executing. */ - MachineResult handleEvent(@Nullable String eventName, @Nullable Object[] arguments); + MachineResult handleEvent( @Nullable String eventName, @Nullable Object[] arguments ); /** * Close the Lua machine, aborting any running functions and deleting the internal state. diff --git a/src/main/java/dan200/computercraft/core/lua/MachineResult.java b/src/main/java/dan200/computercraft/core/lua/MachineResult.java index 5e947abab..f5cc1058b 100644 --- a/src/main/java/dan200/computercraft/core/lua/MachineResult.java +++ b/src/main/java/dan200/computercraft/core/lua/MachineResult.java @@ -6,12 +6,11 @@ package dan200.computercraft.core.lua; -import java.io.InputStream; +import dan200.computercraft.core.computer.TimeoutState; import javax.annotation.Nonnull; import javax.annotation.Nullable; - -import dan200.computercraft.core.computer.TimeoutState; +import java.io.InputStream; /** * The result of executing an action on a machine. @@ -21,55 +20,62 @@ import dan200.computercraft.core.computer.TimeoutState; * @see ILuaMachine#loadBios(InputStream) * @see ILuaMachine#handleEvent(String, Object[]) */ -public final class MachineResult { +public final class MachineResult +{ /** * A successful complete execution. */ - public static final MachineResult OK = new MachineResult(false, false, null); + public static final MachineResult OK = new MachineResult( false, false, null ); /** * A successful paused execution. */ - public static final MachineResult PAUSE = new MachineResult(false, true, null); + public static final MachineResult PAUSE = new MachineResult( false, true, null ); /** * An execution which timed out. */ - public static final MachineResult TIMEOUT = new MachineResult(true, false, TimeoutState.ABORT_MESSAGE); + public static final MachineResult TIMEOUT = new MachineResult( true, false, TimeoutState.ABORT_MESSAGE ); /** * An error with no user-friendly error message. */ - public static final MachineResult GENERIC_ERROR = new MachineResult(true, false, null); + public static final MachineResult GENERIC_ERROR = new MachineResult( true, false, null ); private final boolean error; private final boolean pause; private final String message; - private MachineResult(boolean error, boolean pause, String message) { + private MachineResult( boolean error, boolean pause, String message ) + { this.pause = pause; this.message = message; this.error = error; } - public static MachineResult error(@Nonnull String error) { - return new MachineResult(true, false, error); + public static MachineResult error( @Nonnull String error ) + { + return new MachineResult( true, false, error ); } - public static MachineResult error(@Nonnull Exception error) { - return new MachineResult(true, false, error.getMessage()); + public static MachineResult error( @Nonnull Exception error ) + { + return new MachineResult( true, false, error.getMessage() ); } - public boolean isError() { + public boolean isError() + { return this.error; } - public boolean isPause() { + public boolean isPause() + { return this.pause; } @Nullable - public String getMessage() { + public String getMessage() + { return this.message; } } diff --git a/src/main/java/dan200/computercraft/core/lua/ResultInterpreterFunction.java b/src/main/java/dan200/computercraft/core/lua/ResultInterpreterFunction.java index 12aacf219..90b6bd70b 100644 --- a/src/main/java/dan200/computercraft/core/lua/ResultInterpreterFunction.java +++ b/src/main/java/dan200/computercraft/core/lua/ResultInterpreterFunction.java @@ -5,34 +5,29 @@ */ package dan200.computercraft.core.lua; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.ILuaCallback; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.lua.*; import dan200.computercraft.core.asm.LuaMethod; -import org.squiddev.cobalt.LuaError; -import org.squiddev.cobalt.LuaState; -import org.squiddev.cobalt.LuaThread; -import org.squiddev.cobalt.UnwindThrowable; -import org.squiddev.cobalt.Varargs; +import org.squiddev.cobalt.*; import org.squiddev.cobalt.debug.DebugFrame; import org.squiddev.cobalt.function.ResumableVarArgFunction; +import javax.annotation.Nonnull; + /** * Calls a {@link LuaMethod}, and interprets the resulting {@link MethodResult}, either returning the result or yielding and resuming the supplied * continuation. */ -class ResultInterpreterFunction extends ResumableVarArgFunction { +class ResultInterpreterFunction extends ResumableVarArgFunction +{ private final CobaltLuaMachine machine; private final LuaMethod method; private final Object instance; private final ILuaContext context; private final String name; - ResultInterpreterFunction(CobaltLuaMachine machine, LuaMethod method, Object instance, ILuaContext context, String name) { + + ResultInterpreterFunction( CobaltLuaMachine machine, LuaMethod method, Object instance, ILuaContext context, String name ) + { this.machine = machine; this.method = method; this.instance = instance; @@ -41,72 +36,92 @@ class ResultInterpreterFunction extends ResumableVarArgFunction= this.varargs.count()) { + public Object get( int index ) + { + if( index < 0 || index >= this.varargs.count() ) + { return null; } Object[] cache = this.cache; - if (cache == null) { + if( cache == null ) + { cache = this.cache = new Object[this.varargs.count()]; - } else { + } + else + { Object existing = cache[index]; - if (existing != null) { + if( existing != null ) + { return existing; } } - return cache[index] = CobaltLuaMachine.toObject(this.varargs.arg(index + 1), null); + return cache[index] = CobaltLuaMachine.toObject( this.varargs.arg( index + 1 ), null ); } @Override - public long getLong(int index) throws LuaException { - LuaValue value = this.varargs.arg(index + 1); - if (!(value instanceof LuaNumber)) { - throw LuaValues.badArgument(index, "number", value.typeName()); + public long getLong( int index ) throws LuaException + { + LuaValue value = this.varargs.arg( index + 1 ); + if( !(value instanceof LuaNumber) ) + { + throw LuaValues.badArgument( index, "number", value.typeName() ); } - return value instanceof LuaInteger ? value.toInteger() : (long) LuaValues.checkFinite(index, value.toDouble()); + return value instanceof LuaInteger ? value.toInteger() : (long) LuaValues.checkFinite( index, value.toDouble() ); } @Override - public double getDouble(int index) throws LuaException { - LuaValue value = this.varargs.arg(index + 1); - if (!(value instanceof LuaNumber)) { - throw LuaValues.badArgument(index, "number", value.typeName()); + public double getDouble( int index ) throws LuaException + { + LuaValue value = this.varargs.arg( index + 1 ); + if( !(value instanceof LuaNumber) ) + { + throw LuaValues.badArgument( index, "number", value.typeName() ); } return value.toDouble(); } @Nonnull @Override - public ByteBuffer getBytes(int index) throws LuaException { - LuaValue value = this.varargs.arg(index + 1); - if (!(value instanceof LuaBaseString)) { - throw LuaValues.badArgument(index, "string", value.typeName()); + public ByteBuffer getBytes( int index ) throws LuaException + { + LuaValue value = this.varargs.arg( index + 1 ); + if( !(value instanceof LuaBaseString) ) + { + throw LuaValues.badArgument( index, "string", value.typeName() ); } LuaString str = ((LuaBaseString) value).strvalue(); - return ByteBuffer.wrap(str.bytes, str.offset, str.length) - .asReadOnlyBuffer(); + return ByteBuffer.wrap( str.bytes, str.offset, str.length ) + .asReadOnlyBuffer(); } @Override - public Optional optBytes(int index) throws LuaException { - LuaValue value = this.varargs.arg(index + 1); - if (value.isNil()) { + public Optional optBytes( int index ) throws LuaException + { + LuaValue value = this.varargs.arg( index + 1 ); + if( value.isNil() ) + { return Optional.empty(); } - if (!(value instanceof LuaBaseString)) { - throw LuaValues.badArgument(index, "string", value.typeName()); + if( !(value instanceof LuaBaseString) ) + { + throw LuaValues.badArgument( index, "string", value.typeName() ); } LuaString str = ((LuaBaseString) value).strvalue(); - return Optional.of(ByteBuffer.wrap(str.bytes, str.offset, str.length) - .asReadOnlyBuffer()); + return Optional.of( ByteBuffer.wrap( str.bytes, str.offset, str.length ) + .asReadOnlyBuffer() ); } } diff --git a/src/main/java/dan200/computercraft/core/terminal/Terminal.java b/src/main/java/dan200/computercraft/core/terminal/Terminal.java index 8fcc07c6f..08fe1d01f 100644 --- a/src/main/java/dan200/computercraft/core/terminal/Terminal.java +++ b/src/main/java/dan200/computercraft/core/terminal/Terminal.java @@ -6,15 +6,15 @@ package dan200.computercraft.core.terminal; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Palette; - import net.minecraft.nbt.CompoundTag; import net.minecraft.network.PacketByteBuf; -public class Terminal { +import javax.annotation.Nonnull; + +public class Terminal +{ private static final String base16 = "0123456789abcdef"; private final Palette m_palette = new Palette(); private final Runnable onChanged; @@ -29,11 +29,13 @@ public class Terminal { private TextBuffer[] m_textColour; private TextBuffer[] m_backgroundColour; - public Terminal(int width, int height) { - this(width, height, null); + public Terminal( int width, int height ) + { + this( width, height, null ); } - public Terminal(int width, int height, Runnable changedCallback) { + public Terminal( int width, int height, Runnable changedCallback ) + { this.m_width = width; this.m_height = height; this.onChanged = changedCallback; @@ -41,14 +43,16 @@ public class Terminal { this.m_text = new TextBuffer[this.m_height]; this.m_textColour = new TextBuffer[this.m_height]; this.m_backgroundColour = new TextBuffer[this.m_height]; - for (int i = 0; i < this.m_height; i++) { - this.m_text[i] = new TextBuffer(' ', this.m_width); - this.m_textColour[i] = new TextBuffer(base16.charAt(this.m_cursorColour), this.m_width); - this.m_backgroundColour[i] = new TextBuffer(base16.charAt(this.m_cursorBackgroundColour), this.m_width); + for( int i = 0; i < this.m_height; i++ ) + { + this.m_text[i] = new TextBuffer( ' ', this.m_width ); + this.m_textColour[i] = new TextBuffer( base16.charAt( this.m_cursorColour ), this.m_width ); + this.m_backgroundColour[i] = new TextBuffer( base16.charAt( this.m_cursorBackgroundColour ), this.m_width ); } } - public synchronized void reset() { + public synchronized void reset() + { this.m_cursorColour = 0; this.m_cursorBackgroundColour = 15; this.m_cursorX = 0; @@ -59,31 +63,39 @@ public class Terminal { this.m_palette.resetColours(); } - public synchronized void clear() { - for (int y = 0; y < this.m_height; y++) { - this.m_text[y].fill(' '); - this.m_textColour[y].fill(base16.charAt(this.m_cursorColour)); - this.m_backgroundColour[y].fill(base16.charAt(this.m_cursorBackgroundColour)); + public synchronized void clear() + { + for( int y = 0; y < this.m_height; y++ ) + { + this.m_text[y].fill( ' ' ); + this.m_textColour[y].fill( base16.charAt( this.m_cursorColour ) ); + this.m_backgroundColour[y].fill( base16.charAt( this.m_cursorBackgroundColour ) ); } this.setChanged(); } - public final void setChanged() { - if (this.onChanged != null) { + public final void setChanged() + { + if( this.onChanged != null ) + { this.onChanged.run(); } } - public int getWidth() { + public int getWidth() + { return this.m_width; } - public int getHeight() { + public int getHeight() + { return this.m_height; } - public synchronized void resize(int width, int height) { - if (width == this.m_width && height == this.m_height) { + public synchronized void resize( int width, int height ) + { + if( width == this.m_width && height == this.m_height ) + { return; } @@ -99,118 +111,148 @@ public class Terminal { this.m_text = new TextBuffer[this.m_height]; this.m_textColour = new TextBuffer[this.m_height]; this.m_backgroundColour = new TextBuffer[this.m_height]; - for (int i = 0; i < this.m_height; i++) { - if (i >= oldHeight) { - this.m_text[i] = new TextBuffer(' ', this.m_width); - this.m_textColour[i] = new TextBuffer(base16.charAt(this.m_cursorColour), this.m_width); - this.m_backgroundColour[i] = new TextBuffer(base16.charAt(this.m_cursorBackgroundColour), this.m_width); - } else if (this.m_width == oldWidth) { + for( int i = 0; i < this.m_height; i++ ) + { + if( i >= oldHeight ) + { + this.m_text[i] = new TextBuffer( ' ', this.m_width ); + this.m_textColour[i] = new TextBuffer( base16.charAt( this.m_cursorColour ), this.m_width ); + this.m_backgroundColour[i] = new TextBuffer( base16.charAt( this.m_cursorBackgroundColour ), this.m_width ); + } + else if( this.m_width == oldWidth ) + { this.m_text[i] = oldText[i]; this.m_textColour[i] = oldTextColour[i]; this.m_backgroundColour[i] = oldBackgroundColour[i]; - } else { - this.m_text[i] = new TextBuffer(' ', this.m_width); - this.m_textColour[i] = new TextBuffer(base16.charAt(this.m_cursorColour), this.m_width); - this.m_backgroundColour[i] = new TextBuffer(base16.charAt(this.m_cursorBackgroundColour), this.m_width); - this.m_text[i].write(oldText[i]); - this.m_textColour[i].write(oldTextColour[i]); - this.m_backgroundColour[i].write(oldBackgroundColour[i]); + } + else + { + this.m_text[i] = new TextBuffer( ' ', this.m_width ); + this.m_textColour[i] = new TextBuffer( base16.charAt( this.m_cursorColour ), this.m_width ); + this.m_backgroundColour[i] = new TextBuffer( base16.charAt( this.m_cursorBackgroundColour ), this.m_width ); + this.m_text[i].write( oldText[i] ); + this.m_textColour[i].write( oldTextColour[i] ); + this.m_backgroundColour[i].write( oldBackgroundColour[i] ); } } this.setChanged(); } - public void setCursorPos(int x, int y) { - if (this.m_cursorX != x || this.m_cursorY != y) { + public void setCursorPos( int x, int y ) + { + if( this.m_cursorX != x || this.m_cursorY != y ) + { this.m_cursorX = x; this.m_cursorY = y; this.setChanged(); } } - public int getCursorX() { + public int getCursorX() + { return this.m_cursorX; } - public int getCursorY() { + public int getCursorY() + { return this.m_cursorY; } - public boolean getCursorBlink() { + public boolean getCursorBlink() + { return this.m_cursorBlink; } - public void setCursorBlink(boolean blink) { - if (this.m_cursorBlink != blink) { + public void setCursorBlink( boolean blink ) + { + if( this.m_cursorBlink != blink ) + { this.m_cursorBlink = blink; this.setChanged(); } } - public int getTextColour() { + public int getTextColour() + { return this.m_cursorColour; } - public void setTextColour(int colour) { - if (this.m_cursorColour != colour) { + public void setTextColour( int colour ) + { + if( this.m_cursorColour != colour ) + { this.m_cursorColour = colour; this.setChanged(); } } - public int getBackgroundColour() { + public int getBackgroundColour() + { return this.m_cursorBackgroundColour; } - public void setBackgroundColour(int colour) { - if (this.m_cursorBackgroundColour != colour) { + public void setBackgroundColour( int colour ) + { + if( this.m_cursorBackgroundColour != colour ) + { this.m_cursorBackgroundColour = colour; this.setChanged(); } } @Nonnull - public Palette getPalette() { + public Palette getPalette() + { return this.m_palette; } - public synchronized void blit(String text, String textColour, String backgroundColour) { + public synchronized void blit( String text, String textColour, String backgroundColour ) + { int x = this.m_cursorX; int y = this.m_cursorY; - if (y >= 0 && y < this.m_height) { - this.m_text[y].write(text, x); - this.m_textColour[y].write(textColour, x); - this.m_backgroundColour[y].write(backgroundColour, x); + if( y >= 0 && y < this.m_height ) + { + this.m_text[y].write( text, x ); + this.m_textColour[y].write( textColour, x ); + this.m_backgroundColour[y].write( backgroundColour, x ); this.setChanged(); } } - public synchronized void write(String text) { + public synchronized void write( String text ) + { int x = this.m_cursorX; int y = this.m_cursorY; - if (y >= 0 && y < this.m_height) { - this.m_text[y].write(text, x); - this.m_textColour[y].fill(base16.charAt(this.m_cursorColour), x, x + text.length()); - this.m_backgroundColour[y].fill(base16.charAt(this.m_cursorBackgroundColour), x, x + text.length()); + if( y >= 0 && y < this.m_height ) + { + this.m_text[y].write( text, x ); + this.m_textColour[y].fill( base16.charAt( this.m_cursorColour ), x, x + text.length() ); + this.m_backgroundColour[y].fill( base16.charAt( this.m_cursorBackgroundColour ), x, x + text.length() ); this.setChanged(); } } - public synchronized void scroll(int yDiff) { - if (yDiff != 0) { + public synchronized void scroll( int yDiff ) + { + if( yDiff != 0 ) + { TextBuffer[] newText = new TextBuffer[this.m_height]; TextBuffer[] newTextColour = new TextBuffer[this.m_height]; TextBuffer[] newBackgroundColour = new TextBuffer[this.m_height]; - for (int y = 0; y < this.m_height; y++) { + for( int y = 0; y < this.m_height; y++ ) + { int oldY = y + yDiff; - if (oldY >= 0 && oldY < this.m_height) { + if( oldY >= 0 && oldY < this.m_height ) + { newText[y] = this.m_text[oldY]; newTextColour[y] = this.m_textColour[oldY]; newBackgroundColour[y] = this.m_backgroundColour[oldY]; - } else { - newText[y] = new TextBuffer(' ', this.m_width); - newTextColour[y] = new TextBuffer(base16.charAt(this.m_cursorColour), this.m_width); - newBackgroundColour[y] = new TextBuffer(base16.charAt(this.m_cursorBackgroundColour), this.m_width); + } + else + { + newText[y] = new TextBuffer( ' ', this.m_width ); + newTextColour[y] = new TextBuffer( base16.charAt( this.m_cursorColour ), this.m_width ); + newBackgroundColour[y] = new TextBuffer( base16.charAt( this.m_cursorBackgroundColour ), this.m_width ); } } this.m_text = newText; @@ -220,75 +262,91 @@ public class Terminal { } } - public synchronized void clearLine() { + public synchronized void clearLine() + { int y = this.m_cursorY; - if (y >= 0 && y < this.m_height) { - this.m_text[y].fill(' '); - this.m_textColour[y].fill(base16.charAt(this.m_cursorColour)); - this.m_backgroundColour[y].fill(base16.charAt(this.m_cursorBackgroundColour)); + if( y >= 0 && y < this.m_height ) + { + this.m_text[y].fill( ' ' ); + this.m_textColour[y].fill( base16.charAt( this.m_cursorColour ) ); + this.m_backgroundColour[y].fill( base16.charAt( this.m_cursorBackgroundColour ) ); this.setChanged(); } } - public synchronized TextBuffer getLine(int y) { - if (y >= 0 && y < this.m_height) { + public synchronized TextBuffer getLine( int y ) + { + if( y >= 0 && y < this.m_height ) + { return this.m_text[y]; } return null; } - public synchronized void setLine(int y, String text, String textColour, String backgroundColour) { - this.m_text[y].write(text); - this.m_textColour[y].write(textColour); - this.m_backgroundColour[y].write(backgroundColour); + public synchronized void setLine( int y, String text, String textColour, String backgroundColour ) + { + this.m_text[y].write( text ); + this.m_textColour[y].write( textColour ); + this.m_backgroundColour[y].write( backgroundColour ); this.setChanged(); } - public synchronized TextBuffer getTextColourLine(int y) { - if (y >= 0 && y < this.m_height) { + public synchronized TextBuffer getTextColourLine( int y ) + { + if( y >= 0 && y < this.m_height ) + { return this.m_textColour[y]; } return null; } - public synchronized TextBuffer getBackgroundColourLine(int y) { - if (y >= 0 && y < this.m_height) { + public synchronized TextBuffer getBackgroundColourLine( int y ) + { + if( y >= 0 && y < this.m_height ) + { return this.m_backgroundColour[y]; } return null; } - public synchronized void write(PacketByteBuf buffer) { - buffer.writeInt(this.m_cursorX); - buffer.writeInt(this.m_cursorY); - buffer.writeBoolean(this.m_cursorBlink); - buffer.writeByte(this.m_cursorBackgroundColour << 4 | this.m_cursorColour); + public synchronized void write( PacketByteBuf buffer ) + { + buffer.writeInt( this.m_cursorX ); + buffer.writeInt( this.m_cursorY ); + buffer.writeBoolean( this.m_cursorBlink ); + buffer.writeByte( this.m_cursorBackgroundColour << 4 | this.m_cursorColour ); - for (int y = 0; y < this.m_height; y++) { + for( int y = 0; y < this.m_height; y++ ) + { TextBuffer text = this.m_text[y]; TextBuffer textColour = this.m_textColour[y]; TextBuffer backColour = this.m_backgroundColour[y]; - for (int x = 0; x < this.m_width; x++) { - buffer.writeByte(text.charAt(x) & 0xFF); - buffer.writeByte(getColour(backColour.charAt(x), Colour.BLACK) << 4 | getColour(textColour.charAt(x), Colour.WHITE)); + for( int x = 0; x < this.m_width; x++ ) + { + buffer.writeByte( text.charAt( x ) & 0xFF ); + buffer.writeByte( getColour( backColour.charAt( x ), Colour.BLACK ) << 4 | getColour( textColour.charAt( x ), Colour.WHITE ) ); } } - this.m_palette.write(buffer); + this.m_palette.write( buffer ); } - public static int getColour(char c, Colour def) { - if (c >= '0' && c <= '9') { + public static int getColour( char c, Colour def ) + { + if( c >= '0' && c <= '9' ) + { return c - '0'; } - if (c >= 'a' && c <= 'f') { + if( c >= 'a' && c <= 'f' ) + { return c - 'a' + 10; } return 15 - def.ordinal(); } - public synchronized void read(PacketByteBuf buffer) { + public synchronized void read( PacketByteBuf buffer ) + { this.m_cursorX = buffer.readInt(); this.m_cursorY = buffer.readInt(); this.m_cursorBlink = buffer.readBoolean(); @@ -297,63 +355,72 @@ public class Terminal { this.m_cursorBackgroundColour = (cursorColour >> 4) & 0xF; this.m_cursorColour = cursorColour & 0xF; - for (int y = 0; y < this.m_height; y++) { + for( int y = 0; y < this.m_height; y++ ) + { TextBuffer text = this.m_text[y]; TextBuffer textColour = this.m_textColour[y]; TextBuffer backColour = this.m_backgroundColour[y]; - for (int x = 0; x < this.m_width; x++) { - text.setChar(x, (char) (buffer.readByte() & 0xFF)); + for( int x = 0; x < this.m_width; x++ ) + { + text.setChar( x, (char) (buffer.readByte() & 0xFF) ); byte colour = buffer.readByte(); - backColour.setChar(x, base16.charAt((colour >> 4) & 0xF)); - textColour.setChar(x, base16.charAt(colour & 0xF)); + backColour.setChar( x, base16.charAt( (colour >> 4) & 0xF ) ); + textColour.setChar( x, base16.charAt( colour & 0xF ) ); } } - this.m_palette.read(buffer); + this.m_palette.read( buffer ); this.setChanged(); } - public synchronized CompoundTag writeToNBT(CompoundTag nbt) { - nbt.putInt("term_cursorX", this.m_cursorX); - nbt.putInt("term_cursorY", this.m_cursorY); - nbt.putBoolean("term_cursorBlink", this.m_cursorBlink); - nbt.putInt("term_textColour", this.m_cursorColour); - nbt.putInt("term_bgColour", this.m_cursorBackgroundColour); - for (int n = 0; n < this.m_height; n++) { - nbt.putString("term_text_" + n, this.m_text[n].toString()); - nbt.putString("term_textColour_" + n, this.m_textColour[n].toString()); - nbt.putString("term_textBgColour_" + n, this.m_backgroundColour[n].toString()); + public synchronized CompoundTag writeToNBT( CompoundTag nbt ) + { + nbt.putInt( "term_cursorX", this.m_cursorX ); + nbt.putInt( "term_cursorY", this.m_cursorY ); + nbt.putBoolean( "term_cursorBlink", this.m_cursorBlink ); + nbt.putInt( "term_textColour", this.m_cursorColour ); + nbt.putInt( "term_bgColour", this.m_cursorBackgroundColour ); + for( int n = 0; n < this.m_height; n++ ) + { + nbt.putString( "term_text_" + n, this.m_text[n].toString() ); + nbt.putString( "term_textColour_" + n, this.m_textColour[n].toString() ); + nbt.putString( "term_textBgColour_" + n, this.m_backgroundColour[n].toString() ); } - this.m_palette.writeToNBT(nbt); + this.m_palette.writeToNBT( nbt ); return nbt; } - public synchronized void readFromNBT(CompoundTag nbt) { - this.m_cursorX = nbt.getInt("term_cursorX"); - this.m_cursorY = nbt.getInt("term_cursorY"); - this.m_cursorBlink = nbt.getBoolean("term_cursorBlink"); - this.m_cursorColour = nbt.getInt("term_textColour"); - this.m_cursorBackgroundColour = nbt.getInt("term_bgColour"); + public synchronized void readFromNBT( CompoundTag nbt ) + { + this.m_cursorX = nbt.getInt( "term_cursorX" ); + this.m_cursorY = nbt.getInt( "term_cursorY" ); + this.m_cursorBlink = nbt.getBoolean( "term_cursorBlink" ); + this.m_cursorColour = nbt.getInt( "term_textColour" ); + this.m_cursorBackgroundColour = nbt.getInt( "term_bgColour" ); - for (int n = 0; n < this.m_height; n++) { - this.m_text[n].fill(' '); - if (nbt.contains("term_text_" + n)) { - this.m_text[n].write(nbt.getString("term_text_" + n)); + for( int n = 0; n < this.m_height; n++ ) + { + this.m_text[n].fill( ' ' ); + if( nbt.contains( "term_text_" + n ) ) + { + this.m_text[n].write( nbt.getString( "term_text_" + n ) ); } - this.m_textColour[n].fill(base16.charAt(this.m_cursorColour)); - if (nbt.contains("term_textColour_" + n)) { - this.m_textColour[n].write(nbt.getString("term_textColour_" + n)); + this.m_textColour[n].fill( base16.charAt( this.m_cursorColour ) ); + if( nbt.contains( "term_textColour_" + n ) ) + { + this.m_textColour[n].write( nbt.getString( "term_textColour_" + n ) ); } - this.m_backgroundColour[n].fill(base16.charAt(this.m_cursorBackgroundColour)); - if (nbt.contains("term_textBgColour_" + n)) { - this.m_backgroundColour[n].write(nbt.getString("term_textBgColour_" + n)); + this.m_backgroundColour[n].fill( base16.charAt( this.m_cursorBackgroundColour ) ); + if( nbt.contains( "term_textBgColour_" + n ) ) + { + this.m_backgroundColour[n].write( nbt.getString( "term_textBgColour_" + n ) ); } } - this.m_palette.readFromNBT(nbt); + this.m_palette.readFromNBT( nbt ); this.setChanged(); } } diff --git a/src/main/java/dan200/computercraft/core/tracking/ComputerTracker.java b/src/main/java/dan200/computercraft/core/tracking/ComputerTracker.java index 7979b8777..0fbb848a2 100644 --- a/src/main/java/dan200/computercraft/core/tracking/ComputerTracker.java +++ b/src/main/java/dan200/computercraft/core/tracking/ComputerTracker.java @@ -6,14 +6,14 @@ package dan200.computercraft.core.tracking; -import java.lang.ref.WeakReference; - -import javax.annotation.Nullable; - import dan200.computercraft.core.computer.Computer; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -public class ComputerTracker { +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; + +public class ComputerTracker +{ private final WeakReference computer; private final int computerId; private final Object2LongOpenHashMap fields; @@ -23,13 +23,15 @@ public class ComputerTracker { private long serverCount; private long serverTime; - public ComputerTracker(Computer computer) { - this.computer = new WeakReference<>(computer); + public ComputerTracker( Computer computer ) + { + this.computer = new WeakReference<>( computer ); this.computerId = computer.getID(); this.fields = new Object2LongOpenHashMap<>(); } - ComputerTracker(ComputerTracker timings) { + ComputerTracker( ComputerTracker timings ) + { this.computer = timings.computer; this.computerId = timings.computerId; @@ -40,80 +42,100 @@ public class ComputerTracker { this.serverCount = timings.serverCount; this.serverTime = timings.serverTime; - this.fields = new Object2LongOpenHashMap<>(timings.fields); + this.fields = new Object2LongOpenHashMap<>( timings.fields ); } @Nullable - public Computer getComputer() { + public Computer getComputer() + { return this.computer.get(); } - public int getComputerId() { + public int getComputerId() + { return this.computerId; } - public long getTasks() { + public long getTasks() + { return this.tasks; } - public long getTotalTime() { + public long getTotalTime() + { return this.totalTime; } - public long getMaxTime() { + public long getMaxTime() + { return this.maxTime; } - public long getAverage() { + public long getAverage() + { return this.totalTime / this.tasks; } - void addTaskTiming(long time) { + void addTaskTiming( long time ) + { this.tasks++; this.totalTime += time; - if (time > this.maxTime) { + if( time > this.maxTime ) + { this.maxTime = time; } } - void addMainTiming(long time) { + void addMainTiming( long time ) + { this.serverCount++; this.serverTime += time; } - void addValue(TrackingField field, long change) { - synchronized (this.fields) { - this.fields.addTo(field, change); + void addValue( TrackingField field, long change ) + { + synchronized( this.fields ) + { + this.fields.addTo( field, change ); } } - public String getFormatted(TrackingField field) { - return field.format(this.get(field)); + public String getFormatted( TrackingField field ) + { + return field.format( this.get( field ) ); } - public long get(TrackingField field) { - if (field == TrackingField.TASKS) { + public long get( TrackingField field ) + { + if( field == TrackingField.TASKS ) + { return this.tasks; } - if (field == TrackingField.MAX_TIME) { + if( field == TrackingField.MAX_TIME ) + { return this.maxTime; } - if (field == TrackingField.TOTAL_TIME) { + if( field == TrackingField.TOTAL_TIME ) + { return this.totalTime; } - if (field == TrackingField.AVERAGE_TIME) { + if( field == TrackingField.AVERAGE_TIME ) + { return this.tasks == 0 ? 0 : this.totalTime / this.tasks; } - if (field == TrackingField.SERVER_COUNT) { + if( field == TrackingField.SERVER_COUNT ) + { return this.serverCount; } - if (field == TrackingField.SERVER_TIME) { + if( field == TrackingField.SERVER_TIME ) + { return this.serverTime; } - synchronized (this.fields) { - return this.fields.getLong(field); + synchronized( this.fields ) + { + return this.fields.getLong( field ); } } } diff --git a/src/main/java/dan200/computercraft/core/tracking/Tracker.java b/src/main/java/dan200/computercraft/core/tracking/Tracker.java index 7daf006af..fd9220c9e 100644 --- a/src/main/java/dan200/computercraft/core/tracking/Tracker.java +++ b/src/main/java/dan200/computercraft/core/tracking/Tracker.java @@ -8,16 +8,18 @@ package dan200.computercraft.core.tracking; import dan200.computercraft.core.computer.Computer; -public interface Tracker { +public interface Tracker +{ /** * Report how long a task executed on the computer thread took. * * Computer thread tasks include events or a computer being turned on/off. * * @param computer The computer processing this task - * @param time The time taken for this task. + * @param time The time taken for this task. */ - default void addTaskTiming(Computer computer, long time) { + default void addTaskTiming( Computer computer, long time ) + { } /** @@ -26,9 +28,10 @@ public interface Tracker { * Server tasks include actions performed by peripherals. * * @param computer The computer processing this task - * @param time The time taken for this task. + * @param time The time taken for this task. */ - default void addServerTiming(Computer computer, long time) { + default void addServerTiming( Computer computer, long time ) + { } /** @@ -36,9 +39,10 @@ public interface Tracker { * "average". * * @param computer The computer to increment - * @param field The field to increment. - * @param change The amount to increment said field by. + * @param field The field to increment. + * @param change The amount to increment said field by. */ - default void addValue(Computer computer, TrackingField field, long change) { + default void addValue( Computer computer, TrackingField field, long change ) + { } } diff --git a/src/main/java/dan200/computercraft/core/tracking/Tracking.java b/src/main/java/dan200/computercraft/core/tracking/Tracking.java index 34e826900..01347f294 100644 --- a/src/main/java/dan200/computercraft/core/tracking/Tracking.java +++ b/src/main/java/dan200/computercraft/core/tracking/Tracking.java @@ -6,16 +6,17 @@ package dan200.computercraft.core.tracking; +import dan200.computercraft.core.computer.Computer; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; -import dan200.computercraft.core.computer.Computer; - -public final class Tracking { - static final AtomicInteger tracking = new AtomicInteger(0); +public final class Tracking +{ + static final AtomicInteger tracking = new AtomicInteger( 0 ); private static final Object lock = new Object(); private static final HashMap contexts = new HashMap<>(); @@ -23,73 +24,95 @@ public final class Tracking { private Tracking() {} - public static TrackingContext getContext(UUID uuid) { - synchronized (lock) { - TrackingContext context = contexts.get(uuid); - if (context == null) { - contexts.put(uuid, context = new TrackingContext()); + public static TrackingContext getContext( UUID uuid ) + { + synchronized( lock ) + { + TrackingContext context = contexts.get( uuid ); + if( context == null ) + { + contexts.put( uuid, context = new TrackingContext() ); } return context; } } - public static void add(Tracker tracker) { - synchronized (lock) { - trackers.add(tracker); + public static void add( Tracker tracker ) + { + synchronized( lock ) + { + trackers.add( tracker ); tracking.incrementAndGet(); } } - public static void addTaskTiming(Computer computer, long time) { - if (tracking.get() == 0) { + public static void addTaskTiming( Computer computer, long time ) + { + if( tracking.get() == 0 ) + { return; } - synchronized (contexts) { - for (TrackingContext context : contexts.values()) { - context.addTaskTiming(computer, time); + synchronized( contexts ) + { + for( TrackingContext context : contexts.values() ) + { + context.addTaskTiming( computer, time ); } - for (Tracker tracker : trackers) { - tracker.addTaskTiming(computer, time); + for( Tracker tracker : trackers ) + { + tracker.addTaskTiming( computer, time ); } } } - public static void addServerTiming(Computer computer, long time) { - if (tracking.get() == 0) { + public static void addServerTiming( Computer computer, long time ) + { + if( tracking.get() == 0 ) + { return; } - synchronized (contexts) { - for (TrackingContext context : contexts.values()) { - context.addServerTiming(computer, time); + synchronized( contexts ) + { + for( TrackingContext context : contexts.values() ) + { + context.addServerTiming( computer, time ); } - for (Tracker tracker : trackers) { - tracker.addServerTiming(computer, time); + for( Tracker tracker : trackers ) + { + tracker.addServerTiming( computer, time ); } } } - public static void addValue(Computer computer, TrackingField field, long change) { - if (tracking.get() == 0) { + public static void addValue( Computer computer, TrackingField field, long change ) + { + if( tracking.get() == 0 ) + { return; } - synchronized (lock) { - for (TrackingContext context : contexts.values()) { - context.addValue(computer, field, change); + synchronized( lock ) + { + for( TrackingContext context : contexts.values() ) + { + context.addValue( computer, field, change ); } - for (Tracker tracker : trackers) { - tracker.addValue(computer, field, change); + for( Tracker tracker : trackers ) + { + tracker.addValue( computer, field, change ); } } } - public static void reset() { - synchronized (lock) { + public static void reset() + { + synchronized( lock ) + { contexts.clear(); trackers.clear(); - tracking.set(0); + tracking.set( 0 ); } } } diff --git a/src/main/java/dan200/computercraft/core/tracking/TrackingContext.java b/src/main/java/dan200/computercraft/core/tracking/TrackingContext.java index b8bcfb81a..24d448061 100644 --- a/src/main/java/dan200/computercraft/core/tracking/TrackingContext.java +++ b/src/main/java/dan200/computercraft/core/tracking/TrackingContext.java @@ -6,26 +6,29 @@ package dan200.computercraft.core.tracking; +import com.google.common.collect.MapMaker; +import dan200.computercraft.core.computer.Computer; + import java.util.ArrayList; import java.util.List; import java.util.Map; -import com.google.common.collect.MapMaker; -import dan200.computercraft.core.computer.Computer; - /** * Tracks timing information about computers, including how long they ran for and the number of events they handled. * * Note that this will track computers which have been deleted (hence the presence of {@link #timingLookup} and {@link #timings} */ -public class TrackingContext implements Tracker { +public class TrackingContext implements Tracker +{ private final List timings = new ArrayList<>(); private final Map timingLookup = new MapMaker().weakKeys() - .makeMap(); + .makeMap(); private boolean tracking = false; - public synchronized void start() { - if (!this.tracking) { + public synchronized void start() + { + if( !this.tracking ) + { Tracking.tracking.incrementAndGet(); } this.tracking = true; @@ -34,8 +37,10 @@ public class TrackingContext implements Tracker { this.timingLookup.clear(); } - public synchronized boolean stop() { - if (!this.tracking) { + public synchronized boolean stop() + { + if( !this.tracking ) + { return false; } @@ -45,69 +50,84 @@ public class TrackingContext implements Tracker { return true; } - public synchronized List getImmutableTimings() { - ArrayList timings = new ArrayList<>(this.timings.size()); - for (ComputerTracker timing : this.timings) { - timings.add(new ComputerTracker(timing)); + public synchronized List getImmutableTimings() + { + ArrayList timings = new ArrayList<>( this.timings.size() ); + for( ComputerTracker timing : this.timings ) + { + timings.add( new ComputerTracker( timing ) ); } return timings; } - public synchronized List getTimings() { - return new ArrayList<>(this.timings); + public synchronized List getTimings() + { + return new ArrayList<>( this.timings ); } @Override - public void addTaskTiming(Computer computer, long time) { - if (!this.tracking) { + public void addTaskTiming( Computer computer, long time ) + { + if( !this.tracking ) + { return; } - synchronized (this) { - ComputerTracker computerTimings = this.timingLookup.get(computer); - if (computerTimings == null) { - computerTimings = new ComputerTracker(computer); - this.timingLookup.put(computer, computerTimings); - this.timings.add(computerTimings); + synchronized( this ) + { + ComputerTracker computerTimings = this.timingLookup.get( computer ); + if( computerTimings == null ) + { + computerTimings = new ComputerTracker( computer ); + this.timingLookup.put( computer, computerTimings ); + this.timings.add( computerTimings ); } - computerTimings.addTaskTiming(time); + computerTimings.addTaskTiming( time ); } } @Override - public void addServerTiming(Computer computer, long time) { - if (!this.tracking) { + public void addServerTiming( Computer computer, long time ) + { + if( !this.tracking ) + { return; } - synchronized (this) { - ComputerTracker computerTimings = this.timingLookup.get(computer); - if (computerTimings == null) { - computerTimings = new ComputerTracker(computer); - this.timingLookup.put(computer, computerTimings); - this.timings.add(computerTimings); + synchronized( this ) + { + ComputerTracker computerTimings = this.timingLookup.get( computer ); + if( computerTimings == null ) + { + computerTimings = new ComputerTracker( computer ); + this.timingLookup.put( computer, computerTimings ); + this.timings.add( computerTimings ); } - computerTimings.addMainTiming(time); + computerTimings.addMainTiming( time ); } } @Override - public void addValue(Computer computer, TrackingField field, long change) { - if (!this.tracking) { + public void addValue( Computer computer, TrackingField field, long change ) + { + if( !this.tracking ) + { return; } - synchronized (this) { - ComputerTracker computerTimings = this.timingLookup.get(computer); - if (computerTimings == null) { - computerTimings = new ComputerTracker(computer); - this.timingLookup.put(computer, computerTimings); - this.timings.add(computerTimings); + synchronized( this ) + { + ComputerTracker computerTimings = this.timingLookup.get( computer ); + if( computerTimings == null ) + { + computerTimings = new ComputerTracker( computer ); + this.timingLookup.put( computer, computerTimings ); + this.timings.add( computerTimings ); } - computerTimings.addValue(field, change); + computerTimings.addValue( field, change ); } } } diff --git a/src/main/java/dan200/computercraft/core/tracking/TrackingField.java b/src/main/java/dan200/computercraft/core/tracking/TrackingField.java index d4e9ef17b..2ffd29d78 100644 --- a/src/main/java/dan200/computercraft/core/tracking/TrackingField.java +++ b/src/main/java/dan200/computercraft/core/tracking/TrackingField.java @@ -11,77 +11,88 @@ import java.util.HashMap; import java.util.Map; import java.util.function.LongFunction; -public final class TrackingField { +public final class TrackingField +{ private static final Map fields = new HashMap<>(); - public static final TrackingField TASKS = TrackingField.of("tasks", x -> String.format("%4d", x)); - public static final TrackingField TOTAL_TIME = TrackingField.of("total", x -> String.format("%7.1fms", x / 1e6)); - public static final TrackingField AVERAGE_TIME = TrackingField.of("average", x -> String.format("%4.1fms", x / 1e6)); - public static final TrackingField MAX_TIME = TrackingField.of("max", x -> String.format("%5.1fms", x / 1e6)); + public static final TrackingField TASKS = TrackingField.of( "tasks", x -> String.format( "%4d", x ) ); + public static final TrackingField TOTAL_TIME = TrackingField.of( "total", x -> String.format( "%7.1fms", x / 1e6 ) ); + public static final TrackingField AVERAGE_TIME = TrackingField.of( "average", x -> String.format( "%4.1fms", x / 1e6 ) ); + public static final TrackingField MAX_TIME = TrackingField.of( "max", x -> String.format( "%5.1fms", x / 1e6 ) ); - public static final TrackingField SERVER_COUNT = TrackingField.of("server_count", x -> String.format("%4d", x)); - public static final TrackingField SERVER_TIME = TrackingField.of("server_time", x -> String.format("%7.1fms", x / 1e6)); + public static final TrackingField SERVER_COUNT = TrackingField.of( "server_count", x -> String.format( "%4d", x ) ); + public static final TrackingField SERVER_TIME = TrackingField.of( "server_time", x -> String.format( "%7.1fms", x / 1e6 ) ); - public static final TrackingField PERIPHERAL_OPS = TrackingField.of("peripheral", TrackingField::formatDefault); - public static final TrackingField FS_OPS = TrackingField.of("fs", TrackingField::formatDefault); - public static final TrackingField TURTLE_OPS = TrackingField.of("turtle", TrackingField::formatDefault); + public static final TrackingField PERIPHERAL_OPS = TrackingField.of( "peripheral", TrackingField::formatDefault ); + public static final TrackingField FS_OPS = TrackingField.of( "fs", TrackingField::formatDefault ); + public static final TrackingField TURTLE_OPS = TrackingField.of( "turtle", TrackingField::formatDefault ); - public static final TrackingField HTTP_REQUESTS = TrackingField.of("http", TrackingField::formatDefault); - public static final TrackingField COROUTINES_CREATED = TrackingField.of("coroutines_created", x -> String.format("%4d", x)); - public static final TrackingField COROUTINES_DISPOSED = TrackingField.of("coroutines_dead", x -> String.format("%4d", x)); + public static final TrackingField HTTP_REQUESTS = TrackingField.of( "http", TrackingField::formatDefault ); + public static final TrackingField COROUTINES_CREATED = TrackingField.of( "coroutines_created", x -> String.format( "%4d", x ) ); + public static final TrackingField COROUTINES_DISPOSED = TrackingField.of( "coroutines_dead", x -> String.format( "%4d", x ) ); /** * So technically a kibibyte, but let's not argue here. */ private static final int KILOBYTE_SIZE = 1024; private static final String SI_PREFIXES = "KMGT"; - public static final TrackingField HTTP_UPLOAD = TrackingField.of("http_upload", TrackingField::formatBytes); - public static final TrackingField HTTP_DOWNLOAD = TrackingField.of("http_download", TrackingField::formatBytes); - public static final TrackingField WEBSOCKET_INCOMING = TrackingField.of("websocket_incoming", TrackingField::formatBytes); - public static final TrackingField WEBSOCKET_OUTGOING = TrackingField.of("websocket_outgoing", TrackingField::formatBytes); + public static final TrackingField HTTP_UPLOAD = TrackingField.of( "http_upload", TrackingField::formatBytes ); + public static final TrackingField HTTP_DOWNLOAD = TrackingField.of( "http_download", TrackingField::formatBytes ); + public static final TrackingField WEBSOCKET_INCOMING = TrackingField.of( "websocket_incoming", TrackingField::formatBytes ); + public static final TrackingField WEBSOCKET_OUTGOING = TrackingField.of( "websocket_outgoing", TrackingField::formatBytes ); private final String id; private final String translationKey; private final LongFunction format; - private TrackingField(String id, LongFunction format) { + private TrackingField( String id, LongFunction format ) + { this.id = id; this.translationKey = "tracking_field.computercraft." + id + ".name"; this.format = format; } - public static TrackingField of(String id, LongFunction format) { - TrackingField field = new TrackingField(id, format); - fields.put(id, field); + public static TrackingField of( String id, LongFunction format ) + { + TrackingField field = new TrackingField( id, format ); + fields.put( id, field ); return field; } - public static Map fields() { - return Collections.unmodifiableMap(fields); + public static Map fields() + { + return Collections.unmodifiableMap( fields ); } - private static String formatDefault(long value) { - return String.format("%6d", value); + private static String formatDefault( long value ) + { + return String.format( "%6d", value ); } - private static String formatBytes(long bytes) { - if (bytes < 1024) { - return String.format("%10d B", bytes); + private static String formatBytes( long bytes ) + { + if( bytes < 1024 ) + { + return String.format( "%10d B", bytes ); } - int exp = (int) (Math.log(bytes) / Math.log(KILOBYTE_SIZE)); - if (exp > SI_PREFIXES.length()) { + int exp = (int) (Math.log( bytes ) / Math.log( KILOBYTE_SIZE )); + if( exp > SI_PREFIXES.length() ) + { exp = SI_PREFIXES.length(); } - return String.format("%10.1f %siB", bytes / Math.pow(KILOBYTE_SIZE, exp), SI_PREFIXES.charAt(exp - 1)); + return String.format( "%10.1f %siB", bytes / Math.pow( KILOBYTE_SIZE, exp ), SI_PREFIXES.charAt( exp - 1 ) ); } - public String id() { + public String id() + { return this.id; } - public String translationKey() { + public String translationKey() + { return this.translationKey; } - public String format(long value) { - return this.format.apply(value); + public String format( long value ) + { + return this.format.apply( value ); } } diff --git a/src/main/java/dan200/computercraft/fabric/events/ClientUnloadWorldEvent.java b/src/main/java/dan200/computercraft/fabric/events/ClientUnloadWorldEvent.java index 946c07f4d..ce687d947 100644 --- a/src/main/java/dan200/computercraft/fabric/events/ClientUnloadWorldEvent.java +++ b/src/main/java/dan200/computercraft/fabric/events/ClientUnloadWorldEvent.java @@ -13,10 +13,11 @@ public interface ClientUnloadWorldEvent { Event EVENT = EventFactory.createArrayBacked( ClientUnloadWorldEvent.class, callbacks -> () -> { - for( ClientUnloadWorldEvent callback : callbacks) { + for( ClientUnloadWorldEvent callback : callbacks ) + { callback.onClientUnloadWorld(); } - }); + } ); void onClientUnloadWorld(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/AffineTransformationAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/AffineTransformationAccess.java index c1cfb8d0a..8ddc8dbdc 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/AffineTransformationAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/AffineTransformationAccess.java @@ -5,21 +5,21 @@ */ package dan200.computercraft.fabric.mixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - import net.minecraft.client.util.math.AffineTransformation; import net.minecraft.client.util.math.Vector3f; import net.minecraft.util.math.Quaternion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; -@Mixin (AffineTransformation.class) -public interface AffineTransformationAccess { - @Accessor - Vector3f getTranslation(); +@Mixin( AffineTransformation.class ) +public interface AffineTransformationAccess +{ + @Accessor + Vector3f getTranslation(); - @Accessor - Vector3f getScale(); + @Accessor + Vector3f getScale(); - @Accessor - Quaternion getRotation1(); + @Accessor + Quaternion getRotation1(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/BakedQuadAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/BakedQuadAccess.java index 9759c7016..fa7541eca 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/BakedQuadAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/BakedQuadAccess.java @@ -5,14 +5,14 @@ */ package dan200.computercraft.fabric.mixin; +import net.minecraft.client.render.model.BakedQuad; +import net.minecraft.client.texture.Sprite; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.client.render.model.BakedQuad; -import net.minecraft.client.texture.Sprite; - -@Mixin (BakedQuad.class) -public interface BakedQuadAccess { - @Accessor - Sprite getSprite(); +@Mixin( BakedQuad.class ) +public interface BakedQuadAccess +{ + @Accessor + Sprite getSprite(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/ChatHudAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/ChatHudAccess.java index b9c44bc9c..9d86ea657 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/ChatHudAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/ChatHudAccess.java @@ -5,17 +5,17 @@ */ package dan200.computercraft.fabric.mixin; +import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; -import net.minecraft.client.gui.hud.ChatHud; -import net.minecraft.text.Text; - -@Mixin (ChatHud.class) -public interface ChatHudAccess { - @Invoker - void callAddMessage(Text text, int messageId); +@Mixin( ChatHud.class ) +public interface ChatHudAccess +{ + @Invoker + void callAddMessage( Text text, int messageId ); @Invoker - void callRemoveMessage(int messageId); + void callRemoveMessage( int messageId ); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/HeldItemRendererAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/HeldItemRendererAccess.java index f5224cecd..a799fdf3a 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/HeldItemRendererAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/HeldItemRendererAccess.java @@ -5,22 +5,22 @@ */ package dan200.computercraft.fabric.mixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.item.HeldItemRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Arm; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; -@Mixin (HeldItemRenderer.class) -public interface HeldItemRendererAccess { - @Invoker - float callGetMapAngle(float tickDelta); +@Mixin( HeldItemRenderer.class ) +public interface HeldItemRendererAccess +{ + @Invoker + float callGetMapAngle( float tickDelta ); - @Invoker - void callRenderArm(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, Arm arm); + @Invoker + void callRenderArm( MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, Arm arm ); - @Invoker - void callRenderArmHoldingItem(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm); + @Invoker + void callRenderArmHoldingItem( MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm ); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MinecraftServerAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/MinecraftServerAccess.java index 022e55569..8ce40b911 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MinecraftServerAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MinecraftServerAccess.java @@ -5,14 +5,14 @@ */ package dan200.computercraft.fabric.mixin; +import net.minecraft.resource.ServerResourceManager; +import net.minecraft.server.MinecraftServer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.resource.ServerResourceManager; -import net.minecraft.server.MinecraftServer; - -@Mixin (MinecraftServer.class) -public interface MinecraftServerAccess { - @Accessor - ServerResourceManager getServerResourceManager(); +@Mixin( MinecraftServer.class ) +public interface MinecraftServerAccess +{ + @Accessor + ServerResourceManager getServerResourceManager(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinBlock.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinBlock.java index c758b5935..0dd5c35f1 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinBlock.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinBlock.java @@ -6,26 +6,28 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.shared.util.DropConsumer; +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.block.Block; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - /** * @see Block#dropStack(World, BlockPos, ItemStack) */ -@Mixin (Block.class) -public class MixinBlock { - @Inject (method = "dropStack", - at = @At (value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z"), - cancellable = true) - private static void dropStack(World world, BlockPos pos, ItemStack stack, CallbackInfo callbackInfo) { - if (DropConsumer.onHarvestDrops(world, pos, stack)) { +@Mixin( Block.class ) +public class MixinBlock +{ + @Inject( method = "dropStack", + at = @At( value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" ), + cancellable = true ) + private static void dropStack( World world, BlockPos pos, ItemStack stack, CallbackInfo callbackInfo ) + { + if( DropConsumer.onHarvestDrops( world, pos, stack ) ) + { callbackInfo.cancel(); } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinEntity.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinEntity.java index a9835de87..baee509b6 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinEntity.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinEntity.java @@ -6,26 +6,28 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.shared.util.DropConsumer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.ItemEntity; +import net.minecraft.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.item.ItemStack; - /** * @see Entity#dropStack(ItemStack, float) */ -@Mixin (Entity.class) -public class MixinEntity { - @Inject (method = "dropStack(Lnet/minecraft/item/ItemStack;F)Lnet/minecraft/entity/ItemEntity;", - at = @At (value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z"), - cancellable = true) - public void dropStack(ItemStack stack, float height, CallbackInfoReturnable callbackInfo) { - if (DropConsumer.onLivingDrops((Entity) (Object) this, stack)) { - callbackInfo.setReturnValue(null); +@Mixin( Entity.class ) +public class MixinEntity +{ + @Inject( method = "dropStack(Lnet/minecraft/item/ItemStack;F)Lnet/minecraft/entity/ItemEntity;", + at = @At( value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" ), + cancellable = true ) + public void dropStack( ItemStack stack, float height, CallbackInfoReturnable callbackInfo ) + { + if( DropConsumer.onLivingDrops( (Entity) (Object) this, stack ) ) + { + callbackInfo.setReturnValue( null ); } } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinHeldItemRenderer.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinHeldItemRenderer.java index dfc91c6f5..675ecbaff 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinHeldItemRenderer.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinHeldItemRenderer.java @@ -9,12 +9,8 @@ import dan200.computercraft.client.render.ItemPocketRenderer; import dan200.computercraft.client.render.ItemPrintoutRenderer; import dan200.computercraft.shared.media.items.ItemPrintout; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.item.HeldItemRenderer; @@ -22,36 +18,45 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.util.Arm; import net.minecraft.util.Hand; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Mixin (HeldItemRenderer.class) -@Environment (EnvType.CLIENT) -public class MixinHeldItemRenderer { +@Mixin( HeldItemRenderer.class ) +@Environment( EnvType.CLIENT ) +public class MixinHeldItemRenderer +{ @Shadow - private void renderArmHoldingItem(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, - Arm arm) { + private void renderArmHoldingItem( MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, + Arm arm ) + { } @Shadow - private float getMapAngle(float pitch) { + private float getMapAngle( float pitch ) + { return 0; } - @Inject (method = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderFirstPersonItem(Lnet/minecraft/client/network/AbstractClientPlayerEntity;" + - "FFLnet/minecraft/util/Hand;FLnet/minecraft/item/ItemStack;FLnet/minecraft/client/util/math/MatrixStack;" + - "Lnet/minecraft/client/render/VertexConsumerProvider;I)V", - at = @At ("HEAD"), - cancellable = true) - public void renderFirstPersonItem_Injected(AbstractClientPlayerEntity player, float var2, float pitch, Hand hand, float swingProgress, - ItemStack stack, float equipProgress, MatrixStack matrixStack, VertexConsumerProvider provider, int light, - CallbackInfo callback) { - if (stack.getItem() instanceof ItemPrintout) { - ItemPrintoutRenderer.INSTANCE.renderItemFirstPerson(matrixStack, provider, light, hand, pitch, equipProgress, swingProgress, stack); + @Inject( method = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderFirstPersonItem(Lnet/minecraft/client/network/AbstractClientPlayerEntity;" + + "FFLnet/minecraft/util/Hand;FLnet/minecraft/item/ItemStack;FLnet/minecraft/client/util/math/MatrixStack;" + + "Lnet/minecraft/client/render/VertexConsumerProvider;I)V", + at = @At( "HEAD" ), + cancellable = true ) + public void renderFirstPersonItem_Injected( AbstractClientPlayerEntity player, float var2, float pitch, Hand hand, float swingProgress, + ItemStack stack, float equipProgress, MatrixStack matrixStack, VertexConsumerProvider provider, int light, + CallbackInfo callback ) + { + if( stack.getItem() instanceof ItemPrintout ) + { + ItemPrintoutRenderer.INSTANCE.renderItemFirstPerson( matrixStack, provider, light, hand, pitch, equipProgress, swingProgress, stack ); callback.cancel(); - } else if (stack.getItem() instanceof ItemPocketComputer) { - ItemPocketRenderer.INSTANCE.renderItemFirstPerson(matrixStack, provider, light, hand, pitch, equipProgress, swingProgress, stack); + } + else if( stack.getItem() instanceof ItemPocketComputer ) + { + ItemPocketRenderer.INSTANCE.renderItemFirstPerson( matrixStack, provider, light, hand, pitch, equipProgress, swingProgress, stack ); callback.cancel(); } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinItemFrameEntityRenderer.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinItemFrameEntityRenderer.java index 07bef1555..a63706f37 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinItemFrameEntityRenderer.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinItemFrameEntityRenderer.java @@ -7,29 +7,30 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.client.render.ItemPrintoutRenderer; import dan200.computercraft.shared.media.items.ItemPrintout; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.ItemFrameEntityRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Mixin (ItemFrameEntityRenderer.class) -@Environment (EnvType.CLIENT) -public class MixinItemFrameEntityRenderer { - @Inject (method = "render", at = @At ("HEAD"), cancellable = true) - private void renderItem_Injected(ItemFrameEntity itemFrameEntity, float f, float g, MatrixStack matrixStack, - VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo info) { +@Mixin( ItemFrameEntityRenderer.class ) +@Environment( EnvType.CLIENT ) +public class MixinItemFrameEntityRenderer +{ + @Inject( method = "render", at = @At( "HEAD" ), cancellable = true ) + private void renderItem_Injected( ItemFrameEntity itemFrameEntity, float f, float g, MatrixStack matrixStack, + VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo info ) + { ItemStack stack = itemFrameEntity.getHeldItemStack(); - if (stack.getItem() instanceof ItemPrintout) { - ItemPrintoutRenderer.INSTANCE.renderInFrame(matrixStack, vertexConsumerProvider, stack); + if( stack.getItem() instanceof ItemPrintout ) + { + ItemPrintoutRenderer.INSTANCE.renderInFrame( matrixStack, vertexConsumerProvider, stack ); info.cancel(); } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinMinecraftClient.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinMinecraftClient.java index c99fbe55e..8539fc6b9 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinMinecraftClient.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinMinecraftClient.java @@ -7,6 +7,7 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.client.FrameInfo; import dan200.computercraft.fabric.events.ClientUnloadWorldEvent; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.world.ClientWorld; import org.spongepowered.asm.mixin.Mixin; @@ -14,23 +15,24 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.MinecraftClient; - -@Mixin (MinecraftClient.class) +@Mixin( MinecraftClient.class ) public abstract class MixinMinecraftClient { - @Inject (method = "render", at = @At ("HEAD")) - private void onRender(CallbackInfo info) { + @Inject( method = "render", at = @At( "HEAD" ) ) + private void onRender( CallbackInfo info ) + { FrameInfo.onRenderFrame(); } - @Inject(method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At ("RETURN")) - private void disconnectAfter(Screen screen, CallbackInfo info) { + @Inject( method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At( "RETURN" ) ) + private void disconnectAfter( Screen screen, CallbackInfo info ) + { ClientUnloadWorldEvent.EVENT.invoker().onClientUnloadWorld(); } - @Inject(method = "joinWorld", at = @At("RETURN")) - private void joinWorldAfter(ClientWorld world, CallbackInfo info) { + @Inject( method = "joinWorld", at = @At( "RETURN" ) ) + private void joinWorldAfter( ClientWorld world, CallbackInfo info ) + { ClientUnloadWorldEvent.EVENT.invoker().onClientUnloadWorld(); } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinScreen.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinScreen.java index 7092a577f..d53ba9939 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinScreen.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinScreen.java @@ -6,22 +6,23 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.shared.command.ClientCommands; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.Screen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.gui.screen.Screen; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Mixin (Screen.class) -@Environment (EnvType.CLIENT) -public class MixinScreen { - @Inject (method = "sendMessage(Ljava/lang/String;Z)V", at = @At ("HEAD"), cancellable = true) - public void sendClientCommand(String message, boolean add, CallbackInfo info) { - if (ClientCommands.onClientSendMessage(message)) { +@Mixin( Screen.class ) +@Environment( EnvType.CLIENT ) +public class MixinScreen +{ + @Inject( method = "sendMessage(Ljava/lang/String;Z)V", at = @At( "HEAD" ), cancellable = true ) + public void sendClientCommand( String message, boolean add, CallbackInfo info ) + { + if( ClientCommands.onClientSendMessage( message ) ) + { info.cancel(); } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinServerPlayerInteractionManager.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinServerPlayerInteractionManager.java index c028dc960..3ca7e4620 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinServerPlayerInteractionManager.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinServerPlayerInteractionManager.java @@ -21,17 +21,21 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(ServerPlayerInteractionManager.class) -public class MixinServerPlayerInteractionManager { - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;copy()Lnet/minecraft/item/ItemStack;", ordinal = 0), method = "interactBlock(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;", cancellable = true) - private void interact(ServerPlayerEntity player, World world, ItemStack stack, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable cir) { +@Mixin( ServerPlayerInteractionManager.class ) +public class MixinServerPlayerInteractionManager +{ + @Inject( at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;copy()Lnet/minecraft/item/ItemStack;", ordinal = 0 ), method = "interactBlock(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;", cancellable = true ) + private void interact( ServerPlayerEntity player, World world, ItemStack stack, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable cir ) + { BlockPos pos = hitResult.getBlockPos(); - BlockState state = world.getBlockState(pos); - if (player.getMainHandStack().getItem() == ComputerCraftRegistry.ModItems.DISK && state.getBlock() == ComputerCraftRegistry.ModBlocks.DISK_DRIVE) { - ActionResult actionResult = state.onUse(world, player, hand, hitResult); - if (actionResult.isAccepted()) { - Criteria.ITEM_USED_ON_BLOCK.test(player, pos, stack); - cir.setReturnValue(actionResult); + BlockState state = world.getBlockState( pos ); + if( player.getMainHandStack().getItem() == ComputerCraftRegistry.ModItems.DISK && state.getBlock() == ComputerCraftRegistry.ModBlocks.DISK_DRIVE ) + { + ActionResult actionResult = state.onUse( world, player, hand, hitResult ); + if( actionResult.isAccepted() ) + { + Criteria.ITEM_USED_ON_BLOCK.test( player, pos, stack ); + cir.setReturnValue( actionResult ); } } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinServerWorld.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinServerWorld.java index b392f0bff..ab08f7b2e 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinServerWorld.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinServerWorld.java @@ -6,23 +6,25 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.shared.util.DropConsumer; +import net.minecraft.entity.Entity; +import net.minecraft.server.world.ServerWorld; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import net.minecraft.entity.Entity; -import net.minecraft.server.world.ServerWorld; - /** * @see ServerWorld#spawnEntity(Entity) */ -@Mixin (ServerWorld.class) -public class MixinServerWorld { - @Inject (method = "spawnEntity", at = @At ("HEAD"), cancellable = true) - public void spawnEntity(Entity entity, CallbackInfoReturnable callbackInfo) { - if (DropConsumer.onEntitySpawn(entity)) { - callbackInfo.setReturnValue(false); +@Mixin( ServerWorld.class ) +public class MixinServerWorld +{ + @Inject( method = "spawnEntity", at = @At( "HEAD" ), cancellable = true ) + public void spawnEntity( Entity entity, CallbackInfoReturnable callbackInfo ) + { + if( DropConsumer.onEntitySpawn( entity ) ) + { + callbackInfo.setReturnValue( false ); } } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinWorld.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinWorld.java index ef8d1745f..c4fba913c 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinWorld.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinWorld.java @@ -5,48 +5,55 @@ */ package dan200.computercraft.fabric.mixin; -import java.util.Collection; - -import javax.annotation.Nullable; - import dan200.computercraft.shared.common.TileGeneric; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import javax.annotation.Nullable; +import java.util.Collection; /** * Horrible bodge to ensure a {@link BlockEntity}'s world is always present when setting a TE during another TE's tick. * * Forge does this, this is just a bodge to get Fabric in line with that behaviour. */ -@Mixin (World.class) -public class MixinWorld { - @Shadow protected boolean iteratingTickingBlockEntities; +@Mixin( World.class ) +public class MixinWorld +{ + @Shadow + protected boolean iteratingTickingBlockEntities; - @Inject (method = "setBlockEntity", at = @At ("HEAD")) - public void setBlockEntity(BlockPos pos, @Nullable BlockEntity entity, CallbackInfo info) { - if (!World.isOutOfBuildLimitVertically(pos) && entity != null && !entity.isRemoved() && this.iteratingTickingBlockEntities) { - setWorld(entity, this); + @Inject( method = "setBlockEntity", at = @At( "HEAD" ) ) + public void setBlockEntity( BlockPos pos, @Nullable BlockEntity entity, CallbackInfo info ) + { + if( !World.isOutOfBuildLimitVertically( pos ) && entity != null && !entity.isRemoved() && this.iteratingTickingBlockEntities ) + { + setWorld( entity, this ); } } - private static void setWorld(BlockEntity entity, Object world) { - if (entity.getWorld() != world && entity instanceof TileGeneric) { - entity.setLocation((World) world, entity.getPos()); + private static void setWorld( BlockEntity entity, Object world ) + { + if( entity.getWorld() != world && entity instanceof TileGeneric ) + { + entity.setLocation( (World) world, entity.getPos() ); } } - @Inject (method = "addBlockEntities", at = @At ("HEAD")) - public void addBlockEntities(Collection entities, CallbackInfo info) { - if (this.iteratingTickingBlockEntities) { - for (BlockEntity entity : entities) { - setWorld(entity, this); + @Inject( method = "addBlockEntities", at = @At( "HEAD" ) ) + public void addBlockEntities( Collection entities, CallbackInfo info ) + { + if( this.iteratingTickingBlockEntities ) + { + for( BlockEntity entity : entities ) + { + setWorld( entity, this ); } } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MixinWorldRenderer.java b/src/main/java/dan200/computercraft/fabric/mixin/MixinWorldRenderer.java index a65769185..fc16eb218 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MixinWorldRenderer.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MixinWorldRenderer.java @@ -7,42 +7,43 @@ package dan200.computercraft.fabric.mixin; import dan200.computercraft.client.render.CableHighlightRenderer; import dan200.computercraft.client.render.MonitorHighlightRenderer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Mixin (WorldRenderer.class) -@Environment (EnvType.CLIENT) -public class MixinWorldRenderer { - @Inject (method = "drawBlockOutline", cancellable = true, at = @At ("HEAD")) - public void drawBlockOutline(MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double d, double e, double f, BlockPos blockPos, - BlockState blockState, CallbackInfo info) { - if (CableHighlightRenderer.drawHighlight(matrixStack, - vertexConsumer, - entity, - d, - e, - f, - blockPos, - blockState) || MonitorHighlightRenderer.drawHighlight(matrixStack, - vertexConsumer, - entity, - d, - e, - f, - blockPos, - blockState)) { +@Mixin( WorldRenderer.class ) +@Environment( EnvType.CLIENT ) +public class MixinWorldRenderer +{ + @Inject( method = "drawBlockOutline", cancellable = true, at = @At( "HEAD" ) ) + public void drawBlockOutline( MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double d, double e, double f, BlockPos blockPos, + BlockState blockState, CallbackInfo info ) + { + if( CableHighlightRenderer.drawHighlight( matrixStack, + vertexConsumer, + entity, + d, + e, + f, + blockPos, + blockState ) || MonitorHighlightRenderer.drawHighlight( matrixStack, + vertexConsumer, + entity, + d, + e, + f, + blockPos, + blockState ) ) + { info.cancel(); } } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/MusicDiscItemAccessor.java b/src/main/java/dan200/computercraft/fabric/mixin/MusicDiscItemAccessor.java index dc41422ba..58a9fc4c8 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/MusicDiscItemAccessor.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/MusicDiscItemAccessor.java @@ -10,8 +10,9 @@ import net.minecraft.sound.SoundEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -@Mixin(MusicDiscItem.class) -public interface MusicDiscItemAccessor { +@Mixin( MusicDiscItem.class ) +public interface MusicDiscItemAccessor +{ @Accessor SoundEvent getSound(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/SignBlockEntityAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/SignBlockEntityAccess.java index 153f22707..e1aa351da 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/SignBlockEntityAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/SignBlockEntityAccess.java @@ -5,14 +5,14 @@ */ package dan200.computercraft.fabric.mixin; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.text.Text; - -@Mixin (SignBlockEntity.class) -public interface SignBlockEntityAccess { - @Accessor - Text[] getText(); +@Mixin( SignBlockEntity.class ) +public interface SignBlockEntityAccess +{ + @Accessor + Text[] getText(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/SoundEventAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/SoundEventAccess.java index fdaa67d05..87e9c7896 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/SoundEventAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/SoundEventAccess.java @@ -5,14 +5,14 @@ */ package dan200.computercraft.fabric.mixin; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.sound.SoundEvent; -import net.minecraft.util.Identifier; - -@Mixin (SoundEvent.class) -public interface SoundEventAccess { - @Accessor - Identifier getId(); +@Mixin( SoundEvent.class ) +public interface SoundEventAccess +{ + @Accessor + Identifier getId(); } diff --git a/src/main/java/dan200/computercraft/fabric/mixin/WorldSavePathAccess.java b/src/main/java/dan200/computercraft/fabric/mixin/WorldSavePathAccess.java index 798606425..4c78d0161 100644 --- a/src/main/java/dan200/computercraft/fabric/mixin/WorldSavePathAccess.java +++ b/src/main/java/dan200/computercraft/fabric/mixin/WorldSavePathAccess.java @@ -5,13 +5,13 @@ */ package dan200.computercraft.fabric.mixin; +import net.minecraft.util.WorldSavePath; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; -import net.minecraft.util.WorldSavePath; - -@Mixin (WorldSavePath.class) -public interface WorldSavePathAccess { - @Invoker("") - static WorldSavePath createWorldSavePath(String relativePath) { throw new UnsupportedOperationException(); } +@Mixin( WorldSavePath.class ) +public interface WorldSavePathAccess +{ + @Invoker( "" ) + static WorldSavePath createWorldSavePath( String relativePath ) { throw new UnsupportedOperationException(); } } diff --git a/src/main/java/dan200/computercraft/shared/BundledRedstone.java b/src/main/java/dan200/computercraft/shared/BundledRedstone.java index e7f3e629f..8c8be9b79 100644 --- a/src/main/java/dan200/computercraft/shared/BundledRedstone.java +++ b/src/main/java/dan200/computercraft/shared/BundledRedstone.java @@ -6,54 +6,63 @@ package dan200.computercraft.shared; -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider; - import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public final class BundledRedstone { +import javax.annotation.Nonnull; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; + +public final class BundledRedstone +{ private static final Set providers = new LinkedHashSet<>(); private BundledRedstone() {} - public static synchronized void register(@Nonnull IBundledRedstoneProvider provider) { - Objects.requireNonNull(provider, "provider cannot be null"); - providers.add(provider); + public static synchronized void register( @Nonnull IBundledRedstoneProvider provider ) + { + Objects.requireNonNull( provider, "provider cannot be null" ); + providers.add( provider ); } - public static int getDefaultOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side) { - return World.isInBuildLimit(pos) ? DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput(world, pos, side) : -1; + public static int getDefaultOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ) + { + return World.isInBuildLimit( pos ) ? DefaultBundledRedstoneProvider.getDefaultBundledRedstoneOutput( world, pos, side ) : -1; } - public static int getOutput(World world, BlockPos pos, Direction side) { - int signal = getUnmaskedOutput(world, pos, side); + public static int getOutput( World world, BlockPos pos, Direction side ) + { + int signal = getUnmaskedOutput( world, pos, side ); return signal >= 0 ? signal : 0; } - private static int getUnmaskedOutput(World world, BlockPos pos, Direction side) { - if (!World.isInBuildLimit(pos)) { + private static int getUnmaskedOutput( World world, BlockPos pos, Direction side ) + { + if( !World.isInBuildLimit( pos ) ) + { return -1; } // Try the providers in order: int combinedSignal = -1; - for (IBundledRedstoneProvider bundledRedstoneProvider : providers) { - try { - int signal = bundledRedstoneProvider.getBundledRedstoneOutput(world, pos, side); - if (signal >= 0) { + for( IBundledRedstoneProvider bundledRedstoneProvider : providers ) + { + try + { + int signal = bundledRedstoneProvider.getBundledRedstoneOutput( world, pos, side ); + if( signal >= 0 ) + { combinedSignal = combinedSignal < 0 ? signal & 0xffff : combinedSignal | (signal & 0xffff); } - } catch (Exception e) { - ComputerCraft.log.error("Bundled redstone provider " + bundledRedstoneProvider + " errored.", e); + } + catch( Exception e ) + { + ComputerCraft.log.error( "Bundled redstone provider " + bundledRedstoneProvider + " errored.", e ); } } diff --git a/src/main/java/dan200/computercraft/shared/ComputerCraftRegistry.java b/src/main/java/dan200/computercraft/shared/ComputerCraftRegistry.java index 6b7147242..3e45b482f 100644 --- a/src/main/java/dan200/computercraft/shared/ComputerCraftRegistry.java +++ b/src/main/java/dan200/computercraft/shared/ComputerCraftRegistry.java @@ -6,13 +6,6 @@ package dan200.computercraft.shared; -import static net.minecraft.util.registry.Registry.BLOCK_ENTITY_TYPE; - -import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Supplier; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.shared.common.ContainerHeldItem; @@ -29,11 +22,7 @@ import dan200.computercraft.shared.media.items.ItemTreasureDisk; import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive; import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive; import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive; -import dan200.computercraft.shared.peripheral.modem.wired.BlockCable; -import dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull; -import dan200.computercraft.shared.peripheral.modem.wired.ItemBlockCable; -import dan200.computercraft.shared.peripheral.modem.wired.TileCable; -import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull; +import dan200.computercraft.shared.peripheral.modem.wired.*; import dan200.computercraft.shared.peripheral.modem.wireless.BlockWirelessModem; import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem; import dan200.computercraft.shared.peripheral.monitor.BlockMonitor; @@ -54,7 +43,8 @@ import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; import dan200.computercraft.shared.turtle.items.ItemTurtle; import dan200.computercraft.shared.turtle.upgrades.*; import dan200.computercraft.shared.util.FixedPointTileEntityType; - +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; import net.minecraft.block.Blocks; @@ -73,234 +63,258 @@ import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry; -import org.apache.http.client.utils.Idn; +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; -public final class ComputerCraftRegistry { +import static net.minecraft.util.registry.Registry.BLOCK_ENTITY_TYPE; + +public final class ComputerCraftRegistry +{ public static final String MOD_ID = ComputerCraft.MOD_ID; - public static void init() { + public static void init() + { Object[] o = { ModTiles.CABLE, ModBlocks.CABLE, ModItems.CABLE, ModEntities.TURTLE_PLAYER, ModContainers.COMPUTER, - }; + }; TurtleUpgrades.registerTurtleUpgrades(); PocketUpgrades.registerPocketUpgrades(); } - public static final class ModBlocks { - public static final BlockComputer COMPUTER_NORMAL = register("computer_normal", - new BlockComputer(properties(), ComputerFamily.NORMAL, ModTiles.COMPUTER_NORMAL)); - public static final BlockComputer COMPUTER_ADVANCED = register("computer_advanced", - new BlockComputer(properties(), - ComputerFamily.ADVANCED, - ModTiles.COMPUTER_ADVANCED)); - public static final BlockComputer COMPUTER_COMMAND = register("computer_command", - new BlockComputer(FabricBlockSettings.copyOf(Blocks.STONE) - .strength(-1, 6000000.0F), - ComputerFamily.COMMAND, - ModTiles.COMPUTER_COMMAND)); - public static final BlockTurtle TURTLE_NORMAL = register("turtle_normal", - new BlockTurtle(turtleProperties(), ComputerFamily.NORMAL, ModTiles.TURTLE_NORMAL)); - public static final BlockTurtle TURTLE_ADVANCED = register("turtle_advanced", - new BlockTurtle(turtleProperties(), ComputerFamily.ADVANCED, ModTiles.TURTLE_ADVANCED)); - public static final BlockSpeaker SPEAKER = register("speaker", new BlockSpeaker(properties())); - public static final BlockDiskDrive DISK_DRIVE = register("disk_drive", new BlockDiskDrive(properties())); - public static final BlockPrinter PRINTER = register("printer", new BlockPrinter(properties())); - public static final BlockMonitor MONITOR_NORMAL = register("monitor_normal", new BlockMonitor(properties(), ModTiles.MONITOR_NORMAL)); - public static final BlockMonitor MONITOR_ADVANCED = register("monitor_advanced", new BlockMonitor(properties(), ModTiles.MONITOR_ADVANCED)); - public static final BlockWirelessModem WIRELESS_MODEM_NORMAL = register("wireless_modem_normal", - new BlockWirelessModem(properties(), ModTiles.WIRELESS_MODEM_NORMAL)); - public static final BlockWirelessModem WIRELESS_MODEM_ADVANCED = register("wireless_modem_advanced", - new BlockWirelessModem(properties(), ModTiles.WIRELESS_MODEM_ADVANCED)); - public static final BlockWiredModemFull WIRED_MODEM_FULL = register("wired_modem_full", - new BlockWiredModemFull(emProperties(), ModTiles.WIRED_MODEM_FULL)); - public static final BlockCable CABLE = register("cable", new BlockCable(emProperties())); + public static final class ModBlocks + { + public static final BlockComputer COMPUTER_NORMAL = register( "computer_normal", + new BlockComputer( properties(), ComputerFamily.NORMAL, ModTiles.COMPUTER_NORMAL ) ); + public static final BlockComputer COMPUTER_ADVANCED = register( "computer_advanced", + new BlockComputer( properties(), + ComputerFamily.ADVANCED, + ModTiles.COMPUTER_ADVANCED ) ); + public static final BlockComputer COMPUTER_COMMAND = register( "computer_command", + new BlockComputer( FabricBlockSettings.copyOf( Blocks.STONE ) + .strength( -1, 6000000.0F ), + ComputerFamily.COMMAND, + ModTiles.COMPUTER_COMMAND ) ); + public static final BlockTurtle TURTLE_NORMAL = register( "turtle_normal", + new BlockTurtle( turtleProperties(), ComputerFamily.NORMAL, ModTiles.TURTLE_NORMAL ) ); + public static final BlockTurtle TURTLE_ADVANCED = register( "turtle_advanced", + new BlockTurtle( turtleProperties(), ComputerFamily.ADVANCED, ModTiles.TURTLE_ADVANCED ) ); + public static final BlockSpeaker SPEAKER = register( "speaker", new BlockSpeaker( properties() ) ); + public static final BlockDiskDrive DISK_DRIVE = register( "disk_drive", new BlockDiskDrive( properties() ) ); + public static final BlockPrinter PRINTER = register( "printer", new BlockPrinter( properties() ) ); + public static final BlockMonitor MONITOR_NORMAL = register( "monitor_normal", new BlockMonitor( properties(), ModTiles.MONITOR_NORMAL ) ); + public static final BlockMonitor MONITOR_ADVANCED = register( "monitor_advanced", new BlockMonitor( properties(), ModTiles.MONITOR_ADVANCED ) ); + public static final BlockWirelessModem WIRELESS_MODEM_NORMAL = register( "wireless_modem_normal", + new BlockWirelessModem( properties(), ModTiles.WIRELESS_MODEM_NORMAL ) ); + public static final BlockWirelessModem WIRELESS_MODEM_ADVANCED = register( "wireless_modem_advanced", + new BlockWirelessModem( properties(), ModTiles.WIRELESS_MODEM_ADVANCED ) ); + public static final BlockWiredModemFull WIRED_MODEM_FULL = register( "wired_modem_full", + new BlockWiredModemFull( emProperties(), ModTiles.WIRED_MODEM_FULL ) ); + public static final BlockCable CABLE = register( "cable", new BlockCable( emProperties() ) ); - private static Block.Settings properties() { + private static Block.Settings properties() + { //return FabricBlockSettings.copyOf(Blocks.GLASS) - // .strength(2); - return AbstractBlock.Settings.of(Material.GLASS) - .strength(2F) - .sounds(BlockSoundGroup.STONE) + // .strength(2); + return AbstractBlock.Settings.of( Material.GLASS ) + .strength( 2F ) + .sounds( BlockSoundGroup.STONE ) .nonOpaque(); } - private static Block.Settings turtleProperties() { - return FabricBlockSettings.copyOf(Blocks.STONE) - .strength(2.5f); + private static Block.Settings turtleProperties() + { + return FabricBlockSettings.copyOf( Blocks.STONE ) + .strength( 2.5f ); } - private static Block.Settings emProperties() { - return FabricBlockSettings.copyOf(Blocks.STONE) - .strength(1.5f); + private static Block.Settings emProperties() + { + return FabricBlockSettings.copyOf( Blocks.STONE ) + .strength( 1.5f ); } - public static T register(String id, T value) { - return Registry.register(Registry.BLOCK, new Identifier(MOD_ID, id), value); + public static T register( String id, T value ) + { + return Registry.register( Registry.BLOCK, new Identifier( MOD_ID, id ), value ); } } - public static class ModTiles { + public static class ModTiles + { - public static final BlockEntityType MONITOR_NORMAL = ofBlock(() -> ModBlocks.MONITOR_NORMAL, - "monitor_normal", - f -> new TileMonitor(f, false)); - public static final BlockEntityType MONITOR_ADVANCED = ofBlock(() -> ModBlocks.MONITOR_ADVANCED, - "monitor_advanced", - f -> new TileMonitor(f, true)); - public static final BlockEntityType COMPUTER_NORMAL = ofBlock(() -> ModBlocks.COMPUTER_NORMAL, - "computer_normal", - f -> new TileComputer(ComputerFamily.NORMAL, f)); - public static final BlockEntityType COMPUTER_ADVANCED = ofBlock(() -> ModBlocks.COMPUTER_ADVANCED, - "computer_advanced", - f -> new TileComputer(ComputerFamily.ADVANCED, f)); - public static final BlockEntityType COMPUTER_COMMAND = ofBlock(() -> ModBlocks.COMPUTER_COMMAND, - "computer_command", - f -> new TileCommandComputer(ComputerFamily.COMMAND, f)); - public static final BlockEntityType TURTLE_NORMAL = ofBlock(() -> ModBlocks.TURTLE_NORMAL, - "turtle_normal", - f -> new TileTurtle(f, ComputerFamily.NORMAL)); - public static final BlockEntityType TURTLE_ADVANCED = ofBlock(() -> ModBlocks.TURTLE_ADVANCED, - "turtle_advanced", - f -> new TileTurtle(f, ComputerFamily.ADVANCED)); - public static final BlockEntityType SPEAKER = ofBlock(() -> ModBlocks.SPEAKER, "speaker", TileSpeaker::new); - public static final BlockEntityType DISK_DRIVE = ofBlock(() -> ModBlocks.DISK_DRIVE, "disk_drive", TileDiskDrive::new); - public static final BlockEntityType PRINTER = ofBlock(() -> ModBlocks.PRINTER, "printer", TilePrinter::new); - public static final BlockEntityType WIRED_MODEM_FULL = ofBlock(() -> ModBlocks.WIRED_MODEM_FULL, - "wired_modem_full", - TileWiredModemFull::new); - public static final BlockEntityType CABLE = ofBlock(() -> ModBlocks.CABLE, "cable", TileCable::new); - public static final BlockEntityType WIRELESS_MODEM_NORMAL = ofBlock(() -> ModBlocks.WIRELESS_MODEM_NORMAL, - "wireless_modem_normal", - f -> new TileWirelessModem(f, false)); - public static final BlockEntityType WIRELESS_MODEM_ADVANCED = ofBlock(() -> ModBlocks.WIRELESS_MODEM_ADVANCED, - "wireless_modem_advanced", - f -> new TileWirelessModem(f, true)); + public static final BlockEntityType MONITOR_NORMAL = ofBlock( () -> ModBlocks.MONITOR_NORMAL, + "monitor_normal", + f -> new TileMonitor( f, false ) ); + public static final BlockEntityType MONITOR_ADVANCED = ofBlock( () -> ModBlocks.MONITOR_ADVANCED, + "monitor_advanced", + f -> new TileMonitor( f, true ) ); + public static final BlockEntityType COMPUTER_NORMAL = ofBlock( () -> ModBlocks.COMPUTER_NORMAL, + "computer_normal", + f -> new TileComputer( ComputerFamily.NORMAL, f ) ); + public static final BlockEntityType COMPUTER_ADVANCED = ofBlock( () -> ModBlocks.COMPUTER_ADVANCED, + "computer_advanced", + f -> new TileComputer( ComputerFamily.ADVANCED, f ) ); + public static final BlockEntityType COMPUTER_COMMAND = ofBlock( () -> ModBlocks.COMPUTER_COMMAND, + "computer_command", + f -> new TileCommandComputer( ComputerFamily.COMMAND, f ) ); + public static final BlockEntityType TURTLE_NORMAL = ofBlock( () -> ModBlocks.TURTLE_NORMAL, + "turtle_normal", + f -> new TileTurtle( f, ComputerFamily.NORMAL ) ); + public static final BlockEntityType TURTLE_ADVANCED = ofBlock( () -> ModBlocks.TURTLE_ADVANCED, + "turtle_advanced", + f -> new TileTurtle( f, ComputerFamily.ADVANCED ) ); + public static final BlockEntityType SPEAKER = ofBlock( () -> ModBlocks.SPEAKER, "speaker", TileSpeaker::new ); + public static final BlockEntityType DISK_DRIVE = ofBlock( () -> ModBlocks.DISK_DRIVE, "disk_drive", TileDiskDrive::new ); + public static final BlockEntityType PRINTER = ofBlock( () -> ModBlocks.PRINTER, "printer", TilePrinter::new ); + public static final BlockEntityType WIRED_MODEM_FULL = ofBlock( () -> ModBlocks.WIRED_MODEM_FULL, + "wired_modem_full", + TileWiredModemFull::new ); + public static final BlockEntityType CABLE = ofBlock( () -> ModBlocks.CABLE, "cable", TileCable::new ); + public static final BlockEntityType WIRELESS_MODEM_NORMAL = ofBlock( () -> ModBlocks.WIRELESS_MODEM_NORMAL, + "wireless_modem_normal", + f -> new TileWirelessModem( f, false ) ); + public static final BlockEntityType WIRELESS_MODEM_ADVANCED = ofBlock( () -> ModBlocks.WIRELESS_MODEM_ADVANCED, + "wireless_modem_advanced", + f -> new TileWirelessModem( f, true ) ); - private static BlockEntityType ofBlock(Supplier block, String id, Function, T> factory) { - return Registry.register(BLOCK_ENTITY_TYPE, - new Identifier(MOD_ID, id), - FixedPointTileEntityType.create(Objects.requireNonNull(block), factory)); + private static BlockEntityType ofBlock( Supplier block, String id, Function, T> factory ) + { + return Registry.register( BLOCK_ENTITY_TYPE, + new Identifier( MOD_ID, id ), + FixedPointTileEntityType.create( Objects.requireNonNull( block ), factory ) ); } } - public static final class ModItems { + public static final class ModItems + { private static final ItemGroup mainItemGroup = ComputerCraft.MAIN_GROUP; - public static final ItemComputer COMPUTER_NORMAL = ofBlock(ModBlocks.COMPUTER_NORMAL, ItemComputer::new); - public static final ItemComputer COMPUTER_ADVANCED = ofBlock(ModBlocks.COMPUTER_ADVANCED, ItemComputer::new); - public static final ItemComputer COMPUTER_COMMAND = ofBlock(ModBlocks.COMPUTER_COMMAND, ItemComputer::new); - public static final ItemPocketComputer POCKET_COMPUTER_NORMAL = register("pocket_computer_normal", - new ItemPocketComputer(properties().maxCount(1), ComputerFamily.NORMAL)); - public static final ItemPocketComputer POCKET_COMPUTER_ADVANCED = register("pocket_computer_advanced", - new ItemPocketComputer(properties().maxCount(1), - ComputerFamily.ADVANCED)); - public static final ItemTurtle TURTLE_NORMAL = ofBlock(ModBlocks.TURTLE_NORMAL, ItemTurtle::new); - public static final ItemTurtle TURTLE_ADVANCED = ofBlock(ModBlocks.TURTLE_ADVANCED, ItemTurtle::new); - public static final ItemDisk DISK = register("disk", new ItemDisk(properties().maxCount(1))); - public static final ItemTreasureDisk TREASURE_DISK = register("treasure_disk", new ItemTreasureDisk(properties().maxCount(1))); - public static final ItemPrintout PRINTED_PAGE = register("printed_page", new ItemPrintout(properties().maxCount(1), ItemPrintout.Type.PAGE)); - public static final ItemPrintout PRINTED_PAGES = register("printed_pages", new ItemPrintout(properties().maxCount(1), ItemPrintout.Type.PAGES)); - public static final ItemPrintout PRINTED_BOOK = register("printed_book", new ItemPrintout(properties().maxCount(1), ItemPrintout.Type.BOOK)); - public static final BlockItem SPEAKER = ofBlock(ModBlocks.SPEAKER, BlockItem::new); - public static final BlockItem DISK_DRIVE = ofBlock(ModBlocks.DISK_DRIVE, BlockItem::new); - public static final BlockItem PRINTER = ofBlock(ModBlocks.PRINTER, BlockItem::new); - public static final BlockItem MONITOR_NORMAL = ofBlock(ModBlocks.MONITOR_NORMAL, BlockItem::new); - public static final BlockItem MONITOR_ADVANCED = ofBlock(ModBlocks.MONITOR_ADVANCED, BlockItem::new); - public static final BlockItem WIRELESS_MODEM_NORMAL = ofBlock(ModBlocks.WIRELESS_MODEM_NORMAL, BlockItem::new); - public static final BlockItem WIRELESS_MODEM_ADVANCED = ofBlock(ModBlocks.WIRELESS_MODEM_ADVANCED, BlockItem::new); - public static final BlockItem WIRED_MODEM_FULL = ofBlock(ModBlocks.WIRED_MODEM_FULL, BlockItem::new); - public static final ItemBlockCable.Cable CABLE = register("cable", new ItemBlockCable.Cable(ModBlocks.CABLE, properties())); - public static final ItemBlockCable.WiredModem WIRED_MODEM = register("wired_modem", new ItemBlockCable.WiredModem(ModBlocks.CABLE, properties())); + public static final ItemComputer COMPUTER_NORMAL = ofBlock( ModBlocks.COMPUTER_NORMAL, ItemComputer::new ); + public static final ItemComputer COMPUTER_ADVANCED = ofBlock( ModBlocks.COMPUTER_ADVANCED, ItemComputer::new ); + public static final ItemComputer COMPUTER_COMMAND = ofBlock( ModBlocks.COMPUTER_COMMAND, ItemComputer::new ); + public static final ItemPocketComputer POCKET_COMPUTER_NORMAL = register( "pocket_computer_normal", + new ItemPocketComputer( properties().maxCount( 1 ), ComputerFamily.NORMAL ) ); + public static final ItemPocketComputer POCKET_COMPUTER_ADVANCED = register( "pocket_computer_advanced", + new ItemPocketComputer( properties().maxCount( 1 ), + ComputerFamily.ADVANCED ) ); + public static final ItemTurtle TURTLE_NORMAL = ofBlock( ModBlocks.TURTLE_NORMAL, ItemTurtle::new ); + public static final ItemTurtle TURTLE_ADVANCED = ofBlock( ModBlocks.TURTLE_ADVANCED, ItemTurtle::new ); + public static final ItemDisk DISK = register( "disk", new ItemDisk( properties().maxCount( 1 ) ) ); + public static final ItemTreasureDisk TREASURE_DISK = register( "treasure_disk", new ItemTreasureDisk( properties().maxCount( 1 ) ) ); + public static final ItemPrintout PRINTED_PAGE = register( "printed_page", new ItemPrintout( properties().maxCount( 1 ), ItemPrintout.Type.PAGE ) ); + public static final ItemPrintout PRINTED_PAGES = register( "printed_pages", new ItemPrintout( properties().maxCount( 1 ), ItemPrintout.Type.PAGES ) ); + public static final ItemPrintout PRINTED_BOOK = register( "printed_book", new ItemPrintout( properties().maxCount( 1 ), ItemPrintout.Type.BOOK ) ); + public static final BlockItem SPEAKER = ofBlock( ModBlocks.SPEAKER, BlockItem::new ); + public static final BlockItem DISK_DRIVE = ofBlock( ModBlocks.DISK_DRIVE, BlockItem::new ); + public static final BlockItem PRINTER = ofBlock( ModBlocks.PRINTER, BlockItem::new ); + public static final BlockItem MONITOR_NORMAL = ofBlock( ModBlocks.MONITOR_NORMAL, BlockItem::new ); + public static final BlockItem MONITOR_ADVANCED = ofBlock( ModBlocks.MONITOR_ADVANCED, BlockItem::new ); + public static final BlockItem WIRELESS_MODEM_NORMAL = ofBlock( ModBlocks.WIRELESS_MODEM_NORMAL, BlockItem::new ); + public static final BlockItem WIRELESS_MODEM_ADVANCED = ofBlock( ModBlocks.WIRELESS_MODEM_ADVANCED, BlockItem::new ); + public static final BlockItem WIRED_MODEM_FULL = ofBlock( ModBlocks.WIRED_MODEM_FULL, BlockItem::new ); + public static final ItemBlockCable.Cable CABLE = register( "cable", new ItemBlockCable.Cable( ModBlocks.CABLE, properties() ) ); + public static final ItemBlockCable.WiredModem WIRED_MODEM = register( "wired_modem", new ItemBlockCable.WiredModem( ModBlocks.CABLE, properties() ) ); - private static I ofBlock(B parent, BiFunction supplier) { - return Registry.register(Registry.ITEM, Registry.BLOCK.getId(parent), supplier.apply(parent, properties())); + private static I ofBlock( B parent, BiFunction supplier ) + { + return Registry.register( Registry.ITEM, Registry.BLOCK.getId( parent ), supplier.apply( parent, properties() ) ); } - private static Item.Settings properties() { - return new Item.Settings().group(mainItemGroup); + private static Item.Settings properties() + { + return new Item.Settings().group( mainItemGroup ); } - private static T register(String id, T item) { - return Registry.register(Registry.ITEM, new Identifier(MOD_ID, id), item); + private static T register( String id, T item ) + { + return Registry.register( Registry.ITEM, new Identifier( MOD_ID, id ), item ); } } - public static class ModEntities { - public static final EntityType TURTLE_PLAYER = Registry.register(Registry.ENTITY_TYPE, - new Identifier(MOD_ID, "turtle_player"), - EntityType.Builder.create(SpawnGroup.MISC).disableSaving() - .disableSummon() - .setDimensions( - 0, - 0) - .build( - ComputerCraft.MOD_ID + ":turtle_player")); + public static class ModEntities + { + public static final EntityType TURTLE_PLAYER = Registry.register( Registry.ENTITY_TYPE, + new Identifier( MOD_ID, "turtle_player" ), + EntityType.Builder.create( SpawnGroup.MISC ).disableSaving() + .disableSummon() + .setDimensions( + 0, + 0 ) + .build( + ComputerCraft.MOD_ID + ":turtle_player" ) ); } - public static class ModContainers { - public static final ScreenHandlerType COMPUTER = registerExtended("computer", ContainerComputer::new); - public static final ScreenHandlerType POCKET_COMPUTER = registerExtended("pocket_computer", ContainerPocketComputer::new); - public static final ScreenHandlerType TURTLE = registerExtended("turtle", ContainerTurtle::new); - public static final ScreenHandlerType DISK_DRIVE = registerSimple("disk_drive", ContainerDiskDrive::new); - public static final ScreenHandlerType PRINTER = registerSimple("printer", ContainerPrinter::new); - public static final ScreenHandlerType PRINTOUT = registerExtended("printout", ContainerHeldItem::createPrintout); - public static final ScreenHandlerType VIEW_COMPUTER = registerExtended("view_computer", ContainerViewComputer::new); + public static class ModContainers + { + public static final ScreenHandlerType COMPUTER = registerExtended( "computer", ContainerComputer::new ); + public static final ScreenHandlerType POCKET_COMPUTER = registerExtended( "pocket_computer", ContainerPocketComputer::new ); + public static final ScreenHandlerType TURTLE = registerExtended( "turtle", ContainerTurtle::new ); + public static final ScreenHandlerType DISK_DRIVE = registerSimple( "disk_drive", ContainerDiskDrive::new ); + public static final ScreenHandlerType PRINTER = registerSimple( "printer", ContainerPrinter::new ); + public static final ScreenHandlerType PRINTOUT = registerExtended( "printout", ContainerHeldItem::createPrintout ); + public static final ScreenHandlerType VIEW_COMPUTER = registerExtended( "view_computer", ContainerViewComputer::new ); - private static ScreenHandlerType registerSimple(String id, - ScreenHandlerRegistry.SimpleClientHandlerFactory function) { - return ScreenHandlerRegistry.registerSimple(new Identifier(MOD_ID, id), function); + private static ScreenHandlerType registerSimple( String id, + ScreenHandlerRegistry.SimpleClientHandlerFactory function ) + { + return ScreenHandlerRegistry.registerSimple( new Identifier( MOD_ID, id ), function ); } - private static ScreenHandlerType registerExtended(String id, ScreenHandlerRegistry.ExtendedClientHandlerFactory function) { - return ScreenHandlerRegistry.registerExtended(new Identifier(MOD_ID, id), function); + private static ScreenHandlerType registerExtended( String id, ScreenHandlerRegistry.ExtendedClientHandlerFactory function ) + { + return ScreenHandlerRegistry.registerExtended( new Identifier( MOD_ID, id ), function ); } } - public static final class TurtleUpgrades { - public static TurtleModem wirelessModemNormal = new TurtleModem(false, new Identifier(ComputerCraft.MOD_ID, "wireless_modem_normal")); - public static TurtleModem wirelessModemAdvanced = new TurtleModem(true, new Identifier(ComputerCraft.MOD_ID, "wireless_modem_advanced")); - public static TurtleSpeaker speaker = new TurtleSpeaker(new Identifier(ComputerCraft.MOD_ID, "speaker")); + public static final class TurtleUpgrades + { + public static TurtleModem wirelessModemNormal = new TurtleModem( false, new Identifier( ComputerCraft.MOD_ID, "wireless_modem_normal" ) ); + public static TurtleModem wirelessModemAdvanced = new TurtleModem( true, new Identifier( ComputerCraft.MOD_ID, "wireless_modem_advanced" ) ); + public static TurtleSpeaker speaker = new TurtleSpeaker( new Identifier( ComputerCraft.MOD_ID, "speaker" ) ); - public static TurtleCraftingTable craftingTable = new TurtleCraftingTable(new Identifier("minecraft", "crafting_table")); - public static TurtleSword diamondSword = new TurtleSword(new Identifier("minecraft", "diamond_sword"), Items.DIAMOND_SWORD); - public static TurtleShovel diamondShovel = new TurtleShovel(new Identifier("minecraft", "diamond_shovel"), Items.DIAMOND_SHOVEL); - public static TurtleTool diamondPickaxe = new TurtleTool(new Identifier("minecraft", "diamond_pickaxe"), Items.DIAMOND_PICKAXE); - public static TurtleAxe diamondAxe = new TurtleAxe(new Identifier("minecraft", "diamond_axe"), Items.DIAMOND_AXE); - public static TurtleHoe diamondHoe = new TurtleHoe(new Identifier("minecraft", "diamond_hoe"), Items.DIAMOND_HOE); + public static TurtleCraftingTable craftingTable = new TurtleCraftingTable( new Identifier( "minecraft", "crafting_table" ) ); + public static TurtleSword diamondSword = new TurtleSword( new Identifier( "minecraft", "diamond_sword" ), Items.DIAMOND_SWORD ); + public static TurtleShovel diamondShovel = new TurtleShovel( new Identifier( "minecraft", "diamond_shovel" ), Items.DIAMOND_SHOVEL ); + public static TurtleTool diamondPickaxe = new TurtleTool( new Identifier( "minecraft", "diamond_pickaxe" ), Items.DIAMOND_PICKAXE ); + public static TurtleAxe diamondAxe = new TurtleAxe( new Identifier( "minecraft", "diamond_axe" ), Items.DIAMOND_AXE ); + public static TurtleHoe diamondHoe = new TurtleHoe( new Identifier( "minecraft", "diamond_hoe" ), Items.DIAMOND_HOE ); - public static TurtleTool netheritePickaxe = new TurtleTool(new Identifier("minecraft", "netherite_pickaxe"), Items.NETHERITE_PICKAXE); + public static TurtleTool netheritePickaxe = new TurtleTool( new Identifier( "minecraft", "netherite_pickaxe" ), Items.NETHERITE_PICKAXE ); - public static void registerTurtleUpgrades() { - ComputerCraftAPI.registerTurtleUpgrade(wirelessModemNormal); - ComputerCraftAPI.registerTurtleUpgrade(wirelessModemAdvanced); - ComputerCraftAPI.registerTurtleUpgrade(speaker); + public static void registerTurtleUpgrades() + { + ComputerCraftAPI.registerTurtleUpgrade( wirelessModemNormal ); + ComputerCraftAPI.registerTurtleUpgrade( wirelessModemAdvanced ); + ComputerCraftAPI.registerTurtleUpgrade( speaker ); - ComputerCraftAPI.registerTurtleUpgrade(craftingTable); - ComputerCraftAPI.registerTurtleUpgrade(diamondSword); - ComputerCraftAPI.registerTurtleUpgrade(diamondShovel); - ComputerCraftAPI.registerTurtleUpgrade(diamondPickaxe); - ComputerCraftAPI.registerTurtleUpgrade(diamondAxe); - ComputerCraftAPI.registerTurtleUpgrade(diamondHoe); + ComputerCraftAPI.registerTurtleUpgrade( craftingTable ); + ComputerCraftAPI.registerTurtleUpgrade( diamondSword ); + ComputerCraftAPI.registerTurtleUpgrade( diamondShovel ); + ComputerCraftAPI.registerTurtleUpgrade( diamondPickaxe ); + ComputerCraftAPI.registerTurtleUpgrade( diamondAxe ); + ComputerCraftAPI.registerTurtleUpgrade( diamondHoe ); - ComputerCraftAPI.registerTurtleUpgrade(netheritePickaxe); + ComputerCraftAPI.registerTurtleUpgrade( netheritePickaxe ); } } - public static final class PocketUpgrades { - public static PocketModem wirelessModemNormal = new PocketModem(false); - public static PocketModem wirelessModemAdvanced = new PocketModem(true); + public static final class PocketUpgrades + { + public static PocketModem wirelessModemNormal = new PocketModem( false ); + public static PocketModem wirelessModemAdvanced = new PocketModem( true ); public static PocketSpeaker speaker = new PocketSpeaker(); - public static void registerPocketUpgrades() { - ComputerCraftAPI.registerPocketUpgrade(wirelessModemNormal); - ComputerCraftAPI.registerPocketUpgrade(wirelessModemAdvanced); - ComputerCraftAPI.registerPocketUpgrade(speaker); + public static void registerPocketUpgrades() + { + ComputerCraftAPI.registerPocketUpgrade( wirelessModemNormal ); + ComputerCraftAPI.registerPocketUpgrade( wirelessModemAdvanced ); + ComputerCraftAPI.registerPocketUpgrade( speaker ); } } diff --git a/src/main/java/dan200/computercraft/shared/MediaProviders.java b/src/main/java/dan200/computercraft/shared/MediaProviders.java index 35f1682dc..a76eef0be 100644 --- a/src/main/java/dan200/computercraft/shared/MediaProviders.java +++ b/src/main/java/dan200/computercraft/shared/MediaProviders.java @@ -6,43 +6,50 @@ package dan200.computercraft.shared; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.media.IMedia; +import dan200.computercraft.api.media.IMediaProvider; +import net.minecraft.item.ItemStack; + +import javax.annotation.Nonnull; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; -import javax.annotation.Nonnull; - -import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.media.IMedia; -import dan200.computercraft.api.media.IMediaProvider; - -import net.minecraft.item.ItemStack; - -public final class MediaProviders { +public final class MediaProviders +{ private static final Set providers = new LinkedHashSet<>(); private MediaProviders() {} - public static synchronized void register(@Nonnull IMediaProvider provider) { - Objects.requireNonNull(provider, "provider cannot be null"); - providers.add(provider); + public static synchronized void register( @Nonnull IMediaProvider provider ) + { + Objects.requireNonNull( provider, "provider cannot be null" ); + providers.add( provider ); } - public static IMedia get(@Nonnull ItemStack stack) { - if (stack.isEmpty()) { + public static IMedia get( @Nonnull ItemStack stack ) + { + if( stack.isEmpty() ) + { return null; } // Try the handlers in order: - for (IMediaProvider mediaProvider : providers) { - try { - IMedia media = mediaProvider.getMedia(stack); - if (media != null) { + for( IMediaProvider mediaProvider : providers ) + { + try + { + IMedia media = mediaProvider.getMedia( stack ); + if( media != null ) + { return media; } - } catch (Exception e) { + } + catch( Exception e ) + { // mod misbehaved, ignore it - ComputerCraft.log.error("Media provider " + mediaProvider + " errored.", e); + ComputerCraft.log.error( "Media provider " + mediaProvider + " errored.", e ); } } return null; diff --git a/src/main/java/dan200/computercraft/shared/Peripherals.java b/src/main/java/dan200/computercraft/shared/Peripherals.java index 0db0e06f7..38fc5676e 100644 --- a/src/main/java/dan200/computercraft/shared/Peripherals.java +++ b/src/main/java/dan200/computercraft/shared/Peripherals.java @@ -6,53 +6,59 @@ package dan200.computercraft.shared; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Objects; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; - import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider; -import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public final class Peripherals { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Objects; + +public final class Peripherals +{ private static final Collection providers = new LinkedHashSet<>(); private Peripherals() {} - public static synchronized void register(@Nonnull IPeripheralProvider provider) { - Objects.requireNonNull(provider, "provider cannot be null"); - providers.add(provider); + public static synchronized void register( @Nonnull IPeripheralProvider provider ) + { + Objects.requireNonNull( provider, "provider cannot be null" ); + providers.add( provider ); } @Nullable - public static IPeripheral getPeripheral(World world, BlockPos pos, Direction side) { - return World.isInBuildLimit(pos) && !world.isClient ? getPeripheralAt(world, pos, side) : null; + public static IPeripheral getPeripheral( World world, BlockPos pos, Direction side ) + { + return World.isInBuildLimit( pos ) && !world.isClient ? getPeripheralAt( world, pos, side ) : null; } @Nullable - private static IPeripheral getPeripheralAt(World world, BlockPos pos, Direction side) { + private static IPeripheral getPeripheralAt( World world, BlockPos pos, Direction side ) + { // Try the handlers in order: - for (IPeripheralProvider peripheralProvider : providers) { - try { - IPeripheral peripheral = peripheralProvider.getPeripheral(world, pos, side); - if (peripheral != null) { + for( IPeripheralProvider peripheralProvider : providers ) + { + try + { + IPeripheral peripheral = peripheralProvider.getPeripheral( world, pos, side ); + if( peripheral != null ) + { return peripheral; } - } catch (Exception e) { - ComputerCraft.log.error("Peripheral provider " + peripheralProvider + " errored.", e); + } + catch( Exception e ) + { + ComputerCraft.log.error( "Peripheral provider " + peripheralProvider + " errored.", e ); } } - return GenericPeripheralProvider.getPeripheral(world, pos, side); + return GenericPeripheralProvider.getPeripheral( world, pos, side ); } } diff --git a/src/main/java/dan200/computercraft/shared/PocketUpgrades.java b/src/main/java/dan200/computercraft/shared/PocketUpgrades.java index 6704ac02b..0c5820bea 100644 --- a/src/main/java/dan200/computercraft/shared/PocketUpgrades.java +++ b/src/main/java/dan200/computercraft/shared/PocketUpgrades.java @@ -38,7 +38,7 @@ public final class PocketUpgrades // Infer the mod id by the identifier of the upgrade. This is not how the forge api works, so it may break peripheral mods using the api. // TODO: get the mod id of the mod that is currently being loaded. - ModContainer mc = FabricLoader.getInstance().getModContainer(upgrade.getUpgradeID().getNamespace()).orElseGet(null); + ModContainer mc = FabricLoader.getInstance().getModContainer( upgrade.getUpgradeID().getNamespace() ).orElseGet( null ); if( mc != null && mc.getMetadata().getId() != null ) upgradeOwners.put( upgrade, mc.getMetadata().getId() ); } @@ -85,4 +85,4 @@ public final class PocketUpgrades { return Collections.unmodifiableCollection( upgrades.values() ); } -} \ No newline at end of file +} diff --git a/src/main/java/dan200/computercraft/shared/TurtlePermissions.java b/src/main/java/dan200/computercraft/shared/TurtlePermissions.java index baf466be3..f6236a770 100644 --- a/src/main/java/dan200/computercraft/shared/TurtlePermissions.java +++ b/src/main/java/dan200/computercraft/shared/TurtlePermissions.java @@ -9,27 +9,31 @@ package dan200.computercraft.shared; import com.google.common.eventbus.Subscribe; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.event.TurtleActionEvent; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -public final class TurtlePermissions { - public static boolean isBlockEditable(World world, BlockPos pos, PlayerEntity player) { - return isBlockEnterable(world, pos, player); +public final class TurtlePermissions +{ + public static boolean isBlockEditable( World world, BlockPos pos, PlayerEntity player ) + { + return isBlockEnterable( world, pos, player ); } - public static boolean isBlockEnterable(World world, BlockPos pos, PlayerEntity player) { + public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity player ) + { MinecraftServer server = world.getServer(); - return server == null || world.isClient || (world instanceof ServerWorld && !server.isSpawnProtected((ServerWorld) world, pos, player)); + return server == null || world.isClient || (world instanceof ServerWorld && !server.isSpawnProtected( (ServerWorld) world, pos, player )); } @Subscribe - public void onTurtleAction(TurtleActionEvent event) { - if (ComputerCraft.turtleDisabledActions.contains(event.getAction())) { - event.setCanceled(true, "Action has been disabled"); + public void onTurtleAction( TurtleActionEvent event ) + { + if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) ) + { + event.setCanceled( true, "Action has been disabled" ); } } } diff --git a/src/main/java/dan200/computercraft/shared/TurtleUpgrades.java b/src/main/java/dan200/computercraft/shared/TurtleUpgrades.java index 5153367ca..255f2d68b 100644 --- a/src/main/java/dan200/computercraft/shared/TurtleUpgrades.java +++ b/src/main/java/dan200/computercraft/shared/TurtleUpgrades.java @@ -12,11 +12,7 @@ import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Stream; public final class TurtleUpgrades @@ -32,7 +28,7 @@ public final class TurtleUpgrades { this.upgrade = upgrade; this.id = upgrade.getUpgradeID() - .toString(); + .toString(); // TODO This should be the mod id of the mod the peripheral comes from this.modId = ComputerCraft.MOD_ID; this.enabled = true; @@ -178,4 +174,4 @@ public final class TurtleUpgrades wrappers.remove( upgrade ); needsRebuild = true; } -} \ No newline at end of file +} diff --git a/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java b/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java index 472a6a2f8..41c593766 100644 --- a/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java +++ b/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java @@ -28,7 +28,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket; -import net.minecraft.screen.NamedScreenHandlerFactory; import net.minecraft.screen.ScreenHandler; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; diff --git a/src/main/java/dan200/computercraft/shared/command/CommandUtils.java b/src/main/java/dan200/computercraft/shared/command/CommandUtils.java index 375dd4402..d64a7935d 100644 --- a/src/main/java/dan200/computercraft/shared/command/CommandUtils.java +++ b/src/main/java/dan200/computercraft/shared/command/CommandUtils.java @@ -6,56 +6,67 @@ package dan200.computercraft.shared.command; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import dan200.computercraft.api.turtle.FakePlayer; +import net.minecraft.command.CommandSource; +import net.minecraft.entity.Entity; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; + import java.util.Arrays; import java.util.Locale; import java.util.concurrent.CompletableFuture; import java.util.function.Function; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import dan200.computercraft.api.turtle.FakePlayer; - -import net.minecraft.entity.Entity; -import net.minecraft.command.CommandSource; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.network.ServerPlayerEntity; - -public final class CommandUtils { +public final class CommandUtils +{ private CommandUtils() {} - public static boolean isPlayer(ServerCommandSource output) { + public static boolean isPlayer( ServerCommandSource output ) + { Entity sender = output.getEntity(); return sender instanceof ServerPlayerEntity && !(sender instanceof FakePlayer) && ((ServerPlayerEntity) sender).networkHandler != null; } - @SuppressWarnings ("unchecked") - public static CompletableFuture suggestOnServer(CommandContext context, SuggestionsBuilder builder, - Function, CompletableFuture> supplier) { + @SuppressWarnings( "unchecked" ) + public static CompletableFuture suggestOnServer( CommandContext context, SuggestionsBuilder builder, + Function, CompletableFuture> supplier ) + { Object source = context.getSource(); - if (!(source instanceof CommandSource)) { + if( !(source instanceof CommandSource) ) + { return Suggestions.empty(); - } else if (source instanceof ServerCommandSource) { - return supplier.apply((CommandContext) context); - } else { - return ((CommandSource) source).getCompletions((CommandContext) context, builder); + } + else if( source instanceof ServerCommandSource ) + { + return supplier.apply( (CommandContext) context ); + } + else + { + return ((CommandSource) source).getCompletions( (CommandContext) context, builder ); } } - public static CompletableFuture suggest(SuggestionsBuilder builder, T[] candidates, Function toString) { - return suggest(builder, Arrays.asList(candidates), toString); + public static CompletableFuture suggest( SuggestionsBuilder builder, T[] candidates, Function toString ) + { + return suggest( builder, Arrays.asList( candidates ), toString ); } - public static CompletableFuture suggest(SuggestionsBuilder builder, Iterable candidates, Function toString) { + public static CompletableFuture suggest( SuggestionsBuilder builder, Iterable candidates, Function toString ) + { String remaining = builder.getRemaining() - .toLowerCase(Locale.ROOT); - for (T choice : candidates) { - String name = toString.apply(choice); - if (!name.toLowerCase(Locale.ROOT) - .startsWith(remaining)) { + .toLowerCase( Locale.ROOT ); + for( T choice : candidates ) + { + String name = toString.apply( choice ); + if( !name.toLowerCase( Locale.ROOT ) + .startsWith( remaining ) ) + { continue; } - builder.suggest(name); + builder.suggest( name ); } return builder.buildFuture(); diff --git a/src/main/java/dan200/computercraft/shared/command/Exceptions.java b/src/main/java/dan200/computercraft/shared/command/Exceptions.java index 2e635b3fe..88f173093 100644 --- a/src/main/java/dan200/computercraft/shared/command/Exceptions.java +++ b/src/main/java/dan200/computercraft/shared/command/Exceptions.java @@ -9,29 +9,32 @@ package dan200.computercraft.shared.command; import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType; import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; - import net.minecraft.text.TranslatableText; -public final class Exceptions { - public static final DynamicCommandExceptionType COMPUTER_ARG_NONE = translated1("argument.computercraft.computer.no_matching"); - public static final Dynamic2CommandExceptionType COMPUTER_ARG_MANY = translated2("argument.computercraft.computer.many_matching"); +public final class Exceptions +{ + public static final DynamicCommandExceptionType COMPUTER_ARG_NONE = translated1( "argument.computercraft.computer.no_matching" ); + public static final Dynamic2CommandExceptionType COMPUTER_ARG_MANY = translated2( "argument.computercraft.computer.many_matching" ); - public static final DynamicCommandExceptionType TRACKING_FIELD_ARG_NONE = translated1("argument.computercraft.tracking_field.no_field"); - public static final SimpleCommandExceptionType ARGUMENT_EXPECTED = translated("argument.computercraft.argument_expected"); - static final SimpleCommandExceptionType NOT_TRACKING_EXCEPTION = translated("commands.computercraft.track.stop.not_enabled"); - static final SimpleCommandExceptionType NO_TIMINGS_EXCEPTION = translated("commands.computercraft.track.dump.no_timings"); - static final SimpleCommandExceptionType TP_NOT_THERE = translated("commands.computercraft.tp.not_there"); - static final SimpleCommandExceptionType TP_NOT_PLAYER = translated("commands.computercraft.tp.not_player"); + public static final DynamicCommandExceptionType TRACKING_FIELD_ARG_NONE = translated1( "argument.computercraft.tracking_field.no_field" ); + public static final SimpleCommandExceptionType ARGUMENT_EXPECTED = translated( "argument.computercraft.argument_expected" ); + static final SimpleCommandExceptionType NOT_TRACKING_EXCEPTION = translated( "commands.computercraft.track.stop.not_enabled" ); + static final SimpleCommandExceptionType NO_TIMINGS_EXCEPTION = translated( "commands.computercraft.track.dump.no_timings" ); + static final SimpleCommandExceptionType TP_NOT_THERE = translated( "commands.computercraft.tp.not_there" ); + static final SimpleCommandExceptionType TP_NOT_PLAYER = translated( "commands.computercraft.tp.not_player" ); - private static SimpleCommandExceptionType translated(String key) { - return new SimpleCommandExceptionType(new TranslatableText(key)); + private static SimpleCommandExceptionType translated( String key ) + { + return new SimpleCommandExceptionType( new TranslatableText( key ) ); } - private static DynamicCommandExceptionType translated1(String key) { - return new DynamicCommandExceptionType(x -> new TranslatableText(key, x)); + private static DynamicCommandExceptionType translated1( String key ) + { + return new DynamicCommandExceptionType( x -> new TranslatableText( key, x ) ); } - private static Dynamic2CommandExceptionType translated2(String key) { - return new Dynamic2CommandExceptionType((x, y) -> new TranslatableText(key, x, y)); + private static Dynamic2CommandExceptionType translated2( String key ) + { + return new Dynamic2CommandExceptionType( ( x, y ) -> new TranslatableText( key, x, y ) ); } } diff --git a/src/main/java/dan200/computercraft/shared/command/arguments/ArgumentSerializers.java b/src/main/java/dan200/computercraft/shared/command/arguments/ArgumentSerializers.java index cb885e65f..a8520734d 100644 --- a/src/main/java/dan200/computercraft/shared/command/arguments/ArgumentSerializers.java +++ b/src/main/java/dan200/computercraft/shared/command/arguments/ArgumentSerializers.java @@ -8,30 +8,34 @@ package dan200.computercraft.shared.command.arguments; import com.mojang.brigadier.arguments.ArgumentType; import dan200.computercraft.ComputerCraft; - import net.minecraft.command.argument.ArgumentTypes; import net.minecraft.command.argument.serialize.ArgumentSerializer; import net.minecraft.command.argument.serialize.ConstantArgumentSerializer; import net.minecraft.util.Identifier; -public final class ArgumentSerializers { - public static void register() { - register(new Identifier(ComputerCraft.MOD_ID, "tracking_field"), TrackingFieldArgumentType.trackingField()); - register(new Identifier(ComputerCraft.MOD_ID, "computer"), ComputerArgumentType.oneComputer()); - register(new Identifier(ComputerCraft.MOD_ID, "computers"), ComputersArgumentType.class, new ComputersArgumentType.Serializer()); - registerUnsafe(new Identifier(ComputerCraft.MOD_ID, "repeat"), RepeatArgumentType.class, new RepeatArgumentType.Serializer()); +public final class ArgumentSerializers +{ + public static void register() + { + register( new Identifier( ComputerCraft.MOD_ID, "tracking_field" ), TrackingFieldArgumentType.trackingField() ); + register( new Identifier( ComputerCraft.MOD_ID, "computer" ), ComputerArgumentType.oneComputer() ); + register( new Identifier( ComputerCraft.MOD_ID, "computers" ), ComputersArgumentType.class, new ComputersArgumentType.Serializer() ); + registerUnsafe( new Identifier( ComputerCraft.MOD_ID, "repeat" ), RepeatArgumentType.class, new RepeatArgumentType.Serializer() ); } - private static > void register(Identifier id, T instance) { - registerUnsafe(id, instance.getClass(), new ConstantArgumentSerializer<>(() -> instance)); + private static > void register( Identifier id, T instance ) + { + registerUnsafe( id, instance.getClass(), new ConstantArgumentSerializer<>( () -> instance ) ); } - private static > void register(Identifier id, Class type, ArgumentSerializer serializer) { - ArgumentTypes.register(id.toString(), type, serializer); + private static > void register( Identifier id, Class type, ArgumentSerializer serializer ) + { + ArgumentTypes.register( id.toString(), type, serializer ); } - @SuppressWarnings ("unchecked") - private static > void registerUnsafe(Identifier id, Class type, ArgumentSerializer serializer) { - ArgumentTypes.register(id.toString(), type, (ArgumentSerializer) serializer); + @SuppressWarnings( "unchecked" ) + private static > void registerUnsafe( Identifier id, Class type, ArgumentSerializer serializer ) + { + ArgumentTypes.register( id.toString(), type, (ArgumentSerializer) serializer ); } } diff --git a/src/main/java/dan200/computercraft/shared/command/arguments/ChoiceArgumentType.java b/src/main/java/dan200/computercraft/shared/command/arguments/ChoiceArgumentType.java index f2da90763..aa6e48fea 100644 --- a/src/main/java/dan200/computercraft/shared/command/arguments/ChoiceArgumentType.java +++ b/src/main/java/dan200/computercraft/shared/command/arguments/ChoiceArgumentType.java @@ -6,14 +6,6 @@ package dan200.computercraft.shared.command.arguments; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - import com.mojang.brigadier.Message; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; @@ -23,13 +15,19 @@ import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -public abstract class ChoiceArgumentType implements ArgumentType { +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; + +public abstract class ChoiceArgumentType implements ArgumentType +{ private final Iterable choices; private final Function name; private final Function tooltip; private final DynamicCommandExceptionType exception; - protected ChoiceArgumentType(Iterable choices, Function name, Function tooltip, DynamicCommandExceptionType exception) { + protected ChoiceArgumentType( Iterable choices, Function name, Function tooltip, DynamicCommandExceptionType exception ) + { this.choices = choices; this.name = name; this.tooltip = tooltip; @@ -37,44 +35,52 @@ public abstract class ChoiceArgumentType implements ArgumentType { } @Override - public T parse(StringReader reader) throws CommandSyntaxException { + public T parse( StringReader reader ) throws CommandSyntaxException + { int start = reader.getCursor(); String name = reader.readUnquotedString(); - for (T choice : this.choices) { - String choiceName = this.name.apply(choice); - if (name.equals(choiceName)) { + for( T choice : this.choices ) + { + String choiceName = this.name.apply( choice ); + if( name.equals( choiceName ) ) + { return choice; } } - reader.setCursor(start); - throw this.exception.createWithContext(reader, name); + reader.setCursor( start ); + throw this.exception.createWithContext( reader, name ); } @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + public CompletableFuture listSuggestions( CommandContext context, SuggestionsBuilder builder ) + { String remaining = builder.getRemaining() - .toLowerCase(Locale.ROOT); - for (T choice : this.choices) { - String name = this.name.apply(choice); - if (!name.toLowerCase(Locale.ROOT) - .startsWith(remaining)) { + .toLowerCase( Locale.ROOT ); + for( T choice : this.choices ) + { + String name = this.name.apply( choice ); + if( !name.toLowerCase( Locale.ROOT ) + .startsWith( remaining ) ) + { continue; } - builder.suggest(name, this.tooltip.apply(choice)); + builder.suggest( name, this.tooltip.apply( choice ) ); } return builder.buildFuture(); } @Override - public Collection getExamples() { - List items = this.choices instanceof Collection ? new ArrayList<>(((Collection) this.choices).size()) : new ArrayList<>(); - for (T choice : this.choices) { - items.add(this.name.apply(choice)); + public Collection getExamples() + { + List items = this.choices instanceof Collection ? new ArrayList<>( ((Collection) this.choices).size() ) : new ArrayList<>(); + for( T choice : this.choices ) + { + items.add( this.name.apply( choice ) ); } - items.sort(Comparator.naturalOrder()); + items.sort( Comparator.naturalOrder() ); return items; } } diff --git a/src/main/java/dan200/computercraft/shared/command/arguments/ComputerArgumentType.java b/src/main/java/dan200/computercraft/shared/command/arguments/ComputerArgumentType.java index b7f53fabf..06840b154 100644 --- a/src/main/java/dan200/computercraft/shared/command/arguments/ComputerArgumentType.java +++ b/src/main/java/dan200/computercraft/shared/command/arguments/ComputerArgumentType.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.command.arguments; -import static dan200.computercraft.shared.command.Exceptions.COMPUTER_ARG_MANY; - -import java.util.Collection; -import java.util.concurrent.CompletableFuture; - import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.context.CommandContext; @@ -19,73 +14,90 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import dan200.computercraft.shared.command.arguments.ComputersArgumentType.ComputersSupplier; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.server.command.ServerCommandSource; -public final class ComputerArgumentType implements ArgumentType { +import java.util.Collection; +import java.util.concurrent.CompletableFuture; + +import static dan200.computercraft.shared.command.Exceptions.COMPUTER_ARG_MANY; + +public final class ComputerArgumentType implements ArgumentType +{ private static final ComputerArgumentType INSTANCE = new ComputerArgumentType(); - private ComputerArgumentType() { + private ComputerArgumentType() + { } - public static ComputerArgumentType oneComputer() { + public static ComputerArgumentType oneComputer() + { return INSTANCE; } - public static ServerComputer getComputerArgument(CommandContext context, String name) throws CommandSyntaxException { - return context.getArgument(name, ComputerSupplier.class) - .unwrap(context.getSource()); + public static ServerComputer getComputerArgument( CommandContext context, String name ) throws CommandSyntaxException + { + return context.getArgument( name, ComputerSupplier.class ) + .unwrap( context.getSource() ); } @Override - public ComputerSupplier parse(StringReader reader) throws CommandSyntaxException { + public ComputerSupplier parse( StringReader reader ) throws CommandSyntaxException + { int start = reader.getCursor(); ComputersSupplier supplier = ComputersArgumentType.someComputers() - .parse(reader); + .parse( reader ); String selector = reader.getString() - .substring(start, reader.getCursor()); + .substring( start, reader.getCursor() ); return s -> { - Collection computers = supplier.unwrap(s); + Collection computers = supplier.unwrap( s ); - if (computers.size() == 1) { + if( computers.size() == 1 ) + { return computers.iterator() - .next(); + .next(); } StringBuilder builder = new StringBuilder(); boolean first = true; - for (ServerComputer computer : computers) { - if (first) { + for( ServerComputer computer : computers ) + { + if( first ) + { first = false; - } else { - builder.append(", "); + } + else + { + builder.append( ", " ); } - builder.append(computer.getInstanceID()); + builder.append( computer.getInstanceID() ); } // We have an incorrect number of computers: reset and throw an error - reader.setCursor(start); - throw COMPUTER_ARG_MANY.createWithContext(reader, selector, builder.toString()); + reader.setCursor( start ); + throw COMPUTER_ARG_MANY.createWithContext( reader, selector, builder.toString() ); }; } @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + public CompletableFuture listSuggestions( CommandContext context, SuggestionsBuilder builder ) + { return ComputersArgumentType.someComputers() - .listSuggestions(context, builder); + .listSuggestions( context, builder ); } @Override - public Collection getExamples() { + public Collection getExamples() + { return ComputersArgumentType.someComputers() - .getExamples(); + .getExamples(); } @FunctionalInterface - public interface ComputerSupplier { - ServerComputer unwrap(ServerCommandSource source) throws CommandSyntaxException; + public interface ComputerSupplier + { + ServerComputer unwrap( ServerCommandSource source ) throws CommandSyntaxException; } } diff --git a/src/main/java/dan200/computercraft/shared/command/arguments/ComputersArgumentType.java b/src/main/java/dan200/computercraft/shared/command/arguments/ComputersArgumentType.java index efce72ec0..e69ae8558 100644 --- a/src/main/java/dan200/computercraft/shared/command/arguments/ComputersArgumentType.java +++ b/src/main/java/dan200/computercraft/shared/command/arguments/ComputersArgumentType.java @@ -6,25 +6,6 @@ package dan200.computercraft.shared.command.arguments; -import static dan200.computercraft.shared.command.CommandUtils.suggest; -import static dan200.computercraft.shared.command.CommandUtils.suggestOnServer; -import static dan200.computercraft.shared.command.Exceptions.COMPUTER_ARG_NONE; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import javax.annotation.Nonnull; - import com.google.gson.JsonObject; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; @@ -35,155 +16,201 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.command.argument.serialize.ArgumentSerializer; import net.minecraft.network.PacketByteBuf; import net.minecraft.server.command.ServerCommandSource; -public final class ComputersArgumentType implements ArgumentType { - private static final ComputersArgumentType MANY = new ComputersArgumentType(false); - private static final ComputersArgumentType SOME = new ComputersArgumentType(true); +import javax.annotation.Nonnull; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; - private static final List EXAMPLES = Arrays.asList("0", "#0", "@Label", "~Advanced"); +import static dan200.computercraft.shared.command.CommandUtils.suggest; +import static dan200.computercraft.shared.command.CommandUtils.suggestOnServer; +import static dan200.computercraft.shared.command.Exceptions.COMPUTER_ARG_NONE; + +public final class ComputersArgumentType implements ArgumentType +{ + private static final ComputersArgumentType MANY = new ComputersArgumentType( false ); + private static final ComputersArgumentType SOME = new ComputersArgumentType( true ); + + private static final List EXAMPLES = Arrays.asList( "0", "#0", "@Label", "~Advanced" ); private final boolean requireSome; - private ComputersArgumentType(boolean requireSome) { + private ComputersArgumentType( boolean requireSome ) + { this.requireSome = requireSome; } - public static ComputersArgumentType manyComputers() { + public static ComputersArgumentType manyComputers() + { return MANY; } - public static ComputersArgumentType someComputers() { + public static ComputersArgumentType someComputers() + { return SOME; } - public static Collection getComputersArgument(CommandContext context, String name) throws CommandSyntaxException { - return context.getArgument(name, ComputersSupplier.class) - .unwrap(context.getSource()); + public static Collection getComputersArgument( CommandContext context, String name ) throws CommandSyntaxException + { + return context.getArgument( name, ComputersSupplier.class ) + .unwrap( context.getSource() ); } - public static Set unwrap(ServerCommandSource source, Collection suppliers) throws CommandSyntaxException { + public static Set unwrap( ServerCommandSource source, Collection suppliers ) throws CommandSyntaxException + { Set computers = new HashSet<>(); - for (ComputersSupplier supplier : suppliers) { - computers.addAll(supplier.unwrap(source)); + for( ComputersSupplier supplier : suppliers ) + { + computers.addAll( supplier.unwrap( source ) ); } return computers; } @Override - public ComputersSupplier parse(StringReader reader) throws CommandSyntaxException { + public ComputersSupplier parse( StringReader reader ) throws CommandSyntaxException + { int start = reader.getCursor(); char kind = reader.peek(); ComputersSupplier computers; - if (kind == '@') { + if( kind == '@' ) + { reader.skip(); String label = reader.readUnquotedString(); - computers = getComputers(x -> Objects.equals(label, x.getLabel())); - } else if (kind == '~') { + computers = getComputers( x -> Objects.equals( label, x.getLabel() ) ); + } + else if( kind == '~' ) + { reader.skip(); String family = reader.readUnquotedString(); - computers = getComputers(x -> x.getFamily() - .name() - .equalsIgnoreCase(family)); - } else if (kind == '#') { + computers = getComputers( x -> x.getFamily() + .name() + .equalsIgnoreCase( family ) ); + } + else if( kind == '#' ) + { reader.skip(); int id = reader.readInt(); - computers = getComputers(x -> x.getID() == id); - } else { + computers = getComputers( x -> x.getID() == id ); + } + else + { int instance = reader.readInt(); computers = s -> { - ServerComputer computer = ComputerCraft.serverComputerRegistry.get(instance); - return computer == null ? Collections.emptyList() : Collections.singletonList(computer); + ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instance ); + return computer == null ? Collections.emptyList() : Collections.singletonList( computer ); }; } - if (this.requireSome) { + if( this.requireSome ) + { String selector = reader.getString() - .substring(start, reader.getCursor()); + .substring( start, reader.getCursor() ); return source -> { - Collection matched = computers.unwrap(source); - if (matched.isEmpty()) { - throw COMPUTER_ARG_NONE.create(selector); + Collection matched = computers.unwrap( source ); + if( matched.isEmpty() ) + { + throw COMPUTER_ARG_NONE.create( selector ); } return matched; }; - } else { + } + else + { return computers; } } @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + public CompletableFuture listSuggestions( CommandContext context, SuggestionsBuilder builder ) + { String remaining = builder.getRemaining(); // We can run this one on the client, for obvious reasons. - if (remaining.startsWith("~")) { - return suggest(builder, ComputerFamily.values(), x -> "~" + x.name()); + if( remaining.startsWith( "~" ) ) + { + return suggest( builder, ComputerFamily.values(), x -> "~" + x.name() ); } // Verify we've a command source and we're running on the server - return suggestOnServer(context, builder, s -> { - if (remaining.startsWith("@")) { - suggestComputers(builder, remaining, x -> { + return suggestOnServer( context, builder, s -> { + if( remaining.startsWith( "@" ) ) + { + suggestComputers( builder, remaining, x -> { String label = x.getLabel(); return label == null ? null : "@" + label; - }); - } else if (remaining.startsWith("#")) { - suggestComputers(builder, remaining, c -> "#" + c.getID()); - } else { - suggestComputers(builder, remaining, c -> Integer.toString(c.getInstanceID())); + } ); + } + else if( remaining.startsWith( "#" ) ) + { + suggestComputers( builder, remaining, c -> "#" + c.getID() ); + } + else + { + suggestComputers( builder, remaining, c -> Integer.toString( c.getInstanceID() ) ); } return builder.buildFuture(); - }); + } ); } @Override - public Collection getExamples() { + public Collection getExamples() + { return EXAMPLES; } - private static void suggestComputers(SuggestionsBuilder builder, String remaining, Function renderer) { - remaining = remaining.toLowerCase(Locale.ROOT); - for (ServerComputer computer : ComputerCraft.serverComputerRegistry.getComputers()) { - String converted = renderer.apply(computer); - if (converted != null && converted.toLowerCase(Locale.ROOT) - .startsWith(remaining)) { - builder.suggest(converted); + private static void suggestComputers( SuggestionsBuilder builder, String remaining, Function renderer ) + { + remaining = remaining.toLowerCase( Locale.ROOT ); + for( ServerComputer computer : ComputerCraft.serverComputerRegistry.getComputers() ) + { + String converted = renderer.apply( computer ); + if( converted != null && converted.toLowerCase( Locale.ROOT ) + .startsWith( remaining ) ) + { + builder.suggest( converted ); } } } - private static ComputersSupplier getComputers(Predicate predicate) { - return s -> Collections.unmodifiableList(ComputerCraft.serverComputerRegistry.getComputers() - .stream() - .filter(predicate) - .collect(Collectors.toList())); + private static ComputersSupplier getComputers( Predicate predicate ) + { + return s -> Collections.unmodifiableList( ComputerCraft.serverComputerRegistry.getComputers() + .stream() + .filter( predicate ) + .collect( Collectors.toList() ) ); } @FunctionalInterface - public interface ComputersSupplier { - Collection unwrap(ServerCommandSource source) throws CommandSyntaxException; + public interface ComputersSupplier + { + Collection unwrap( ServerCommandSource source ) throws CommandSyntaxException; } - public static class Serializer implements ArgumentSerializer { + public static class Serializer implements ArgumentSerializer + { @Override - public void toPacket(@Nonnull ComputersArgumentType arg, @Nonnull PacketByteBuf buf) { - buf.writeBoolean(arg.requireSome); + public void toPacket( @Nonnull ComputersArgumentType arg, @Nonnull PacketByteBuf buf ) + { + buf.writeBoolean( arg.requireSome ); } @Nonnull @Override - public ComputersArgumentType fromPacket(@Nonnull PacketByteBuf buf) { + public ComputersArgumentType fromPacket( @Nonnull PacketByteBuf buf ) + { return buf.readBoolean() ? SOME : MANY; } @Override - public void toJson(@Nonnull ComputersArgumentType arg, @Nonnull JsonObject json) { - json.addProperty("requireSome", arg.requireSome); + public void toJson( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json ) + { + json.addProperty( "requireSome", arg.requireSome ); } } } diff --git a/src/main/java/dan200/computercraft/shared/command/arguments/RepeatArgumentType.java b/src/main/java/dan200/computercraft/shared/command/arguments/RepeatArgumentType.java index 36a6f1009..6f6ac8931 100644 --- a/src/main/java/dan200/computercraft/shared/command/arguments/RepeatArgumentType.java +++ b/src/main/java/dan200/computercraft/shared/command/arguments/RepeatArgumentType.java @@ -6,15 +6,6 @@ package dan200.computercraft.shared.command.arguments; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; - -import javax.annotation.Nonnull; - import com.google.gson.JsonObject; import com.mojang.brigadier.Message; import com.mojang.brigadier.StringReader; @@ -24,13 +15,20 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; - import net.minecraft.command.argument.ArgumentTypes; import net.minecraft.command.argument.serialize.ArgumentSerializer; import net.minecraft.network.PacketByteBuf; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; + /** * Reads one argument multiple times. * @@ -42,13 +40,15 @@ import net.minecraft.text.Text; * @param The type of each value returned * @param The type of the inner parser. This will normally be a {@link List} or {@code T}. */ -public final class RepeatArgumentType implements ArgumentType> { +public final class RepeatArgumentType implements ArgumentType> +{ private final ArgumentType child; private final BiConsumer, U> appender; private final boolean flatten; private final SimpleCommandExceptionType some; - private RepeatArgumentType(ArgumentType child, BiConsumer, U> appender, boolean flatten, SimpleCommandExceptionType some) { + private RepeatArgumentType( ArgumentType child, BiConsumer, U> appender, boolean flatten, SimpleCommandExceptionType some ) + { this.child = child; this.appender = appender; this.flatten = flatten; @@ -60,104 +60,123 @@ public final class RepeatArgumentType implements ArgumentType> { return new RepeatArgumentType<>( appender, List::add, false, missing ); } - public static RepeatArgumentType> someFlat(ArgumentType> appender, SimpleCommandExceptionType missing) { - return new RepeatArgumentType<>(appender, List::addAll, true, missing); + public static RepeatArgumentType> someFlat( ArgumentType> appender, SimpleCommandExceptionType missing ) + { + return new RepeatArgumentType<>( appender, List::addAll, true, missing ); } @Override - public List parse(StringReader reader) throws CommandSyntaxException { + public List parse( StringReader reader ) throws CommandSyntaxException + { boolean hadSome = false; List out = new ArrayList<>(); - while (true) { + while( true ) + { reader.skipWhitespace(); - if (!reader.canRead()) { + if( !reader.canRead() ) + { break; } int startParse = reader.getCursor(); - this.appender.accept(out, this.child.parse(reader)); + this.appender.accept( out, this.child.parse( reader ) ); hadSome = true; - if (reader.getCursor() == startParse) { - throw new IllegalStateException(this.child + " did not consume any input on " + reader.getRemaining()); + if( reader.getCursor() == startParse ) + { + throw new IllegalStateException( this.child + " did not consume any input on " + reader.getRemaining() ); } } // Note that each child may return an empty list, we just require that some actual input // was consumed. // We should probably review that this is sensible in the future. - if (!hadSome) { - throw this.some.createWithContext(reader); + if( !hadSome ) + { + throw this.some.createWithContext( reader ); } - return Collections.unmodifiableList(out); + return Collections.unmodifiableList( out ); } @Override - public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { - StringReader reader = new StringReader(builder.getInput()); - reader.setCursor(builder.getStart()); + public CompletableFuture listSuggestions( CommandContext context, SuggestionsBuilder builder ) + { + StringReader reader = new StringReader( builder.getInput() ); + reader.setCursor( builder.getStart() ); int previous = reader.getCursor(); - while (reader.canRead()) { - try { - this.child.parse(reader); - } catch (CommandSyntaxException e) { + while( reader.canRead() ) + { + try + { + this.child.parse( reader ); + } + catch( CommandSyntaxException e ) + { break; } int cursor = reader.getCursor(); reader.skipWhitespace(); - if (cursor == reader.getCursor()) { + if( cursor == reader.getCursor() ) + { break; } previous = reader.getCursor(); } - reader.setCursor(previous); - return this.child.listSuggestions(context, builder.createOffset(previous)); + reader.setCursor( previous ); + return this.child.listSuggestions( context, builder.createOffset( previous ) ); } @Override - public Collection getExamples() { + public Collection getExamples() + { return this.child.getExamples(); } - public static class Serializer implements ArgumentSerializer> { + public static class Serializer implements ArgumentSerializer> + { @Override - public void toPacket(@Nonnull RepeatArgumentType arg, @Nonnull PacketByteBuf buf) { - buf.writeBoolean(arg.flatten); - ArgumentTypes.toPacket(buf, arg.child); - buf.writeText(getMessage(arg)); + public void toPacket( @Nonnull RepeatArgumentType arg, @Nonnull PacketByteBuf buf ) + { + buf.writeBoolean( arg.flatten ); + ArgumentTypes.toPacket( buf, arg.child ); + buf.writeText( getMessage( arg ) ); } @Nonnull @Override - @SuppressWarnings ({ + @SuppressWarnings( { "unchecked", "rawtypes" - }) - public RepeatArgumentType fromPacket(@Nonnull PacketByteBuf buf) { + } ) + public RepeatArgumentType fromPacket( @Nonnull PacketByteBuf buf ) + { boolean isList = buf.readBoolean(); - ArgumentType child = ArgumentTypes.fromPacket(buf); + ArgumentType child = ArgumentTypes.fromPacket( buf ); Text message = buf.readText(); - BiConsumer, ?> appender = isList ? (list, x) -> list.addAll((Collection) x) : List::add; - return new RepeatArgumentType(child, appender, isList, new SimpleCommandExceptionType(message)); + BiConsumer, ?> appender = isList ? ( list, x ) -> list.addAll( (Collection) x ) : List::add; + return new RepeatArgumentType( child, appender, isList, new SimpleCommandExceptionType( message ) ); } @Override - public void toJson(@Nonnull RepeatArgumentType arg, @Nonnull JsonObject json) { - json.addProperty("flatten", arg.flatten); - json.addProperty("child", "<>"); // TODO: Potentially serialize this using reflection. - json.addProperty("error", Text.Serializer.toJson(getMessage(arg))); + public void toJson( @Nonnull RepeatArgumentType arg, @Nonnull JsonObject json ) + { + json.addProperty( "flatten", arg.flatten ); + json.addProperty( "child", "<>" ); // TODO: Potentially serialize this using reflection. + json.addProperty( "error", Text.Serializer.toJson( getMessage( arg ) ) ); } - private static Text getMessage(RepeatArgumentType arg) { + private static Text getMessage( RepeatArgumentType arg ) + { Message message = arg.some.create() - .getRawMessage(); - if (message instanceof Text) { + .getRawMessage(); + if( message instanceof Text ) + { return (Text) message; } - return new LiteralText(message.getString()); + return new LiteralText( message.getString() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/command/arguments/TrackingFieldArgumentType.java b/src/main/java/dan200/computercraft/shared/command/arguments/TrackingFieldArgumentType.java index 5f529ebf6..06f2330fd 100644 --- a/src/main/java/dan200/computercraft/shared/command/arguments/TrackingFieldArgumentType.java +++ b/src/main/java/dan200/computercraft/shared/command/arguments/TrackingFieldArgumentType.java @@ -6,20 +6,23 @@ package dan200.computercraft.shared.command.arguments; -import static dan200.computercraft.shared.command.text.ChatHelpers.translate; - import dan200.computercraft.core.tracking.TrackingField; import dan200.computercraft.shared.command.Exceptions; -public final class TrackingFieldArgumentType extends ChoiceArgumentType { +import static dan200.computercraft.shared.command.text.ChatHelpers.translate; + +public final class TrackingFieldArgumentType extends ChoiceArgumentType +{ private static final TrackingFieldArgumentType INSTANCE = new TrackingFieldArgumentType(); - private TrackingFieldArgumentType() { - super(TrackingField.fields() - .values(), TrackingField::id, x -> translate(x.translationKey()), Exceptions.TRACKING_FIELD_ARG_NONE); + private TrackingFieldArgumentType() + { + super( TrackingField.fields() + .values(), TrackingField::id, x -> translate( x.translationKey() ), Exceptions.TRACKING_FIELD_ARG_NONE ); } - public static TrackingFieldArgumentType trackingField() { + public static TrackingFieldArgumentType trackingField() + { return INSTANCE; } } diff --git a/src/main/java/dan200/computercraft/shared/command/builder/ArgCommand.java b/src/main/java/dan200/computercraft/shared/command/builder/ArgCommand.java index 58f190ca2..ea834c4c8 100644 --- a/src/main/java/dan200/computercraft/shared/command/builder/ArgCommand.java +++ b/src/main/java/dan200/computercraft/shared/command/builder/ArgCommand.java @@ -17,6 +17,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; * @param The argument given to this command when executed. */ @FunctionalInterface -public interface ArgCommand { - int run(CommandContext ctx, T arg) throws CommandSyntaxException; +public interface ArgCommand +{ + int run( CommandContext ctx, T arg ) throws CommandSyntaxException; } diff --git a/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java b/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java index 8191f43ca..901e97eb3 100644 --- a/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java +++ b/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java @@ -6,15 +6,6 @@ package dan200.computercraft.shared.command.builder; -import static dan200.computercraft.shared.command.Exceptions.ARGUMENT_EXPECTED; -import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.literal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; -import java.util.function.Supplier; - import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; @@ -22,100 +13,126 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.tree.CommandNode; import dan200.computercraft.shared.command.arguments.RepeatArgumentType; - import net.minecraft.server.command.ServerCommandSource; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import static dan200.computercraft.shared.command.Exceptions.ARGUMENT_EXPECTED; +import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.literal; + /** * An alternative way of building command nodes, so one does not have to nest. {@link ArgumentBuilder#then(CommandNode)}s. * * @param The command source we consume. */ -public class CommandBuilder implements CommandNodeBuilder> { +public class CommandBuilder implements CommandNodeBuilder> +{ private List> args = new ArrayList<>(); private Predicate requires; - public static CommandBuilder args() { + public static CommandBuilder args() + { return new CommandBuilder<>(); } - public static CommandBuilder command(String literal) { + public static CommandBuilder command( String literal ) + { CommandBuilder builder = new CommandBuilder<>(); - builder.args.add(literal(literal)); + builder.args.add( literal( literal ) ); return builder; } - public CommandBuilder requires(Predicate predicate) { - this.requires = this.requires == null ? predicate : this.requires.and(predicate); + public CommandBuilder requires( Predicate predicate ) + { + this.requires = this.requires == null ? predicate : this.requires.and( predicate ); return this; } - public CommandBuilder arg(String name, ArgumentType type) { - this.args.add(RequiredArgumentBuilder.argument(name, type)); + public CommandBuilder arg( String name, ArgumentType type ) + { + this.args.add( RequiredArgumentBuilder.argument( name, type ) ); return this; } - public CommandNodeBuilder>> argManyValue(String name, ArgumentType type, T defaultValue) { - return this.argManyValue(name, type, Collections.singletonList(defaultValue)); + public CommandNodeBuilder>> argManyValue( String name, ArgumentType type, T defaultValue ) + { + return this.argManyValue( name, type, Collections.singletonList( defaultValue ) ); } - public CommandNodeBuilder>> argManyValue(String name, ArgumentType type, List empty) { - return this.argMany(name, type, () -> empty); + public CommandNodeBuilder>> argManyValue( String name, ArgumentType type, List empty ) + { + return this.argMany( name, type, () -> empty ); } - public CommandNodeBuilder>> argMany(String name, ArgumentType type, Supplier> empty) { - return this.argMany(name, RepeatArgumentType.some(type, ARGUMENT_EXPECTED), empty); + public CommandNodeBuilder>> argMany( String name, ArgumentType type, Supplier> empty ) + { + return this.argMany( name, RepeatArgumentType.some( type, ARGUMENT_EXPECTED ), empty ); } - private CommandNodeBuilder>> argMany(String name, RepeatArgumentType type, Supplier> empty) { - if (this.args.isEmpty()) { - throw new IllegalStateException("Cannot have empty arg chain builder"); + private CommandNodeBuilder>> argMany( String name, RepeatArgumentType type, Supplier> empty ) + { + if( this.args.isEmpty() ) + { + throw new IllegalStateException( "Cannot have empty arg chain builder" ); } return command -> { // The node for no arguments - ArgumentBuilder tail = this.tail(ctx -> command.run(ctx, empty.get())); + ArgumentBuilder tail = this.tail( ctx -> command.run( ctx, empty.get() ) ); // The node for one or more arguments - ArgumentBuilder moreArg = RequiredArgumentBuilder.>argument(name, type).executes(ctx -> command.run(ctx, getList(ctx, name))); + ArgumentBuilder moreArg = RequiredArgumentBuilder.>argument( name, type ).executes( ctx -> command.run( ctx, getList( ctx, name ) ) ); // Chain all of them together! - tail.then(moreArg); - return this.link(tail); + tail.then( moreArg ); + return this.link( tail ); }; } - private ArgumentBuilder tail(Command command) { - ArgumentBuilder defaultTail = this.args.get(this.args.size() - 1); - defaultTail.executes(command); - if (this.requires != null) { - defaultTail.requires(this.requires); + private ArgumentBuilder tail( Command command ) + { + ArgumentBuilder defaultTail = this.args.get( this.args.size() - 1 ); + defaultTail.executes( command ); + if( this.requires != null ) + { + defaultTail.requires( this.requires ); } return defaultTail; } - @SuppressWarnings ("unchecked") - private static List getList(CommandContext context, String name) { - return (List) context.getArgument(name, List.class); + @SuppressWarnings( "unchecked" ) + private static List getList( CommandContext context, String name ) + { + return (List) context.getArgument( name, List.class ); } - private CommandNode link(ArgumentBuilder tail) { - for (int i = this.args.size() - 2; i >= 0; i--) { - tail = this.args.get(i) - .then(tail); + private CommandNode link( ArgumentBuilder tail ) + { + for( int i = this.args.size() - 2; i >= 0; i-- ) + { + tail = this.args.get( i ) + .then( tail ); } return tail.build(); } - public CommandNodeBuilder>> argManyFlatten(String name, ArgumentType> type, Supplier> empty) { - return this.argMany(name, RepeatArgumentType.someFlat(type, ARGUMENT_EXPECTED), empty); + public CommandNodeBuilder>> argManyFlatten( String name, ArgumentType> type, Supplier> empty ) + { + return this.argMany( name, RepeatArgumentType.someFlat( type, ARGUMENT_EXPECTED ), empty ); } @Override - public CommandNode executes(Command command) { - if (this.args.isEmpty()) { - throw new IllegalStateException("Cannot have empty arg chain builder"); + public CommandNode executes( Command command ) + { + if( this.args.isEmpty() ) + { + throw new IllegalStateException( "Cannot have empty arg chain builder" ); } - return this.link(this.tail(command)); + return this.link( this.tail( command ) ); } } diff --git a/src/main/java/dan200/computercraft/shared/command/builder/CommandNodeBuilder.java b/src/main/java/dan200/computercraft/shared/command/builder/CommandNodeBuilder.java index 765dcca2d..dc10a5eea 100644 --- a/src/main/java/dan200/computercraft/shared/command/builder/CommandNodeBuilder.java +++ b/src/main/java/dan200/computercraft/shared/command/builder/CommandNodeBuilder.java @@ -15,12 +15,13 @@ import com.mojang.brigadier.tree.CommandNode; * @param The type of action to execute when this command is run. */ @FunctionalInterface -public interface CommandNodeBuilder { +public interface CommandNodeBuilder +{ /** * Generate a command node which executes this command. * * @param command The command to run * @return The constructed node. */ - CommandNode executes(T command); + CommandNode executes( T command ); } diff --git a/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java b/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java index 1d728d9f1..58767e62d 100644 --- a/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java +++ b/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java @@ -6,14 +6,6 @@ package dan200.computercraft.shared.command.builder; -import static dan200.computercraft.shared.command.text.ChatHelpers.coloured; -import static dan200.computercraft.shared.command.text.ChatHelpers.translate; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.annotation.Nonnull; - import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.ArgumentBuilder; @@ -21,7 +13,6 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.LiteralCommandNode; - import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.ClickEvent; import net.minecraft.text.LiteralText; @@ -29,169 +20,201 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collection; + +import static dan200.computercraft.shared.command.text.ChatHelpers.coloured; +import static dan200.computercraft.shared.command.text.ChatHelpers.translate; + /** * An alternative to {@link LiteralArgumentBuilder} which also provides a {@code /... help} command, and defaults to that command when no arguments are * given. */ -public final class HelpingArgumentBuilder extends LiteralArgumentBuilder { +public final class HelpingArgumentBuilder extends LiteralArgumentBuilder +{ private static final Formatting HEADER = Formatting.LIGHT_PURPLE; private static final Formatting SYNOPSIS = Formatting.AQUA; private static final Formatting NAME = Formatting.GREEN; private final Collection children = new ArrayList<>(); - private HelpingArgumentBuilder(String literal) { - super(literal); + private HelpingArgumentBuilder( String literal ) + { + super( literal ); } - public static HelpingArgumentBuilder choice(String literal) { - return new HelpingArgumentBuilder(literal); + public static HelpingArgumentBuilder choice( String literal ) + { + return new HelpingArgumentBuilder( literal ); } - private static Command helpForChild(CommandNode node, String id, String command) { + private static Command helpForChild( CommandNode node, String id, String command ) + { return context -> { context.getSource() - .sendFeedback(getHelp(context, - node, - id + "." + node.getName() - .replace('-', '_'), - command + " " + node.getName()), false); + .sendFeedback( getHelp( context, + node, + id + "." + node.getName() + .replace( '-', '_' ), + command + " " + node.getName() ), false ); return 0; }; } - private static Text getHelp(CommandContext context, CommandNode node, String id, String command) { + private static Text getHelp( CommandContext context, CommandNode node, String id, String command ) + { // An ugly hack to extract usage information from the dispatcher. We generate a temporary node, generate // the shorthand usage, and emit that. CommandDispatcher dispatcher = context.getSource() - .getMinecraftServer() - .getCommandManager() - .getDispatcher(); - CommandNode temp = new LiteralCommandNode<>("_", null, x -> true, null, null, false); - temp.addChild(node); - String usage = dispatcher.getSmartUsage(temp, context.getSource()) - .get(node) - .substring(node.getName() - .length()); + .getMinecraftServer() + .getCommandManager() + .getDispatcher(); + CommandNode temp = new LiteralCommandNode<>( "_", null, x -> true, null, null, false ); + temp.addChild( node ); + String usage = dispatcher.getSmartUsage( temp, context.getSource() ) + .get( node ) + .substring( node.getName() + .length() ); - MutableText output = new LiteralText("").append(coloured("/" + command + usage, HEADER)) - .append(" ") - .append(coloured(translate("commands." + id + ".synopsis"), SYNOPSIS)) - .append("\n") - .append(translate("commands." + id + ".desc")); + MutableText output = new LiteralText( "" ).append( coloured( "/" + command + usage, HEADER ) ) + .append( " " ) + .append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) ) + .append( "\n" ) + .append( translate( "commands." + id + ".desc" ) ); - for (CommandNode child : node.getChildren()) { - if (!child.getRequirement() - .test(context.getSource()) || !(child instanceof LiteralCommandNode)) { + for( CommandNode child : node.getChildren() ) + { + if( !child.getRequirement() + .test( context.getSource() ) || !(child instanceof LiteralCommandNode) ) + { continue; } - output.append("\n"); + output.append( "\n" ); - MutableText component = coloured(child.getName(), NAME); + MutableText component = coloured( child.getName(), NAME ); component.getStyle() - .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " " + child.getName())); - output.append(component); + .withClickEvent( new ClickEvent( ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " " + child.getName() ) ); + output.append( component ); - output.append(" - ") - .append(translate("commands." + id + "." + child.getName() + ".synopsis")); + output.append( " - " ) + .append( translate( "commands." + id + "." + child.getName() + ".synopsis" ) ); } return output; } @Override - public LiteralArgumentBuilder then(final ArgumentBuilder argument) { - if (this.getRedirect() != null) { - throw new IllegalStateException("Cannot add children to a redirected node"); + public LiteralArgumentBuilder then( final ArgumentBuilder argument ) + { + if( this.getRedirect() != null ) + { + throw new IllegalStateException( "Cannot add children to a redirected node" ); } - if (argument instanceof HelpingArgumentBuilder) { - this.children.add((HelpingArgumentBuilder) argument); - } else if (argument instanceof LiteralArgumentBuilder) { - super.then(argument); - } else { - throw new IllegalStateException("HelpingArgumentBuilder can only accept literal children"); + if( argument instanceof HelpingArgumentBuilder ) + { + this.children.add( (HelpingArgumentBuilder) argument ); + } + else if( argument instanceof LiteralArgumentBuilder ) + { + super.then( argument ); + } + else + { + throw new IllegalStateException( "HelpingArgumentBuilder can only accept literal children" ); } return this; } @Override - public LiteralArgumentBuilder then(CommandNode argument) { - if (!(argument instanceof LiteralCommandNode)) { - throw new IllegalStateException("HelpingArgumentBuilder can only accept literal children"); + public LiteralArgumentBuilder then( CommandNode argument ) + { + if( !(argument instanceof LiteralCommandNode) ) + { + throw new IllegalStateException( "HelpingArgumentBuilder can only accept literal children" ); } - return super.then(argument); + return super.then( argument ); } @Override - public LiteralArgumentBuilder executes(final Command command) { - throw new IllegalStateException("Cannot use executes on a HelpingArgumentBuilder"); + public LiteralArgumentBuilder executes( final Command command ) + { + throw new IllegalStateException( "Cannot use executes on a HelpingArgumentBuilder" ); } @Override - public LiteralCommandNode build() { - return this.buildImpl(this.getLiteral().replace('-', '_'), this.getLiteral()); + public LiteralCommandNode build() + { + return this.buildImpl( this.getLiteral().replace( '-', '_' ), this.getLiteral() ); } - private LiteralCommandNode build(@Nonnull String id, @Nonnull String command) { - return this.buildImpl(id + "." + this.getLiteral().replace('-', '_'), command + " " + this.getLiteral()); + private LiteralCommandNode build( @Nonnull String id, @Nonnull String command ) + { + return this.buildImpl( id + "." + this.getLiteral().replace( '-', '_' ), command + " " + this.getLiteral() ); } - private LiteralCommandNode buildImpl(String id, String command) { - HelpCommand helpCommand = new HelpCommand(id, command); - LiteralCommandNode node = new LiteralCommandNode<>(this.getLiteral(), - helpCommand, this.getRequirement(), - this.getRedirect(), this.getRedirectModifier(), this.isFork()); + private LiteralCommandNode buildImpl( String id, String command ) + { + HelpCommand helpCommand = new HelpCommand( id, command ); + LiteralCommandNode node = new LiteralCommandNode<>( this.getLiteral(), + helpCommand, this.getRequirement(), + this.getRedirect(), this.getRedirectModifier(), this.isFork() ); helpCommand.node = node; // Set up a /... help command LiteralArgumentBuilder helpNode = - LiteralArgumentBuilder.literal("help").requires(x -> this.getArguments().stream() - .anyMatch( - y -> y.getRequirement() - .test( - x))) - .executes(helpCommand); + LiteralArgumentBuilder.literal( "help" ).requires( x -> this.getArguments().stream() + .anyMatch( + y -> y.getRequirement() + .test( + x ) ) ) + .executes( helpCommand ); // Add all normal command children to this and the help node - for (CommandNode child : this.getArguments()) { - node.addChild(child); + for( CommandNode child : this.getArguments() ) + { + node.addChild( child ); - helpNode.then(LiteralArgumentBuilder.literal(child.getName()).requires(child.getRequirement()) - .executes(helpForChild(child, id, command)) - .build()); + helpNode.then( LiteralArgumentBuilder.literal( child.getName() ).requires( child.getRequirement() ) + .executes( helpForChild( child, id, command ) ) + .build() ); } // And add alternative versions of which forward instead - for (HelpingArgumentBuilder childBuilder : this.children) { - LiteralCommandNode child = childBuilder.build(id, command); - node.addChild(child); - helpNode.then(LiteralArgumentBuilder.literal(child.getName()).requires(child.getRequirement()) - .executes(helpForChild(child, id, command)) - .redirect(child.getChild("help")) - .build()); + for( HelpingArgumentBuilder childBuilder : this.children ) + { + LiteralCommandNode child = childBuilder.build( id, command ); + node.addChild( child ); + helpNode.then( LiteralArgumentBuilder.literal( child.getName() ).requires( child.getRequirement() ) + .executes( helpForChild( child, id, command ) ) + .redirect( child.getChild( "help" ) ) + .build() ); } - node.addChild(helpNode.build()); + node.addChild( helpNode.build() ); return node; } - private static final class HelpCommand implements Command { + private static final class HelpCommand implements Command + { private final String id; private final String command; LiteralCommandNode node; - private HelpCommand(String id, String command) { + private HelpCommand( String id, String command ) + { this.id = id; this.command = command; } @Override - public int run(CommandContext context) { + public int run( CommandContext context ) + { context.getSource() - .sendFeedback(getHelp(context, this.node, this.id, this.command), false); + .sendFeedback( getHelp( context, this.node, this.id, this.command ), false ); return 0; } } diff --git a/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java b/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java index 56d4a7201..03a8deae0 100644 --- a/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java +++ b/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java @@ -82,7 +82,7 @@ public final class ChatHelpers style = style.withClickEvent( click ); style = style.withHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) ); - component.setStyle(style); + component.setStyle( style ); return component; } diff --git a/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java b/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java index e96081f77..4a48e8391 100644 --- a/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java +++ b/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java @@ -6,44 +6,50 @@ package dan200.computercraft.shared.command.text; -import javax.annotation.Nullable; - -import org.apache.commons.lang3.StringUtils; - import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import org.apache.commons.lang3.StringUtils; -public class ServerTableFormatter implements TableFormatter { +import javax.annotation.Nullable; + +public class ServerTableFormatter implements TableFormatter +{ private final ServerCommandSource source; - public ServerTableFormatter(ServerCommandSource source) { + public ServerTableFormatter( ServerCommandSource source ) + { this.source = source; } @Override @Nullable - public Text getPadding(Text component, int width) { - int extraWidth = width - this.getWidth(component); - if (extraWidth <= 0) { + public Text getPadding( Text component, int width ) + { + int extraWidth = width - this.getWidth( component ); + if( extraWidth <= 0 ) + { return null; } - return new LiteralText(StringUtils.repeat(' ', extraWidth)); + return new LiteralText( StringUtils.repeat( ' ', extraWidth ) ); } @Override - public int getColumnPadding() { + public int getColumnPadding() + { return 1; } @Override - public int getWidth(Text component) { + public int getWidth( Text component ) + { return component.getString() - .length(); + .length(); } @Override - public void writeLine(int id, Text component) { - this.source.sendFeedback(component, false); + public void writeLine( int id, Text component ) + { + this.source.sendFeedback( component, false ); } } diff --git a/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java b/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java index 89c9d9588..800068e29 100644 --- a/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java +++ b/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java @@ -6,65 +6,74 @@ package dan200.computercraft.shared.command.text; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.command.CommandUtils; import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.network.client.ChatTableClientMessage; - import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; -public class TableBuilder { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class TableBuilder +{ private final int id; private final Text[] headers; private final ArrayList rows = new ArrayList<>(); private int columns = -1; private int additional; - public TableBuilder(int id, @Nonnull Text... headers) { - if (id < 0) { - throw new IllegalArgumentException("ID must be positive"); + public TableBuilder( int id, @Nonnull Text... headers ) + { + if( id < 0 ) + { + throw new IllegalArgumentException( "ID must be positive" ); } this.id = id; this.headers = headers; this.columns = headers.length; } - public TableBuilder(int id) { - if (id < 0) { - throw new IllegalArgumentException("ID must be positive"); + public TableBuilder( int id ) + { + if( id < 0 ) + { + throw new IllegalArgumentException( "ID must be positive" ); } this.id = id; this.headers = null; } - public TableBuilder(int id, @Nonnull String... headers) { - if (id < 0) { - throw new IllegalArgumentException("ID must be positive"); + public TableBuilder( int id, @Nonnull String... headers ) + { + if( id < 0 ) + { + throw new IllegalArgumentException( "ID must be positive" ); } this.id = id; this.headers = new Text[headers.length]; this.columns = headers.length; - for (int i = 0; i < headers.length; i++) { - this.headers[i] = ChatHelpers.header(headers[i]); + for( int i = 0; i < headers.length; i++ ) + { + this.headers[i] = ChatHelpers.header( headers[i] ); } } - public void row(@Nonnull Text... row) { - if (this.columns == -1) { + public void row( @Nonnull Text... row ) + { + if( this.columns == -1 ) + { this.columns = row.length; } - if (row.length != this.columns) { - throw new IllegalArgumentException("Row is the incorrect length"); + if( row.length != this.columns ) + { + throw new IllegalArgumentException( "Row is the incorrect length" ); } - this.rows.add(row); + this.rows.add( row ); } /** @@ -74,7 +83,8 @@ public class TableBuilder { * * @return This table's type. */ - public int getId() { + public int getId() + { return this.id; } @@ -85,35 +95,44 @@ public class TableBuilder { * * @return The number of columns. */ - public int getColumns() { + public int getColumns() + { return this.columns; } @Nullable - public Text[] getHeaders() { + public Text[] getHeaders() + { return this.headers; } @Nonnull - public List getRows() { + public List getRows() + { return this.rows; } - public int getAdditional() { + public int getAdditional() + { return this.additional; } - public void setAdditional(int additional) { + public void setAdditional( int additional ) + { this.additional = additional; } - public void display(ServerCommandSource source) { - if (CommandUtils.isPlayer(source)) { - this.trim(18); - NetworkHandler.sendToPlayer((ServerPlayerEntity) source.getEntity(), new ChatTableClientMessage(this)); - } else { - this.trim(100); - new ServerTableFormatter(source).display(this); + public void display( ServerCommandSource source ) + { + if( CommandUtils.isPlayer( source ) ) + { + this.trim( 18 ); + NetworkHandler.sendToPlayer( (ServerPlayerEntity) source.getEntity(), new ChatTableClientMessage( this ) ); + } + else + { + this.trim( 100 ); + new ServerTableFormatter( source ).display( this ); } } @@ -122,11 +141,13 @@ public class TableBuilder { * * @param height The desired height. */ - public void trim(int height) { - if (this.rows.size() > height) { + public void trim( int height ) + { + if( this.rows.size() > height ) + { this.additional += this.rows.size() - height - 1; - this.rows.subList(height - 1, this.rows.size()) - .clear(); + this.rows.subList( height - 1, this.rows.size() ) + .clear(); } } } diff --git a/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java b/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java index 90c02e1ea..ae11ae058 100644 --- a/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java +++ b/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java @@ -6,23 +6,25 @@ package dan200.computercraft.shared.command.text; -import static dan200.computercraft.shared.command.text.ChatHelpers.coloured; -import static dan200.computercraft.shared.command.text.ChatHelpers.translate; - -import javax.annotation.Nullable; - -import org.apache.commons.lang3.StringUtils; - import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import org.apache.commons.lang3.StringUtils; -public interface TableFormatter { - Text SEPARATOR = coloured("| ", Formatting.GRAY); - Text HEADER = coloured("=", Formatting.GRAY); +import javax.annotation.Nullable; - default int display(TableBuilder table) { - if (table.getColumns() <= 0) { +import static dan200.computercraft.shared.command.text.ChatHelpers.coloured; +import static dan200.computercraft.shared.command.text.ChatHelpers.translate; + +public interface TableFormatter +{ + Text SEPARATOR = coloured( "| ", Formatting.GRAY ); + Text HEADER = coloured( "=", Formatting.GRAY ); + + default int display( TableBuilder table ) + { + if( table.getColumns() <= 0 ) + { return 0; } @@ -31,16 +33,21 @@ public interface TableFormatter { int[] maxWidths = new int[columns]; Text[] headers = table.getHeaders(); - if (headers != null) { - for (int i = 0; i < columns; i++) { - maxWidths[i] = this.getWidth(headers[i]); + if( headers != null ) + { + for( int i = 0; i < columns; i++ ) + { + maxWidths[i] = this.getWidth( headers[i] ); } } - for (Text[] row : table.getRows()) { - for (int i = 0; i < row.length; i++) { - int width = this.getWidth(row[i]); - if (width > maxWidths[i]) { + for( Text[] row : table.getRows() ) + { + for( int i = 0; i < row.length; i++ ) + { + int width = this.getWidth( row[i] ); + if( width > maxWidths[i] ) + { maxWidths[i] = width; } } @@ -49,60 +56,69 @@ public interface TableFormatter { // Add a small amount of padding after each column { int padding = this.getColumnPadding(); - for (int i = 0; i < maxWidths.length - 1; i++) { + for( int i = 0; i < maxWidths.length - 1; i++ ) + { maxWidths[i] += padding; } } // And compute the total width - int totalWidth = (columns - 1) * this.getWidth(SEPARATOR); - for (int x : maxWidths) { + int totalWidth = (columns - 1) * this.getWidth( SEPARATOR ); + for( int x : maxWidths ) + { totalWidth += x; } - if (headers != null) { - LiteralText line = new LiteralText(""); - for (int i = 0; i < columns - 1; i++) { - line.append(headers[i]); - Text padding = this.getPadding(headers[i], maxWidths[i]); - if (padding != null) { - line.append(padding); + if( headers != null ) + { + LiteralText line = new LiteralText( "" ); + for( int i = 0; i < columns - 1; i++ ) + { + line.append( headers[i] ); + Text padding = this.getPadding( headers[i], maxWidths[i] ); + if( padding != null ) + { + line.append( padding ); } - line.append(SEPARATOR); + line.append( SEPARATOR ); } - line.append(headers[columns - 1]); + line.append( headers[columns - 1] ); - this.writeLine(rowId++, line); + this.writeLine( rowId++, line ); // Write a separator line. We round the width up rather than down to make // it a tad prettier. - int rowCharWidth = this.getWidth(HEADER); + int rowCharWidth = this.getWidth( HEADER ); int rowWidth = totalWidth / rowCharWidth + (totalWidth % rowCharWidth == 0 ? 0 : 1); - this.writeLine(rowId++, coloured(StringUtils.repeat(HEADER.getString(), rowWidth), Formatting.GRAY)); + this.writeLine( rowId++, coloured( StringUtils.repeat( HEADER.getString(), rowWidth ), Formatting.GRAY ) ); } - for (Text[] row : table.getRows()) { - LiteralText line = new LiteralText(""); - for (int i = 0; i < columns - 1; i++) { - line.append(row[i]); - Text padding = this.getPadding(row[i], maxWidths[i]); - if (padding != null) { - line.append(padding); + for( Text[] row : table.getRows() ) + { + LiteralText line = new LiteralText( "" ); + for( int i = 0; i < columns - 1; i++ ) + { + line.append( row[i] ); + Text padding = this.getPadding( row[i], maxWidths[i] ); + if( padding != null ) + { + line.append( padding ); } - line.append(SEPARATOR); + line.append( SEPARATOR ); } - line.append(row[columns - 1]); - this.writeLine(rowId++, line); + line.append( row[columns - 1] ); + this.writeLine( rowId++, line ); } - if (table.getAdditional() > 0) { - this.writeLine(rowId++, coloured(translate("commands.computercraft.generic.additional_rows", table.getAdditional()), Formatting.AQUA)); + if( table.getAdditional() > 0 ) + { + this.writeLine( rowId++, coloured( translate( "commands.computercraft.generic.additional_rows", table.getAdditional() ), Formatting.AQUA ) ); } return rowId - table.getId(); } - int getWidth(Text component); + int getWidth( Text component ); /** * Get the minimum padding between each column. @@ -115,11 +131,11 @@ public interface TableFormatter { * Get additional padding for the component. * * @param component The component to pad - * @param width The desired width for the component + * @param width The desired width for the component * @return The padding for this component, or {@code null} if none is needed. */ @Nullable - Text getPadding(Text component, int width); + Text getPadding( Text component, int width ); - void writeLine(int id, Text component); + void writeLine( int id, Text component ); } diff --git a/src/main/java/dan200/computercraft/shared/common/BlockGeneric.java b/src/main/java/dan200/computercraft/shared/common/BlockGeneric.java index 95a16920f..5b5ce5a32 100644 --- a/src/main/java/dan200/computercraft/shared/common/BlockGeneric.java +++ b/src/main/java/dan200/computercraft/shared/common/BlockGeneric.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.common; -import java.util.Random; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import net.minecraft.block.Block; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; @@ -26,40 +21,52 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockView; import net.minecraft.world.World; -public abstract class BlockGeneric extends BlockWithEntity { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Random; + +public abstract class BlockGeneric extends BlockWithEntity +{ private final BlockEntityType type; - public BlockGeneric(Settings settings, BlockEntityType type) { - super(settings); + public BlockGeneric( Settings settings, BlockEntityType type ) + { + super( settings ); this.type = type; } @Override - public BlockRenderType getRenderType(BlockState state) { + public BlockRenderType getRenderType( BlockState state ) + { return BlockRenderType.MODEL; } @Override @Deprecated - public final void neighborUpdate(@Nonnull BlockState state, World world, @Nonnull BlockPos pos, @Nonnull Block neighbourBlock, - @Nonnull BlockPos neighbourPos, boolean isMoving) { - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileGeneric) { - ((TileGeneric) tile).onNeighbourChange(neighbourPos); + public final void neighborUpdate( @Nonnull BlockState state, World world, @Nonnull BlockPos pos, @Nonnull Block neighbourBlock, + @Nonnull BlockPos neighbourPos, boolean isMoving ) + { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileGeneric ) + { + ((TileGeneric) tile).onNeighbourChange( neighbourPos ); } } @Override @Deprecated - public final void onStateReplaced(@Nonnull BlockState block, @Nonnull World world, @Nonnull BlockPos pos, BlockState replace, boolean bool) { - if (block.getBlock() == replace.getBlock()) { + public final void onStateReplaced( @Nonnull BlockState block, @Nonnull World world, @Nonnull BlockPos pos, BlockState replace, boolean bool ) + { + if( block.getBlock() == replace.getBlock() ) + { return; } - BlockEntity tile = world.getBlockEntity(pos); - super.onStateReplaced(block, world, pos, replace, bool); - world.removeBlockEntity(pos); - if (tile instanceof TileGeneric) { + BlockEntity tile = world.getBlockEntity( pos ); + super.onStateReplaced( block, world, pos, replace, bool ); + world.removeBlockEntity( pos ); + if( tile instanceof TileGeneric ) + { ((TileGeneric) tile).destroy(); } } @@ -67,24 +74,28 @@ public abstract class BlockGeneric extends BlockWithEntity { @Nonnull @Override @Deprecated - public final ActionResult onUse(@Nonnull BlockState state, World world, @Nonnull BlockPos pos, @Nonnull PlayerEntity player, @Nonnull Hand hand, - @Nonnull BlockHitResult hit) { - BlockEntity tile = world.getBlockEntity(pos); - return tile instanceof TileGeneric ? ((TileGeneric) tile).onActivate(player, hand, hit) : ActionResult.PASS; + public final ActionResult onUse( @Nonnull BlockState state, World world, @Nonnull BlockPos pos, @Nonnull PlayerEntity player, @Nonnull Hand hand, + @Nonnull BlockHitResult hit ) + { + BlockEntity tile = world.getBlockEntity( pos ); + return tile instanceof TileGeneric ? ((TileGeneric) tile).onActivate( player, hand, hit ) : ActionResult.PASS; } @Override @Deprecated - public void scheduledTick(@Nonnull BlockState state, ServerWorld world, @Nonnull BlockPos pos, @Nonnull Random rand) { - BlockEntity te = world.getBlockEntity(pos); - if (te instanceof TileGeneric) { + public void scheduledTick( @Nonnull BlockState state, ServerWorld world, @Nonnull BlockPos pos, @Nonnull Random rand ) + { + BlockEntity te = world.getBlockEntity( pos ); + if( te instanceof TileGeneric ) + { ((TileGeneric) te).blockTick(); } } @Nullable @Override - public BlockEntity createBlockEntity(@Nonnull BlockView world) { + public BlockEntity createBlockEntity( @Nonnull BlockView world ) + { return this.type.instantiate(); } } diff --git a/src/main/java/dan200/computercraft/shared/common/ClientTerminal.java b/src/main/java/dan200/computercraft/shared/common/ClientTerminal.java index 5aa12c5b7..e3fd875fb 100644 --- a/src/main/java/dan200/computercraft/shared/common/ClientTerminal.java +++ b/src/main/java/dan200/computercraft/shared/common/ClientTerminal.java @@ -8,21 +8,23 @@ package dan200.computercraft.shared.common; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.network.client.TerminalState; - import net.minecraft.nbt.CompoundTag; -public class ClientTerminal implements ITerminal { +public class ClientTerminal implements ITerminal +{ private boolean m_colour; private Terminal m_terminal; private boolean m_terminalChanged; - public ClientTerminal(boolean colour) { + public ClientTerminal( boolean colour ) + { this.m_colour = colour; this.m_terminal = null; this.m_terminalChanged = false; } - public boolean pollTerminalChanged() { + public boolean pollTerminalChanged() + { boolean changed = this.m_terminalChanged; this.m_terminalChanged = false; return changed; @@ -31,48 +33,64 @@ public class ClientTerminal implements ITerminal { // ITerminal implementation @Override - public Terminal getTerminal() { + public Terminal getTerminal() + { return this.m_terminal; } @Override - public boolean isColour() { + public boolean isColour() + { return this.m_colour; } - public void read(TerminalState state) { + public void read( TerminalState state ) + { this.m_colour = state.colour; - if (state.hasTerminal()) { - this.resizeTerminal(state.width, state.height); - state.apply(this.m_terminal); - } else { + if( state.hasTerminal() ) + { + this.resizeTerminal( state.width, state.height ); + state.apply( this.m_terminal ); + } + else + { this.deleteTerminal(); } } - private void resizeTerminal(int width, int height) { - if (this.m_terminal == null) { - this.m_terminal = new Terminal(width, height, () -> this.m_terminalChanged = true); + private void resizeTerminal( int width, int height ) + { + if( this.m_terminal == null ) + { + this.m_terminal = new Terminal( width, height, () -> this.m_terminalChanged = true ); this.m_terminalChanged = true; - } else { - this.m_terminal.resize(width, height); + } + else + { + this.m_terminal.resize( width, height ); } } - private void deleteTerminal() { - if (this.m_terminal != null) { + private void deleteTerminal() + { + if( this.m_terminal != null ) + { this.m_terminal = null; this.m_terminalChanged = true; } } - public void readDescription(CompoundTag nbt) { - this.m_colour = nbt.getBoolean("colour"); - if (nbt.contains("terminal")) { - CompoundTag terminal = nbt.getCompound("terminal"); - this.resizeTerminal(terminal.getInt("term_width"), terminal.getInt("term_height")); - this.m_terminal.readFromNBT(terminal); - } else { + public void readDescription( CompoundTag nbt ) + { + this.m_colour = nbt.getBoolean( "colour" ); + if( nbt.contains( "terminal" ) ) + { + CompoundTag terminal = nbt.getCompound( "terminal" ); + this.resizeTerminal( terminal.getInt( "term_width" ), terminal.getInt( "term_height" ) ); + this.m_terminal.readFromNBT( terminal ); + } + else + { this.deleteTerminal(); } } diff --git a/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java b/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java index 00b0990a9..251bb104b 100644 --- a/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java +++ b/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java @@ -6,11 +6,8 @@ package dan200.computercraft.shared.common; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.util.ColourTracker; import dan200.computercraft.shared.util.ColourUtils; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.recipe.RecipeSerializer; @@ -20,31 +17,44 @@ import net.minecraft.util.DyeColor; import net.minecraft.util.Identifier; import net.minecraft.world.World; -public final class ColourableRecipe extends SpecialCraftingRecipe { - public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>(ColourableRecipe::new); +import javax.annotation.Nonnull; - private ColourableRecipe(Identifier id) { - super(id); +public final class ColourableRecipe extends SpecialCraftingRecipe +{ + public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>( ColourableRecipe::new ); + + private ColourableRecipe( Identifier id ) + { + super( id ); } @Override - public boolean matches(@Nonnull CraftingInventory inv, @Nonnull World world) { + public boolean matches( @Nonnull CraftingInventory inv, @Nonnull World world ) + { boolean hasColourable = false; boolean hasDye = false; - for (int i = 0; i < inv.size(); i++) { - ItemStack stack = inv.getStack(i); - if (stack.isEmpty()) { + for( int i = 0; i < inv.size(); i++ ) + { + ItemStack stack = inv.getStack( i ); + if( stack.isEmpty() ) + { continue; } - if (stack.getItem() instanceof IColouredItem) { - if (hasColourable) { + if( stack.getItem() instanceof IColouredItem ) + { + if( hasColourable ) + { return false; } hasColourable = true; - } else if (ColourUtils.getStackColour(stack) != null) { + } + else if( ColourUtils.getStackColour( stack ) != null ) + { hasDye = true; - } else { + } + else + { return false; } } @@ -54,15 +64,18 @@ public final class ColourableRecipe extends SpecialCraftingRecipe { @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inv) { + public ItemStack craft( @Nonnull CraftingInventory inv ) + { ItemStack colourable = ItemStack.EMPTY; ColourTracker tracker = new ColourTracker(); - for (int i = 0; i < inv.size(); i++) { - ItemStack stack = inv.getStack(i); + for( int i = 0; i < inv.size(); i++ ) + { + ItemStack stack = inv.getStack( i ); - if (stack.isEmpty()) { + if( stack.isEmpty() ) + { continue; } else @@ -80,13 +93,15 @@ public final class ColourableRecipe extends SpecialCraftingRecipe { } @Override - public boolean fits(int x, int y) { + public boolean fits( int x, int y ) + { return x >= 2 && y >= 2; } @Override @Nonnull - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } } diff --git a/src/main/java/dan200/computercraft/shared/common/ContainerHeldItem.java b/src/main/java/dan200/computercraft/shared/common/ContainerHeldItem.java index 2bc83d038..3d22443a0 100644 --- a/src/main/java/dan200/computercraft/shared/common/ContainerHeldItem.java +++ b/src/main/java/dan200/computercraft/shared/common/ContainerHeldItem.java @@ -6,12 +6,9 @@ package dan200.computercraft.shared.common; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.network.container.HeldItemContainerData; - +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; @@ -23,49 +20,59 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Hand; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; -public class ContainerHeldItem extends ScreenHandler { +public class ContainerHeldItem extends ScreenHandler +{ private final ItemStack stack; private final Hand hand; - public ContainerHeldItem(ScreenHandlerType type, int id, PlayerEntity player, Hand hand) { - super(type, id); + public ContainerHeldItem( ScreenHandlerType type, int id, PlayerEntity player, Hand hand ) + { + super( type, id ); this.hand = hand; - this.stack = player.getStackInHand(hand) - .copy(); + this.stack = player.getStackInHand( hand ) + .copy(); } - public static ContainerHeldItem createPrintout(int id, PlayerInventory inventory, PacketByteBuf data) { - return createPrintout(id, inventory, new HeldItemContainerData(data)); + public static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, PacketByteBuf data ) + { + return createPrintout( id, inventory, new HeldItemContainerData( data ) ); } - public static ContainerHeldItem createPrintout(int id, PlayerInventory inventory, HeldItemContainerData data) { - return new ContainerHeldItem(ComputerCraftRegistry.ModContainers.PRINTOUT, id, inventory.player, data.getHand()); + public static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, HeldItemContainerData data ) + { + return new ContainerHeldItem( ComputerCraftRegistry.ModContainers.PRINTOUT, id, inventory.player, data.getHand() ); } @Nonnull - public ItemStack getStack() { + public ItemStack getStack() + { return this.stack; } @Override - public boolean canUse(@Nonnull PlayerEntity player) { - if (!player.isAlive()) { + public boolean canUse( @Nonnull PlayerEntity player ) + { + if( !player.isAlive() ) + { return false; } - ItemStack stack = player.getStackInHand(this.hand); + ItemStack stack = player.getStackInHand( this.hand ); return stack == this.stack || !stack.isEmpty() && !this.stack.isEmpty() && stack.getItem() == this.stack.getItem(); } - public static class Factory implements NamedScreenHandlerFactory, ExtendedScreenHandlerFactory { + public static class Factory implements NamedScreenHandlerFactory, ExtendedScreenHandlerFactory + { private final ScreenHandlerType type; private final Text name; private final Hand hand; - public Factory(ScreenHandlerType type, ItemStack stack, Hand hand) { + public Factory( ScreenHandlerType type, ItemStack stack, Hand hand ) + { this.type = type; this.name = stack.getName(); this.hand = hand; @@ -73,19 +80,22 @@ public class ContainerHeldItem extends ScreenHandler { @Nonnull @Override - public Text getDisplayName() { + public Text getDisplayName() + { return this.name; } @Nullable @Override - public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player) { - return new ContainerHeldItem(this.type, id, player, this.hand); + public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player ) + { + return new ContainerHeldItem( this.type, id, player, this.hand ); } @Override - public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf) { - packetByteBuf.writeEnumConstant(this.hand); + public void writeScreenOpeningData( ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf ) + { + packetByteBuf.writeEnumConstant( this.hand ); } } } diff --git a/src/main/java/dan200/computercraft/shared/common/DefaultBundledRedstoneProvider.java b/src/main/java/dan200/computercraft/shared/common/DefaultBundledRedstoneProvider.java index da5fc974e..b1642f413 100644 --- a/src/main/java/dan200/computercraft/shared/common/DefaultBundledRedstoneProvider.java +++ b/src/main/java/dan200/computercraft/shared/common/DefaultBundledRedstoneProvider.java @@ -6,28 +6,32 @@ package dan200.computercraft.shared.common; -import javax.annotation.Nonnull; - import dan200.computercraft.api.redstone.IBundledRedstoneProvider; - import net.minecraft.block.Block; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class DefaultBundledRedstoneProvider implements IBundledRedstoneProvider { +import javax.annotation.Nonnull; + +public class DefaultBundledRedstoneProvider implements IBundledRedstoneProvider +{ @Override - public int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side) { - return getDefaultBundledRedstoneOutput(world, pos, side); + public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ) + { + return getDefaultBundledRedstoneOutput( world, pos, side ); } - public static int getDefaultBundledRedstoneOutput(World world, BlockPos pos, Direction side) { - Block block = world.getBlockState(pos) - .getBlock(); - if (block instanceof IBundledRedstoneBlock) { + public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, Direction side ) + { + Block block = world.getBlockState( pos ) + .getBlock(); + if( block instanceof IBundledRedstoneBlock ) + { IBundledRedstoneBlock generic = (IBundledRedstoneBlock) block; - if (generic.getBundledRedstoneConnectivity(world, pos, side)) { - return generic.getBundledRedstoneOutput(world, pos, side); + if( generic.getBundledRedstoneConnectivity( world, pos, side ) ) + { + return generic.getBundledRedstoneOutput( world, pos, side ); } } return -1; diff --git a/src/main/java/dan200/computercraft/shared/common/IBundledRedstoneBlock.java b/src/main/java/dan200/computercraft/shared/common/IBundledRedstoneBlock.java index a0a459727..0be19a1ff 100644 --- a/src/main/java/dan200/computercraft/shared/common/IBundledRedstoneBlock.java +++ b/src/main/java/dan200/computercraft/shared/common/IBundledRedstoneBlock.java @@ -10,8 +10,9 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public interface IBundledRedstoneBlock { - boolean getBundledRedstoneConnectivity(World world, BlockPos pos, Direction side); +public interface IBundledRedstoneBlock +{ + boolean getBundledRedstoneConnectivity( World world, BlockPos pos, Direction side ); - int getBundledRedstoneOutput(World world, BlockPos pos, Direction side); + int getBundledRedstoneOutput( World world, BlockPos pos, Direction side ); } diff --git a/src/main/java/dan200/computercraft/shared/common/IColouredItem.java b/src/main/java/dan200/computercraft/shared/common/IColouredItem.java index 05cf3a0f2..d654d9466 100644 --- a/src/main/java/dan200/computercraft/shared/common/IColouredItem.java +++ b/src/main/java/dan200/computercraft/shared/common/IColouredItem.java @@ -9,33 +9,42 @@ package dan200.computercraft.shared.common; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; -public interface IColouredItem { +public interface IColouredItem +{ String NBT_COLOUR = "Color"; - default int getColour(ItemStack stack) { - return getColourBasic(stack); + default int getColour( ItemStack stack ) + { + return getColourBasic( stack ); } - static int getColourBasic(ItemStack stack) { + static int getColourBasic( ItemStack stack ) + { CompoundTag tag = stack.getTag(); - return tag != null && tag.contains(NBT_COLOUR) ? tag.getInt(NBT_COLOUR) : -1; + return tag != null && tag.contains( NBT_COLOUR ) ? tag.getInt( NBT_COLOUR ) : -1; } - default ItemStack withColour(ItemStack stack, int colour) { + default ItemStack withColour( ItemStack stack, int colour ) + { ItemStack copy = stack.copy(); - setColourBasic(copy, colour); + setColourBasic( copy, colour ); return copy; } - static void setColourBasic(ItemStack stack, int colour) { - if (colour == -1) { + static void setColourBasic( ItemStack stack, int colour ) + { + if( colour == -1 ) + { CompoundTag tag = stack.getTag(); - if (tag != null) { - tag.remove(NBT_COLOUR); + if( tag != null ) + { + tag.remove( NBT_COLOUR ); } - } else { + } + else + { stack.getOrCreateTag() - .putInt(NBT_COLOUR, colour); + .putInt( NBT_COLOUR, colour ); } } } diff --git a/src/main/java/dan200/computercraft/shared/common/ITerminal.java b/src/main/java/dan200/computercraft/shared/common/ITerminal.java index 75dc8196c..2a6a9a9e0 100644 --- a/src/main/java/dan200/computercraft/shared/common/ITerminal.java +++ b/src/main/java/dan200/computercraft/shared/common/ITerminal.java @@ -8,7 +8,8 @@ package dan200.computercraft.shared.common; import dan200.computercraft.core.terminal.Terminal; -public interface ITerminal { +public interface ITerminal +{ Terminal getTerminal(); boolean isColour(); diff --git a/src/main/java/dan200/computercraft/shared/common/ServerTerminal.java b/src/main/java/dan200/computercraft/shared/common/ServerTerminal.java index 25153a647..294335aa1 100644 --- a/src/main/java/dan200/computercraft/shared/common/ServerTerminal.java +++ b/src/main/java/dan200/computercraft/shared/common/ServerTerminal.java @@ -6,79 +6,95 @@ package dan200.computercraft.shared.common; -import java.util.concurrent.atomic.AtomicBoolean; - import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.network.client.TerminalState; - import net.minecraft.nbt.CompoundTag; -public class ServerTerminal implements ITerminal { +import java.util.concurrent.atomic.AtomicBoolean; + +public class ServerTerminal implements ITerminal +{ private final boolean m_colour; - private final AtomicBoolean m_terminalChanged = new AtomicBoolean(false); + private final AtomicBoolean m_terminalChanged = new AtomicBoolean( false ); private Terminal m_terminal; private boolean m_terminalChangedLastFrame = false; - public ServerTerminal(boolean colour) { + public ServerTerminal( boolean colour ) + { this.m_colour = colour; this.m_terminal = null; } - public ServerTerminal(boolean colour, int terminalWidth, int terminalHeight) { + public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight ) + { this.m_colour = colour; - this.m_terminal = new Terminal(terminalWidth, terminalHeight, this::markTerminalChanged); + this.m_terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged ); } - protected void markTerminalChanged() { - this.m_terminalChanged.set(true); + protected void markTerminalChanged() + { + this.m_terminalChanged.set( true ); } - protected void resize(int width, int height) { - if (this.m_terminal == null) { - this.m_terminal = new Terminal(width, height, this::markTerminalChanged); + protected void resize( int width, int height ) + { + if( this.m_terminal == null ) + { + this.m_terminal = new Terminal( width, height, this::markTerminalChanged ); this.markTerminalChanged(); - } else { - this.m_terminal.resize(width, height); + } + else + { + this.m_terminal.resize( width, height ); } } - public void delete() { - if (this.m_terminal != null) { + public void delete() + { + if( this.m_terminal != null ) + { this.m_terminal = null; this.markTerminalChanged(); } } - public void update() { - this.m_terminalChangedLastFrame = this.m_terminalChanged.getAndSet(false); + public void update() + { + this.m_terminalChangedLastFrame = this.m_terminalChanged.getAndSet( false ); } - public boolean hasTerminalChanged() { + public boolean hasTerminalChanged() + { return this.m_terminalChangedLastFrame; } @Override - public Terminal getTerminal() { + public Terminal getTerminal() + { return this.m_terminal; } @Override - public boolean isColour() { + public boolean isColour() + { return this.m_colour; } - public TerminalState write() { - return new TerminalState(this.m_colour, this.m_terminal); + public TerminalState write() + { + return new TerminalState( this.m_colour, this.m_terminal ); } - public void writeDescription(CompoundTag nbt) { - nbt.putBoolean("colour", this.m_colour); - if (this.m_terminal != null) { + public void writeDescription( CompoundTag nbt ) + { + nbt.putBoolean( "colour", this.m_colour ); + if( this.m_terminal != null ) + { CompoundTag terminal = new CompoundTag(); - terminal.putInt("term_width", this.m_terminal.getWidth()); - terminal.putInt("term_height", this.m_terminal.getHeight()); - this.m_terminal.writeToNBT(terminal); - nbt.put("terminal", terminal); + terminal.putInt( "term_width", this.m_terminal.getWidth() ); + terminal.putInt( "term_height", this.m_terminal.getHeight() ); + this.m_terminal.writeToNBT( terminal ); + nbt.put( "terminal", terminal ); } } } diff --git a/src/main/java/dan200/computercraft/shared/common/TileGeneric.java b/src/main/java/dan200/computercraft/shared/common/TileGeneric.java index a2d37e532..a1936ca4d 100644 --- a/src/main/java/dan200/computercraft/shared/common/TileGeneric.java +++ b/src/main/java/dan200/computercraft/shared/common/TileGeneric.java @@ -6,8 +6,7 @@ package dan200.computercraft.shared.common; -import javax.annotation.Nonnull; - +import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; @@ -18,71 +17,88 @@ import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; +import javax.annotation.Nonnull; -public abstract class TileGeneric extends BlockEntity implements BlockEntityClientSerializable { - public TileGeneric(BlockEntityType type) { - super(type); +public abstract class TileGeneric extends BlockEntity implements BlockEntityClientSerializable +{ + public TileGeneric( BlockEntityType type ) + { + super( type ); } - public void destroy() { + public void destroy() + { } - public void onChunkUnloaded() { + public void onChunkUnloaded() + { } - public final void updateBlock() { + public final void updateBlock() + { this.markDirty(); BlockPos pos = this.getPos(); BlockState state = this.getCachedState(); - this.getWorld().updateListeners(pos, state, state, 3); + this.getWorld().updateListeners( pos, state, state, 3 ); } @Nonnull - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { return ActionResult.PASS; } - public void onNeighbourChange(@Nonnull BlockPos neighbour) { + public void onNeighbourChange( @Nonnull BlockPos neighbour ) + { } - public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) { + public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour ) + { } - protected void blockTick() { + protected void blockTick() + { } - public boolean isUsable(PlayerEntity player, boolean ignoreRange) { - if (player == null || !player.isAlive() || this.getWorld().getBlockEntity(this.getPos()) != this) { + public boolean isUsable( PlayerEntity player, boolean ignoreRange ) + { + if( player == null || !player.isAlive() || this.getWorld().getBlockEntity( this.getPos() ) != this ) + { return false; } - if (ignoreRange) { + if( ignoreRange ) + { return true; } - double range = this.getInteractRange(player); + double range = this.getInteractRange( player ); BlockPos pos = this.getPos(); - return player.getEntityWorld() == this.getWorld() && player.squaredDistanceTo(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5) <= range * range; + return player.getEntityWorld() == this.getWorld() && player.squaredDistanceTo( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ) <= range * range; } - protected double getInteractRange(PlayerEntity player) { + protected double getInteractRange( PlayerEntity player ) + { return 8.0; } @Override - public void fromClientTag(CompoundTag compoundTag) { - this.readDescription(compoundTag); + public void fromClientTag( CompoundTag compoundTag ) + { + this.readDescription( compoundTag ); } - protected void readDescription(@Nonnull CompoundTag nbt) { + protected void readDescription( @Nonnull CompoundTag nbt ) + { } @Override - public CompoundTag toClientTag(CompoundTag compoundTag) { - this.writeDescription(compoundTag); + public CompoundTag toClientTag( CompoundTag compoundTag ) + { + this.writeDescription( compoundTag ); return compoundTag; } - protected void writeDescription(@Nonnull CompoundTag nbt) { + protected void writeDescription( @Nonnull CompoundTag nbt ) + { } } diff --git a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java index 4966ba1ca..dd52f0bb0 100644 --- a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java +++ b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java @@ -6,24 +6,13 @@ package dan200.computercraft.shared.computer.apis; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.google.common.collect.ImmutableMap; import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.LiteralCommandNode; import dan200.computercraft.ComputerCraft; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.ILuaAPI; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.*; import dan200.computercraft.shared.computer.blocks.TileCommandComputer; import dan200.computercraft.shared.util.NBTUtil; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -36,19 +25,24 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; +import java.util.*; + /** * @cc.module commands */ -public class CommandAPI implements ILuaAPI { +public class CommandAPI implements ILuaAPI +{ private final TileCommandComputer computer; - public CommandAPI(TileCommandComputer computer) { + public CommandAPI( TileCommandComputer computer ) + { this.computer = computer; } @Override - public String[] getNames() { - return new String[] {"commands"}; + public String[] getNames() + { + return new String[] { "commands" }; } /** @@ -60,48 +54,56 @@ public class CommandAPI implements ILuaAPI { * @cc.treturn { string... } The output of this command, as a list of lines. * @cc.treturn number|nil The number of "affected" objects, or `nil` if the command failed. The definition of this varies from command to command. * @cc.usage Set the block above the command computer to stone. - *
    +     * 
          *     commands.exec("setblock ~ ~1 ~ minecraft:stone")
          *     
    */ - @LuaFunction (mainThread = true) - public final Object[] exec(String command) { - return this.doCommand(command); + @LuaFunction( mainThread = true ) + public final Object[] exec( String command ) + { + return this.doCommand( command ); } - private Object[] doCommand(String command) { + private Object[] doCommand( String command ) + { MinecraftServer server = this.computer.getWorld() - .getServer(); - if (server == null || !server.areCommandBlocksEnabled()) { + .getServer(); + if( server == null || !server.areCommandBlocksEnabled() ) + { return new Object[] { false, - createOutput("Command blocks disabled by server") + createOutput( "Command blocks disabled by server" ) }; } CommandManager commandManager = server.getCommandManager(); TileCommandComputer.CommandReceiver receiver = this.computer.getReceiver(); - try { + try + { receiver.clearOutput(); - int result = commandManager.execute(this.computer.getSource(), command); + int result = commandManager.execute( this.computer.getSource(), command ); return new Object[] { result > 0, receiver.copyOutput(), result }; - } catch (Throwable t) { - if (ComputerCraft.logComputerErrors) { - ComputerCraft.log.error("Error running command.", t); + } + catch( Throwable t ) + { + if( ComputerCraft.logComputerErrors ) + { + ComputerCraft.log.error( "Error running command.", t ); } return new Object[] { false, - createOutput("Java Exception Thrown: " + t) + createOutput( "Java Exception Thrown: " + t ) }; } } - private static Object createOutput(String output) { - return new Object[] {output}; + private static Object createOutput( String output ) + { + return new Object[] { output }; } /** @@ -118,14 +120,15 @@ public class CommandAPI implements ILuaAPI { * @return The "task id". When this command has been executed, it will queue a `task_complete` event with a matching id. * @throws LuaException (hidden) If the task cannot be created. * @cc.usage Asynchronously sets the block above the computer to stone. - *
    +     * 
          *     commands.execAsync("~ ~1 ~ minecraft:stone")
          *     
    * @cc.see parallel One may also use the parallel API to run multiple commands at once. */ @LuaFunction - public final long execAsync(ILuaContext context, String command) throws LuaException { - return context.issueMainThreadTask(() -> this.doCommand(command)); + public final long execAsync( ILuaContext context, String command ) throws LuaException + { + return context.issueMainThreadTask( () -> this.doCommand( command ) ); } /** @@ -136,29 +139,35 @@ public class CommandAPI implements ILuaAPI { * @throws LuaException (hidden) On non-string arguments. * @cc.tparam string ... The sub-command to complete. */ - @LuaFunction (mainThread = true) - public final List list(IArguments args) throws LuaException { + @LuaFunction( mainThread = true ) + public final List list( IArguments args ) throws LuaException + { MinecraftServer server = this.computer.getWorld() - .getServer(); + .getServer(); - if (server == null) { + if( server == null ) + { return Collections.emptyList(); } CommandNode node = server.getCommandManager() - .getDispatcher() - .getRoot(); - for (int j = 0; j < args.count(); j++) { - String name = args.getString(j); - node = node.getChild(name); - if (!(node instanceof LiteralCommandNode)) { + .getDispatcher() + .getRoot(); + for( int j = 0; j < args.count(); j++ ) + { + String name = args.getString( j ); + node = node.getChild( name ); + if( !(node instanceof LiteralCommandNode) ) + { return Collections.emptyList(); } } List result = new ArrayList<>(); - for (CommandNode child : node.getChildren()) { - if (child instanceof LiteralCommandNode) { - result.add(child.getName()); + for( CommandNode child : node.getChildren() ) + { + if( child instanceof LiteralCommandNode ) + { + result.add( child.getName() ); } } return result; @@ -174,7 +183,8 @@ public class CommandAPI implements ILuaAPI { * @cc.see gps.locate To get the position of a non-command computer. */ @LuaFunction - public final Object[] getBlockPosition() { + public final Object[] getBlockPosition() + { // This is probably safe to do on the Lua thread. Probably. BlockPos pos = this.computer.getPos(); return new Object[] { @@ -201,27 +211,33 @@ public class CommandAPI implements ILuaAPI { * @throws LuaException If the coordinates are not within the world. * @throws LuaException If trying to get information about more than 4096 blocks. */ - @LuaFunction (mainThread = true) - public final List> getBlockInfos(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) throws LuaException { + @LuaFunction( mainThread = true ) + public final List> getBlockInfos( int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) throws LuaException + { // Get the details of the block World world = this.computer.getWorld(); - BlockPos min = new BlockPos(Math.min(minX, maxX), Math.min(minY, maxY), Math.min(minZ, maxZ)); - BlockPos max = new BlockPos(Math.max(minX, maxX), Math.max(minY, maxY), Math.max(minZ, maxZ)); - if (!World.isInBuildLimit(min) || !World.isInBuildLimit(max)) { - throw new LuaException("Co-ordinates out of range"); + BlockPos min = new BlockPos( Math.min( minX, maxX ), Math.min( minY, maxY ), Math.min( minZ, maxZ ) ); + BlockPos max = new BlockPos( Math.max( minX, maxX ), Math.max( minY, maxY ), Math.max( minZ, maxZ ) ); + if( !World.isInBuildLimit( min ) || !World.isInBuildLimit( max ) ) + { + throw new LuaException( "Co-ordinates out of range" ); } int blocks = (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1); - if (blocks > 4096) { - throw new LuaException("Too many blocks"); + if( blocks > 4096 ) + { + throw new LuaException( "Too many blocks" ); } - List> results = new ArrayList<>(blocks); - for (int y = min.getY(); y <= max.getY(); y++) { - for (int z = min.getZ(); z <= max.getZ(); z++) { - for (int x = min.getX(); x <= max.getX(); x++) { - BlockPos pos = new BlockPos(x, y, z); - results.add(getBlockInfo(world, pos)); + List> results = new ArrayList<>( blocks ); + for( int y = min.getY(); y <= max.getY(); y++ ) + { + for( int z = min.getZ(); z <= max.getZ(); z++ ) + { + for( int x = min.getX(); x <= max.getX(); x++ ) + { + BlockPos pos = new BlockPos( x, y, z ); + results.add( getBlockInfo( world, pos ) ); } } } @@ -229,42 +245,47 @@ public class CommandAPI implements ILuaAPI { return results; } - private static Map getBlockInfo(World world, BlockPos pos) { + private static Map getBlockInfo( World world, BlockPos pos ) + { // Get the details of the block - BlockState state = world.getBlockState(pos); + BlockState state = world.getBlockState( pos ); Block block = state.getBlock(); Map table = new HashMap<>(); - table.put("name", - Registry.BLOCK.getId(block) - .toString()); - table.put("world", world.getRegistryKey()); + table.put( "name", + Registry.BLOCK.getId( block ) + .toString() ); + table.put( "world", world.getRegistryKey() ); Map stateTable = new HashMap<>(); - for (ImmutableMap.Entry, Comparable> entry : state.getEntries() - .entrySet()) { + for( ImmutableMap.Entry, Comparable> entry : state.getEntries() + .entrySet() ) + { Property property = entry.getKey(); - stateTable.put(property.getName(), getPropertyValue(property, entry.getValue())); + stateTable.put( property.getName(), getPropertyValue( property, entry.getValue() ) ); } - table.put("state", stateTable); + table.put( "state", stateTable ); - BlockEntity tile = world.getBlockEntity(pos); - if (tile != null) { - table.put("nbt", NBTUtil.toLua(tile.toTag(new CompoundTag()))); + BlockEntity tile = world.getBlockEntity( pos ); + if( tile != null ) + { + table.put( "nbt", NBTUtil.toLua( tile.toTag( new CompoundTag() ) ) ); } return table; } - @SuppressWarnings ({ + @SuppressWarnings( { "unchecked", "rawtypes" - }) - private static Object getPropertyValue(Property property, Comparable value) { - if (value instanceof String || value instanceof Number || value instanceof Boolean) { + } ) + private static Object getPropertyValue( Property property, Comparable value ) + { + if( value instanceof String || value instanceof Number || value instanceof Boolean ) + { return value; } - return property.name(value); + return property.name( value ); } /** @@ -279,15 +300,19 @@ public class CommandAPI implements ILuaAPI { * @return The given block's information. * @throws LuaException If the coordinates are not within the world, or are not currently loaded. */ - @LuaFunction (mainThread = true) - public final Map getBlockInfo(int x, int y, int z) throws LuaException { + @LuaFunction( mainThread = true ) + public final Map getBlockInfo( int x, int y, int z ) throws LuaException + { // Get the details of the block World world = this.computer.getWorld(); - BlockPos position = new BlockPos(x, y, z); - if (World.isInBuildLimit(position)) { - return getBlockInfo(world, position); - } else { - throw new LuaException("Co-ordinates out of range"); + BlockPos position = new BlockPos( x, y, z ); + if( World.isInBuildLimit( position ) ) + { + return getBlockInfo( world, position ); + } + else + { + throw new LuaException( "Co-ordinates out of range" ); } } } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputer.java b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputer.java index cb5971424..d64b679da 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputer.java @@ -6,13 +6,9 @@ package dan200.computercraft.shared.computer.blocks; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerState; import dan200.computercraft.shared.computer.items.ComputerItemFactory; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; @@ -24,32 +20,40 @@ import net.minecraft.state.property.EnumProperty; import net.minecraft.state.property.Properties; import net.minecraft.util.math.Direction; -public class BlockComputer extends BlockComputerBase { - public static final EnumProperty STATE = EnumProperty.of("state", ComputerState.class); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class BlockComputer extends BlockComputerBase +{ + public static final EnumProperty STATE = EnumProperty.of( "state", ComputerState.class ); public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - public BlockComputer(Settings settings, ComputerFamily family, BlockEntityType type) { - super(settings, family, type); - this.setDefaultState(this.getDefaultState().with(FACING, Direction.NORTH) - .with(STATE, ComputerState.OFF)); + public BlockComputer( Settings settings, ComputerFamily family, BlockEntityType type ) + { + super( settings, family, type ); + this.setDefaultState( this.getDefaultState().with( FACING, Direction.NORTH ) + .with( STATE, ComputerState.OFF ) ); } @Nullable @Override - public BlockState getPlacementState(ItemPlacementContext placement) { - return this.getDefaultState().with(FACING, - placement.getPlayerFacing() - .getOpposite()); + public BlockState getPlacementState( ItemPlacementContext placement ) + { + return this.getDefaultState().with( FACING, + placement.getPlayerFacing() + .getOpposite() ); } @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(FACING, STATE); + protected void appendProperties( StateManager.Builder builder ) + { + builder.add( FACING, STATE ); } @Nonnull @Override - protected ItemStack getItem(TileComputerBase tile) { - return tile instanceof TileComputer ? ComputerItemFactory.create((TileComputer) tile) : ItemStack.EMPTY; + protected ItemStack getItem( TileComputerBase tile ) + { + return tile instanceof TileComputer ? ComputerItemFactory.create( (TileComputer) tile ) : ItemStack.EMPTY; } } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java index 5ab2db712..a14f539d9 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java @@ -6,9 +6,6 @@ package dan200.computercraft.shared.computer.blocks; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.shared.common.BlockGeneric; @@ -16,7 +13,6 @@ import dan200.computercraft.shared.common.IBundledRedstoneBlock; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.items.IComputerItem; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; @@ -34,135 +30,162 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.BlockView; import net.minecraft.world.World; -public abstract class BlockComputerBase extends BlockGeneric implements IBundledRedstoneBlock { - private static final Identifier DROP = new Identifier(ComputerCraft.MOD_ID, "computer"); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public abstract class BlockComputerBase extends BlockGeneric implements IBundledRedstoneBlock +{ + private static final Identifier DROP = new Identifier( ComputerCraft.MOD_ID, "computer" ); private final ComputerFamily family; - protected BlockComputerBase(Settings settings, ComputerFamily family, BlockEntityType type) { - super(settings, type); + protected BlockComputerBase( Settings settings, ComputerFamily family, BlockEntityType type ) + { + super( settings, type ); this.family = family; } @Override @Deprecated - public void onBlockAdded(@Nonnull BlockState state, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState oldState, boolean isMoving) { - super.onBlockAdded(state, world, pos, oldState, isMoving); + public void onBlockAdded( @Nonnull BlockState state, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState oldState, boolean isMoving ) + { + super.onBlockAdded( state, world, pos, oldState, isMoving ); - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileComputerBase) { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileComputerBase ) + { ((TileComputerBase) tile).updateInput(); } } @Override @Deprecated - public boolean emitsRedstonePower(@Nonnull BlockState state) { + public boolean emitsRedstonePower( @Nonnull BlockState state ) + { return true; } @Override @Deprecated - public int getWeakRedstonePower(@Nonnull BlockState state, @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction incomingSide) { - return this.getStrongRedstonePower(state, world, pos, incomingSide); + public int getWeakRedstonePower( @Nonnull BlockState state, @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction incomingSide ) + { + return this.getStrongRedstonePower( state, world, pos, incomingSide ); } @Override @Deprecated - public int getStrongRedstonePower(@Nonnull BlockState state, BlockView world, @Nonnull BlockPos pos, @Nonnull Direction incomingSide) { - BlockEntity entity = world.getBlockEntity(pos); - if (!(entity instanceof TileComputerBase)) { + public int getStrongRedstonePower( @Nonnull BlockState state, BlockView world, @Nonnull BlockPos pos, @Nonnull Direction incomingSide ) + { + BlockEntity entity = world.getBlockEntity( pos ); + if( !(entity instanceof TileComputerBase) ) + { return 0; } TileComputerBase computerEntity = (TileComputerBase) entity; ServerComputer computer = computerEntity.getServerComputer(); - if (computer == null) { + if( computer == null ) + { return 0; } - ComputerSide localSide = computerEntity.remapToLocalSide(incomingSide.getOpposite()); - return computer.getRedstoneOutput(localSide); + ComputerSide localSide = computerEntity.remapToLocalSide( incomingSide.getOpposite() ); + return computer.getRedstoneOutput( localSide ); } - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.family; } @Override - public boolean getBundledRedstoneConnectivity(World world, BlockPos pos, Direction side) { + public boolean getBundledRedstoneConnectivity( World world, BlockPos pos, Direction side ) + { return true; } @Override - public int getBundledRedstoneOutput(World world, BlockPos pos, Direction side) { - BlockEntity entity = world.getBlockEntity(pos); - if (!(entity instanceof TileComputerBase)) { + public int getBundledRedstoneOutput( World world, BlockPos pos, Direction side ) + { + BlockEntity entity = world.getBlockEntity( pos ); + if( !(entity instanceof TileComputerBase) ) + { return 0; } TileComputerBase computerEntity = (TileComputerBase) entity; ServerComputer computer = computerEntity.getServerComputer(); - if (computer == null) { + if( computer == null ) + { return 0; } - ComputerSide localSide = computerEntity.remapToLocalSide(side); - return computer.getBundledRedstoneOutput(localSide); + ComputerSide localSide = computerEntity.remapToLocalSide( side ); + return computer.getBundledRedstoneOutput( localSide ); } @Override - public void afterBreak(@Nonnull World world, PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity tile, - @Nonnull ItemStack tool) { + public void afterBreak( @Nonnull World world, PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity tile, + @Nonnull ItemStack tool ) + { // Don't drop blocks here - see onBlockHarvested. - player.incrementStat(Stats.MINED.getOrCreateStat(this)); - player.addExhaustion(0.005F); + player.incrementStat( Stats.MINED.getOrCreateStat( this ) ); + player.addExhaustion( 0.005F ); } @Override - public void onPlaced(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, @Nonnull ItemStack stack) { - super.onPlaced(world, pos, state, placer, stack); + public void onPlaced( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, @Nonnull ItemStack stack ) + { + super.onPlaced( world, pos, state, placer, stack ); - BlockEntity tile = world.getBlockEntity(pos); - if (!world.isClient && tile instanceof IComputerTile && stack.getItem() instanceof IComputerItem) { + BlockEntity tile = world.getBlockEntity( pos ); + if( !world.isClient && tile instanceof IComputerTile && stack.getItem() instanceof IComputerItem ) + { IComputerTile computer = (IComputerTile) tile; IComputerItem item = (IComputerItem) stack.getItem(); - int id = item.getComputerID(stack); - if (id != -1) { - computer.setComputerID(id); + int id = item.getComputerID( stack ); + if( id != -1 ) + { + computer.setComputerID( id ); } - String label = item.getLabel(stack); - if (label != null) { - computer.setLabel(label); + String label = item.getLabel( stack ); + if( label != null ) + { + computer.setLabel( label ); } } } @Nonnull @Override - public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) { - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileComputerBase) { - ItemStack result = this.getItem((TileComputerBase) tile); - if (!result.isEmpty()) { + public ItemStack getPickStack( BlockView world, BlockPos pos, BlockState state ) + { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileComputerBase ) + { + ItemStack result = this.getItem( (TileComputerBase) tile ); + if( !result.isEmpty() ) + { return result; } } - return super.getPickStack(world, pos, state); + return super.getPickStack( world, pos, state ); } @Nonnull - protected abstract ItemStack getItem(TileComputerBase tile); + protected abstract ItemStack getItem( TileComputerBase tile ); @Override - public void onBreak(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull PlayerEntity player) { + public void onBreak( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull PlayerEntity player ) + { // Call super as it is what provides sound and block break particles. Does not do anything else. - super.onBreak(world, pos, state, player); + super.onBreak( world, pos, state, player ); - if (!(world instanceof ServerWorld)) { + if( !(world instanceof ServerWorld) ) + { return; } ServerWorld serverWorld = (ServerWorld) world; @@ -170,20 +193,22 @@ public abstract class BlockComputerBase extends Bloc // We drop the item here instead of doing it in the harvest method, as we should // drop computers for creative players too. - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileComputerBase) { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileComputerBase ) + { TileComputerBase computer = (TileComputerBase) tile; - LootContext.Builder context = new LootContext.Builder(serverWorld).random(world.random) - .parameter(LootContextParameters.ORIGIN, Vec3d.ofCenter(pos)) - .parameter(LootContextParameters.TOOL, player.getMainHandStack()) - .parameter(LootContextParameters.THIS_ENTITY, player) - .parameter(LootContextParameters.BLOCK_ENTITY, tile) - .putDrop(DROP, (ctx, out) -> out.accept(this.getItem(computer))); - for (ItemStack item : state.getDroppedStacks(context)) { - dropStack(world, pos, item); + LootContext.Builder context = new LootContext.Builder( serverWorld ).random( world.random ) + .parameter( LootContextParameters.ORIGIN, Vec3d.ofCenter( pos ) ) + .parameter( LootContextParameters.TOOL, player.getMainHandStack() ) + .parameter( LootContextParameters.THIS_ENTITY, player ) + .parameter( LootContextParameters.BLOCK_ENTITY, tile ) + .putDrop( DROP, ( ctx, out ) -> out.accept( this.getItem( computer ) ) ); + for( ItemStack item : state.getDroppedStacks( context ) ) + { + dropStack( world, pos, item ); } - state.onStacksDropped(serverWorld, pos, player.getMainHandStack()); + state.onStacksDropped( serverWorld, pos, player.getMainHandStack() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java b/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java index c285650cb..86758b264 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java @@ -6,13 +6,13 @@ package dan200.computercraft.shared.computer.blocks; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.apis.OSAPI; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * A computer or turtle wrapped as a peripheral. * @@ -21,29 +21,34 @@ import dan200.computercraft.core.apis.OSAPI; * * @cc.module computer */ -public class ComputerPeripheral implements IPeripheral { +public class ComputerPeripheral implements IPeripheral +{ private final String type; private final ComputerProxy computer; - public ComputerPeripheral(String type, ComputerProxy computer) { + public ComputerPeripheral( String type, ComputerProxy computer ) + { this.type = type; this.computer = computer; } @Nonnull @Override - public String getType() { + public String getType() + { return this.type; } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return this.computer.getTile(); } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other instanceof ComputerPeripheral && this.computer == ((ComputerPeripheral) other).computer; } @@ -51,7 +56,8 @@ public class ComputerPeripheral implements IPeripheral { * Turn the other computer on. */ @LuaFunction - public final void turnOn() { + public final void turnOn() + { this.computer.turnOn(); } @@ -59,7 +65,8 @@ public class ComputerPeripheral implements IPeripheral { * Shutdown the other computer. */ @LuaFunction - public final void shutdown() { + public final void shutdown() + { this.computer.shutdown(); } @@ -67,7 +74,8 @@ public class ComputerPeripheral implements IPeripheral { * Reboot or turn on the other computer. */ @LuaFunction - public final void reboot() { + public final void reboot() + { this.computer.reboot(); } @@ -78,7 +86,8 @@ public class ComputerPeripheral implements IPeripheral { * @see OSAPI#getComputerID() To get your computer's ID. */ @LuaFunction - public final int getID() { + public final int getID() + { return this.computer.assignID(); } @@ -88,7 +97,8 @@ public class ComputerPeripheral implements IPeripheral { * @return If the computer is on. */ @LuaFunction - public final boolean isOn() { + public final boolean isOn() + { return this.computer.isOn(); } @@ -100,7 +110,8 @@ public class ComputerPeripheral implements IPeripheral { */ @Nullable @LuaFunction - public final String getLabel() { + public final String getLabel() + { return this.computer.getLabel(); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerProxy.java b/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerProxy.java index c2c52587d..b59a3c24a 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerProxy.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerProxy.java @@ -6,67 +6,85 @@ package dan200.computercraft.shared.computer.blocks; -import java.util.function.Supplier; - import dan200.computercraft.shared.computer.core.IComputer; import dan200.computercraft.shared.computer.core.ServerComputer; +import java.util.function.Supplier; + /** * A proxy object for computer objects, delegating to {@link IComputer} or {@link TileComputer} where appropriate. */ -public class ComputerProxy { +public class ComputerProxy +{ private final Supplier get; - public ComputerProxy(Supplier get) { + public ComputerProxy( Supplier get ) + { this.get = get; } - public void turnOn() { + public void turnOn() + { TileComputerBase tile = this.getTile(); ServerComputer computer = tile.getServerComputer(); - if (computer == null) { + if( computer == null ) + { tile.m_startOn = true; - } else { + } + else + { computer.turnOn(); } } - protected TileComputerBase getTile() { + protected TileComputerBase getTile() + { return this.get.get(); } - public void shutdown() { + public void shutdown() + { TileComputerBase tile = this.getTile(); ServerComputer computer = tile.getServerComputer(); - if (computer == null) { + if( computer == null ) + { tile.m_startOn = false; - } else { + } + else + { computer.shutdown(); } } - public void reboot() { + public void reboot() + { TileComputerBase tile = this.getTile(); ServerComputer computer = tile.getServerComputer(); - if (computer == null) { + if( computer == null ) + { tile.m_startOn = true; - } else { + } + else + { computer.reboot(); } } - public int assignID() { + public int assignID() + { TileComputerBase tile = this.getTile(); ServerComputer computer = tile.getServerComputer(); return computer == null ? tile.getComputerID() : computer.getID(); } - public boolean isOn() { + public boolean isOn() + { ServerComputer computer = this.getTile().getServerComputer(); return computer != null && computer.isOn(); } - public String getLabel() { + public String getLabel() + { TileComputerBase tile = this.getTile(); ServerComputer computer = tile.getServerComputer(); return computer == null ? tile.getLabel() : computer.getLabel(); diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/IComputerTile.java b/src/main/java/dan200/computercraft/shared/computer/blocks/IComputerTile.java index 4e02f64c9..ba3e4fc0d 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/IComputerTile.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/IComputerTile.java @@ -8,14 +8,15 @@ package dan200.computercraft.shared.computer.blocks; import dan200.computercraft.shared.computer.core.ComputerFamily; -public interface IComputerTile { +public interface IComputerTile +{ int getComputerID(); - void setComputerID(int id); + void setComputerID( int id ); String getLabel(); - void setLabel(String label); + void setLabel( String label ); ComputerFamily getFamily(); } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java index e29f14665..97d3c9e62 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileCommandComputer.java @@ -6,17 +6,10 @@ package dan200.computercraft.shared.computer.blocks; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.apis.CommandAPI; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; @@ -30,100 +23,125 @@ import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameRules; -public class TileCommandComputer extends TileComputer { +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class TileCommandComputer extends TileComputer +{ private final CommandReceiver receiver; - public TileCommandComputer(ComputerFamily family, BlockEntityType type) { - super(family, type); + public TileCommandComputer( ComputerFamily family, BlockEntityType type ) + { + super( family, type ); this.receiver = new CommandReceiver(); } - public CommandReceiver getReceiver() { + public CommandReceiver getReceiver() + { return this.receiver; } - public ServerCommandSource getSource() { + public ServerCommandSource getSource() + { ServerComputer computer = this.getServerComputer(); String name = "@"; - if (computer != null) { + if( computer != null ) + { String label = computer.getLabel(); - if (label != null) { + if( label != null ) + { name = label; } } - return new ServerCommandSource(this.receiver, - new Vec3d(this.pos.getX() + 0.5, this.pos.getY() + 0.5, this.pos.getZ() + 0.5), - Vec2f.ZERO, - (ServerWorld) this.getWorld(), - 2, - name, - new LiteralText(name), - this.getWorld().getServer(), - null); + return new ServerCommandSource( this.receiver, + new Vec3d( this.pos.getX() + 0.5, this.pos.getY() + 0.5, this.pos.getZ() + 0.5 ), + Vec2f.ZERO, + (ServerWorld) this.getWorld(), + 2, + name, + new LiteralText( name ), + this.getWorld().getServer(), + null ); } @Override - protected ServerComputer createComputer(int instanceID, int id) { - ServerComputer computer = super.createComputer(instanceID, id); - computer.addAPI(new CommandAPI(this)); + protected ServerComputer createComputer( int instanceID, int id ) + { + ServerComputer computer = super.createComputer( instanceID, id ); + computer.addAPI( new CommandAPI( this ) ); return computer; } @Override - public boolean isUsable(PlayerEntity player, boolean ignoreRange) { - return isUsable(player) && super.isUsable(player, ignoreRange); + public boolean isUsable( PlayerEntity player, boolean ignoreRange ) + { + return isUsable( player ) && super.isUsable( player, ignoreRange ); } - public static boolean isUsable(PlayerEntity player) { + public static boolean isUsable( PlayerEntity player ) + { MinecraftServer server = player.getServer(); - if (server == null || !server.areCommandBlocksEnabled()) { - player.sendMessage(new TranslatableText("advMode.notEnabled"), true); + if( server == null || !server.areCommandBlocksEnabled() ) + { + player.sendMessage( new TranslatableText( "advMode.notEnabled" ), true ); return false; - } else if (ComputerCraft.commandRequireCreative ? !player.isCreativeLevelTwoOp() : !server.getPlayerManager() - .isOperator(player.getGameProfile())) { - player.sendMessage(new TranslatableText("advMode.notAllowed"), true); + } + else if( ComputerCraft.commandRequireCreative ? !player.isCreativeLevelTwoOp() : !server.getPlayerManager() + .isOperator( player.getGameProfile() ) ) + { + player.sendMessage( new TranslatableText( "advMode.notAllowed" ), true ); return false; } return true; } - public class CommandReceiver implements CommandOutput { + public class CommandReceiver implements CommandOutput + { private final Map output = new HashMap<>(); - public void clearOutput() { + public void clearOutput() + { this.output.clear(); } - public Map getOutput() { + public Map getOutput() + { return this.output; } - public Map copyOutput() { - return new HashMap<>(this.output); + public Map copyOutput() + { + return new HashMap<>( this.output ); } @Override - public void sendSystemMessage(@Nonnull Text textComponent, @Nonnull UUID id) { - this.output.put(this.output.size() + 1, textComponent.getString()); + public void sendSystemMessage( @Nonnull Text textComponent, @Nonnull UUID id ) + { + this.output.put( this.output.size() + 1, textComponent.getString() ); } @Override - public boolean shouldReceiveFeedback() { + public boolean shouldReceiveFeedback() + { return TileCommandComputer.this.getWorld().getGameRules() - .getBoolean(GameRules.SEND_COMMAND_FEEDBACK); + .getBoolean( GameRules.SEND_COMMAND_FEEDBACK ); } @Override - public boolean shouldTrackOutput() { + public boolean shouldTrackOutput() + { return true; } @Override - public boolean shouldBroadcastConsoleToOps() { + public boolean shouldBroadcastConsoleToOps() + { return TileCommandComputer.this.getWorld().getGameRules() - .getBoolean(GameRules.COMMAND_BLOCK_OUTPUT); + .getBoolean( GameRules.COMMAND_BLOCK_OUTPUT ); } } } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java index 3cd2b1908..5a487a1f4 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputer.java @@ -6,16 +6,12 @@ package dan200.computercraft.shared.computer.blocks; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ComputerState; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.inventory.ContainerComputer; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; @@ -23,62 +19,79 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.screen.ScreenHandler; import net.minecraft.util.math.Direction; -public class TileComputer extends TileComputerBase { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class TileComputer extends TileComputerBase +{ private ComputerProxy proxy; - public TileComputer(ComputerFamily family, BlockEntityType type) { - super(type, family); + public TileComputer( ComputerFamily family, BlockEntityType type ) + { + super( type, family ); } - public boolean isUsableByPlayer(PlayerEntity player) { - return this.isUsable(player, false); + public boolean isUsableByPlayer( PlayerEntity player ) + { + return this.isUsable( player, false ); } @Override - protected void updateBlockState(ComputerState newState) { + protected void updateBlockState( ComputerState newState ) + { BlockState existing = this.getCachedState(); - if (existing.get(BlockComputer.STATE) != newState) { - this.getWorld().setBlockState(this.getPos(), existing.with(BlockComputer.STATE, newState), 3); + if( existing.get( BlockComputer.STATE ) != newState ) + { + this.getWorld().setBlockState( this.getPos(), existing.with( BlockComputer.STATE, newState ), 3 ); } } @Override - public Direction getDirection() { - return this.getCachedState().get(BlockComputer.FACING); + public Direction getDirection() + { + return this.getCachedState().get( BlockComputer.FACING ); } @Override - protected ComputerSide remapLocalSide(ComputerSide localSide) { + protected ComputerSide remapLocalSide( ComputerSide localSide ) + { // For legacy reasons, computers invert the meaning of "left" and "right". A computer's front is facing // towards you, but a turtle's front is facing the other way. - if (localSide == ComputerSide.RIGHT) { + if( localSide == ComputerSide.RIGHT ) + { return ComputerSide.LEFT; } - if (localSide == ComputerSide.LEFT) { + if( localSide == ComputerSide.LEFT ) + { return ComputerSide.RIGHT; } return localSide; } @Override - protected ServerComputer createComputer(int instanceID, int id) { + protected ServerComputer createComputer( int instanceID, int id ) + { ComputerFamily family = this.getFamily(); - ServerComputer computer = new ServerComputer(this.getWorld(), - id, this.label, - instanceID, - family, - ComputerCraft.computerTermWidth, - ComputerCraft.computerTermHeight); - computer.setPosition(this.getPos()); + ServerComputer computer = new ServerComputer( this.getWorld(), + id, this.label, + instanceID, + family, + ComputerCraft.computerTermWidth, + ComputerCraft.computerTermHeight ); + computer.setPosition( this.getPos() ); return computer; } @Override - public ComputerProxy createProxy() { - if (this.proxy == null) { - this.proxy = new ComputerProxy(() -> this) { + public ComputerProxy createProxy() + { + if( this.proxy == null ) + { + this.proxy = new ComputerProxy( () -> this ) + { @Override - protected TileComputerBase getTile() { + protected TileComputerBase getTile() + { return TileComputer.this; } }; @@ -88,8 +101,9 @@ public class TileComputer extends TileComputerBase { @Nullable @Override - public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player) { - return new ContainerComputer(id, this); + public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player ) + { + return new ContainerComputer( id, this ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java index c12d44bc4..a0d1e6ea7 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.computer.blocks; -import java.util.Objects; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralTile; @@ -25,7 +20,7 @@ import dan200.computercraft.shared.network.container.ComputerContainerData; import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.RedstoneUtil; import joptsimple.internal.Strings; - +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.RedstoneWireBlock; @@ -49,10 +44,13 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Objects; public abstract class TileComputerBase extends TileGeneric implements IComputerTile, Tickable, IPeripheralTile, Nameable, NamedScreenHandlerFactory, - ExtendedScreenHandlerFactory { + ExtendedScreenHandlerFactory +{ private static final String NBT_ID = "ComputerId"; private static final String NBT_LABEL = "Label"; private static final String NBT_ON = "On"; @@ -64,16 +62,19 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT private boolean m_on = false; private boolean m_fresh = false; - public TileComputerBase(BlockEntityType type, ComputerFamily family) { - super(type); + public TileComputerBase( BlockEntityType type, ComputerFamily family ) + { + super( type ); this.family = family; } @Override - public void destroy() { + public void destroy() + { this.unload(); - for (Direction dir : DirectionUtil.FACINGS) { - RedstoneUtil.propagateRedstoneOutput(this.getWorld(), this.getPos(), dir); + for( Direction dir : DirectionUtil.FACINGS ) + { + RedstoneUtil.propagateRedstoneOutput( this.getWorld(), this.getPos(), dir ); } } @@ -83,10 +84,13 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT unload(); } - protected void unload() { - if (this.m_instanceID >= 0) { - if (!this.getWorld().isClient) { - ComputerCraft.serverComputerRegistry.remove(this.m_instanceID); + protected void unload() + { + if( this.m_instanceID >= 0 ) + { + if( !this.getWorld().isClient ) + { + ComputerCraft.serverComputerRegistry.remove( this.m_instanceID ); } this.m_instanceID = -1; } @@ -94,160 +98,194 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { - ItemStack currentItem = player.getStackInHand(hand); - if (!currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && this.canNameWithTag(player) && currentItem.hasCustomName()) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { + ItemStack currentItem = player.getStackInHand( hand ); + if( !currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && this.canNameWithTag( player ) && currentItem.hasCustomName() ) + { // Label to rename computer - if (!this.getWorld().isClient) { - this.setLabel(currentItem.getName() - .getString()); - currentItem.decrement(1); + if( !this.getWorld().isClient ) + { + this.setLabel( currentItem.getName() + .getString() ); + currentItem.decrement( 1 ); } return ActionResult.SUCCESS; - } else if (!player.isInSneakingPose()) { + } + else if( !player.isInSneakingPose() ) + { // Regular right click to activate computer - if (!this.getWorld().isClient && this.isUsable(player, false)) { + if( !this.getWorld().isClient && this.isUsable( player, false ) ) + { this.createServerComputer().turnOn(); - this.createServerComputer().sendTerminalState(player); - new ComputerContainerData(this.createServerComputer()).open(player, this); + this.createServerComputer().sendTerminalState( player ); + new ComputerContainerData( this.createServerComputer() ).open( player, this ); } return ActionResult.SUCCESS; } return ActionResult.PASS; } - protected boolean canNameWithTag(PlayerEntity player) { + protected boolean canNameWithTag( PlayerEntity player ) + { return false; } - public ServerComputer createServerComputer() { - if (this.getWorld().isClient) { + public ServerComputer createServerComputer() + { + if( this.getWorld().isClient ) + { return null; } boolean changed = false; - if (this.m_instanceID < 0) { + if( this.m_instanceID < 0 ) + { this.m_instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID(); changed = true; } - if (!ComputerCraft.serverComputerRegistry.contains(this.m_instanceID)) { - ServerComputer computer = this.createComputer(this.m_instanceID, this.m_computerID); - ComputerCraft.serverComputerRegistry.add(this.m_instanceID, computer); + if( !ComputerCraft.serverComputerRegistry.contains( this.m_instanceID ) ) + { + ServerComputer computer = this.createComputer( this.m_instanceID, this.m_computerID ); + ComputerCraft.serverComputerRegistry.add( this.m_instanceID, computer ); this.m_fresh = true; changed = true; } - if (changed) { + if( changed ) + { this.updateBlock(); this.updateInput(); } - return ComputerCraft.serverComputerRegistry.get(this.m_instanceID); + return ComputerCraft.serverComputerRegistry.get( this.m_instanceID ); } - public ServerComputer getServerComputer() { - return this.getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get(this.m_instanceID); + public ServerComputer getServerComputer() + { + return this.getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get( this.m_instanceID ); } - protected abstract ServerComputer createComputer(int instanceID, int id); + protected abstract ServerComputer createComputer( int instanceID, int id ); - public void updateInput() { - if (this.getWorld() == null || this.getWorld().isClient) { + public void updateInput() + { + if( this.getWorld() == null || this.getWorld().isClient ) + { return; } // Update all sides ServerComputer computer = this.getServerComputer(); - if (computer == null) { + if( computer == null ) + { return; } BlockPos pos = computer.getPosition(); - for (Direction dir : DirectionUtil.FACINGS) { - this.updateSideInput(computer, dir, pos.offset(dir)); + for( Direction dir : DirectionUtil.FACINGS ) + { + this.updateSideInput( computer, dir, pos.offset( dir ) ); } } - private void updateSideInput(ServerComputer computer, Direction dir, BlockPos offset) { + private void updateSideInput( ServerComputer computer, Direction dir, BlockPos offset ) + { Direction offsetSide = dir.getOpposite(); - ComputerSide localDir = this.remapToLocalSide(dir); + ComputerSide localDir = this.remapToLocalSide( dir ); - computer.setRedstoneInput(localDir, getRedstoneInput(this.world, offset, dir)); - computer.setBundledRedstoneInput(localDir, BundledRedstone.getOutput(this.getWorld(), offset, offsetSide)); - if (!this.isPeripheralBlockedOnSide(localDir)) { - IPeripheral peripheral = Peripherals.getPeripheral(this.getWorld(), offset, offsetSide); - computer.setPeripheral(localDir, peripheral); + computer.setRedstoneInput( localDir, getRedstoneInput( this.world, offset, dir ) ); + computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( this.getWorld(), offset, offsetSide ) ); + if( !this.isPeripheralBlockedOnSide( localDir ) ) + { + IPeripheral peripheral = Peripherals.getPeripheral( this.getWorld(), offset, offsetSide ); + computer.setPeripheral( localDir, peripheral ); } } - protected ComputerSide remapToLocalSide(Direction globalSide) { - return this.remapLocalSide(DirectionUtil.toLocal(this.getDirection(), globalSide)); + protected ComputerSide remapToLocalSide( Direction globalSide ) + { + return this.remapLocalSide( DirectionUtil.toLocal( this.getDirection(), globalSide ) ); } /** * Gets the redstone input for an adjacent block. * * @param world The world we exist in - * @param pos The position of the neighbour - * @param side The side we are reading from + * @param pos The position of the neighbour + * @param side The side we are reading from * @return The effective redstone power */ - protected static int getRedstoneInput(World world, BlockPos pos, Direction side) { - int power = world.getEmittedRedstonePower(pos, side); - if (power >= 15) { + protected static int getRedstoneInput( World world, BlockPos pos, Direction side ) + { + int power = world.getEmittedRedstonePower( pos, side ); + if( power >= 15 ) + { return power; } - BlockState neighbour = world.getBlockState(pos); - return neighbour.getBlock() == Blocks.REDSTONE_WIRE ? Math.max(power, neighbour.get(RedstoneWireBlock.POWER)) : power; + BlockState neighbour = world.getBlockState( pos ); + return neighbour.getBlock() == Blocks.REDSTONE_WIRE ? Math.max( power, neighbour.get( RedstoneWireBlock.POWER ) ) : power; } - protected boolean isPeripheralBlockedOnSide(ComputerSide localSide) { + protected boolean isPeripheralBlockedOnSide( ComputerSide localSide ) + { return false; } - protected ComputerSide remapLocalSide(ComputerSide localSide) { + protected ComputerSide remapLocalSide( ComputerSide localSide ) + { return localSide; } protected abstract Direction getDirection(); @Override - public void onNeighbourChange(@Nonnull BlockPos neighbour) { - this.updateInput(neighbour); + public void onNeighbourChange( @Nonnull BlockPos neighbour ) + { + this.updateInput( neighbour ); } @Override - public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) { - this.updateInput(neighbour); + public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour ) + { + this.updateInput( neighbour ); } @Override - protected void readDescription(@Nonnull CompoundTag nbt) { - super.readDescription(nbt); - this.label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null; - this.m_computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1; + protected void readDescription( @Nonnull CompoundTag nbt ) + { + super.readDescription( nbt ); + this.label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; + this.m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; } @Override - protected void writeDescription(@Nonnull CompoundTag nbt) { - super.writeDescription(nbt); - if (this.label != null) { - nbt.putString(NBT_LABEL, this.label); + protected void writeDescription( @Nonnull CompoundTag nbt ) + { + super.writeDescription( nbt ); + if( this.label != null ) + { + nbt.putString( NBT_LABEL, this.label ); } - if (this.m_computerID >= 0) { - nbt.putInt(NBT_ID, this.m_computerID); + if( this.m_computerID >= 0 ) + { + nbt.putInt( NBT_ID, this.m_computerID ); } } @Override - public void tick() { - if (!this.getWorld().isClient) { + public void tick() + { + if( !this.getWorld().isClient ) + { ServerComputer computer = this.createServerComputer(); - if (computer == null) { + if( computer == null ) + { return; } // If the computer isn't on and should be, then turn it on - if (this.m_startOn || (this.m_fresh && this.m_on)) { + if( this.m_startOn || (this.m_fresh && this.m_on) ) + { computer.turnOn(); this.m_startOn = false; } @@ -259,75 +297,89 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT this.label = computer.getLabel(); this.m_on = computer.isOn(); - if (computer.hasOutputChanged()) { + if( computer.hasOutputChanged() ) + { this.updateOutput(); } // Update the block state if needed. We don't fire a block update intentionally, // as this only really is needed on the client side. - this.updateBlockState(computer.getState()); + this.updateBlockState( computer.getState() ); - if (computer.hasOutputChanged()) { + if( computer.hasOutputChanged() ) + { this.updateOutput(); } } } - public void updateOutput() { + public void updateOutput() + { // Update redstone this.updateBlock(); - for (Direction dir : DirectionUtil.FACINGS) { - RedstoneUtil.propagateRedstoneOutput(this.getWorld(), this.getPos(), dir); + for( Direction dir : DirectionUtil.FACINGS ) + { + RedstoneUtil.propagateRedstoneOutput( this.getWorld(), this.getPos(), dir ); } } - protected abstract void updateBlockState(ComputerState newState); + protected abstract void updateBlockState( ComputerState newState ); @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); // Load ID, label and power state - this.m_computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1; - this.label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null; - this.m_on = this.m_startOn = nbt.getBoolean(NBT_ON); + this.m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; + this.label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; + this.m_on = this.m_startOn = nbt.getBoolean( NBT_ON ); } @Nonnull @Override - public CompoundTag toTag(@Nonnull CompoundTag nbt) { + public CompoundTag toTag( @Nonnull CompoundTag nbt ) + { // Save ID, label and power state - if (this.m_computerID >= 0) { - nbt.putInt(NBT_ID, this.m_computerID); + if( this.m_computerID >= 0 ) + { + nbt.putInt( NBT_ID, this.m_computerID ); } - if (this.label != null) { - nbt.putString(NBT_LABEL, this.label); + if( this.label != null ) + { + nbt.putString( NBT_LABEL, this.label ); } - nbt.putBoolean(NBT_ON, this.m_on); + nbt.putBoolean( NBT_ON, this.m_on ); - return super.toTag(nbt); + return super.toTag( nbt ); } @Override - public void markRemoved() { + public void markRemoved() + { this.unload(); super.markRemoved(); } - private void updateInput(BlockPos neighbour) { - if (this.getWorld() == null || this.getWorld().isClient) { + private void updateInput( BlockPos neighbour ) + { + if( this.getWorld() == null || this.getWorld().isClient ) + { return; } ServerComputer computer = this.getServerComputer(); - if (computer == null) { + if( computer == null ) + { return; } - for (Direction dir : DirectionUtil.FACINGS) { - BlockPos offset = this.pos.offset(dir); - if (offset.equals(neighbour)) { - this.updateSideInput(computer, dir, offset); + for( Direction dir : DirectionUtil.FACINGS ) + { + BlockPos offset = this.pos.offset( dir ); + if( offset.equals( neighbour ) ) + { + this.updateSideInput( computer, dir, offset ); return; } } @@ -336,66 +388,80 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT this.updateInput(); } - private void updateInput(Direction dir) { - if (this.getWorld() == null || this.getWorld().isClient) { + private void updateInput( Direction dir ) + { + if( this.getWorld() == null || this.getWorld().isClient ) + { return; } ServerComputer computer = this.getServerComputer(); - if (computer == null) { + if( computer == null ) + { return; } - this.updateSideInput(computer, dir, this.pos.offset(dir)); + this.updateSideInput( computer, dir, this.pos.offset( dir ) ); } @Override - public final int getComputerID() { + public final int getComputerID() + { return this.m_computerID; } @Override - public final void setComputerID(int id) { - if (this.getWorld().isClient || this.m_computerID == id) { + public final void setComputerID( int id ) + { + if( this.getWorld().isClient || this.m_computerID == id ) + { return; } this.m_computerID = id; ServerComputer computer = this.getServerComputer(); - if (computer != null) { - computer.setID(this.m_computerID); + if( computer != null ) + { + computer.setID( this.m_computerID ); } this.markDirty(); } @Override - public final String getLabel() { + public final String getLabel() + { return this.label; } // Networking stuff @Override - public final void setLabel(String label) { - if (this.getWorld().isClient || Objects.equals(this.label, label)) { + public final void setLabel( String label ) + { + if( this.getWorld().isClient || Objects.equals( this.label, label ) ) + { return; } this.label = label; ServerComputer computer = this.getServerComputer(); - if (computer != null) { - computer.setLabel(label); + if( computer != null ) + { + computer.setLabel( label ); } this.markDirty(); } @Override - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.family; } - protected void transferStateFrom(TileComputerBase copy) { - if (copy.m_computerID != this.m_computerID || copy.m_instanceID != this.m_instanceID) { + protected void transferStateFrom( TileComputerBase copy ) + { + if( copy.m_computerID != this.m_computerID || copy.m_instanceID != this.m_instanceID ) + { this.unload(); this.m_instanceID = copy.m_instanceID; this.m_computerID = copy.m_computerID; @@ -409,39 +475,45 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { - return new ComputerPeripheral("computer", this.createProxy()); + public IPeripheral getPeripheral( Direction side ) + { + return new ComputerPeripheral( "computer", this.createProxy() ); } public abstract ComputerProxy createProxy(); @Nonnull @Override - public Text getName() { - return this.hasCustomName() ? new LiteralText(this.label) : new TranslatableText(this.getCachedState().getBlock() - .getTranslationKey()); + public Text getName() + { + return this.hasCustomName() ? new LiteralText( this.label ) : new TranslatableText( this.getCachedState().getBlock() + .getTranslationKey() ); } @Override - public boolean hasCustomName() { - return !Strings.isNullOrEmpty(this.label); + public boolean hasCustomName() + { + return !Strings.isNullOrEmpty( this.label ); } @Nonnull @Override - public Text getDisplayName() { + public Text getDisplayName() + { return Nameable.super.getDisplayName(); } @Nullable @Override - public Text getCustomName() { - return this.hasCustomName() ? new LiteralText(this.label) : null; + public Text getCustomName() + { + return this.hasCustomName() ? new LiteralText( this.label ) : null; } @Override - public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf) { - packetByteBuf.writeInt(this.getServerComputer().getInstanceID()); - packetByteBuf.writeEnumConstant(this.getServerComputer().getFamily()); + public void writeScreenOpeningData( ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf ) + { + packetByteBuf.writeInt( this.getServerComputer().getInstanceID() ); + packetByteBuf.writeEnumConstant( this.getServerComputer().getFamily() ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java index 46dd11e1c..dece0c369 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java @@ -8,15 +8,11 @@ package dan200.computercraft.shared.computer.core; import dan200.computercraft.shared.common.ClientTerminal; import dan200.computercraft.shared.network.NetworkHandler; -import dan200.computercraft.shared.network.server.ComputerActionServerMessage; -import dan200.computercraft.shared.network.server.KeyEventServerMessage; -import dan200.computercraft.shared.network.server.MouseEventServerMessage; -import dan200.computercraft.shared.network.server.QueueEventServerMessage; -import dan200.computercraft.shared.network.server.RequestComputerMessage; - +import dan200.computercraft.shared.network.server.*; import net.minecraft.nbt.CompoundTag; -public class ClientComputer extends ClientTerminal implements IComputer { +public class ClientComputer extends ClientTerminal implements IComputer +{ private final int m_instanceID; private boolean m_on = false; @@ -24,94 +20,111 @@ public class ClientComputer extends ClientTerminal implements IComputer { private CompoundTag m_userData = null; - public ClientComputer(int instanceID) { - super(false); + public ClientComputer( int instanceID ) + { + super( false ); this.m_instanceID = instanceID; } - public CompoundTag getUserData() { + public CompoundTag getUserData() + { return this.m_userData; } - public void requestState() { + public void requestState() + { // Request state from server - NetworkHandler.sendToServer(new RequestComputerMessage(this.getInstanceID())); + NetworkHandler.sendToServer( new RequestComputerMessage( this.getInstanceID() ) ); } // IComputer @Override - public int getInstanceID() { + public int getInstanceID() + { return this.m_instanceID; } @Override - public void turnOn() { + public void turnOn() + { // Send turnOn to server - NetworkHandler.sendToServer(new ComputerActionServerMessage(this.m_instanceID, ComputerActionServerMessage.Action.TURN_ON)); + NetworkHandler.sendToServer( new ComputerActionServerMessage( this.m_instanceID, ComputerActionServerMessage.Action.TURN_ON ) ); } @Override - public void shutdown() { + public void shutdown() + { // Send shutdown to server - NetworkHandler.sendToServer(new ComputerActionServerMessage(this.m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN)); + NetworkHandler.sendToServer( new ComputerActionServerMessage( this.m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) ); } @Override - public void reboot() { + public void reboot() + { // Send reboot to server - NetworkHandler.sendToServer(new ComputerActionServerMessage(this.m_instanceID, ComputerActionServerMessage.Action.REBOOT)); + NetworkHandler.sendToServer( new ComputerActionServerMessage( this.m_instanceID, ComputerActionServerMessage.Action.REBOOT ) ); } @Override - public void queueEvent(String event, Object[] arguments) { + public void queueEvent( String event, Object[] arguments ) + { // Send event to server - NetworkHandler.sendToServer(new QueueEventServerMessage(this.m_instanceID, event, arguments)); + NetworkHandler.sendToServer( new QueueEventServerMessage( this.m_instanceID, event, arguments ) ); } @Override - public boolean isOn() { + public boolean isOn() + { return this.m_on; } @Override - public boolean isCursorDisplayed() { + public boolean isCursorDisplayed() + { return this.m_on && this.m_blinking; } @Override - public void keyDown(int key, boolean repeat) { - NetworkHandler.sendToServer(new KeyEventServerMessage(this.m_instanceID, - repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, - key)); + public void keyDown( int key, boolean repeat ) + { + NetworkHandler.sendToServer( new KeyEventServerMessage( this.m_instanceID, + repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, + key ) ); } @Override - public void keyUp(int key) { - NetworkHandler.sendToServer(new KeyEventServerMessage(this.m_instanceID, KeyEventServerMessage.TYPE_UP, key)); + public void keyUp( int key ) + { + NetworkHandler.sendToServer( new KeyEventServerMessage( this.m_instanceID, KeyEventServerMessage.TYPE_UP, key ) ); } @Override - public void mouseClick(int button, int x, int y) { - NetworkHandler.sendToServer(new MouseEventServerMessage(this.m_instanceID, MouseEventServerMessage.TYPE_CLICK, button, x, y)); + public void mouseClick( int button, int x, int y ) + { + NetworkHandler.sendToServer( new MouseEventServerMessage( this.m_instanceID, MouseEventServerMessage.TYPE_CLICK, button, x, y ) ); } @Override - public void mouseUp(int button, int x, int y) { - NetworkHandler.sendToServer(new MouseEventServerMessage(this.m_instanceID, MouseEventServerMessage.TYPE_UP, button, x, y)); + public void mouseUp( int button, int x, int y ) + { + NetworkHandler.sendToServer( new MouseEventServerMessage( this.m_instanceID, MouseEventServerMessage.TYPE_UP, button, x, y ) ); } @Override - public void mouseDrag(int button, int x, int y) { - NetworkHandler.sendToServer(new MouseEventServerMessage(this.m_instanceID, MouseEventServerMessage.TYPE_DRAG, button, x, y)); + public void mouseDrag( int button, int x, int y ) + { + NetworkHandler.sendToServer( new MouseEventServerMessage( this.m_instanceID, MouseEventServerMessage.TYPE_DRAG, button, x, y ) ); } @Override - public void mouseScroll(int direction, int x, int y) { - NetworkHandler.sendToServer(new MouseEventServerMessage(this.m_instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y)); + public void mouseScroll( int direction, int x, int y ) + { + NetworkHandler.sendToServer( new MouseEventServerMessage( this.m_instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) ); } - public void setState(ComputerState state, CompoundTag userData) { + public void setState( ComputerState state, CompoundTag userData ) + { this.m_on = state != ComputerState.OFF; this.m_blinking = state == ComputerState.BLINKING; this.m_userData = userData; diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ClientComputerRegistry.java b/src/main/java/dan200/computercraft/shared/computer/core/ClientComputerRegistry.java index b2b8efba5..725a8c7a5 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ClientComputerRegistry.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ClientComputerRegistry.java @@ -6,10 +6,12 @@ package dan200.computercraft.shared.computer.core; -public class ClientComputerRegistry extends ComputerRegistry { +public class ClientComputerRegistry extends ComputerRegistry +{ @Override - public void add(int instanceID, ClientComputer computer) { - super.add(instanceID, computer); + public void add( int instanceID, ClientComputer computer ) + { + super.add( instanceID, computer ); computer.requestState(); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ComputerFamily.java b/src/main/java/dan200/computercraft/shared/computer/core/ComputerFamily.java index 8ca1124b5..5964b3dbd 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ComputerFamily.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ComputerFamily.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.computer.core; -public enum ComputerFamily { +public enum ComputerFamily +{ NORMAL, ADVANCED, COMMAND } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ComputerRegistry.java b/src/main/java/dan200/computercraft/shared/computer/core/ComputerRegistry.java index 7a035c2ba..bc80c4cae 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ComputerRegistry.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ComputerRegistry.java @@ -11,56 +11,69 @@ import java.util.HashMap; import java.util.Map; import java.util.Random; -public class ComputerRegistry { +public class ComputerRegistry +{ private Map m_computers; private int m_nextUnusedInstanceID; private int m_sessionID; - protected ComputerRegistry() { + protected ComputerRegistry() + { this.m_computers = new HashMap<>(); this.reset(); } - public void reset() { + public void reset() + { this.m_computers.clear(); this.m_nextUnusedInstanceID = 0; this.m_sessionID = new Random().nextInt(); } - public int getSessionID() { + public int getSessionID() + { return this.m_sessionID; } - public int getUnusedInstanceID() { + public int getUnusedInstanceID() + { return this.m_nextUnusedInstanceID++; } - public Collection getComputers() { + public Collection getComputers() + { return this.m_computers.values(); } - public T get(int instanceID) { - if (instanceID >= 0) { - if (this.m_computers.containsKey(instanceID)) { - return this.m_computers.get(instanceID); + public T get( int instanceID ) + { + if( instanceID >= 0 ) + { + if( this.m_computers.containsKey( instanceID ) ) + { + return this.m_computers.get( instanceID ); } } return null; } - public boolean contains(int instanceID) { - return this.m_computers.containsKey(instanceID); + public boolean contains( int instanceID ) + { + return this.m_computers.containsKey( instanceID ); } - public void add(int instanceID, T computer) { - if (this.m_computers.containsKey(instanceID)) { - this.remove(instanceID); + public void add( int instanceID, T computer ) + { + if( this.m_computers.containsKey( instanceID ) ) + { + this.remove( instanceID ); } - this.m_computers.put(instanceID, computer); - this.m_nextUnusedInstanceID = Math.max(this.m_nextUnusedInstanceID, instanceID + 1); + this.m_computers.put( instanceID, computer ); + this.m_nextUnusedInstanceID = Math.max( this.m_nextUnusedInstanceID, instanceID + 1 ); } - public void remove(int instanceID) { - this.m_computers.remove(instanceID); + public void remove( int instanceID ) + { + this.m_computers.remove( instanceID ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ComputerState.java b/src/main/java/dan200/computercraft/shared/computer/core/ComputerState.java index f45b03be9..59c48797f 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ComputerState.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ComputerState.java @@ -6,27 +6,31 @@ package dan200.computercraft.shared.computer.core; -import javax.annotation.Nonnull; - import net.minecraft.util.StringIdentifiable; -public enum ComputerState implements StringIdentifiable { - OFF("off"), ON("on"), BLINKING("blinking"); +import javax.annotation.Nonnull; + +public enum ComputerState implements StringIdentifiable +{ + OFF( "off" ), ON( "on" ), BLINKING( "blinking" ); private final String name; - ComputerState(String name) { + ComputerState( String name ) + { this.name = name; } @Nonnull @Override - public String asString() { + public String asString() + { return this.name; } @Override - public String toString() { + public String toString() + { return this.name; } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/IComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/IComputer.java index 67481a857..0a119990c 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/IComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/IComputer.java @@ -8,7 +8,8 @@ package dan200.computercraft.shared.computer.core; import dan200.computercraft.shared.common.ITerminal; -public interface IComputer extends ITerminal, InputHandler { +public interface IComputer extends ITerminal, InputHandler +{ int getInstanceID(); void turnOn(); @@ -17,15 +18,18 @@ public interface IComputer extends ITerminal, InputHandler { void reboot(); - default void queueEvent(String event) { - this.queueEvent(event, null); + default void queueEvent( String event ) + { + this.queueEvent( event, null ); } @Override - void queueEvent(String event, Object[] arguments); + void queueEvent( String event, Object[] arguments ); - default ComputerState getState() { - if (!this.isOn()) { + default ComputerState getState() + { + if( !this.isOn() ) + { return ComputerState.OFF; } return this.isCursorDisplayed() ? ComputerState.BLINKING : ComputerState.ON; diff --git a/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java index 249a18c09..b25eae0a0 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java @@ -13,7 +13,8 @@ import javax.annotation.Nullable; * An instance of {@link Container} which provides a computer. You should implement this if you provide custom computers/GUIs to interact with them. */ @FunctionalInterface -public interface IContainerComputer { +public interface IContainerComputer +{ /** * Get the computer you are interacting with. * @@ -30,7 +31,8 @@ public interface IContainerComputer { * @return This container's input. */ @Nonnull - default InputState getInput() { - return new InputState(this); + default InputState getInput() + { + return new InputState( this ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/InputHandler.java b/src/main/java/dan200/computercraft/shared/computer/core/InputHandler.java index 7accc2e1c..7cc9bd2ba 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/InputHandler.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/InputHandler.java @@ -12,54 +12,61 @@ package dan200.computercraft.shared.computer.core; * @see InputState * @see IComputer */ -public interface InputHandler { - default void keyDown(int key, boolean repeat) { - this.queueEvent("key", - new Object[] { - key, - repeat - }); +public interface InputHandler +{ + default void keyDown( int key, boolean repeat ) + { + this.queueEvent( "key", + new Object[] { + key, + repeat + } ); } - void queueEvent(String event, Object[] arguments); + void queueEvent( String event, Object[] arguments ); - default void keyUp(int key) { - this.queueEvent("key_up", new Object[] {key}); + default void keyUp( int key ) + { + this.queueEvent( "key_up", new Object[] { key } ); } - default void mouseClick(int button, int x, int y) { - this.queueEvent("mouse_click", - new Object[] { - button, - x, - y - }); + default void mouseClick( int button, int x, int y ) + { + this.queueEvent( "mouse_click", + new Object[] { + button, + x, + y + } ); } - default void mouseUp(int button, int x, int y) { - this.queueEvent("mouse_up", - new Object[] { - button, - x, - y - }); + default void mouseUp( int button, int x, int y ) + { + this.queueEvent( "mouse_up", + new Object[] { + button, + x, + y + } ); } - default void mouseDrag(int button, int x, int y) { - this.queueEvent("mouse_drag", - new Object[] { - button, - x, - y - }); + default void mouseDrag( int button, int x, int y ) + { + this.queueEvent( "mouse_drag", + new Object[] { + button, + x, + y + } ); } - default void mouseScroll(int direction, int x, int y) { - this.queueEvent("mouse_scroll", - new Object[] { - direction, - x, - y - }); + default void mouseScroll( int direction, int x, int y ) + { + this.queueEvent( "mouse_scroll", + new Object[] { + direction, + x, + y + } ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/InputState.java b/src/main/java/dan200/computercraft/shared/computer/core/InputState.java index aff2367f6..d5af8608e 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/InputState.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/InputState.java @@ -13,101 +13,121 @@ import it.unimi.dsi.fastutil.ints.IntSet; /** * An {@link InputHandler} which keeps track of the current key and mouse state, and releases them when the container is closed. */ -public class InputState implements InputHandler { +public class InputState implements InputHandler +{ private final IContainerComputer owner; - private final IntSet keysDown = new IntOpenHashSet(4); + private final IntSet keysDown = new IntOpenHashSet( 4 ); private int lastMouseX; private int lastMouseY; private int lastMouseDown = -1; - public InputState(IContainerComputer owner) { + public InputState( IContainerComputer owner ) + { this.owner = owner; } @Override - public void queueEvent(String event, Object[] arguments) { + public void queueEvent( String event, Object[] arguments ) + { IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.queueEvent(event, arguments); + if( computer != null ) + { + computer.queueEvent( event, arguments ); } } @Override - public void keyDown(int key, boolean repeat) { - this.keysDown.add(key); + public void keyDown( int key, boolean repeat ) + { + this.keysDown.add( key ); IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.keyDown(key, repeat); + if( computer != null ) + { + computer.keyDown( key, repeat ); } } @Override - public void keyUp(int key) { - this.keysDown.remove(key); + public void keyUp( int key ) + { + this.keysDown.remove( key ); IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.keyUp(key); + if( computer != null ) + { + computer.keyUp( key ); } } @Override - public void mouseClick(int button, int x, int y) { + public void mouseClick( int button, int x, int y ) + { this.lastMouseX = x; this.lastMouseY = y; this.lastMouseDown = button; IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.mouseClick(button, x, y); + if( computer != null ) + { + computer.mouseClick( button, x, y ); } } @Override - public void mouseUp(int button, int x, int y) { + public void mouseUp( int button, int x, int y ) + { this.lastMouseX = x; this.lastMouseY = y; this.lastMouseDown = -1; IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.mouseUp(button, x, y); + if( computer != null ) + { + computer.mouseUp( button, x, y ); } } @Override - public void mouseDrag(int button, int x, int y) { + public void mouseDrag( int button, int x, int y ) + { this.lastMouseX = x; this.lastMouseY = y; this.lastMouseDown = button; IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.mouseDrag(button, x, y); + if( computer != null ) + { + computer.mouseDrag( button, x, y ); } } @Override - public void mouseScroll(int direction, int x, int y) { + public void mouseScroll( int direction, int x, int y ) + { this.lastMouseX = x; this.lastMouseY = y; IComputer computer = this.owner.getComputer(); - if (computer != null) { - computer.mouseScroll(direction, x, y); + if( computer != null ) + { + computer.mouseScroll( direction, x, y ); } } - public void close() { + public void close() + { IComputer computer = this.owner.getComputer(); - if (computer != null) { + if( computer != null ) + { IntIterator keys = this.keysDown.iterator(); - while (keys.hasNext()) { - computer.keyUp(keys.nextInt()); + while( keys.hasNext() ) + { + computer.keyUp( keys.nextInt() ); } - if (this.lastMouseDown != -1) { - computer.mouseUp(this.lastMouseDown, this.lastMouseX, this.lastMouseY); + if( this.lastMouseDown != -1 ) + { + computer.mouseUp( this.lastMouseDown, this.lastMouseX, this.lastMouseY ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java index cc4b1a7fa..f5c23375d 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.computer.core; -import java.io.InputStream; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraftAPIImpl; import dan200.computercraft.api.ComputerCraftAPI; @@ -29,7 +24,6 @@ import dan200.computercraft.shared.network.client.ComputerDataClientMessage; import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage; import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage; import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundTag; import net.minecraft.screen.ScreenHandler; @@ -37,7 +31,12 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -public class ServerComputer extends ServerTerminal implements IComputer, IComputerEnvironment { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.InputStream; + +public class ServerComputer extends ServerTerminal implements IComputer, IComputerEnvironment +{ private final int m_instanceID; private final ComputerFamily m_family; private final Computer m_computer; @@ -49,16 +48,17 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput private boolean m_changedLastFrame; private int m_ticksSincePing; - public ServerComputer(World world, int computerID, String label, int instanceID, ComputerFamily family, int terminalWidth, int terminalHeight) { - super(family != ComputerFamily.NORMAL, terminalWidth, terminalHeight); + public ServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family, int terminalWidth, int terminalHeight ) + { + super( family != ComputerFamily.NORMAL, terminalWidth, terminalHeight ); this.m_instanceID = instanceID; this.m_world = world; this.m_position = null; this.m_family = family; - this.m_computer = new Computer(this, this.getTerminal(), computerID); - this.m_computer.setLabel(label); + this.m_computer = new Computer( this, this.getTerminal(), computerID ); + this.m_computer.setLabel( label ); this.m_userData = null; this.m_changed = false; @@ -66,36 +66,44 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput this.m_ticksSincePing = 0; } - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.m_family; } - public World getWorld() { + public World getWorld() + { return this.m_world; } - public void setWorld(World world) { + public void setWorld( World world ) + { this.m_world = world; } - public BlockPos getPosition() { + public BlockPos getPosition() + { return this.m_position; } - public void setPosition(BlockPos pos) { - this.m_position = new BlockPos(pos); + public void setPosition( BlockPos pos ) + { + this.m_position = new BlockPos( pos ); } - public IAPIEnvironment getAPIEnvironment() { + public IAPIEnvironment getAPIEnvironment() + { return this.m_computer.getAPIEnvironment(); } - public Computer getComputer() { + public Computer getComputer() + { return this.m_computer; } @Override - public void update() { + public void update() + { super.update(); this.m_computer.tick(); @@ -105,81 +113,102 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput this.m_ticksSincePing++; } - public void keepAlive() { + public void keepAlive() + { this.m_ticksSincePing = 0; } - public boolean hasTimedOut() { + public boolean hasTimedOut() + { return this.m_ticksSincePing > 100; } - public void unload() { + public void unload() + { this.m_computer.unload(); } - public CompoundTag getUserData() { - if (this.m_userData == null) { + public CompoundTag getUserData() + { + if( this.m_userData == null ) + { this.m_userData = new CompoundTag(); } return this.m_userData; } - public void updateUserData() { + public void updateUserData() + { this.m_changed = true; } - public void broadcastState(boolean force) { - if (this.hasOutputChanged() || force) { + public void broadcastState( boolean force ) + { + if( this.hasOutputChanged() || force ) + { // Send computer state to all clients MinecraftServer server = GameInstanceUtils.getServer(); - if (server != null) { - NetworkHandler.sendToAllPlayers(server, this.createComputerPacket()); + if( server != null ) + { + NetworkHandler.sendToAllPlayers( server, this.createComputerPacket() ); } } - if (this.hasTerminalChanged() || force) { + if( this.hasTerminalChanged() || force ) + { MinecraftServer server = GameInstanceUtils.getServer(); - if (server != null) { + if( server != null ) + { // Send terminal state to clients who are currently interacting with the computer. NetworkMessage packet = null; - for (PlayerEntity player : server.getPlayerManager() - .getPlayerList()) { - if (this.isInteracting(player)) { - if (packet == null) { + for( PlayerEntity player : server.getPlayerManager() + .getPlayerList() ) + { + if( this.isInteracting( player ) ) + { + if( packet == null ) + { packet = this.createTerminalPacket(); } - NetworkHandler.sendToPlayer(player, packet); + NetworkHandler.sendToPlayer( player, packet ); } } } } } - public boolean hasOutputChanged() { + public boolean hasOutputChanged() + { return this.m_changedLastFrame; } - private NetworkMessage createComputerPacket() { - return new ComputerDataClientMessage(this); + private NetworkMessage createComputerPacket() + { + return new ComputerDataClientMessage( this ); } - protected boolean isInteracting(PlayerEntity player) { - return this.getContainer(player) != null; + protected boolean isInteracting( PlayerEntity player ) + { + return this.getContainer( player ) != null; } - protected NetworkMessage createTerminalPacket() { - return new ComputerTerminalClientMessage(this.getInstanceID(), this.write()); + protected NetworkMessage createTerminalPacket() + { + return new ComputerTerminalClientMessage( this.getInstanceID(), this.write() ); } @Nullable - public IContainerComputer getContainer(PlayerEntity player) { - if (player == null) { + public IContainerComputer getContainer( PlayerEntity player ) + { + if( player == null ) + { return null; } ScreenHandler container = player.currentScreenHandler; - if (!(container instanceof IContainerComputer)) { + if( !(container instanceof IContainerComputer) ) + { return null; } @@ -188,12 +217,14 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput } @Override - public int getInstanceID() { + public int getInstanceID() + { return this.m_instanceID; } @Override - public void turnOn() { + public void turnOn() + { // Turn on this.m_computer.turnOn(); } @@ -201,147 +232,176 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput // IComputer @Override - public void shutdown() { + public void shutdown() + { // Shutdown this.m_computer.shutdown(); } @Override - public void reboot() { + public void reboot() + { // Reboot this.m_computer.reboot(); } @Override - public void queueEvent(String event, Object[] arguments) { + public void queueEvent( String event, Object[] arguments ) + { // Queue event - this.m_computer.queueEvent(event, arguments); + this.m_computer.queueEvent( event, arguments ); } @Override - public boolean isOn() { + public boolean isOn() + { return this.m_computer.isOn(); } @Override - public boolean isCursorDisplayed() { + public boolean isCursorDisplayed() + { return this.m_computer.isOn() && this.m_computer.isBlinking(); } - public void sendComputerState(PlayerEntity player) { + public void sendComputerState( PlayerEntity player ) + { // Send state to client - NetworkHandler.sendToPlayer(player, this.createComputerPacket()); + NetworkHandler.sendToPlayer( player, this.createComputerPacket() ); } - public void sendTerminalState(PlayerEntity player) { + public void sendTerminalState( PlayerEntity player ) + { // Send terminal state to client - NetworkHandler.sendToPlayer(player, this.createTerminalPacket()); + NetworkHandler.sendToPlayer( player, this.createTerminalPacket() ); } - public void broadcastDelete() { + public void broadcastDelete() + { // Send deletion to client MinecraftServer server = GameInstanceUtils.getServer(); - if (server != null) { - NetworkHandler.sendToAllPlayers(server, new ComputerDeletedClientMessage(this.getInstanceID())); + if( server != null ) + { + NetworkHandler.sendToAllPlayers( server, new ComputerDeletedClientMessage( this.getInstanceID() ) ); } } - public int getID() { + public int getID() + { return this.m_computer.getID(); } - public void setID(int id) { - this.m_computer.setID(id); + public void setID( int id ) + { + this.m_computer.setID( id ); } - public String getLabel() { + public String getLabel() + { return this.m_computer.getLabel(); } - public void setLabel(String label) { - this.m_computer.setLabel(label); + public void setLabel( String label ) + { + this.m_computer.setLabel( label ); } - public int getRedstoneOutput(ComputerSide side) { + public int getRedstoneOutput( ComputerSide side ) + { return this.m_computer.getEnvironment() - .getExternalRedstoneOutput(side); + .getExternalRedstoneOutput( side ); } - public void setRedstoneInput(ComputerSide side, int level) { + public void setRedstoneInput( ComputerSide side, int level ) + { this.m_computer.getEnvironment() - .setRedstoneInput(side, level); + .setRedstoneInput( side, level ); } - public int getBundledRedstoneOutput(ComputerSide side) { + public int getBundledRedstoneOutput( ComputerSide side ) + { return this.m_computer.getEnvironment() - .getExternalBundledRedstoneOutput(side); + .getExternalBundledRedstoneOutput( side ); } - public void setBundledRedstoneInput(ComputerSide side, int combination) { + public void setBundledRedstoneInput( ComputerSide side, int combination ) + { this.m_computer.getEnvironment() - .setBundledRedstoneInput(side, combination); + .setBundledRedstoneInput( side, combination ); } - public void addAPI(ILuaAPI api) { - this.m_computer.addApi(api); + public void addAPI( ILuaAPI api ) + { + this.m_computer.addApi( api ); } // IComputerEnvironment implementation - public void setPeripheral(ComputerSide side, IPeripheral peripheral) { + public void setPeripheral( ComputerSide side, IPeripheral peripheral ) + { this.m_computer.getEnvironment() - .setPeripheral(side, peripheral); + .setPeripheral( side, peripheral ); } - public IPeripheral getPeripheral(ComputerSide side) { + public IPeripheral getPeripheral( ComputerSide side ) + { return this.m_computer.getEnvironment() - .getPeripheral(side); + .getPeripheral( side ); } @Override - public int getDay() { + public int getDay() + { return (int) ((this.m_world.getTimeOfDay() + 6000) / 24000) + 1; } @Override - public double getTimeOfDay() { + public double getTimeOfDay() + { return (this.m_world.getTimeOfDay() + 6000) % 24000 / 1000.0; } @Override - public long getComputerSpaceLimit() { + public long getComputerSpaceLimit() + { return ComputerCraft.computerSpaceLimit; } @Nonnull @Override - public String getHostString() { - return String.format("ComputerCraft %s (Minecraft %s)", ComputerCraftAPI.getInstalledVersion(), "1.16.4"); + public String getHostString() + { + return String.format( "ComputerCraft %s (Minecraft %s)", ComputerCraftAPI.getInstalledVersion(), "1.16.4" ); } @Nonnull @Override - public String getUserAgent() { + public String getUserAgent() + { return ComputerCraft.MOD_ID + "/" + ComputerCraftAPI.getInstalledVersion(); } @Override - public int assignNewID() { - return ComputerCraftAPI.createUniqueNumberedSaveDir(this.m_world, "computer"); + public int assignNewID() + { + return ComputerCraftAPI.createUniqueNumberedSaveDir( this.m_world, "computer" ); } @Override - public IWritableMount createSaveDirMount(String subPath, long capacity) { - return ComputerCraftAPI.createSaveDirMount(this.m_world, subPath, capacity); + public IWritableMount createSaveDirMount( String subPath, long capacity ) + { + return ComputerCraftAPI.createSaveDirMount( this.m_world, subPath, capacity ); } @Override - public IMount createResourceMount(String domain, String subPath) { - return ComputerCraftAPI.createResourceMount(domain, subPath); + public IMount createResourceMount( String domain, String subPath ) + { + return ComputerCraftAPI.createResourceMount( domain, subPath ); } @Override - public InputStream createResourceFile(String domain, String subPath) { - return ComputerCraftAPIImpl.getResourceFile(domain, subPath); + public InputStream createResourceFile( String domain, String subPath ) + { + return ComputerCraftAPIImpl.getResourceFile( domain, subPath ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java index fa90ad956..2cdcf4052 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java @@ -8,30 +8,39 @@ package dan200.computercraft.shared.computer.core; import java.util.Iterator; -public class ServerComputerRegistry extends ComputerRegistry { - public void update() { +public class ServerComputerRegistry extends ComputerRegistry +{ + public void update() + { Iterator it = this.getComputers().iterator(); - while (it.hasNext()) { + while( it.hasNext() ) + { ServerComputer computer = it.next(); - if (computer.hasTimedOut()) { + if( computer.hasTimedOut() ) + { //System.out.println( "TIMED OUT SERVER COMPUTER " + computer.getInstanceID() ); computer.unload(); computer.broadcastDelete(); it.remove(); //System.out.println( getComputers().size() + " SERVER COMPUTERS" ); - } else { + } + else + { computer.update(); - if (computer.hasTerminalChanged() || computer.hasOutputChanged()) { - computer.broadcastState(false); + if( computer.hasTerminalChanged() || computer.hasOutputChanged() ) + { + computer.broadcastState( false ); } } } } @Override - public void reset() { + public void reset() + { //System.out.println( "RESET SERVER COMPUTERS" ); - for (ServerComputer computer : this.getComputers()) { + for( ServerComputer computer : this.getComputers() ) + { computer.unload(); } super.reset(); @@ -39,32 +48,39 @@ public class ServerComputerRegistry extends ComputerRegistry { } @Override - public void add(int instanceID, ServerComputer computer) { + public void add( int instanceID, ServerComputer computer ) + { //System.out.println( "ADD SERVER COMPUTER " + instanceID ); - super.add(instanceID, computer); - computer.broadcastState(true); + super.add( instanceID, computer ); + computer.broadcastState( true ); //System.out.println( getComputers().size() + " SERVER COMPUTERS" ); } @Override - public void remove(int instanceID) { + public void remove( int instanceID ) + { //System.out.println( "REMOVE SERVER COMPUTER " + instanceID ); - ServerComputer computer = this.get(instanceID); - if (computer != null) { + ServerComputer computer = this.get( instanceID ); + if( computer != null ) + { computer.unload(); computer.broadcastDelete(); } - super.remove(instanceID); + super.remove( instanceID ); //System.out.println( getComputers().size() + " SERVER COMPUTERS" ); } - public ServerComputer lookup(int computerID) { - if (computerID < 0) { + public ServerComputer lookup( int computerID ) + { + if( computerID < 0 ) + { return null; } - for (ServerComputer computer : this.getComputers()) { - if (computer.getID() == computerID) { + for( ServerComputer computer : this.getComputers() ) + { + if( computer.getID() == computerID ) + { return computer; } } diff --git a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java index d7ae8eed1..f4202bbe1 100644 --- a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java @@ -8,16 +8,18 @@ package dan200.computercraft.shared.computer.inventory; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.blocks.TileComputer; - import net.minecraft.entity.player.PlayerInventory; import net.minecraft.network.PacketByteBuf; -public class ContainerComputer extends ContainerComputerBase { - public ContainerComputer(int id, TileComputer tile) { - super(ComputerCraftRegistry.ModContainers.COMPUTER, id, tile::isUsableByPlayer, tile.createServerComputer(), tile.getFamily()); +public class ContainerComputer extends ContainerComputerBase +{ + public ContainerComputer( int id, TileComputer tile ) + { + super( ComputerCraftRegistry.ModContainers.COMPUTER, id, tile::isUsableByPlayer, tile.createServerComputer(), tile.getFamily() ); } - public ContainerComputer(int i, PlayerInventory playerInventory, PacketByteBuf packetByteBuf) { - super(ComputerCraftRegistry.ModContainers.COMPUTER, i, playerInventory, packetByteBuf); + public ContainerComputer( int i, PlayerInventory playerInventory, PacketByteBuf packetByteBuf ) + { + super( ComputerCraftRegistry.ModContainers.COMPUTER, i, playerInventory, packetByteBuf ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputerBase.java index ed33e7488..1d317d5b4 100644 --- a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputerBase.java @@ -6,86 +6,91 @@ package dan200.computercraft.shared.computer.inventory; -import java.util.Objects; -import java.util.function.Predicate; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; -import dan200.computercraft.shared.computer.core.ClientComputer; -import dan200.computercraft.shared.computer.core.ComputerFamily; -import dan200.computercraft.shared.computer.core.IComputer; -import dan200.computercraft.shared.computer.core.IContainerComputer; -import dan200.computercraft.shared.computer.core.InputState; +import dan200.computercraft.shared.computer.core.*; import dan200.computercraft.shared.network.container.ComputerContainerData; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.network.PacketByteBuf; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandlerType; -public class ContainerComputerBase extends ScreenHandler implements IContainerComputer { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Objects; +import java.util.function.Predicate; + +public class ContainerComputerBase extends ScreenHandler implements IContainerComputer +{ private final Predicate canUse; private final IComputer computer; private final ComputerFamily family; - private final InputState input = new InputState(this); + private final InputState input = new InputState( this ); - protected ContainerComputerBase(ScreenHandlerType type, int id, PlayerInventory player, PacketByteBuf packetByteBuf) { - this(type, - id, - x -> true, - getComputer(player, new ComputerContainerData(new PacketByteBuf(packetByteBuf.copy()))), - new ComputerContainerData(new PacketByteBuf(packetByteBuf.copy())).getFamily()); + protected ContainerComputerBase( ScreenHandlerType type, int id, PlayerInventory player, PacketByteBuf packetByteBuf ) + { + this( type, + id, + x -> true, + getComputer( player, new ComputerContainerData( new PacketByteBuf( packetByteBuf.copy() ) ) ), + new ComputerContainerData( new PacketByteBuf( packetByteBuf.copy() ) ).getFamily() ); } - protected ContainerComputerBase(ScreenHandlerType type, int id, Predicate canUse, IComputer computer, - ComputerFamily family) { - super(type, id); + protected ContainerComputerBase( ScreenHandlerType type, int id, Predicate canUse, IComputer computer, + ComputerFamily family ) + { + super( type, id ); this.canUse = canUse; - this.computer = Objects.requireNonNull(computer); + this.computer = Objects.requireNonNull( computer ); this.family = family; } - protected static IComputer getComputer(PlayerInventory player, ComputerContainerData data) { + protected static IComputer getComputer( PlayerInventory player, ComputerContainerData data ) + { int id = data.getInstanceId(); - if (!player.player.world.isClient) { - return ComputerCraft.serverComputerRegistry.get(id); + if( !player.player.world.isClient ) + { + return ComputerCraft.serverComputerRegistry.get( id ); } - ClientComputer computer = ComputerCraft.clientComputerRegistry.get(id); - if (computer == null) { - ComputerCraft.clientComputerRegistry.add(id, computer = new ClientComputer(id)); + ClientComputer computer = ComputerCraft.clientComputerRegistry.get( id ); + if( computer == null ) + { + ComputerCraft.clientComputerRegistry.add( id, computer = new ClientComputer( id ) ); } return computer; } @Nonnull - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.family; } @Nullable @Override - public IComputer getComputer() { + public IComputer getComputer() + { return this.computer; } @Nonnull @Override - public InputState getInput() { + public InputState getInput() + { return this.input; } @Override - public void close(@Nonnull PlayerEntity player) { - super.close(player); + public void close( @Nonnull PlayerEntity player ) + { + super.close( player ); this.input.close(); } @Override - public boolean canUse(@Nonnull PlayerEntity player) { - return this.canUse.test(player); + public boolean canUse( @Nonnull PlayerEntity player ) + { + return this.canUse.test( player ); } } diff --git a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java index dee003e66..d32722b82 100644 --- a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerViewComputer.java @@ -6,8 +6,6 @@ package dan200.computercraft.shared.computer.inventory; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.blocks.TileCommandComputer; @@ -15,42 +13,50 @@ import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.network.container.ViewComputerContainerData; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.network.PacketByteBuf; -public class ContainerViewComputer extends ContainerComputerBase implements IContainerComputer { +import javax.annotation.Nonnull; + +public class ContainerViewComputer extends ContainerComputerBase implements IContainerComputer +{ private final int width; private final int height; - public ContainerViewComputer(int id, ServerComputer computer) { - super(ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, id, player -> canInteractWith(computer, player), computer, computer.getFamily()); + public ContainerViewComputer( int id, ServerComputer computer ) + { + super( ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, id, player -> canInteractWith( computer, player ), computer, computer.getFamily() ); this.width = this.height = 0; } - public ContainerViewComputer(int id, PlayerInventory player, PacketByteBuf packetByteBuf) { - super(ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, id, player, packetByteBuf); - ViewComputerContainerData data = new ViewComputerContainerData(new PacketByteBuf(packetByteBuf.copy())); + public ContainerViewComputer( int id, PlayerInventory player, PacketByteBuf packetByteBuf ) + { + super( ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, id, player, packetByteBuf ); + ViewComputerContainerData data = new ViewComputerContainerData( new PacketByteBuf( packetByteBuf.copy() ) ); this.width = data.getWidth(); this.height = data.getHeight(); } - private static boolean canInteractWith(@Nonnull ServerComputer computer, @Nonnull PlayerEntity player) { + private static boolean canInteractWith( @Nonnull ServerComputer computer, @Nonnull PlayerEntity player ) + { // If this computer no longer exists then discard it. - if (ComputerCraft.serverComputerRegistry.get(computer.getInstanceID()) != computer) { + if( ComputerCraft.serverComputerRegistry.get( computer.getInstanceID() ) != computer ) + { return false; } // If we're a command computer then ensure we're in creative - return computer.getFamily() != ComputerFamily.COMMAND || TileCommandComputer.isUsable(player); + return computer.getFamily() != ComputerFamily.COMMAND || TileCommandComputer.isUsable( player ); } - public int getWidth() { + public int getWidth() + { return this.width; } - public int getHeight() { + public int getHeight() + { return this.height; } } diff --git a/src/main/java/dan200/computercraft/shared/computer/items/ComputerItemFactory.java b/src/main/java/dan200/computercraft/shared/computer/items/ComputerItemFactory.java index 9f3ce0bfa..b267240c5 100644 --- a/src/main/java/dan200/computercraft/shared/computer/items/ComputerItemFactory.java +++ b/src/main/java/dan200/computercraft/shared/computer/items/ComputerItemFactory.java @@ -6,33 +6,36 @@ package dan200.computercraft.shared.computer.items; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.blocks.TileComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; - import net.minecraft.item.ItemStack; -public final class ComputerItemFactory { +import javax.annotation.Nonnull; + +public final class ComputerItemFactory +{ private ComputerItemFactory() {} @Nonnull - public static ItemStack create(TileComputer tile) { - return create(tile.getComputerID(), tile.getLabel(), tile.getFamily()); + public static ItemStack create( TileComputer tile ) + { + return create( tile.getComputerID(), tile.getLabel(), tile.getFamily() ); } @Nonnull - public static ItemStack create(int id, String label, ComputerFamily family) { - switch (family) { - case NORMAL: - return ComputerCraftRegistry.ModItems.COMPUTER_NORMAL.create(id, label); - case ADVANCED: - return ComputerCraftRegistry.ModItems.COMPUTER_ADVANCED.create(id, label); - case COMMAND: - return ComputerCraftRegistry.ModItems.COMPUTER_COMMAND.create(id, label); - default: - return ItemStack.EMPTY; + public static ItemStack create( int id, String label, ComputerFamily family ) + { + switch( family ) + { + case NORMAL: + return ComputerCraftRegistry.ModItems.COMPUTER_NORMAL.create( id, label ); + case ADVANCED: + return ComputerCraftRegistry.ModItems.COMPUTER_ADVANCED.create( id, label ); + case COMMAND: + return ComputerCraftRegistry.ModItems.COMPUTER_COMMAND.create( id, label ); + default: + return ItemStack.EMPTY; } } } diff --git a/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java b/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java index 20fc1add4..1b802e19d 100644 --- a/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java +++ b/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java @@ -6,27 +6,29 @@ package dan200.computercraft.shared.computer.items; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.ComputerFamily; - import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; -public interface IComputerItem { +import javax.annotation.Nonnull; + +public interface IComputerItem +{ String NBT_ID = "ComputerId"; - default int getComputerID(@Nonnull ItemStack stack) { + default int getComputerID( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1; + return nbt != null && nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; } - default String getLabel(@Nonnull ItemStack stack) { + default String getLabel( @Nonnull ItemStack stack ) + { return stack.hasCustomName() ? stack.getName() - .getString() : null; + .getString() : null; } ComputerFamily getFamily(); - ItemStack withFamily(@Nonnull ItemStack stack, @Nonnull ComputerFamily family); + ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ); } diff --git a/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java b/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java index 6618b95fe..4b6da8aa2 100644 --- a/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java @@ -6,36 +6,42 @@ package dan200.computercraft.shared.computer.items; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.blocks.BlockComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; - import net.minecraft.item.ItemStack; import net.minecraft.text.LiteralText; -public class ItemComputer extends ItemComputerBase { - public ItemComputer(BlockComputer block, Settings settings) { - super(block, settings); +import javax.annotation.Nonnull; + +public class ItemComputer extends ItemComputerBase +{ + public ItemComputer( BlockComputer block, Settings settings ) + { + super( block, settings ); } - public ItemStack create(int id, String label) { - ItemStack result = new ItemStack(this); - if (id >= 0) { + public ItemStack create( int id, String label ) + { + ItemStack result = new ItemStack( this ); + if( id >= 0 ) + { result.getOrCreateTag() - .putInt(NBT_ID, id); + .putInt( NBT_ID, id ); } - if (label != null) { - result.setCustomName(new LiteralText(label)); + if( label != null ) + { + result.setCustomName( new LiteralText( label ) ); } return result; } @Override - public ItemStack withFamily(@Nonnull ItemStack stack, @Nonnull ComputerFamily family) { - ItemStack result = ComputerItemFactory.create(this.getComputerID(stack), null, family); - if (stack.hasCustomName()) { - result.setCustomName(stack.getName()); + public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ) + { + ItemStack result = ComputerItemFactory.create( this.getComputerID( stack ), null, family ); + if( stack.hasCustomName() ) + { + result.setCustomName( stack.getName() ); } return result; } diff --git a/src/main/java/dan200/computercraft/shared/computer/items/ItemComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/items/ItemComputerBase.java index 64d0792b4..395ce5b24 100644 --- a/src/main/java/dan200/computercraft/shared/computer/items/ItemComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/items/ItemComputerBase.java @@ -6,18 +6,12 @@ package dan200.computercraft.shared.computer.items; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.media.IMedia; import dan200.computercraft.shared.computer.blocks.BlockComputerBase; import dan200.computercraft.shared.computer.core.ComputerFamily; - import net.minecraft.client.item.TooltipContext; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; @@ -27,53 +21,71 @@ import net.minecraft.text.TranslatableText; import net.minecraft.util.Formatting; import net.minecraft.world.World; -public abstract class ItemComputerBase extends BlockItem implements IComputerItem, IMedia { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public abstract class ItemComputerBase extends BlockItem implements IComputerItem, IMedia +{ private final ComputerFamily family; - public ItemComputerBase(BlockComputerBase block, Settings settings) { - super(block, settings); + public ItemComputerBase( BlockComputerBase block, Settings settings ) + { + super( block, settings ); this.family = block.getFamily(); } @Override - public void appendTooltip(@Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, @Nonnull TooltipContext options) { - if (options.isAdvanced() || this.getLabel(stack) == null) { - int id = this.getComputerID(stack); - if (id >= 0) { - list.add(new TranslatableText("gui.computercraft.tooltip.computer_id", id).formatted(Formatting.GRAY)); + public void appendTooltip( @Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, @Nonnull TooltipContext options ) + { + if( options.isAdvanced() || this.getLabel( stack ) == null ) + { + int id = this.getComputerID( stack ); + if( id >= 0 ) + { + list.add( new TranslatableText( "gui.computercraft.tooltip.computer_id", id ).formatted( Formatting.GRAY ) ); } } } @Override - public String getLabel(@Nonnull ItemStack stack) { - return IComputerItem.super.getLabel(stack); + public String getLabel( @Nonnull ItemStack stack ) + { + return IComputerItem.super.getLabel( stack ); } @Override - public final ComputerFamily getFamily() { + public final ComputerFamily getFamily() + { return this.family; } // IMedia implementation @Override - public boolean setLabel(@Nonnull ItemStack stack, String label) { - if (label != null) { - stack.setCustomName(new LiteralText(label)); - } else { + public boolean setLabel( @Nonnull ItemStack stack, String label ) + { + if( label != null ) + { + stack.setCustomName( new LiteralText( label ) ); + } + else + { stack.removeCustomName(); } return true; } @Override - public IMount createDataMount(@Nonnull ItemStack stack, @Nonnull World world) { + public IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world ) + { ComputerFamily family = this.getFamily(); - if (family != ComputerFamily.COMMAND) { - int id = this.getComputerID(stack); - if (id >= 0) { - return ComputerCraftAPI.createSaveDirMount(world, "computer/" + id, ComputerCraft.computerSpaceLimit); + if( family != ComputerFamily.COMMAND ) + { + int id = this.getComputerID( stack ); + if( id >= 0 ) + { + return ComputerCraftAPI.createSaveDirMount( world, "computer/" + id, ComputerCraft.computerSpaceLimit ); } } return null; diff --git a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java index 5c784728b..07a149301 100644 --- a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java +++ b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java @@ -6,10 +6,7 @@ package dan200.computercraft.shared.computer.recipe; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.items.IComputerItem; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; @@ -18,32 +15,41 @@ import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; +import javax.annotation.Nonnull; + /** * Represents a recipe which converts a computer from one form into another. */ -public abstract class ComputerConvertRecipe extends ShapedRecipe { +public abstract class ComputerConvertRecipe extends ShapedRecipe +{ private final String group; - public ComputerConvertRecipe(Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result) { - super(identifier, group, width, height, ingredients, result); + public ComputerConvertRecipe( Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result ) + { + super( identifier, group, width, height, ingredients, result ); this.group = group; } @Nonnull @Override - public String getGroup() { + public String getGroup() + { return this.group; } @Override - public boolean matches(@Nonnull CraftingInventory inventory, @Nonnull World world) { - if (!super.matches(inventory, world)) { + public boolean matches( @Nonnull CraftingInventory inventory, @Nonnull World world ) + { + if( !super.matches( inventory, world ) ) + { return false; } - for (int i = 0; i < inventory.size(); i++) { - if (inventory.getStack(i) - .getItem() instanceof IComputerItem) { + for( int i = 0; i < inventory.size(); i++ ) + { + if( inventory.getStack( i ) + .getItem() instanceof IComputerItem ) + { return true; } } @@ -53,12 +59,15 @@ public abstract class ComputerConvertRecipe extends ShapedRecipe { @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inventory) { + public ItemStack craft( @Nonnull CraftingInventory inventory ) + { // Find our computer item and convert it. - for (int i = 0; i < inventory.size(); i++) { - ItemStack stack = inventory.getStack(i); - if (stack.getItem() instanceof IComputerItem) { - return this.convert((IComputerItem) stack.getItem(), stack); + for( int i = 0; i < inventory.size(); i++ ) + { + ItemStack stack = inventory.getStack( i ); + if( stack.getItem() instanceof IComputerItem ) + { + return this.convert( (IComputerItem) stack.getItem(), stack ); } } @@ -66,5 +75,5 @@ public abstract class ComputerConvertRecipe extends ShapedRecipe { } @Nonnull - protected abstract ItemStack convert(@Nonnull IComputerItem item, @Nonnull ItemStack stack); + protected abstract ItemStack convert( @Nonnull IComputerItem item, @Nonnull ItemStack stack ); } diff --git a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java index b6ebb380d..265f2900d 100644 --- a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java +++ b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java @@ -6,12 +6,9 @@ package dan200.computercraft.shared.computer.recipe; -import javax.annotation.Nonnull; - import com.google.gson.JsonObject; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.util.RecipeUtil; - import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.recipe.Ingredient; @@ -20,62 +17,73 @@ import net.minecraft.util.Identifier; import net.minecraft.util.JsonHelper; import net.minecraft.util.collection.DefaultedList; -public abstract class ComputerFamilyRecipe extends ComputerConvertRecipe { +import javax.annotation.Nonnull; + +public abstract class ComputerFamilyRecipe extends ComputerConvertRecipe +{ private final ComputerFamily family; - public ComputerFamilyRecipe(Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, - ComputerFamily family) { - super(identifier, group, width, height, ingredients, result); + public ComputerFamilyRecipe( Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, + ComputerFamily family ) + { + super( identifier, group, width, height, ingredients, result ); this.family = family; } - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.family; } - public abstract static class Serializer implements RecipeSerializer { + public abstract static class Serializer implements RecipeSerializer + { @Nonnull @Override - public T read(@Nonnull Identifier identifier, @Nonnull JsonObject json) { - String group = JsonHelper.getString(json, "group", ""); - ComputerFamily family = RecipeUtil.getFamily(json, "family"); + public T read( @Nonnull Identifier identifier, @Nonnull JsonObject json ) + { + String group = JsonHelper.getString( json, "group", "" ); + ComputerFamily family = RecipeUtil.getFamily( json, "family" ); - RecipeUtil.ShapedTemplate template = RecipeUtil.getTemplate(json); - ItemStack result = getItemStack(JsonHelper.getObject(json, "result")); + RecipeUtil.ShapedTemplate template = RecipeUtil.getTemplate( json ); + ItemStack result = getItemStack( JsonHelper.getObject( json, "result" ) ); - return this.create(identifier, group, template.width, template.height, template.ingredients, result, family); + return this.create( identifier, group, template.width, template.height, template.ingredients, result, family ); } - protected abstract T create(Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, - ComputerFamily family); + protected abstract T create( Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, + ComputerFamily family ); @Nonnull @Override - public T read(@Nonnull Identifier identifier, @Nonnull PacketByteBuf buf) { + public T read( @Nonnull Identifier identifier, @Nonnull PacketByteBuf buf ) + { int width = buf.readVarInt(); int height = buf.readVarInt(); - String group = buf.readString(Short.MAX_VALUE); + String group = buf.readString( Short.MAX_VALUE ); - DefaultedList ingredients = DefaultedList.ofSize(width * height, Ingredient.EMPTY); - for (int i = 0; i < ingredients.size(); i++) { - ingredients.set(i, Ingredient.fromPacket(buf)); + DefaultedList ingredients = DefaultedList.ofSize( width * height, Ingredient.EMPTY ); + for( int i = 0; i < ingredients.size(); i++ ) + { + ingredients.set( i, Ingredient.fromPacket( buf ) ); } ItemStack result = buf.readItemStack(); - ComputerFamily family = buf.readEnumConstant(ComputerFamily.class); - return this.create(identifier, group, width, height, ingredients, result, family); + ComputerFamily family = buf.readEnumConstant( ComputerFamily.class ); + return this.create( identifier, group, width, height, ingredients, result, family ); } @Override - public void write(@Nonnull PacketByteBuf buf, @Nonnull T recipe) { - buf.writeVarInt(recipe.getWidth()); - buf.writeVarInt(recipe.getHeight()); - buf.writeString(recipe.getGroup()); - for (Ingredient ingredient : recipe.getPreviewInputs()) { - ingredient.write(buf); + public void write( @Nonnull PacketByteBuf buf, @Nonnull T recipe ) + { + buf.writeVarInt( recipe.getWidth() ); + buf.writeVarInt( recipe.getHeight() ); + buf.writeString( recipe.getGroup() ); + for( Ingredient ingredient : recipe.getPreviewInputs() ) + { + ingredient.write( buf ); } - buf.writeItemStack(recipe.getOutput()); - buf.writeEnumConstant(recipe.getFamily()); + buf.writeItemStack( recipe.getOutput() ); + buf.writeEnumConstant( recipe.getFamily() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerUpgradeRecipe.java b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerUpgradeRecipe.java index 669d4fa98..57954114a 100644 --- a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerUpgradeRecipe.java +++ b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerUpgradeRecipe.java @@ -6,41 +6,46 @@ package dan200.computercraft.shared.computer.recipe; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.items.IComputerItem; - import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.RecipeSerializer; import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; -public class ComputerUpgradeRecipe extends ComputerFamilyRecipe { +import javax.annotation.Nonnull; + +public class ComputerUpgradeRecipe extends ComputerFamilyRecipe +{ public static final RecipeSerializer SERIALIZER = - new dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe.Serializer() { - @Override - protected ComputerUpgradeRecipe create(Identifier identifier, String group, int width, int height, DefaultedList ingredients, - ItemStack result, ComputerFamily family) { - return new ComputerUpgradeRecipe(identifier, group, width, height, ingredients, result, family); - } - }; + new dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe.Serializer() + { + @Override + protected ComputerUpgradeRecipe create( Identifier identifier, String group, int width, int height, DefaultedList ingredients, + ItemStack result, ComputerFamily family ) + { + return new ComputerUpgradeRecipe( identifier, group, width, height, ingredients, result, family ); + } + }; - public ComputerUpgradeRecipe(Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, - ComputerFamily family) { - super(identifier, group, width, height, ingredients, result, family); + public ComputerUpgradeRecipe( Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, + ComputerFamily family ) + { + super( identifier, group, width, height, ingredients, result, family ); } @Nonnull @Override - protected ItemStack convert(@Nonnull IComputerItem item, @Nonnull ItemStack stack) { - return item.withFamily(stack, this.getFamily()); + protected ItemStack convert( @Nonnull IComputerItem item, @Nonnull ItemStack stack ) + { + return item.withFamily( stack, this.getFamily() ); } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } } diff --git a/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java b/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java index 4f95f2e50..ee98295f1 100644 --- a/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java +++ b/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.data; -import java.util.Collections; -import java.util.Set; - -import javax.annotation.Nonnull; - import net.minecraft.block.entity.BlockEntity; import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.condition.LootConditionType; @@ -19,32 +14,41 @@ import net.minecraft.loot.context.LootContextParameter; import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.Nameable; +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Set; + /** * A loot condition which checks if the tile entity has a name. */ -public final class BlockNamedEntityLootCondition implements LootCondition { +public final class BlockNamedEntityLootCondition implements LootCondition +{ public static final BlockNamedEntityLootCondition INSTANCE = new BlockNamedEntityLootCondition(); - public static final LootConditionType TYPE = ConstantLootConditionSerializer.type(INSTANCE); + public static final LootConditionType TYPE = ConstantLootConditionSerializer.type( INSTANCE ); public static final Builder BUILDER = () -> INSTANCE; - private BlockNamedEntityLootCondition() { + private BlockNamedEntityLootCondition() + { } @Override - public boolean test(LootContext lootContext) { - BlockEntity tile = lootContext.get(LootContextParameters.BLOCK_ENTITY); + public boolean test( LootContext lootContext ) + { + BlockEntity tile = lootContext.get( LootContextParameters.BLOCK_ENTITY ); return tile instanceof Nameable && ((Nameable) tile).hasCustomName(); } @Nonnull @Override - public Set> getRequiredParameters() { - return Collections.singleton(LootContextParameters.BLOCK_ENTITY); + public Set> getRequiredParameters() + { + return Collections.singleton( LootContextParameters.BLOCK_ENTITY ); } @Override @Nonnull - public LootConditionType getType() { + public LootConditionType getType() + { return TYPE; } } diff --git a/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java b/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java index 7073b000d..50220fa1c 100644 --- a/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java +++ b/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java @@ -6,34 +6,38 @@ package dan200.computercraft.shared.data; -import javax.annotation.Nonnull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; - import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.condition.LootConditionType; import net.minecraft.util.JsonSerializer; -public final class ConstantLootConditionSerializer implements JsonSerializer { +import javax.annotation.Nonnull; + +public final class ConstantLootConditionSerializer implements JsonSerializer +{ private final T instance; - public ConstantLootConditionSerializer(T instance) { + public ConstantLootConditionSerializer( T instance ) + { this.instance = instance; } - public static LootConditionType type(T condition) { - return new LootConditionType(new ConstantLootConditionSerializer<>(condition)); + public static LootConditionType type( T condition ) + { + return new LootConditionType( new ConstantLootConditionSerializer<>( condition ) ); } @Override - public void toJson(@Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context) { + public void toJson( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context ) + { } @Nonnull @Override - public T fromJson(@Nonnull JsonObject json, @Nonnull JsonDeserializationContext context) { + public T fromJson( @Nonnull JsonObject json, @Nonnull JsonDeserializationContext context ) + { return this.instance; } } diff --git a/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java b/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java index 377dc14da..7b2717d29 100644 --- a/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java +++ b/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java @@ -6,13 +6,7 @@ package dan200.computercraft.shared.data; -import java.util.Collections; -import java.util.Set; - -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.blocks.IComputerTile; - import net.minecraft.block.entity.BlockEntity; import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.condition.LootConditionType; @@ -20,32 +14,41 @@ import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContextParameter; import net.minecraft.loot.context.LootContextParameters; +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Set; + /** * A loot condition which checks if the tile entity has has a non-0 ID. */ -public final class HasComputerIdLootCondition implements LootCondition { +public final class HasComputerIdLootCondition implements LootCondition +{ public static final HasComputerIdLootCondition INSTANCE = new HasComputerIdLootCondition(); - public static final LootConditionType TYPE = ConstantLootConditionSerializer.type(INSTANCE); + public static final LootConditionType TYPE = ConstantLootConditionSerializer.type( INSTANCE ); public static final Builder BUILDER = () -> INSTANCE; - private HasComputerIdLootCondition() { + private HasComputerIdLootCondition() + { } @Override - public boolean test(LootContext lootContext) { - BlockEntity tile = lootContext.get(LootContextParameters.BLOCK_ENTITY); + public boolean test( LootContext lootContext ) + { + BlockEntity tile = lootContext.get( LootContextParameters.BLOCK_ENTITY ); return tile instanceof IComputerTile && ((IComputerTile) tile).getComputerID() >= 0; } @Nonnull @Override - public Set> getRequiredParameters() { - return Collections.singleton(LootContextParameters.BLOCK_ENTITY); + public Set> getRequiredParameters() + { + return Collections.singleton( LootContextParameters.BLOCK_ENTITY ); } @Override @Nonnull - public LootConditionType getType() { + public LootConditionType getType() + { return TYPE; } } diff --git a/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java b/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java index 048d092da..e52690853 100644 --- a/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java +++ b/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.data; -import java.util.Collections; -import java.util.Set; - -import javax.annotation.Nonnull; - import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.loot.condition.LootCondition; @@ -19,32 +14,41 @@ import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContextParameter; import net.minecraft.loot.context.LootContextParameters; +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Set; + /** * A loot condition which checks if the entity is in creative mode. */ -public final class PlayerCreativeLootCondition implements LootCondition { +public final class PlayerCreativeLootCondition implements LootCondition +{ public static final PlayerCreativeLootCondition INSTANCE = new PlayerCreativeLootCondition(); - public static final LootConditionType TYPE = ConstantLootConditionSerializer.type(INSTANCE); + public static final LootConditionType TYPE = ConstantLootConditionSerializer.type( INSTANCE ); public static final Builder BUILDER = () -> INSTANCE; - private PlayerCreativeLootCondition() { + private PlayerCreativeLootCondition() + { } @Override - public boolean test(LootContext lootContext) { - Entity entity = lootContext.get(LootContextParameters.THIS_ENTITY); + public boolean test( LootContext lootContext ) + { + Entity entity = lootContext.get( LootContextParameters.THIS_ENTITY ); return entity instanceof PlayerEntity && ((PlayerEntity) entity).abilities.creativeMode; } @Nonnull @Override - public Set> getRequiredParameters() { - return Collections.singleton(LootContextParameters.THIS_ENTITY); + public Set> getRequiredParameters() + { + return Collections.singleton( LootContextParameters.THIS_ENTITY ); } @Override @Nonnull - public LootConditionType getType() { + public LootConditionType getType() + { return TYPE; } } diff --git a/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java b/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java index a3d1172d5..1455446c9 100644 --- a/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java +++ b/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java @@ -12,10 +12,12 @@ import net.fabricmc.api.Environment; // A stub modmenu entrypoint for when we get there -@Environment(EnvType.CLIENT) -public class ModMenuIntegration implements ModMenuApi { +@Environment( EnvType.CLIENT ) +public class ModMenuIntegration implements ModMenuApi +{ @Override - public ConfigScreenFactory getModConfigScreenFactory() { + public ConfigScreenFactory getModConfigScreenFactory() + { return parent -> null; } } diff --git a/src/main/java/dan200/computercraft/shared/media/items/ItemDisk.java b/src/main/java/dan200/computercraft/shared/media/items/ItemDisk.java index 876ca7122..deeb80c3b 100644 --- a/src/main/java/dan200/computercraft/shared/media/items/ItemDisk.java +++ b/src/main/java/dan200/computercraft/shared/media/items/ItemDisk.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.media.items; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.filesystem.IMount; @@ -18,7 +13,6 @@ import dan200.computercraft.api.media.IMedia; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.IColouredItem; import dan200.computercraft.shared.util.Colour; - import net.minecraft.client.item.TooltipContext; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; @@ -31,83 +25,107 @@ import net.minecraft.util.Formatting; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; -public class ItemDisk extends Item implements IMedia, IColouredItem { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class ItemDisk extends Item implements IMedia, IColouredItem +{ private static final String NBT_ID = "DiskId"; - public ItemDisk(Settings settings) { - super(settings); + public ItemDisk( Settings settings ) + { + super( settings ); } @Override - public void appendTooltip(@Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, TooltipContext options) { - if (options.isAdvanced()) { - int id = getDiskID(stack); - if (id >= 0) { - list.add(new TranslatableText("gui.computercraft.tooltip.disk_id", id).formatted(Formatting.GRAY)); + public void appendTooltip( @Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, TooltipContext options ) + { + if( options.isAdvanced() ) + { + int id = getDiskID( stack ); + if( id >= 0 ) + { + list.add( new TranslatableText( "gui.computercraft.tooltip.disk_id", id ).formatted( Formatting.GRAY ) ); } } } @Override - public void appendStacks(@Nonnull ItemGroup tabs, @Nonnull DefaultedList list) { - if (!this.isIn(tabs)) { + public void appendStacks( @Nonnull ItemGroup tabs, @Nonnull DefaultedList list ) + { + if( !this.isIn( tabs ) ) + { return; } - for (int colour = 0; colour < 16; colour++) { - list.add(createFromIDAndColour(-1, null, Colour.VALUES[colour].getHex())); + for( int colour = 0; colour < 16; colour++ ) + { + list.add( createFromIDAndColour( -1, null, Colour.VALUES[colour].getHex() ) ); } } @Nonnull - public static ItemStack createFromIDAndColour(int id, String label, int colour) { - ItemStack stack = new ItemStack(ComputerCraftRegistry.ModItems.DISK); - setDiskID(stack, id); - ComputerCraftRegistry.ModItems.DISK.setLabel(stack, label); - IColouredItem.setColourBasic(stack, colour); + public static ItemStack createFromIDAndColour( int id, String label, int colour ) + { + ItemStack stack = new ItemStack( ComputerCraftRegistry.ModItems.DISK ); + setDiskID( stack, id ); + ComputerCraftRegistry.ModItems.DISK.setLabel( stack, label ); + IColouredItem.setColourBasic( stack, colour ); return stack; } - private static void setDiskID(@Nonnull ItemStack stack, int id) { - if (id >= 0) { + private static void setDiskID( @Nonnull ItemStack stack, int id ) + { + if( id >= 0 ) + { stack.getOrCreateTag() - .putInt(NBT_ID, id); + .putInt( NBT_ID, id ); } } - public static int getDiskID(@Nonnull ItemStack stack) { + public static int getDiskID( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1; + return nbt != null && nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; } @Override - public String getLabel(@Nonnull ItemStack stack) { + public String getLabel( @Nonnull ItemStack stack ) + { return stack.hasCustomName() ? stack.getName() - .getString() : null; + .getString() : null; } @Override - public boolean setLabel(@Nonnull ItemStack stack, String label) { - if (label != null) { - stack.setCustomName(new LiteralText(label)); - } else { + public boolean setLabel( @Nonnull ItemStack stack, String label ) + { + if( label != null ) + { + stack.setCustomName( new LiteralText( label ) ); + } + else + { stack.removeCustomName(); } return true; } @Override - public IMount createDataMount(@Nonnull ItemStack stack, @Nonnull World world) { - int diskID = getDiskID(stack); - if (diskID < 0) { - diskID = ComputerCraftAPI.createUniqueNumberedSaveDir(world, "disk"); - setDiskID(stack, diskID); + public IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world ) + { + int diskID = getDiskID( stack ); + if( diskID < 0 ) + { + diskID = ComputerCraftAPI.createUniqueNumberedSaveDir( world, "disk" ); + setDiskID( stack, diskID ); } - return ComputerCraftAPI.createSaveDirMount(world, "disk/" + diskID, ComputerCraft.floppySpaceLimit); + return ComputerCraftAPI.createSaveDirMount( world, "disk/" + diskID, ComputerCraft.floppySpaceLimit ); } @Override - public int getColour(@Nonnull ItemStack stack) { - int colour = IColouredItem.getColourBasic(stack); + public int getColour( @Nonnull ItemStack stack ) + { + int colour = IColouredItem.getColourBasic( stack ); return colour == -1 ? Colour.WHITE.getHex() : colour; } } diff --git a/src/main/java/dan200/computercraft/shared/media/items/ItemPrintout.java b/src/main/java/dan200/computercraft/shared/media/items/ItemPrintout.java index 4986327cc..480e8c08d 100644 --- a/src/main/java/dan200/computercraft/shared/media/items/ItemPrintout.java +++ b/src/main/java/dan200/computercraft/shared/media/items/ItemPrintout.java @@ -6,14 +6,9 @@ package dan200.computercraft.shared.media.items; -import java.util.List; - -import javax.annotation.Nonnull; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.network.container.HeldItemContainerData; - import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; @@ -26,7 +21,11 @@ import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; -public class ItemPrintout extends Item { +import javax.annotation.Nonnull; +import java.util.List; + +public class ItemPrintout extends Item +{ public static final int LINES_PER_PAGE = 21; public static final int LINE_MAX_LENGTH = 25; public static final int MAX_PAGES = 16; @@ -36,39 +35,49 @@ public class ItemPrintout extends Item { private static final String NBT_LINE_COLOUR = "Color"; private final Type type; - public ItemPrintout(Settings settings, Type type) { - super(settings); + public ItemPrintout( Settings settings, Type type ) + { + super( settings ); this.type = type; } @Nonnull - public static ItemStack createSingleFromTitleAndText(String title, String[] text, String[] colours) { - return ComputerCraftRegistry.ModItems.PRINTED_PAGE.createFromTitleAndText(title, text, colours); + public static ItemStack createSingleFromTitleAndText( String title, String[] text, String[] colours ) + { + return ComputerCraftRegistry.ModItems.PRINTED_PAGE.createFromTitleAndText( title, text, colours ); } @Nonnull - private ItemStack createFromTitleAndText(String title, String[] text, String[] colours) { - ItemStack stack = new ItemStack(this); + private ItemStack createFromTitleAndText( String title, String[] text, String[] colours ) + { + ItemStack stack = new ItemStack( this ); // Build NBT - if (title != null) { + if( title != null ) + { stack.getOrCreateTag() - .putString(NBT_TITLE, title); + .putString( NBT_TITLE, title ); } - if (text != null) { + if( text != null ) + { CompoundTag tag = stack.getOrCreateTag(); - tag.putInt(NBT_PAGES, text.length / LINES_PER_PAGE); - for (int i = 0; i < text.length; i++) { - if (text[i] != null) { - tag.putString(NBT_LINE_TEXT + i, text[i]); + tag.putInt( NBT_PAGES, text.length / LINES_PER_PAGE ); + for( int i = 0; i < text.length; i++ ) + { + if( text[i] != null ) + { + tag.putString( NBT_LINE_TEXT + i, text[i] ); } } } - if (colours != null) { + if( colours != null ) + { CompoundTag tag = stack.getOrCreateTag(); - for (int i = 0; i < colours.length; i++) { - if (colours[i] != null) { - tag.putString(NBT_LINE_COLOUR + i, colours[i]); + for( int i = 0; i < colours.length; i++ ) + { + if( colours[i] != null ) + { + tag.putString( NBT_LINE_COLOUR + i, colours[i] ); } } } @@ -78,68 +87,82 @@ public class ItemPrintout extends Item { } @Nonnull - public static ItemStack createMultipleFromTitleAndText(String title, String[] text, String[] colours) { - return ComputerCraftRegistry.ModItems.PRINTED_PAGES.createFromTitleAndText(title, text, colours); + public static ItemStack createMultipleFromTitleAndText( String title, String[] text, String[] colours ) + { + return ComputerCraftRegistry.ModItems.PRINTED_PAGES.createFromTitleAndText( title, text, colours ); } @Nonnull - public static ItemStack createBookFromTitleAndText(String title, String[] text, String[] colours) { - return ComputerCraftRegistry.ModItems.PRINTED_BOOK.createFromTitleAndText(title, text, colours); + public static ItemStack createBookFromTitleAndText( String title, String[] text, String[] colours ) + { + return ComputerCraftRegistry.ModItems.PRINTED_BOOK.createFromTitleAndText( title, text, colours ); } - public static String[] getText(@Nonnull ItemStack stack) { - return getLines(stack, NBT_LINE_TEXT); + public static String[] getText( @Nonnull ItemStack stack ) + { + return getLines( stack, NBT_LINE_TEXT ); } - private static String[] getLines(@Nonnull ItemStack stack, String prefix) { + private static String[] getLines( @Nonnull ItemStack stack, String prefix ) + { CompoundTag nbt = stack.getTag(); - int numLines = getPageCount(stack) * LINES_PER_PAGE; + int numLines = getPageCount( stack ) * LINES_PER_PAGE; String[] lines = new String[numLines]; - for (int i = 0; i < lines.length; i++) { - lines[i] = nbt != null ? nbt.getString(prefix + i) : ""; + for( int i = 0; i < lines.length; i++ ) + { + lines[i] = nbt != null ? nbt.getString( prefix + i ) : ""; } return lines; } - public static int getPageCount(@Nonnull ItemStack stack) { + public static int getPageCount( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_PAGES) ? nbt.getInt(NBT_PAGES) : 1; + return nbt != null && nbt.contains( NBT_PAGES ) ? nbt.getInt( NBT_PAGES ) : 1; } - public static String[] getColours(@Nonnull ItemStack stack) { - return getLines(stack, NBT_LINE_COLOUR); + public static String[] getColours( @Nonnull ItemStack stack ) + { + return getLines( stack, NBT_LINE_COLOUR ); } @Nonnull @Override - public TypedActionResult use(World world, @Nonnull PlayerEntity player, @Nonnull Hand hand) { - if (!world.isClient) { - new HeldItemContainerData(hand).open(player, - new ContainerHeldItem.Factory(ComputerCraftRegistry.ModContainers.PRINTOUT, - player.getStackInHand(hand), - hand)); + public TypedActionResult use( World world, @Nonnull PlayerEntity player, @Nonnull Hand hand ) + { + if( !world.isClient ) + { + new HeldItemContainerData( hand ).open( player, + new ContainerHeldItem.Factory( ComputerCraftRegistry.ModContainers.PRINTOUT, + player.getStackInHand( hand ), + hand ) ); } - return new TypedActionResult<>(ActionResult.SUCCESS, player.getStackInHand(hand)); + return new TypedActionResult<>( ActionResult.SUCCESS, player.getStackInHand( hand ) ); } @Override - public void appendTooltip(@Nonnull ItemStack stack, World world, @Nonnull List list, @Nonnull TooltipContext options) { - String title = getTitle(stack); - if (title != null && !title.isEmpty()) { - list.add(new LiteralText(title)); + public void appendTooltip( @Nonnull ItemStack stack, World world, @Nonnull List list, @Nonnull TooltipContext options ) + { + String title = getTitle( stack ); + if( title != null && !title.isEmpty() ) + { + list.add( new LiteralText( title ) ); } } - public static String getTitle(@Nonnull ItemStack stack) { + public static String getTitle( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_TITLE) ? nbt.getString(NBT_TITLE) : null; + return nbt != null && nbt.contains( NBT_TITLE ) ? nbt.getString( NBT_TITLE ) : null; } - public Type getType() { + public Type getType() + { return this.type; } - public enum Type { + public enum Type + { PAGE, PAGES, BOOK } } diff --git a/src/main/java/dan200/computercraft/shared/media/items/ItemTreasureDisk.java b/src/main/java/dan200/computercraft/shared/media/items/ItemTreasureDisk.java index 8a7e76957..7e0783999 100644 --- a/src/main/java/dan200/computercraft/shared/media/items/ItemTreasureDisk.java +++ b/src/main/java/dan200/computercraft/shared/media/items/ItemTreasureDisk.java @@ -6,19 +6,12 @@ package dan200.computercraft.shared.media.items; -import java.io.IOException; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.media.IMedia; import dan200.computercraft.core.filesystem.SubMount; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.util.Colour; - import net.minecraft.client.item.TooltipContext; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; @@ -29,85 +22,113 @@ import net.minecraft.text.Text; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; -public class ItemTreasureDisk extends Item implements IMedia { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.IOException; +import java.util.List; + +public class ItemTreasureDisk extends Item implements IMedia +{ private static final String NBT_TITLE = "Title"; private static final String NBT_COLOUR = "Colour"; private static final String NBT_SUB_PATH = "SubPath"; - public ItemTreasureDisk(Settings settings) { - super(settings); + public ItemTreasureDisk( Settings settings ) + { + super( settings ); } - public static ItemStack create(String subPath, int colourIndex) { - ItemStack result = new ItemStack(ComputerCraftRegistry.ModItems.TREASURE_DISK); + public static ItemStack create( String subPath, int colourIndex ) + { + ItemStack result = new ItemStack( ComputerCraftRegistry.ModItems.TREASURE_DISK ); CompoundTag nbt = result.getOrCreateTag(); - nbt.putString(NBT_SUB_PATH, subPath); + nbt.putString( NBT_SUB_PATH, subPath ); - int slash = subPath.indexOf('/'); - if (slash >= 0) { - String author = subPath.substring(0, slash); - String title = subPath.substring(slash + 1); - nbt.putString(NBT_TITLE, "\"" + title + "\" by " + author); - } else { - nbt.putString(NBT_TITLE, "untitled"); + int slash = subPath.indexOf( '/' ); + if( slash >= 0 ) + { + String author = subPath.substring( 0, slash ); + String title = subPath.substring( slash + 1 ); + nbt.putString( NBT_TITLE, "\"" + title + "\" by " + author ); } - nbt.putInt(NBT_COLOUR, Colour.values()[colourIndex].getHex()); + else + { + nbt.putString( NBT_TITLE, "untitled" ); + } + nbt.putInt( NBT_COLOUR, Colour.values()[colourIndex].getHex() ); return result; } - public static int getColour(@Nonnull ItemStack stack) { + public static int getColour( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_COLOUR) ? nbt.getInt(NBT_COLOUR) : Colour.BLUE.getHex(); + return nbt != null && nbt.contains( NBT_COLOUR ) ? nbt.getInt( NBT_COLOUR ) : Colour.BLUE.getHex(); } @Override - public void appendTooltip(@Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, @Nonnull TooltipContext tooltipOptions) { - String label = getTitle(stack); - if (!label.isEmpty()) { - list.add(new LiteralText(label)); + public void appendTooltip( @Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, @Nonnull TooltipContext tooltipOptions ) + { + String label = getTitle( stack ); + if( !label.isEmpty() ) + { + list.add( new LiteralText( label ) ); } } @Override - public void appendStacks(@Nonnull ItemGroup group, @Nonnull DefaultedList stacks) { + public void appendStacks( @Nonnull ItemGroup group, @Nonnull DefaultedList stacks ) + { } @Nonnull - private static String getTitle(@Nonnull ItemStack stack) { + private static String getTitle( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_TITLE) ? nbt.getString(NBT_TITLE) : "'alongtimeago' by dan200"; + return nbt != null && nbt.contains( NBT_TITLE ) ? nbt.getString( NBT_TITLE ) : "'alongtimeago' by dan200"; } @Override - public String getLabel(@Nonnull ItemStack stack) { - return getTitle(stack); + public String getLabel( @Nonnull ItemStack stack ) + { + return getTitle( stack ); } @Override - public IMount createDataMount(@Nonnull ItemStack stack, @Nonnull World world) { + public IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world ) + { IMount rootTreasure = getTreasureMount(); - String subPath = getSubPath(stack); - try { - if (rootTreasure.exists(subPath)) { - return new SubMount(rootTreasure, subPath); - } else if (rootTreasure.exists("deprecated/" + subPath)) { - return new SubMount(rootTreasure, "deprecated/" + subPath); - } else { + String subPath = getSubPath( stack ); + try + { + if( rootTreasure.exists( subPath ) ) + { + return new SubMount( rootTreasure, subPath ); + } + else if( rootTreasure.exists( "deprecated/" + subPath ) ) + { + return new SubMount( rootTreasure, "deprecated/" + subPath ); + } + else + { return null; } - } catch (IOException e) { + } + catch( IOException e ) + { return null; } } - private static IMount getTreasureMount() { - return ComputerCraftAPI.createResourceMount("computercraft", "lua/treasure"); + private static IMount getTreasureMount() + { + return ComputerCraftAPI.createResourceMount( "computercraft", "lua/treasure" ); } @Nonnull - private static String getSubPath(@Nonnull ItemStack stack) { + private static String getSubPath( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_SUB_PATH) ? nbt.getString(NBT_SUB_PATH) : "dan200/alongtimeago"; + return nbt != null && nbt.contains( NBT_SUB_PATH ) ? nbt.getString( NBT_SUB_PATH ) : "dan200/alongtimeago"; } } diff --git a/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java b/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java index 17c76ee1b..304c3581d 100644 --- a/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java +++ b/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java @@ -6,10 +6,7 @@ package dan200.computercraft.shared.media.items; -import javax.annotation.Nonnull; - import dan200.computercraft.api.media.IMedia; - import dan200.computercraft.fabric.mixin.MusicDiscItemAccessor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -17,34 +14,43 @@ import net.minecraft.item.MusicDiscItem; import net.minecraft.sound.SoundEvent; import net.minecraft.text.TranslatableText; +import javax.annotation.Nonnull; + /** * An implementation of IMedia for ItemRecords. */ -public final class RecordMedia implements IMedia { +public final class RecordMedia implements IMedia +{ public static final RecordMedia INSTANCE = new RecordMedia(); - private RecordMedia() { + private RecordMedia() + { } @Override - public String getLabel(@Nonnull ItemStack stack) { - return this.getAudioTitle(stack); + public String getLabel( @Nonnull ItemStack stack ) + { + return this.getAudioTitle( stack ); } @Override - public String getAudioTitle(@Nonnull ItemStack stack) { + public String getAudioTitle( @Nonnull ItemStack stack ) + { Item item = stack.getItem(); - if (!(item instanceof MusicDiscItem)) { + if( !(item instanceof MusicDiscItem) ) + { return null; } - return new TranslatableText(item.getTranslationKey() + ".desc").getString(); + return new TranslatableText( item.getTranslationKey() + ".desc" ).getString(); } @Override - public SoundEvent getAudio(@Nonnull ItemStack stack) { + public SoundEvent getAudio( @Nonnull ItemStack stack ) + { Item item = stack.getItem(); - if (!(item instanceof MusicDiscItem)) { + if( !(item instanceof MusicDiscItem) ) + { return null; } return ((MusicDiscItemAccessor) item).getSound(); diff --git a/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java b/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java index 24006f1ee..a64bce717 100644 --- a/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java +++ b/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java @@ -6,13 +6,10 @@ package dan200.computercraft.shared.media.recipes; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.ColourTracker; import dan200.computercraft.shared.util.ColourUtils; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -24,32 +21,44 @@ import net.minecraft.util.DyeColor; import net.minecraft.util.Identifier; import net.minecraft.world.World; -public class DiskRecipe extends SpecialCraftingRecipe { - public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>(DiskRecipe::new); - private final Ingredient paper = Ingredient.ofItems(Items.PAPER); - // TODO: Ingredient.fromTag( Tags.Items.DUSTS_REDSTONE ); - private final Ingredient redstone = Ingredient.ofItems(Items.REDSTONE); +import javax.annotation.Nonnull; - public DiskRecipe(Identifier id) { - super(id); +public class DiskRecipe extends SpecialCraftingRecipe +{ + public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>( DiskRecipe::new ); + private final Ingredient paper = Ingredient.ofItems( Items.PAPER ); + // TODO: Ingredient.fromTag( Tags.Items.DUSTS_REDSTONE ); + private final Ingredient redstone = Ingredient.ofItems( Items.REDSTONE ); + + public DiskRecipe( Identifier id ) + { + super( id ); } @Override - public boolean matches(@Nonnull CraftingInventory inv, @Nonnull World world) { + public boolean matches( @Nonnull CraftingInventory inv, @Nonnull World world ) + { boolean paperFound = false; boolean redstoneFound = false; - for (int i = 0; i < inv.size(); i++) { - ItemStack stack = inv.getStack(i); + for( int i = 0; i < inv.size(); i++ ) + { + ItemStack stack = inv.getStack( i ); - if (!stack.isEmpty()) { - if (this.paper.test(stack)) { - if (paperFound) { + if( !stack.isEmpty() ) + { + if( this.paper.test( stack ) ) + { + if( paperFound ) + { return false; } paperFound = true; - } else if (this.redstone.test(stack)) { - if (redstoneFound) { + } + else if( this.redstone.test( stack ) ) + { + if( redstoneFound ) + { return false; } redstoneFound = true; @@ -66,13 +75,16 @@ public class DiskRecipe extends SpecialCraftingRecipe { @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inv) { + public ItemStack craft( @Nonnull CraftingInventory inv ) + { ColourTracker tracker = new ColourTracker(); - for (int i = 0; i < inv.size(); i++) { - ItemStack stack = inv.getStack(i); + for( int i = 0; i < inv.size(); i++ ) + { + ItemStack stack = inv.getStack( i ); - if (stack.isEmpty()) { + if( stack.isEmpty() ) + { continue; } @@ -83,23 +95,26 @@ public class DiskRecipe extends SpecialCraftingRecipe { } } - return ItemDisk.createFromIDAndColour(-1, null, tracker.hasColour() ? tracker.getColour() : Colour.BLUE.getHex()); + return ItemDisk.createFromIDAndColour( -1, null, tracker.hasColour() ? tracker.getColour() : Colour.BLUE.getHex() ); } @Override - public boolean fits(int x, int y) { + public boolean fits( int x, int y ) + { return x >= 2 && y >= 2; } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } @Nonnull @Override - public ItemStack getOutput() { - return ItemDisk.createFromIDAndColour(-1, null, Colour.BLUE.getHex()); + public ItemStack getOutput() + { + return ItemDisk.createFromIDAndColour( -1, null, Colour.BLUE.getHex() ); } } diff --git a/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java b/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java index a94940aca..13e75e73b 100644 --- a/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java +++ b/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java @@ -6,10 +6,7 @@ package dan200.computercraft.shared.media.recipes; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.media.items.ItemPrintout; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -20,30 +17,37 @@ import net.minecraft.recipe.SpecialRecipeSerializer; import net.minecraft.util.Identifier; import net.minecraft.world.World; -public final class PrintoutRecipe extends SpecialCraftingRecipe { - public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>(PrintoutRecipe::new); - private final Ingredient paper = Ingredient.ofItems(net.minecraft.item.Items.PAPER); - private final Ingredient leather = Ingredient.ofItems(net.minecraft.item.Items.LEATHER); - private final Ingredient string = Ingredient.ofItems(Items.STRING); +import javax.annotation.Nonnull; - private PrintoutRecipe(Identifier id) { - super(id); +public final class PrintoutRecipe extends SpecialCraftingRecipe +{ + public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>( PrintoutRecipe::new ); + private final Ingredient paper = Ingredient.ofItems( net.minecraft.item.Items.PAPER ); + private final Ingredient leather = Ingredient.ofItems( net.minecraft.item.Items.LEATHER ); + private final Ingredient string = Ingredient.ofItems( Items.STRING ); + + private PrintoutRecipe( Identifier id ) + { + super( id ); } @Nonnull @Override - public ItemStack getOutput() { - return ItemPrintout.createMultipleFromTitleAndText(null, null, null); + public ItemStack getOutput() + { + return ItemPrintout.createMultipleFromTitleAndText( null, null, null ); } @Override - public boolean matches(@Nonnull CraftingInventory inventory, @Nonnull World world) { - return !this.craft(inventory).isEmpty(); + public boolean matches( @Nonnull CraftingInventory inventory, @Nonnull World world ) + { + return !this.craft( inventory ).isEmpty(); } @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inventory) { + public ItemStack craft( @Nonnull CraftingInventory inventory ) + { // See if we match the recipe, and extract the input disk ID and dye colour int numPages = 0; int numPrintouts = 0; @@ -51,30 +55,44 @@ public final class PrintoutRecipe extends SpecialCraftingRecipe { boolean stringFound = false; boolean leatherFound = false; boolean printoutFound = false; - for (int y = 0; y < inventory.getHeight(); y++) { - for (int x = 0; x < inventory.getWidth(); x++) { - ItemStack stack = inventory.getStack(x + y * inventory.getWidth()); - if (!stack.isEmpty()) { - if (stack.getItem() instanceof ItemPrintout && ((ItemPrintout) stack.getItem()).getType() != ItemPrintout.Type.BOOK) { - if (printouts == null) { + for( int y = 0; y < inventory.getHeight(); y++ ) + { + for( int x = 0; x < inventory.getWidth(); x++ ) + { + ItemStack stack = inventory.getStack( x + y * inventory.getWidth() ); + if( !stack.isEmpty() ) + { + if( stack.getItem() instanceof ItemPrintout && ((ItemPrintout) stack.getItem()).getType() != ItemPrintout.Type.BOOK ) + { + if( printouts == null ) + { printouts = new ItemStack[9]; } printouts[numPrintouts] = stack; - numPages += ItemPrintout.getPageCount(stack); + numPages += ItemPrintout.getPageCount( stack ); numPrintouts++; printoutFound = true; - } else if (this.paper.test(stack)) { - if (printouts == null) { + } + else if( this.paper.test( stack ) ) + { + if( printouts == null ) + { printouts = new ItemStack[9]; } printouts[numPrintouts] = stack; numPages++; numPrintouts++; - } else if (this.string.test(stack) && !stringFound) { + } + else if( this.string.test( stack ) && !stringFound ) + { stringFound = true; - } else if (this.leather.test(stack) && !leatherFound) { + } + else if( this.leather.test( stack ) && !leatherFound ) + { leatherFound = true; - } else { + } + else + { return ItemStack.EMPTY; } } @@ -82,25 +100,32 @@ public final class PrintoutRecipe extends SpecialCraftingRecipe { } // Build some pages with what was passed in - if (numPages <= ItemPrintout.MAX_PAGES && stringFound && printoutFound && numPrintouts >= (leatherFound ? 1 : 2)) { + if( numPages <= ItemPrintout.MAX_PAGES && stringFound && printoutFound && numPrintouts >= (leatherFound ? 1 : 2) ) + { String[] text = new String[numPages * ItemPrintout.LINES_PER_PAGE]; String[] colours = new String[numPages * ItemPrintout.LINES_PER_PAGE]; int line = 0; - for (int printout = 0; printout < numPrintouts; printout++) { + for( int printout = 0; printout < numPrintouts; printout++ ) + { ItemStack stack = printouts[printout]; - if (stack.getItem() instanceof ItemPrintout) { + if( stack.getItem() instanceof ItemPrintout ) + { // Add a printout - String[] pageText = ItemPrintout.getText(printouts[printout]); - String[] pageColours = ItemPrintout.getColours(printouts[printout]); - for (int pageLine = 0; pageLine < pageText.length; pageLine++) { + String[] pageText = ItemPrintout.getText( printouts[printout] ); + String[] pageColours = ItemPrintout.getColours( printouts[printout] ); + for( int pageLine = 0; pageLine < pageText.length; pageLine++ ) + { text[line] = pageText[pageLine]; colours[line] = pageColours[pageLine]; line++; } - } else { + } + else + { // Add a blank page - for (int pageLine = 0; pageLine < ItemPrintout.LINES_PER_PAGE; pageLine++) { + for( int pageLine = 0; pageLine < ItemPrintout.LINES_PER_PAGE; pageLine++ ) + { text[line] = ""; colours[line] = ""; line++; @@ -109,14 +134,18 @@ public final class PrintoutRecipe extends SpecialCraftingRecipe { } String title = null; - if (printouts[0].getItem() instanceof ItemPrintout) { - title = ItemPrintout.getTitle(printouts[0]); + if( printouts[0].getItem() instanceof ItemPrintout ) + { + title = ItemPrintout.getTitle( printouts[0] ); } - if (leatherFound) { - return ItemPrintout.createBookFromTitleAndText(title, text, colours); - } else { - return ItemPrintout.createMultipleFromTitleAndText(title, text, colours); + if( leatherFound ) + { + return ItemPrintout.createBookFromTitleAndText( title, text, colours ); + } + else + { + return ItemPrintout.createMultipleFromTitleAndText( title, text, colours ); } } @@ -124,13 +153,15 @@ public final class PrintoutRecipe extends SpecialCraftingRecipe { } @Override - public boolean fits(int x, int y) { + public boolean fits( int x, int y ) + { return x >= 3 && y >= 3; } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } } diff --git a/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java b/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java index 40debae0b..cf99a32be 100644 --- a/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java +++ b/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java @@ -6,27 +6,20 @@ package dan200.computercraft.shared.network; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; - import dan200.computercraft.ComputerCraft; -import dan200.computercraft.shared.network.client.ChatTableClientMessage; -import dan200.computercraft.shared.network.client.ComputerDataClientMessage; -import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage; -import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage; -import dan200.computercraft.shared.network.client.PlayRecordClientMessage; -import dan200.computercraft.shared.network.server.ComputerActionServerMessage; -import dan200.computercraft.shared.network.server.KeyEventServerMessage; -import dan200.computercraft.shared.network.server.MouseEventServerMessage; -import dan200.computercraft.shared.network.server.QueueEventServerMessage; -import dan200.computercraft.shared.network.server.RequestComputerMessage; +import dan200.computercraft.shared.network.client.*; +import dan200.computercraft.shared.network.server.*; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; +import net.fabricmc.fabric.api.network.PacketContext; +import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.PacketByteBuf; @@ -38,109 +31,119 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; -import net.fabricmc.fabric.api.network.PacketContext; -import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; -import net.fabricmc.loader.api.FabricLoader; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; -public final class NetworkHandler { +public final class NetworkHandler +{ private static final Int2ObjectMap> packetReaders = new Int2ObjectOpenHashMap<>(); private static final Object2IntMap> packetIds = new Object2IntOpenHashMap<>(); - private static final Identifier ID = new Identifier(ComputerCraft.MOD_ID, "main"); + private static final Identifier ID = new Identifier( ComputerCraft.MOD_ID, "main" ); - private NetworkHandler() { + private NetworkHandler() + { } - public static void setup() { - ServerSidePacketRegistry.INSTANCE.register(ID, NetworkHandler::receive); - if (FabricLoader.getInstance() - .getEnvironmentType() == EnvType.CLIENT) { - ClientSidePacketRegistry.INSTANCE.register(ID, NetworkHandler::receive); + public static void setup() + { + ServerSidePacketRegistry.INSTANCE.register( ID, NetworkHandler::receive ); + if( FabricLoader.getInstance() + .getEnvironmentType() == EnvType.CLIENT ) + { + ClientSidePacketRegistry.INSTANCE.register( ID, NetworkHandler::receive ); } // Server messages - registerMainThread(0, ComputerActionServerMessage::new); - registerMainThread(1, QueueEventServerMessage::new); - registerMainThread(2, RequestComputerMessage::new); - registerMainThread(3, KeyEventServerMessage::new); - registerMainThread(4, MouseEventServerMessage::new); + registerMainThread( 0, ComputerActionServerMessage::new ); + registerMainThread( 1, QueueEventServerMessage::new ); + registerMainThread( 2, RequestComputerMessage::new ); + registerMainThread( 3, KeyEventServerMessage::new ); + registerMainThread( 4, MouseEventServerMessage::new ); // Client messages - registerMainThread(10, ChatTableClientMessage::new); - registerMainThread(11, ComputerDataClientMessage::new); - registerMainThread(12, ComputerDeletedClientMessage::new); - registerMainThread(13, ComputerTerminalClientMessage::new); - registerMainThread(14, PlayRecordClientMessage.class, PlayRecordClientMessage::new); + registerMainThread( 10, ChatTableClientMessage::new ); + registerMainThread( 11, ComputerDataClientMessage::new ); + registerMainThread( 12, ComputerDeletedClientMessage::new ); + registerMainThread( 13, ComputerTerminalClientMessage::new ); + registerMainThread( 14, PlayRecordClientMessage.class, PlayRecordClientMessage::new ); } - private static void receive(PacketContext context, PacketByteBuf buffer) { + private static void receive( PacketContext context, PacketByteBuf buffer ) + { int type = buffer.readByte(); - packetReaders.get(type) - .accept(context, buffer); + packetReaders.get( type ) + .accept( context, buffer ); } /** * /** Register packet, and a thread-unsafe handler for it. * - * @param id The identifier for this packet type + * @param id The identifier for this packet type * @param factory The factory for this type of packet. */ - private static void registerMainThread(int id, Supplier factory) { - registerMainThread(id, getType(factory), buf -> { + private static void registerMainThread( int id, Supplier factory ) + { + registerMainThread( id, getType( factory ), buf -> { T instance = factory.get(); - instance.fromBytes(buf); + instance.fromBytes( buf ); return instance; - }); + } ); } /** * /** Register packet, and a thread-unsafe handler for it. * - * @param id The identifier for this packet type + * @param id The identifier for this packet type * @param decoder The factory for this type of packet. */ - private static void registerMainThread(int id, Class type, Function decoder) { - packetIds.put(type, id); - packetReaders.put(id, (context, buf) -> { - T result = decoder.apply(buf); + private static void registerMainThread( int id, Class type, Function decoder ) + { + packetIds.put( type, id ); + packetReaders.put( id, ( context, buf ) -> { + T result = decoder.apply( buf ); context.getTaskQueue() - .execute(() -> result.handle(context)); - }); + .execute( () -> result.handle( context ) ); + } ); } - @SuppressWarnings ("unchecked") - private static Class getType(Supplier supplier) { + @SuppressWarnings( "unchecked" ) + private static Class getType( Supplier supplier ) + { return (Class) supplier.get() - .getClass(); + .getClass(); } - public static void sendToPlayer(PlayerEntity player, NetworkMessage packet) { - ((ServerPlayerEntity) player).networkHandler.sendPacket(new CustomPayloadS2CPacket(ID, encode(packet))); + public static void sendToPlayer( PlayerEntity player, NetworkMessage packet ) + { + ((ServerPlayerEntity) player).networkHandler.sendPacket( new CustomPayloadS2CPacket( ID, encode( packet ) ) ); } - private static PacketByteBuf encode(NetworkMessage message) { - PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); - buf.writeByte(packetIds.getInt(message.getClass())); - message.toBytes(buf); + private static PacketByteBuf encode( NetworkMessage message ) + { + PacketByteBuf buf = new PacketByteBuf( Unpooled.buffer() ); + buf.writeByte( packetIds.getInt( message.getClass() ) ); + message.toBytes( buf ); return buf; } - public static void sendToAllPlayers(MinecraftServer server, NetworkMessage packet) { + public static void sendToAllPlayers( MinecraftServer server, NetworkMessage packet ) + { server.getPlayerManager() - .sendToAll(new CustomPayloadS2CPacket(ID, encode(packet))); + .sendToAll( new CustomPayloadS2CPacket( ID, encode( packet ) ) ); } - @Environment (EnvType.CLIENT) - public static void sendToServer(NetworkMessage packet) { - MinecraftClient.getInstance().player.networkHandler.sendPacket(new CustomPayloadC2SPacket(ID, encode(packet))); + @Environment( EnvType.CLIENT ) + public static void sendToServer( NetworkMessage packet ) + { + MinecraftClient.getInstance().player.networkHandler.sendPacket( new CustomPayloadC2SPacket( ID, encode( packet ) ) ); } - public static void sendToAllAround(NetworkMessage packet, World world, Vec3d pos, double range) { + public static void sendToAllAround( NetworkMessage packet, World world, Vec3d pos, double range ) + { world.getServer() - .getPlayerManager() - .sendToAround(null, pos.x, pos.y, pos.z, range, world.getRegistryKey(), new CustomPayloadS2CPacket(ID, encode(packet))); + .getPlayerManager() + .sendToAround( null, pos.x, pos.y, pos.z, range, world.getRegistryKey(), new CustomPayloadS2CPacket( ID, encode( packet ) ) ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/NetworkMessage.java b/src/main/java/dan200/computercraft/shared/network/NetworkMessage.java index 3dd43457b..911014907 100644 --- a/src/main/java/dan200/computercraft/shared/network/NetworkMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/NetworkMessage.java @@ -6,16 +6,16 @@ package dan200.computercraft.shared.network; -import javax.annotation.Nonnull; - +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.network.PacketByteBuf; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; /** * The base interface for any message which will be sent to the client or server. */ -public interface NetworkMessage { +public interface NetworkMessage +{ /** * Write this packet to a buffer. * @@ -23,7 +23,7 @@ public interface NetworkMessage { * * @param buf The buffer to write data to. */ - void toBytes(@Nonnull PacketByteBuf buf); + void toBytes( @Nonnull PacketByteBuf buf ); /** * Read this packet from a buffer. @@ -32,8 +32,9 @@ public interface NetworkMessage { * * @param buf The buffer to read data from. */ - default void fromBytes(@Nonnull PacketByteBuf buf) { - throw new IllegalStateException("Should have been registered using a \"from bytes\" method"); + default void fromBytes( @Nonnull PacketByteBuf buf ) + { + throw new IllegalStateException( "Should have been registered using a \"from bytes\" method" ); } /** @@ -41,5 +42,5 @@ public interface NetworkMessage { * * @param context The context with which to handle this message */ - void handle(PacketContext context); + void handle( PacketContext context ); } diff --git a/src/main/java/dan200/computercraft/shared/network/client/ChatTableClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/ChatTableClientMessage.java index bc367af65..38edc15d3 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/ChatTableClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/ChatTableClientMessage.java @@ -6,85 +6,100 @@ package dan200.computercraft.shared.network.client; -import javax.annotation.Nonnull; - import dan200.computercraft.client.ClientTableFormatter; import dan200.computercraft.shared.command.text.TableBuilder; import dan200.computercraft.shared.network.NetworkMessage; - -import net.minecraft.network.PacketByteBuf; -import net.minecraft.text.Text; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.network.PacketContext; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; -public class ChatTableClientMessage implements NetworkMessage { +import javax.annotation.Nonnull; + +public class ChatTableClientMessage implements NetworkMessage +{ private TableBuilder table; - public ChatTableClientMessage(TableBuilder table) { - if (table.getColumns() < 0) { - throw new IllegalStateException("Cannot send an empty table"); + public ChatTableClientMessage( TableBuilder table ) + { + if( table.getColumns() < 0 ) + { + throw new IllegalStateException( "Cannot send an empty table" ); } this.table = table; } - public ChatTableClientMessage() { + public ChatTableClientMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - buf.writeVarInt(this.table.getId()); - buf.writeVarInt(this.table.getColumns()); - buf.writeBoolean(this.table.getHeaders() != null); - if (this.table.getHeaders() != null) { - for (Text header : this.table.getHeaders()) { - buf.writeText(header); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + buf.writeVarInt( this.table.getId() ); + buf.writeVarInt( this.table.getColumns() ); + buf.writeBoolean( this.table.getHeaders() != null ); + if( this.table.getHeaders() != null ) + { + for( Text header : this.table.getHeaders() ) + { + buf.writeText( header ); } } - buf.writeVarInt(this.table.getRows() - .size()); - for (Text[] row : this.table.getRows()) { - for (Text column : row) { - buf.writeText(column); + buf.writeVarInt( this.table.getRows() + .size() ); + for( Text[] row : this.table.getRows() ) + { + for( Text column : row ) + { + buf.writeText( column ); } } - buf.writeVarInt(this.table.getAdditional()); + buf.writeVarInt( this.table.getAdditional() ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { + public void fromBytes( @Nonnull PacketByteBuf buf ) + { int id = buf.readVarInt(); int columns = buf.readVarInt(); TableBuilder table; - if (buf.readBoolean()) { + if( buf.readBoolean() ) + { Text[] headers = new Text[columns]; - for (int i = 0; i < columns; i++) { + for( int i = 0; i < columns; i++ ) + { headers[i] = buf.readText(); } - table = new TableBuilder(id, headers); - } else { - table = new TableBuilder(id); + table = new TableBuilder( id, headers ); + } + else + { + table = new TableBuilder( id ); } int rows = buf.readVarInt(); - for (int i = 0; i < rows; i++) { + for( int i = 0; i < rows; i++ ) + { Text[] row = new Text[columns]; - for (int j = 0; j < columns; j++) { + for( int j = 0; j < columns; j++ ) + { row[j] = buf.readText(); } - table.row(row); + table.row( row ); } - table.setAdditional(buf.readVarInt()); + table.setAdditional( buf.readVarInt() ); this.table = table; } @Override - @Environment (EnvType.CLIENT) - public void handle(PacketContext context) { - ClientTableFormatter.INSTANCE.display(this.table); + @Environment( EnvType.CLIENT ) + public void handle( PacketContext context ) + { + ClientTableFormatter.INSTANCE.display( this.table ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/ComputerClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/ComputerClientMessage.java index d1edec94e..7e73f4eb5 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/ComputerClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/ComputerClientMessage.java @@ -6,45 +6,52 @@ package dan200.computercraft.shared.network.client; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ClientComputer; import dan200.computercraft.shared.network.NetworkMessage; - import net.minecraft.network.PacketByteBuf; +import javax.annotation.Nonnull; + /** * A packet, which performs an action on a {@link ClientComputer}. */ -public abstract class ComputerClientMessage implements NetworkMessage { +public abstract class ComputerClientMessage implements NetworkMessage +{ private int instanceId; - public ComputerClientMessage(int instanceId) { + public ComputerClientMessage( int instanceId ) + { this.instanceId = instanceId; } - public ComputerClientMessage() { + public ComputerClientMessage() + { } - public int getInstanceId() { + public int getInstanceId() + { return this.instanceId; } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - buf.writeVarInt(this.instanceId); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + buf.writeVarInt( this.instanceId ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { + public void fromBytes( @Nonnull PacketByteBuf buf ) + { this.instanceId = buf.readVarInt(); } - public ClientComputer getComputer() { - ClientComputer computer = ComputerCraft.clientComputerRegistry.get(this.instanceId); - if (computer == null) { - ComputerCraft.clientComputerRegistry.add(this.instanceId, computer = new ClientComputer(this.instanceId)); + public ClientComputer getComputer() + { + ClientComputer computer = ComputerCraft.clientComputerRegistry.get( this.instanceId ); + if( computer == null ) + { + ComputerCraft.clientComputerRegistry.add( this.instanceId, computer = new ClientComputer( this.instanceId ) ); } return computer; } diff --git a/src/main/java/dan200/computercraft/shared/network/client/ComputerDataClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/ComputerDataClientMessage.java index a466bef3e..4eb829cc1 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/ComputerDataClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/ComputerDataClientMessage.java @@ -6,48 +6,52 @@ package dan200.computercraft.shared.network.client; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.ComputerState; import dan200.computercraft.shared.computer.core.ServerComputer; - +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.PacketByteBuf; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; /** * Provides additional data about a client computer, such as its ID and current state. */ -public class ComputerDataClientMessage extends ComputerClientMessage { +public class ComputerDataClientMessage extends ComputerClientMessage +{ private ComputerState state; private CompoundTag userData; - public ComputerDataClientMessage(ServerComputer computer) { - super(computer.getInstanceID()); + public ComputerDataClientMessage( ServerComputer computer ) + { + super( computer.getInstanceID() ); this.state = computer.getState(); this.userData = computer.getUserData(); } - public ComputerDataClientMessage() { + public ComputerDataClientMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - buf.writeEnumConstant(this.state); - buf.writeCompoundTag(this.userData); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + buf.writeEnumConstant( this.state ); + buf.writeCompoundTag( this.userData ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { - super.fromBytes(buf); - this.state = buf.readEnumConstant(ComputerState.class); + public void fromBytes( @Nonnull PacketByteBuf buf ) + { + super.fromBytes( buf ); + this.state = buf.readEnumConstant( ComputerState.class ); this.userData = buf.readCompoundTag(); } @Override - public void handle(PacketContext context) { - this.getComputer().setState(this.state, this.userData); + public void handle( PacketContext context ) + { + this.getComputer().setState( this.state, this.userData ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/ComputerDeletedClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/ComputerDeletedClientMessage.java index f3a3c8d22..5b858d6e2 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/ComputerDeletedClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/ComputerDeletedClientMessage.java @@ -7,19 +7,22 @@ package dan200.computercraft.shared.network.client; import dan200.computercraft.ComputerCraft; - import net.fabricmc.fabric.api.network.PacketContext; -public class ComputerDeletedClientMessage extends ComputerClientMessage { - public ComputerDeletedClientMessage(int instanceId) { - super(instanceId); +public class ComputerDeletedClientMessage extends ComputerClientMessage +{ + public ComputerDeletedClientMessage( int instanceId ) + { + super( instanceId ); } - public ComputerDeletedClientMessage() { + public ComputerDeletedClientMessage() + { } @Override - public void handle(PacketContext context) { - ComputerCraft.clientComputerRegistry.remove(this.getInstanceId()); + public void handle( PacketContext context ) + { + ComputerCraft.clientComputerRegistry.remove( this.getInstanceId() ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/ComputerTerminalClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/ComputerTerminalClientMessage.java index 8d341a368..d469c8e83 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/ComputerTerminalClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/ComputerTerminalClientMessage.java @@ -6,37 +6,42 @@ package dan200.computercraft.shared.network.client; -import javax.annotation.Nonnull; - +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.network.PacketByteBuf; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; -public class ComputerTerminalClientMessage extends ComputerClientMessage { +public class ComputerTerminalClientMessage extends ComputerClientMessage +{ private TerminalState state; - public ComputerTerminalClientMessage(int instanceId, TerminalState state) { - super(instanceId); + public ComputerTerminalClientMessage( int instanceId, TerminalState state ) + { + super( instanceId ); this.state = state; } - public ComputerTerminalClientMessage() { + public ComputerTerminalClientMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - this.state.write(buf); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + this.state.write( buf ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { - super.fromBytes(buf); - this.state = new TerminalState(buf); + public void fromBytes( @Nonnull PacketByteBuf buf ) + { + super.fromBytes( buf ); + this.state = new TerminalState( buf ); } @Override - public void handle(PacketContext context) { - this.getComputer().read(this.state); + public void handle( PacketContext context ) + { + this.getComputer().read( this.state ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/MonitorClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/MonitorClientMessage.java index 5266f9563..c5966d88e 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/MonitorClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/MonitorClientMessage.java @@ -5,51 +5,56 @@ */ package dan200.computercraft.shared.network.client; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.peripheral.monitor.TileMonitor; - +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.block.entity.BlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.math.BlockPos; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; -public class MonitorClientMessage implements NetworkMessage { +public class MonitorClientMessage implements NetworkMessage +{ private final BlockPos pos; private final TerminalState state; - public MonitorClientMessage(BlockPos pos, TerminalState state) { + public MonitorClientMessage( BlockPos pos, TerminalState state ) + { this.pos = pos; this.state = state; } - public MonitorClientMessage(@Nonnull PacketByteBuf buf) { + public MonitorClientMessage( @Nonnull PacketByteBuf buf ) + { this.pos = buf.readBlockPos(); - this.state = new TerminalState(buf); + this.state = new TerminalState( buf ); } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - buf.writeBlockPos(this.pos); - this.state.write(buf); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + buf.writeBlockPos( this.pos ); + this.state.write( buf ); } @Override - public void handle(PacketContext context) { + public void handle( PacketContext context ) + { ClientPlayerEntity player = MinecraftClient.getInstance().player; - if (player == null || player.world == null) { + if( player == null || player.world == null ) + { return; } - BlockEntity te = player.world.getBlockEntity(this.pos); - if (!(te instanceof TileMonitor)) { + BlockEntity te = player.world.getBlockEntity( this.pos ); + if( !(te instanceof TileMonitor) ) + { return; } - ((TileMonitor) te).read(this.state); + ((TileMonitor) te).read( this.state ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/PlayRecordClientMessage.java b/src/main/java/dan200/computercraft/shared/network/client/PlayRecordClientMessage.java index 0416c9ea5..e8c283653 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/PlayRecordClientMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/client/PlayRecordClientMessage.java @@ -6,11 +6,11 @@ package dan200.computercraft.shared.network.client; -import javax.annotation.Nonnull; - import dan200.computercraft.fabric.mixin.SoundEventAccess; import dan200.computercraft.shared.network.NetworkMessage; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.client.MinecraftClient; import net.minecraft.network.PacketByteBuf; import net.minecraft.sound.SoundEvent; @@ -18,9 +18,7 @@ import net.minecraft.text.LiteralText; import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; /** * Starts or stops a record on the client, depending on if {@link #soundEvent} is {@code null}. @@ -29,53 +27,66 @@ import net.fabricmc.fabric.api.network.PacketContext; * * @see dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive */ -public class PlayRecordClientMessage implements NetworkMessage { +public class PlayRecordClientMessage implements NetworkMessage +{ private final BlockPos pos; private final String name; private final SoundEvent soundEvent; - public PlayRecordClientMessage(BlockPos pos, SoundEvent event, String name) { + public PlayRecordClientMessage( BlockPos pos, SoundEvent event, String name ) + { this.pos = pos; this.name = name; this.soundEvent = event; } - public PlayRecordClientMessage(BlockPos pos) { + public PlayRecordClientMessage( BlockPos pos ) + { this.pos = pos; this.name = null; this.soundEvent = null; } - public PlayRecordClientMessage(PacketByteBuf buf) { + public PlayRecordClientMessage( PacketByteBuf buf ) + { this.pos = buf.readBlockPos(); - if (buf.readBoolean()) { - this.name = buf.readString(Short.MAX_VALUE); - this.soundEvent = Registry.SOUND_EVENT.get(buf.readIdentifier()); - } else { + if( buf.readBoolean() ) + { + this.name = buf.readString( Short.MAX_VALUE ); + this.soundEvent = Registry.SOUND_EVENT.get( buf.readIdentifier() ); + } + else + { this.name = null; this.soundEvent = null; } } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - buf.writeBlockPos(this.pos); - if (this.soundEvent == null) { - buf.writeBoolean(false); - } else { - buf.writeBoolean(true); - buf.writeString(this.name); - buf.writeIdentifier(((SoundEventAccess)this.soundEvent).getId()); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + buf.writeBlockPos( this.pos ); + if( this.soundEvent == null ) + { + buf.writeBoolean( false ); + } + else + { + buf.writeBoolean( true ); + buf.writeString( this.name ); + buf.writeIdentifier( ((SoundEventAccess) this.soundEvent).getId() ); } } @Override - @Environment (EnvType.CLIENT) - public void handle(PacketContext context) { + @Environment( EnvType.CLIENT ) + public void handle( PacketContext context ) + { MinecraftClient mc = MinecraftClient.getInstance(); - mc.worldRenderer.playSong(this.soundEvent, this.pos); - if (this.name != null) { - mc.inGameHud.setRecordPlayingOverlay(new LiteralText(this.name)); + mc.worldRenderer.playSong( this.soundEvent, this.pos ); + if( this.name != null ) + { + mc.inGameHud.setRecordPlayingOverlay( new LiteralText( this.name ) ); } } } diff --git a/src/main/java/dan200/computercraft/shared/network/client/TerminalState.java b/src/main/java/dan200/computercraft/shared/network/client/TerminalState.java index 405eb607c..425579a4f 100644 --- a/src/main/java/dan200/computercraft/shared/network/client/TerminalState.java +++ b/src/main/java/dan200/computercraft/shared/network/client/TerminalState.java @@ -5,6 +5,15 @@ */ package dan200.computercraft.shared.network.client; +import dan200.computercraft.core.terminal.Terminal; +import dan200.computercraft.shared.util.IoUtil; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.Unpooled; +import net.minecraft.network.PacketByteBuf; + +import javax.annotation.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -12,24 +21,14 @@ import java.io.UncheckedIOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -import javax.annotation.Nullable; - -import dan200.computercraft.core.terminal.Terminal; -import dan200.computercraft.shared.util.IoUtil; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.Unpooled; - -import net.minecraft.network.PacketByteBuf; - /** * A snapshot of a terminal's state. * * This is somewhat memory inefficient (we build a buffer, only to write it elsewhere), however it means we get a complete and accurate description of a * terminal, which avoids a lot of complexities with resizing terminals, dirty states, etc... */ -public class TerminalState { +public class TerminalState +{ public final boolean colour; public final int width; @@ -37,125 +36,161 @@ public class TerminalState { private final boolean compress; - @Nullable private final ByteBuf buffer; + @Nullable + private final ByteBuf buffer; private ByteBuf compressed; - public TerminalState(boolean colour, @Nullable Terminal terminal) { - this(colour, terminal, true); + public TerminalState( boolean colour, @Nullable Terminal terminal ) + { + this( colour, terminal, true ); } - public TerminalState(boolean colour, @Nullable Terminal terminal, boolean compress) { + public TerminalState( boolean colour, @Nullable Terminal terminal, boolean compress ) + { this.colour = colour; this.compress = compress; - if (terminal == null) { + if( terminal == null ) + { this.width = this.height = 0; this.buffer = null; - } else { + } + else + { this.width = terminal.getWidth(); this.height = terminal.getHeight(); ByteBuf buf = this.buffer = Unpooled.buffer(); - terminal.write(new PacketByteBuf(buf)); + terminal.write( new PacketByteBuf( buf ) ); } } - public TerminalState(PacketByteBuf buf) { + public TerminalState( PacketByteBuf buf ) + { this.colour = buf.readBoolean(); this.compress = buf.readBoolean(); - if (buf.readBoolean()) { + if( buf.readBoolean() ) + { this.width = buf.readVarInt(); this.height = buf.readVarInt(); int length = buf.readVarInt(); - this.buffer = readCompressed(buf, length, this.compress); - } else { + this.buffer = readCompressed( buf, length, this.compress ); + } + else + { this.width = this.height = 0; this.buffer = null; } } - private static ByteBuf readCompressed(ByteBuf buf, int length, boolean compress) { - if (compress) { + private static ByteBuf readCompressed( ByteBuf buf, int length, boolean compress ) + { + if( compress ) + { ByteBuf buffer = Unpooled.buffer(); InputStream stream = null; - try { - stream = new GZIPInputStream(new ByteBufInputStream(buf, length)); + try + { + stream = new GZIPInputStream( new ByteBufInputStream( buf, length ) ); byte[] swap = new byte[8192]; - while (true) { - int bytes = stream.read(swap); - if (bytes == -1) { + while( true ) + { + int bytes = stream.read( swap ); + if( bytes == -1 ) + { break; } - buffer.writeBytes(swap, 0, bytes); + buffer.writeBytes( swap, 0, bytes ); } - } catch (IOException e) { - throw new UncheckedIOException(e); - } finally { - IoUtil.closeQuietly(stream); + } + catch( IOException e ) + { + throw new UncheckedIOException( e ); + } + finally + { + IoUtil.closeQuietly( stream ); } return buffer; - } else { - ByteBuf buffer = Unpooled.buffer(length); - buf.readBytes(buffer, length); + } + else + { + ByteBuf buffer = Unpooled.buffer( length ); + buf.readBytes( buffer, length ); return buffer; } } - public void write(PacketByteBuf buf) { - buf.writeBoolean(this.colour); - buf.writeBoolean(this.compress); + public void write( PacketByteBuf buf ) + { + buf.writeBoolean( this.colour ); + buf.writeBoolean( this.compress ); - buf.writeBoolean(this.buffer != null); - if (this.buffer != null) { - buf.writeVarInt(this.width); - buf.writeVarInt(this.height); + buf.writeBoolean( this.buffer != null ); + if( this.buffer != null ) + { + buf.writeVarInt( this.width ); + buf.writeVarInt( this.height ); ByteBuf sendBuffer = this.getCompressed(); - buf.writeVarInt(sendBuffer.readableBytes()); - buf.writeBytes(sendBuffer, sendBuffer.readerIndex(), sendBuffer.readableBytes()); + buf.writeVarInt( sendBuffer.readableBytes() ); + buf.writeBytes( sendBuffer, sendBuffer.readerIndex(), sendBuffer.readableBytes() ); } } - private ByteBuf getCompressed() { - if (this.buffer == null) { - throw new NullPointerException("buffer"); + private ByteBuf getCompressed() + { + if( this.buffer == null ) + { + throw new NullPointerException( "buffer" ); } - if (!this.compress) { + if( !this.compress ) + { return this.buffer; } - if (this.compressed != null) { + if( this.compressed != null ) + { return this.compressed; } ByteBuf compressed = Unpooled.directBuffer(); OutputStream stream = null; - try { - stream = new GZIPOutputStream(new ByteBufOutputStream(compressed)); - stream.write(this.buffer.array(), this.buffer.arrayOffset(), this.buffer.readableBytes()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } finally { - IoUtil.closeQuietly(stream); + try + { + stream = new GZIPOutputStream( new ByteBufOutputStream( compressed ) ); + stream.write( this.buffer.array(), this.buffer.arrayOffset(), this.buffer.readableBytes() ); + } + catch( IOException e ) + { + throw new UncheckedIOException( e ); + } + finally + { + IoUtil.closeQuietly( stream ); } return this.compressed = compressed; } - public boolean hasTerminal() { + public boolean hasTerminal() + { return this.buffer != null; } - public int size() { + public int size() + { return this.buffer == null ? 0 : this.buffer.readableBytes(); } - public void apply(Terminal terminal) { - if (this.buffer == null) { - throw new NullPointerException("buffer"); + public void apply( Terminal terminal ) + { + if( this.buffer == null ) + { + throw new NullPointerException( "buffer" ); } - terminal.read(new PacketByteBuf(this.buffer)); + terminal.read( new PacketByteBuf( this.buffer ) ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/container/ComputerContainerData.java b/src/main/java/dan200/computercraft/shared/network/container/ComputerContainerData.java index 7d14588f9..b19bb2c55 100644 --- a/src/main/java/dan200/computercraft/shared/network/container/ComputerContainerData.java +++ b/src/main/java/dan200/computercraft/shared/network/container/ComputerContainerData.java @@ -9,44 +9,51 @@ package dan200.computercraft.shared.network.container; import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.network.PacketByteBuf; import net.minecraft.util.Identifier; -public class ComputerContainerData implements ContainerData { - private static final Identifier IDENTIFIER = new Identifier(ComputerCraft.MOD_ID, "computer_container_data"); +public class ComputerContainerData implements ContainerData +{ + private static final Identifier IDENTIFIER = new Identifier( ComputerCraft.MOD_ID, "computer_container_data" ); private int id; private ComputerFamily family; - public ComputerContainerData(ServerComputer computer) { + public ComputerContainerData( ServerComputer computer ) + { this.id = computer.getInstanceID(); this.family = computer.getFamily(); } - public ComputerContainerData(PacketByteBuf byteBuf) { - this.fromBytes(byteBuf); + public ComputerContainerData( PacketByteBuf byteBuf ) + { + this.fromBytes( byteBuf ); } - public void fromBytes(PacketByteBuf buf) { + public void fromBytes( PacketByteBuf buf ) + { this.id = buf.readInt(); - this.family = buf.readEnumConstant(ComputerFamily.class); + this.family = buf.readEnumConstant( ComputerFamily.class ); } - public Identifier getId() { + public Identifier getId() + { return IDENTIFIER; } @Override - public void toBytes(PacketByteBuf buf) { - buf.writeInt(this.id); - buf.writeEnumConstant(this.family); + public void toBytes( PacketByteBuf buf ) + { + buf.writeInt( this.id ); + buf.writeEnumConstant( this.family ); } - public int getInstanceId() { + public int getInstanceId() + { return this.id; } - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.family; } } diff --git a/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java b/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java index 84d319667..10f167418 100644 --- a/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java +++ b/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java @@ -6,10 +6,7 @@ package dan200.computercraft.shared.network.container; -import java.util.function.Function; - -import javax.annotation.Nonnull; - +import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.network.PacketByteBuf; @@ -18,27 +15,32 @@ import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry; +import javax.annotation.Nonnull; +import java.util.function.Function; /** * An extension over the basic hooks, with a more convenient way of reading and writing data. */ -public interface ContainerData { - static ScreenHandlerType toType(Identifier identifier, Function reader, - Factory factory) { - return ScreenHandlerRegistry.registerExtended(identifier, - (id, playerInventory, packetByteBuf) -> factory.create(id, - playerInventory, - reader.apply(packetByteBuf))); +public interface ContainerData +{ + static ScreenHandlerType toType( Identifier identifier, Function reader, + Factory factory ) + { + return ScreenHandlerRegistry.registerExtended( identifier, + ( id, playerInventory, packetByteBuf ) -> factory.create( id, + playerInventory, + reader.apply( packetByteBuf ) ) ); } - void toBytes(PacketByteBuf buf); + void toBytes( PacketByteBuf buf ); - default void open(PlayerEntity player, NamedScreenHandlerFactory owner) { - player.openHandledScreen(owner); + default void open( PlayerEntity player, NamedScreenHandlerFactory owner ) + { + player.openHandledScreen( owner ); } - interface Factory { - C create(int id, @Nonnull PlayerInventory inventory, T data); + interface Factory + { + C create( int id, @Nonnull PlayerInventory inventory, T data ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/container/HeldItemContainerData.java b/src/main/java/dan200/computercraft/shared/network/container/HeldItemContainerData.java index 7e75a5cd5..63ae39df6 100644 --- a/src/main/java/dan200/computercraft/shared/network/container/HeldItemContainerData.java +++ b/src/main/java/dan200/computercraft/shared/network/container/HeldItemContainerData.java @@ -6,37 +6,41 @@ package dan200.computercraft.shared.network.container; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.common.ContainerHeldItem; - import net.minecraft.network.PacketByteBuf; import net.minecraft.util.Hand; +import javax.annotation.Nonnull; + /** * Opens a printout GUI based on the currently held item. * * @see ContainerHeldItem * @see dan200.computercraft.shared.media.items.ItemPrintout */ -public class HeldItemContainerData implements ContainerData { +public class HeldItemContainerData implements ContainerData +{ private final Hand hand; - public HeldItemContainerData(Hand hand) { + public HeldItemContainerData( Hand hand ) + { this.hand = hand; } - public HeldItemContainerData(PacketByteBuf buffer) { - this.hand = buffer.readEnumConstant(Hand.class); + public HeldItemContainerData( PacketByteBuf buffer ) + { + this.hand = buffer.readEnumConstant( Hand.class ); } @Override - public void toBytes(PacketByteBuf buf) { - buf.writeEnumConstant(this.hand); + public void toBytes( PacketByteBuf buf ) + { + buf.writeEnumConstant( this.hand ); } @Nonnull - public Hand getHand() { + public Hand getHand() + { return this.hand; } } diff --git a/src/main/java/dan200/computercraft/shared/network/container/ViewComputerContainerData.java b/src/main/java/dan200/computercraft/shared/network/container/ViewComputerContainerData.java index 963dc9b74..99ca13879 100644 --- a/src/main/java/dan200/computercraft/shared/network/container/ViewComputerContainerData.java +++ b/src/main/java/dan200/computercraft/shared/network/container/ViewComputerContainerData.java @@ -6,65 +6,75 @@ package dan200.computercraft.shared.network.container; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.network.PacketByteBuf; import net.minecraft.util.Identifier; +import javax.annotation.Nonnull; + /** * View an arbitrary computer on the client. * * @see dan200.computercraft.shared.command.CommandComputerCraft */ -public class ViewComputerContainerData extends ComputerContainerData { - private static final Identifier IDENTIFIER = new Identifier(ComputerCraft.MOD_ID, "view_computer_container_data"); +public class ViewComputerContainerData extends ComputerContainerData +{ + private static final Identifier IDENTIFIER = new Identifier( ComputerCraft.MOD_ID, "view_computer_container_data" ); private int width; private int height; - public ViewComputerContainerData(ServerComputer computer) { - super(computer); + public ViewComputerContainerData( ServerComputer computer ) + { + super( computer ); Terminal terminal = computer.getTerminal(); - if (terminal != null) { + if( terminal != null ) + { this.width = terminal.getWidth(); this.height = terminal.getHeight(); - } else { + } + else + { this.width = this.height = 0; } } - public ViewComputerContainerData(PacketByteBuf packetByteBuf) { - super(new PacketByteBuf(packetByteBuf.copy())); - this.fromBytes(packetByteBuf); + public ViewComputerContainerData( PacketByteBuf packetByteBuf ) + { + super( new PacketByteBuf( packetByteBuf.copy() ) ); + this.fromBytes( packetByteBuf ); } @Override - public void fromBytes(PacketByteBuf buf) { - super.fromBytes(buf); + public void fromBytes( PacketByteBuf buf ) + { + super.fromBytes( buf ); this.width = buf.readVarInt(); this.height = buf.readVarInt(); } @Override - public Identifier getId() { + public Identifier getId() + { return IDENTIFIER; } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - buf.writeVarInt(this.width); - buf.writeVarInt(this.height); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + buf.writeVarInt( this.width ); + buf.writeVarInt( this.height ); } - public int getWidth() { + public int getWidth() + { return this.width; } - public int getHeight() { + public int getHeight() + { return this.height; } } diff --git a/src/main/java/dan200/computercraft/shared/network/server/ComputerActionServerMessage.java b/src/main/java/dan200/computercraft/shared/network/server/ComputerActionServerMessage.java index 59ea51741..8f3ac121a 100644 --- a/src/main/java/dan200/computercraft/shared/network/server/ComputerActionServerMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/server/ComputerActionServerMessage.java @@ -6,52 +6,59 @@ package dan200.computercraft.shared.network.server; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.network.PacketByteBuf; -public class ComputerActionServerMessage extends ComputerServerMessage { +import javax.annotation.Nonnull; + +public class ComputerActionServerMessage extends ComputerServerMessage +{ private Action action; - public ComputerActionServerMessage(int instanceId, Action action) { - super(instanceId); + public ComputerActionServerMessage( int instanceId, Action action ) + { + super( instanceId ); this.action = action; } - public ComputerActionServerMessage() { + public ComputerActionServerMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - buf.writeEnumConstant(this.action); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + buf.writeEnumConstant( this.action ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { - super.fromBytes(buf); - this.action = buf.readEnumConstant(Action.class); + public void fromBytes( @Nonnull PacketByteBuf buf ) + { + super.fromBytes( buf ); + this.action = buf.readEnumConstant( Action.class ); } @Override - protected void handle(@Nonnull ServerComputer computer, @Nonnull IContainerComputer container) { - switch (this.action) { - case TURN_ON: - computer.turnOn(); - break; - case REBOOT: - computer.reboot(); - break; - case SHUTDOWN: - computer.shutdown(); - break; + protected void handle( @Nonnull ServerComputer computer, @Nonnull IContainerComputer container ) + { + switch( this.action ) + { + case TURN_ON: + computer.turnOn(); + break; + case REBOOT: + computer.reboot(); + break; + case SHUTDOWN: + computer.shutdown(); + break; } } - public enum Action { + public enum Action + { TURN_ON, SHUTDOWN, REBOOT } } diff --git a/src/main/java/dan200/computercraft/shared/network/server/ComputerServerMessage.java b/src/main/java/dan200/computercraft/shared/network/server/ComputerServerMessage.java index 06bc1ac62..2a13e607f 100644 --- a/src/main/java/dan200/computercraft/shared/network/server/ComputerServerMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/server/ComputerServerMessage.java @@ -6,56 +6,62 @@ package dan200.computercraft.shared.network.server; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.network.NetworkMessage; - +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.network.PacketByteBuf; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; /** * A packet, which performs an action on a {@link ServerComputer}. * * This requires that the sending player is interacting with that computer via a {@link IContainerComputer}. */ -public abstract class ComputerServerMessage implements NetworkMessage { +public abstract class ComputerServerMessage implements NetworkMessage +{ private int instanceId; - public ComputerServerMessage(int instanceId) { + public ComputerServerMessage( int instanceId ) + { this.instanceId = instanceId; } - public ComputerServerMessage() { + public ComputerServerMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - buf.writeVarInt(this.instanceId); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + buf.writeVarInt( this.instanceId ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { + public void fromBytes( @Nonnull PacketByteBuf buf ) + { this.instanceId = buf.readVarInt(); } @Override - public void handle(PacketContext context) { - ServerComputer computer = ComputerCraft.serverComputerRegistry.get(this.instanceId); - if (computer == null) { + public void handle( PacketContext context ) + { + ServerComputer computer = ComputerCraft.serverComputerRegistry.get( this.instanceId ); + if( computer == null ) + { return; } - IContainerComputer container = computer.getContainer(context.getPlayer()); - if (container == null) { + IContainerComputer container = computer.getContainer( context.getPlayer() ); + if( container == null ) + { return; } - this.handle(computer, container); + this.handle( computer, container ); } - protected abstract void handle(@Nonnull ServerComputer computer, @Nonnull IContainerComputer container); + protected abstract void handle( @Nonnull ServerComputer computer, @Nonnull IContainerComputer container ); } diff --git a/src/main/java/dan200/computercraft/shared/network/server/KeyEventServerMessage.java b/src/main/java/dan200/computercraft/shared/network/server/KeyEventServerMessage.java index 2edf4f2bf..5d6811d11 100644 --- a/src/main/java/dan200/computercraft/shared/network/server/KeyEventServerMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/server/KeyEventServerMessage.java @@ -6,15 +6,15 @@ package dan200.computercraft.shared.network.server; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.InputState; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.network.PacketByteBuf; -public class KeyEventServerMessage extends ComputerServerMessage { +import javax.annotation.Nonnull; + +public class KeyEventServerMessage extends ComputerServerMessage +{ public static final int TYPE_DOWN = 0; public static final int TYPE_REPEAT = 1; public static final int TYPE_UP = 2; @@ -22,36 +22,44 @@ public class KeyEventServerMessage extends ComputerServerMessage { private int type; private int key; - public KeyEventServerMessage(int instanceId, int type, int key) { - super(instanceId); + public KeyEventServerMessage( int instanceId, int type, int key ) + { + super( instanceId ); this.type = type; this.key = key; } - public KeyEventServerMessage() { + public KeyEventServerMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - buf.writeByte(this.type); - buf.writeVarInt(this.key); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + buf.writeByte( this.type ); + buf.writeVarInt( this.key ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { - super.fromBytes(buf); + public void fromBytes( @Nonnull PacketByteBuf buf ) + { + super.fromBytes( buf ); this.type = buf.readByte(); this.key = buf.readVarInt(); } @Override - protected void handle(@Nonnull ServerComputer computer, @Nonnull IContainerComputer container) { + protected void handle( @Nonnull ServerComputer computer, @Nonnull IContainerComputer container ) + { InputState input = container.getInput(); - if (this.type == TYPE_UP) { - input.keyUp(this.key); - } else { - input.keyDown(this.key, this.type == TYPE_REPEAT); + if( this.type == TYPE_UP ) + { + input.keyUp( this.key ); + } + else + { + input.keyDown( this.key, this.type == TYPE_REPEAT ); } } } diff --git a/src/main/java/dan200/computercraft/shared/network/server/MouseEventServerMessage.java b/src/main/java/dan200/computercraft/shared/network/server/MouseEventServerMessage.java index 9f91756f0..763e36ca1 100644 --- a/src/main/java/dan200/computercraft/shared/network/server/MouseEventServerMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/server/MouseEventServerMessage.java @@ -6,15 +6,15 @@ package dan200.computercraft.shared.network.server; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.InputState; import dan200.computercraft.shared.computer.core.ServerComputer; - import net.minecraft.network.PacketByteBuf; -public class MouseEventServerMessage extends ComputerServerMessage { +import javax.annotation.Nonnull; + +public class MouseEventServerMessage extends ComputerServerMessage +{ public static final int TYPE_CLICK = 0; public static final int TYPE_DRAG = 1; public static final int TYPE_UP = 2; @@ -25,29 +25,33 @@ public class MouseEventServerMessage extends ComputerServerMessage { private int y; private int arg; - public MouseEventServerMessage(int instanceId, int type, int arg, int x, int y) { - super(instanceId); + public MouseEventServerMessage( int instanceId, int type, int arg, int x, int y ) + { + super( instanceId ); this.type = type; this.arg = arg; this.x = x; this.y = y; } - public MouseEventServerMessage() { + public MouseEventServerMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - buf.writeByte(this.type); - buf.writeVarInt(this.arg); - buf.writeVarInt(this.x); - buf.writeVarInt(this.y); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + buf.writeByte( this.type ); + buf.writeVarInt( this.arg ); + buf.writeVarInt( this.x ); + buf.writeVarInt( this.y ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { - super.fromBytes(buf); + public void fromBytes( @Nonnull PacketByteBuf buf ) + { + super.fromBytes( buf ); this.type = buf.readByte(); this.arg = buf.readVarInt(); this.x = buf.readVarInt(); @@ -55,21 +59,23 @@ public class MouseEventServerMessage extends ComputerServerMessage { } @Override - protected void handle(@Nonnull ServerComputer computer, @Nonnull IContainerComputer container) { + protected void handle( @Nonnull ServerComputer computer, @Nonnull IContainerComputer container ) + { InputState input = container.getInput(); - switch (this.type) { - case TYPE_CLICK: - input.mouseClick(this.arg, this.x, this.y); - break; - case TYPE_DRAG: - input.mouseDrag(this.arg, this.x, this.y); - break; - case TYPE_UP: - input.mouseUp(this.arg, this.x, this.y); - break; - case TYPE_SCROLL: - input.mouseScroll(this.arg, this.x, this.y); - break; + switch( this.type ) + { + case TYPE_CLICK: + input.mouseClick( this.arg, this.x, this.y ); + break; + case TYPE_DRAG: + input.mouseDrag( this.arg, this.x, this.y ); + break; + case TYPE_UP: + input.mouseUp( this.arg, this.x, this.y ); + break; + case TYPE_SCROLL: + input.mouseScroll( this.arg, this.x, this.y ); + break; } } } diff --git a/src/main/java/dan200/computercraft/shared/network/server/QueueEventServerMessage.java b/src/main/java/dan200/computercraft/shared/network/server/QueueEventServerMessage.java index f6930d60a..dfa262b05 100644 --- a/src/main/java/dan200/computercraft/shared/network/server/QueueEventServerMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/server/QueueEventServerMessage.java @@ -6,53 +6,58 @@ package dan200.computercraft.shared.network.server; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.util.NBTUtil; - import net.minecraft.nbt.CompoundTag; import net.minecraft.network.PacketByteBuf; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * Queue an event on a {@link ServerComputer}. * * @see dan200.computercraft.shared.computer.core.ClientComputer#queueEvent(String) * @see ServerComputer#queueEvent(String) */ -public class QueueEventServerMessage extends ComputerServerMessage { +public class QueueEventServerMessage extends ComputerServerMessage +{ private String event; private Object[] args; - public QueueEventServerMessage(int instanceId, @Nonnull String event, @Nullable Object[] args) { - super(instanceId); + public QueueEventServerMessage( int instanceId, @Nonnull String event, @Nullable Object[] args ) + { + super( instanceId ); this.event = event; this.args = args; } - public QueueEventServerMessage() { + public QueueEventServerMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - super.toBytes(buf); - buf.writeString(this.event); - buf.writeCompoundTag(this.args == null ? null : NBTUtil.encodeObjects(this.args)); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + super.toBytes( buf ); + buf.writeString( this.event ); + buf.writeCompoundTag( this.args == null ? null : NBTUtil.encodeObjects( this.args ) ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { - super.fromBytes(buf); - this.event = buf.readString(Short.MAX_VALUE); + public void fromBytes( @Nonnull PacketByteBuf buf ) + { + super.fromBytes( buf ); + this.event = buf.readString( Short.MAX_VALUE ); CompoundTag args = buf.readCompoundTag(); - this.args = args == null ? null : NBTUtil.decodeObjects(args); + this.args = args == null ? null : NBTUtil.decodeObjects( args ); } @Override - protected void handle(@Nonnull ServerComputer computer, @Nonnull IContainerComputer container) { - computer.queueEvent(this.event, this.args); + protected void handle( @Nonnull ServerComputer computer, @Nonnull IContainerComputer container ) + { + computer.queueEvent( this.event, this.args ); } } diff --git a/src/main/java/dan200/computercraft/shared/network/server/RequestComputerMessage.java b/src/main/java/dan200/computercraft/shared/network/server/RequestComputerMessage.java index f2d095cfd..0b086ad7d 100644 --- a/src/main/java/dan200/computercraft/shared/network/server/RequestComputerMessage.java +++ b/src/main/java/dan200/computercraft/shared/network/server/RequestComputerMessage.java @@ -6,41 +6,46 @@ package dan200.computercraft.shared.network.server; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.network.NetworkMessage; - +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.network.PacketByteBuf; -import net.fabricmc.fabric.api.network.PacketContext; +import javax.annotation.Nonnull; -public class RequestComputerMessage implements NetworkMessage { +public class RequestComputerMessage implements NetworkMessage +{ private int instance; - public RequestComputerMessage(int instance) { + public RequestComputerMessage( int instance ) + { this.instance = instance; } - public RequestComputerMessage() { + public RequestComputerMessage() + { } @Override - public void toBytes(@Nonnull PacketByteBuf buf) { - buf.writeVarInt(this.instance); + public void toBytes( @Nonnull PacketByteBuf buf ) + { + buf.writeVarInt( this.instance ); } @Override - public void fromBytes(@Nonnull PacketByteBuf buf) { + public void fromBytes( @Nonnull PacketByteBuf buf ) + { this.instance = buf.readVarInt(); } @Override - public void handle(PacketContext context) { - ServerComputer computer = ComputerCraft.serverComputerRegistry.get(this.instance); - if (computer != null) { - computer.sendComputerState(context.getPlayer()); + public void handle( PacketContext context ) + { + ServerComputer computer = ComputerCraft.serverComputerRegistry.get( this.instance ); + if( computer != null ) + { + computer.sendComputerState( context.getPlayer() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java index e5cb3c431..722f2a993 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java @@ -6,16 +6,15 @@ package dan200.computercraft.shared.peripheral.commandblock; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.computer.apis.CommandAPI; - import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.util.Identifier; +import javax.annotation.Nonnull; + /** * This peripheral allows you to interact with command blocks. * @@ -25,29 +24,34 @@ import net.minecraft.util.Identifier; * * @cc.module command */ -public class CommandBlockPeripheral implements IPeripheral { - private static final Identifier CAP_ID = new Identifier(ComputerCraft.MOD_ID, "command_block"); +public class CommandBlockPeripheral implements IPeripheral +{ + private static final Identifier CAP_ID = new Identifier( ComputerCraft.MOD_ID, "command_block" ); private final CommandBlockBlockEntity commandBlock; - public CommandBlockPeripheral(CommandBlockBlockEntity commandBlock) { + public CommandBlockPeripheral( CommandBlockBlockEntity commandBlock ) + { this.commandBlock = commandBlock; } @Nonnull @Override - public String getType() { + public String getType() + { return "command"; } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return this.commandBlock; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other != null && other.getClass() == this.getClass(); } @@ -56,10 +60,11 @@ public class CommandBlockPeripheral implements IPeripheral { * * @return The current command. */ - @LuaFunction (mainThread = true) - public final String getCommand() { + @LuaFunction( mainThread = true ) + public final String getCommand() + { return this.commandBlock.getCommandExecutor() - .getCommand(); + .getCommand(); } /** @@ -67,12 +72,13 @@ public class CommandBlockPeripheral implements IPeripheral { * * @param command The new command. */ - @LuaFunction (mainThread = true) - public final void setCommand(String command) { + @LuaFunction( mainThread = true ) + public final void setCommand( String command ) + { this.commandBlock.getCommandExecutor() - .setCommand(command); + .setCommand( command ); this.commandBlock.getCommandExecutor() - .markDirty(); + .markDirty(); } /** @@ -82,13 +88,14 @@ public class CommandBlockPeripheral implements IPeripheral { * @cc.treturn boolean If the command completed successfully. * @cc.treturn string|nil A failure message. */ - @LuaFunction (mainThread = true) - public final Object[] runCommand() { + @LuaFunction( mainThread = true ) + public final Object[] runCommand() + { this.commandBlock.getCommandExecutor() - .execute(this.commandBlock.getWorld()); + .execute( this.commandBlock.getWorld() ); int result = this.commandBlock.getCommandExecutor() - .getSuccessCount(); - return result > 0 ? new Object[] {true} : new Object[] { + .getSuccessCount(); + return result > 0 ? new Object[] { true } : new Object[] { false, "Command failed" }; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/BlockDiskDrive.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/BlockDiskDrive.java index c49e066bb..2eb7fd0b4 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/BlockDiskDrive.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/BlockDiskDrive.java @@ -6,12 +6,8 @@ package dan200.computercraft.shared.peripheral.diskdrive; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.BlockGeneric; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -29,52 +25,66 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class BlockDiskDrive extends BlockGeneric { - static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - static final EnumProperty STATE = EnumProperty.of("state", DiskDriveState.class); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; - public BlockDiskDrive(Settings settings) { - super(settings, ComputerCraftRegistry.ModTiles.DISK_DRIVE); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(FACING, Direction.NORTH) - .with(STATE, DiskDriveState.EMPTY)); +public class BlockDiskDrive extends BlockGeneric +{ + static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; + static final EnumProperty STATE = EnumProperty.of( "state", DiskDriveState.class ); + + public BlockDiskDrive( Settings settings ) + { + super( settings, ComputerCraftRegistry.ModTiles.DISK_DRIVE ); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( FACING, Direction.NORTH ) + .with( STATE, DiskDriveState.EMPTY ) ); } @Nullable @Override - public BlockState getPlacementState(ItemPlacementContext placement) { - return this.getDefaultState().with(FACING, - placement.getPlayerFacing() - .getOpposite()); + public BlockState getPlacementState( ItemPlacementContext placement ) + { + return this.getDefaultState().with( FACING, + placement.getPlayerFacing() + .getOpposite() ); } @Override - public void afterBreak(@Nonnull World world, @Nonnull PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity te - , @Nonnull ItemStack stack) { - if (te instanceof Nameable && ((Nameable) te).hasCustomName()) { - player.incrementStat(Stats.MINED.getOrCreateStat(this)); - player.addExhaustion(0.005F); + public void afterBreak( @Nonnull World world, @Nonnull PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity te + , @Nonnull ItemStack stack ) + { + if( te instanceof Nameable && ((Nameable) te).hasCustomName() ) + { + player.incrementStat( Stats.MINED.getOrCreateStat( this ) ); + player.addExhaustion( 0.005F ); - ItemStack result = new ItemStack(this); - result.setCustomName(((Nameable) te).getCustomName()); - dropStack(world, pos, result); - } else { - super.afterBreak(world, player, pos, state, te, stack); + ItemStack result = new ItemStack( this ); + result.setCustomName( ((Nameable) te).getCustomName() ); + dropStack( world, pos, result ); + } + else + { + super.afterBreak( world, player, pos, state, te, stack ); } } @Override - public void onPlaced(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, ItemStack stack) { - if (stack.hasCustomName()) { - BlockEntity tileentity = world.getBlockEntity(pos); - if (tileentity instanceof TileDiskDrive) { + public void onPlaced( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, ItemStack stack ) + { + if( stack.hasCustomName() ) + { + BlockEntity tileentity = world.getBlockEntity( pos ); + if( tileentity instanceof TileDiskDrive ) + { ((TileDiskDrive) tileentity).customName = stack.getName(); } } } @Override - protected void appendProperties(StateManager.Builder properties) { - properties.add(FACING, STATE); + protected void appendProperties( StateManager.Builder properties ) + { + properties.add( FACING, STATE ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/ContainerDiskDrive.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/ContainerDiskDrive.java index dfd7de656..41ba16eef 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/ContainerDiskDrive.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/ContainerDiskDrive.java @@ -6,10 +6,7 @@ package dan200.computercraft.shared.peripheral.diskdrive; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.ComputerCraftRegistry; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; @@ -18,70 +15,90 @@ import net.minecraft.item.ItemStack; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.Slot; -public class ContainerDiskDrive extends ScreenHandler { +import javax.annotation.Nonnull; + +public class ContainerDiskDrive extends ScreenHandler +{ private final Inventory inventory; - public ContainerDiskDrive(int id, PlayerInventory player) { - this(id, player, new SimpleInventory(1)); + public ContainerDiskDrive( int id, PlayerInventory player ) + { + this( id, player, new SimpleInventory( 1 ) ); } - public ContainerDiskDrive(int id, PlayerInventory player, Inventory inventory) { - super(ComputerCraftRegistry.ModContainers.DISK_DRIVE, id); + public ContainerDiskDrive( int id, PlayerInventory player, Inventory inventory ) + { + super( ComputerCraftRegistry.ModContainers.DISK_DRIVE, id ); this.inventory = inventory; - this.addSlot(new Slot(this.inventory, 0, 8 + 4 * 18, 35)); + this.addSlot( new Slot( this.inventory, 0, 8 + 4 * 18, 35 ) ); - for (int y = 0; y < 3; y++) { - for (int x = 0; x < 9; x++) { - this.addSlot(new Slot(player, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); + for( int y = 0; y < 3; y++ ) + { + for( int x = 0; x < 9; x++ ) + { + this.addSlot( new Slot( player, x + y * 9 + 9, 8 + x * 18, 84 + y * 18 ) ); } } - for (int x = 0; x < 9; x++) { - this.addSlot(new Slot(player, x, 8 + x * 18, 142)); + for( int x = 0; x < 9; x++ ) + { + this.addSlot( new Slot( player, x, 8 + x * 18, 142 ) ); } } @Nonnull @Override - public ItemStack transferSlot(@Nonnull PlayerEntity player, int slotIndex) { - Slot slot = this.slots.get(slotIndex); - if (slot == null || !slot.hasStack()) { + public ItemStack transferSlot( @Nonnull PlayerEntity player, int slotIndex ) + { + Slot slot = this.slots.get( slotIndex ); + if( slot == null || !slot.hasStack() ) + { return ItemStack.EMPTY; } ItemStack existing = slot.getStack() - .copy(); + .copy(); ItemStack result = existing.copy(); - if (slotIndex == 0) { + if( slotIndex == 0 ) + { // Insert into player inventory - if (!this.insertItem(existing, 1, 37, true)) { + if( !this.insertItem( existing, 1, 37, true ) ) + { return ItemStack.EMPTY; } - } else { + } + else + { // Insert into drive inventory - if (!this.insertItem(existing, 0, 1, false)) { + if( !this.insertItem( existing, 0, 1, false ) ) + { return ItemStack.EMPTY; } } - if (existing.isEmpty()) { - slot.setStack(ItemStack.EMPTY); - } else { + if( existing.isEmpty() ) + { + slot.setStack( ItemStack.EMPTY ); + } + else + { slot.markDirty(); } - if (existing.getCount() == result.getCount()) { + if( existing.getCount() == result.getCount() ) + { return ItemStack.EMPTY; } - slot.onTakeItem(player, existing); + slot.onTakeItem( player, existing ); return result; } @Override - public boolean canUse(@Nonnull PlayerEntity player) { - return this.inventory.canPlayerUse(player); + public boolean canUse( @Nonnull PlayerEntity player ) + { + return this.inventory.canPlayerUse( player ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java index 58c4daba0..6ab85c4ae 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.peripheral.diskdrive; -import java.util.Optional; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.media.IMedia; @@ -19,9 +14,12 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.MediaProviders; import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.util.StringUtil; - import net.minecraft.item.ItemStack; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Optional; + /** * Disk drives are a peripheral which allow you to read and write to floppy disks and other "mountable media" (such as computers or turtles). They also * allow you to {@link #playAudio play records}. @@ -34,37 +32,44 @@ import net.minecraft.item.ItemStack; * * @cc.module drive */ -public class DiskDrivePeripheral implements IPeripheral { +public class DiskDrivePeripheral implements IPeripheral +{ private final TileDiskDrive diskDrive; - DiskDrivePeripheral(TileDiskDrive diskDrive) { + DiskDrivePeripheral( TileDiskDrive diskDrive ) + { this.diskDrive = diskDrive; } @Nonnull @Override - public String getType() { + public String getType() + { return "drive"; } @Override - public void attach(@Nonnull IComputerAccess computer) { - this.diskDrive.mount(computer); + public void attach( @Nonnull IComputerAccess computer ) + { + this.diskDrive.mount( computer ); } @Override - public void detach(@Nonnull IComputerAccess computer) { - this.diskDrive.unmount(computer); + public void detach( @Nonnull IComputerAccess computer ) + { + this.diskDrive.unmount( computer ); } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return this.diskDrive; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return this == other || other instanceof DiskDrivePeripheral && ((DiskDrivePeripheral) other).diskDrive == this.diskDrive; } @@ -74,9 +79,10 @@ public class DiskDrivePeripheral implements IPeripheral { * @return Whether a disk is currently inserted in the drive. */ @LuaFunction - public final boolean isDiskPresent() { + public final boolean isDiskPresent() + { return !this.diskDrive.getDiskStack() - .isEmpty(); + .isEmpty(); } /** @@ -86,10 +92,11 @@ public class DiskDrivePeripheral implements IPeripheral { * @cc.treturn string The label of the disk, or {@code nil} if either no disk is inserted or the disk doesn't have a label. */ @LuaFunction - public final Object[] getDiskLabel() { + public final Object[] getDiskLabel() + { ItemStack stack = this.diskDrive.getDiskStack(); - IMedia media = MediaProviders.get(stack); - return media == null ? null : new Object[] {media.getLabel(stack)}; + IMedia media = MediaProviders.get( stack ); + return media == null ? null : new Object[] { media.getLabel( stack ) }; } /** @@ -102,19 +109,22 @@ public class DiskDrivePeripheral implements IPeripheral { * @param labelA The new label of the disk, or {@code nil} to clear. * @throws LuaException If the disk's label can't be changed. */ - @LuaFunction (mainThread = true) - public final void setDiskLabel(Optional labelA) throws LuaException { - String label = labelA.orElse(null); + @LuaFunction( mainThread = true ) + public final void setDiskLabel( Optional labelA ) throws LuaException + { + String label = labelA.orElse( null ); ItemStack stack = this.diskDrive.getDiskStack(); - IMedia media = MediaProviders.get(stack); - if (media == null) { + IMedia media = MediaProviders.get( stack ); + if( media == null ) + { return; } - if (!media.setLabel(stack, StringUtil.normaliseLabel(label))) { - throw new LuaException("Disk label cannot be changed"); + if( !media.setLabel( stack, StringUtil.normaliseLabel( label ) ) ) + { + throw new LuaException( "Disk label cannot be changed" ); } - this.diskDrive.setDiskStack(stack); + this.diskDrive.setDiskStack( stack ); } /** @@ -124,8 +134,9 @@ public class DiskDrivePeripheral implements IPeripheral { * @return Whether a disk with data is inserted. */ @LuaFunction - public final boolean hasData(IComputerAccess computer) { - return this.diskDrive.getDiskMountPath(computer) != null; + public final boolean hasData( IComputerAccess computer ) + { + return this.diskDrive.getDiskMountPath( computer ) != null; } /** @@ -136,8 +147,9 @@ public class DiskDrivePeripheral implements IPeripheral { */ @LuaFunction @Nullable - public final String getMountPath(IComputerAccess computer) { - return this.diskDrive.getDiskMountPath(computer); + public final String getMountPath( IComputerAccess computer ) + { + return this.diskDrive.getDiskMountPath( computer ); } /** @@ -146,10 +158,11 @@ public class DiskDrivePeripheral implements IPeripheral { * @return Whether a disk with audio is inserted. */ @LuaFunction - public final boolean hasAudio() { + public final boolean hasAudio() + { ItemStack stack = this.diskDrive.getDiskStack(); - IMedia media = MediaProviders.get(stack); - return media != null && media.getAudio(stack) != null; + IMedia media = MediaProviders.get( stack ); + return media != null && media.getAudio( stack ) != null; } /** @@ -160,17 +173,19 @@ public class DiskDrivePeripheral implements IPeripheral { */ @LuaFunction @Nullable - public final Object getAudioTitle() { + public final Object getAudioTitle() + { ItemStack stack = this.diskDrive.getDiskStack(); - IMedia media = MediaProviders.get(stack); - return media != null ? media.getAudioTitle(stack) : false; + IMedia media = MediaProviders.get( stack ); + return media != null ? media.getAudioTitle( stack ) : false; } /** * Plays the audio in the inserted disk, if available. */ @LuaFunction - public final void playAudio() { + public final void playAudio() + { this.diskDrive.playDiskAudio(); } @@ -180,7 +195,8 @@ public class DiskDrivePeripheral implements IPeripheral { * @see #playAudio */ @LuaFunction - public final void stopAudio() { + public final void stopAudio() + { this.diskDrive.stopDiskAudio(); } @@ -188,7 +204,8 @@ public class DiskDrivePeripheral implements IPeripheral { * Ejects any disk that may be in the drive. */ @LuaFunction - public final void ejectDisk() { + public final void ejectDisk() + { this.diskDrive.ejectDisk(); } @@ -199,8 +216,9 @@ public class DiskDrivePeripheral implements IPeripheral { * @cc.treturn number The The ID of the disk in the drive, or {@code nil} if no disk with an ID is inserted. */ @LuaFunction - public final Object[] getDiskID() { + public final Object[] getDiskID() + { ItemStack disk = this.diskDrive.getDiskStack(); - return disk.getItem() instanceof ItemDisk ? new Object[] {ItemDisk.getDiskID(disk)} : null; + return disk.getItem() instanceof ItemDisk ? new Object[] { ItemDisk.getDiskID( disk ) } : null; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveState.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveState.java index 6392aa590..56543796d 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveState.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveState.java @@ -6,22 +6,25 @@ package dan200.computercraft.shared.peripheral.diskdrive; -import javax.annotation.Nonnull; - import net.minecraft.util.StringIdentifiable; -public enum DiskDriveState implements StringIdentifiable { - EMPTY("empty"), FULL("full"), INVALID("invalid"); +import javax.annotation.Nonnull; + +public enum DiskDriveState implements StringIdentifiable +{ + EMPTY( "empty" ), FULL( "full" ), INVALID( "invalid" ); private final String name; - DiskDriveState(String name) { + DiskDriveState( String name ) + { this.name = name; } @Override @Nonnull - public String asString() { + public String asString() + { return this.name; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java index 231b34d65..23a2fc3bd 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java @@ -6,13 +6,6 @@ package dan200.computercraft.shared.peripheral.diskdrive; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.media.IMedia; @@ -24,7 +17,6 @@ import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.util.DefaultInventory; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.RecordUtil; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.ItemEntity; @@ -45,112 +37,149 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -public final class TileDiskDrive extends TileGeneric implements DefaultInventory, Tickable, IPeripheralTile, Nameable, NamedScreenHandlerFactory { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public final class TileDiskDrive extends TileGeneric implements DefaultInventory, Tickable, IPeripheralTile, Nameable, NamedScreenHandlerFactory +{ private static final String NBT_NAME = "CustomName"; private static final String NBT_ITEM = "Item"; private final Map m_computers = new HashMap<>(); Text customName; - @Nonnull private ItemStack m_diskStack = ItemStack.EMPTY; + @Nonnull + private ItemStack m_diskStack = ItemStack.EMPTY; private IMount m_diskMount = null; private boolean m_recordQueued = false; private boolean m_recordPlaying = false; private boolean m_restartRecord = false; private boolean m_ejectQueued; - public TileDiskDrive(BlockEntityType type) { - super(type); + + public TileDiskDrive( BlockEntityType type ) + { + super( type ); } @Override - public void destroy() { - this.ejectContents(true); - if (this.m_recordPlaying) { + public void destroy() + { + this.ejectContents( true ); + if( this.m_recordPlaying ) + { this.stopRecord(); } } @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { - if (player.isInSneakingPose()) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { + if( player.isInSneakingPose() ) + { // Try to put a disk into the drive - ItemStack disk = player.getStackInHand(hand); - if (disk.isEmpty()) { + ItemStack disk = player.getStackInHand( hand ); + if( disk.isEmpty() ) + { return ActionResult.PASS; } - if (!this.getWorld().isClient && this.getStack(0).isEmpty() && MediaProviders.get(disk) != null) { - this.setDiskStack(disk); - player.setStackInHand(hand, ItemStack.EMPTY); + if( !this.getWorld().isClient && this.getStack( 0 ).isEmpty() && MediaProviders.get( disk ) != null ) + { + this.setDiskStack( disk ); + player.setStackInHand( hand, ItemStack.EMPTY ); } return ActionResult.SUCCESS; - } else { + } + else + { // Open the GUI - if (!this.getWorld().isClient) { - player.openHandledScreen(this); + if( !this.getWorld().isClient ) + { + player.openHandledScreen( this ); } return ActionResult.SUCCESS; } } - public Direction getDirection() { - return this.getCachedState().get(BlockDiskDrive.FACING); + public Direction getDirection() + { + return this.getCachedState().get( BlockDiskDrive.FACING ); } @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); - this.customName = nbt.contains(NBT_NAME) ? Text.Serializer.fromJson(nbt.getString(NBT_NAME)) : null; - if (nbt.contains(NBT_ITEM)) { - CompoundTag item = nbt.getCompound(NBT_ITEM); - this.m_diskStack = ItemStack.fromTag(item); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); + this.customName = nbt.contains( NBT_NAME ) ? Text.Serializer.fromJson( nbt.getString( NBT_NAME ) ) : null; + if( nbt.contains( NBT_ITEM ) ) + { + CompoundTag item = nbt.getCompound( NBT_ITEM ); + this.m_diskStack = ItemStack.fromTag( item ); this.m_diskMount = null; } } @Nonnull @Override - public CompoundTag toTag(@Nonnull CompoundTag nbt) { - if (this.customName != null) { - nbt.putString(NBT_NAME, Text.Serializer.toJson(this.customName)); + public CompoundTag toTag( @Nonnull CompoundTag nbt ) + { + if( this.customName != null ) + { + nbt.putString( NBT_NAME, Text.Serializer.toJson( this.customName ) ); } - if (!this.m_diskStack.isEmpty()) { + if( !this.m_diskStack.isEmpty() ) + { CompoundTag item = new CompoundTag(); - this.m_diskStack.toTag(item); - nbt.put(NBT_ITEM, item); + this.m_diskStack.toTag( item ); + nbt.put( NBT_ITEM, item ); } - return super.toTag(nbt); + return super.toTag( nbt ); } @Override - public void markDirty() { - if (!this.world.isClient) { + public void markDirty() + { + if( !this.world.isClient ) + { this.updateBlockState(); } super.markDirty(); } @Override - public void tick() { + public void tick() + { // Ejection - if (this.m_ejectQueued) { - this.ejectContents(false); + if( this.m_ejectQueued ) + { + this.ejectContents( false ); this.m_ejectQueued = false; } // Music - synchronized (this) { - if (!this.world.isClient && this.m_recordPlaying != this.m_recordQueued || this.m_restartRecord) { + synchronized( this ) + { + if( !this.world.isClient && this.m_recordPlaying != this.m_recordQueued || this.m_restartRecord ) + { this.m_restartRecord = false; - if (this.m_recordQueued) { + if( this.m_recordQueued ) + { IMedia contents = this.getDiskMedia(); - SoundEvent record = contents != null ? contents.getAudio(this.m_diskStack) : null; - if (record != null) { + SoundEvent record = contents != null ? contents.getAudio( this.m_diskStack ) : null; + if( record != null ) + { this.m_recordPlaying = true; this.playRecord(); - } else { + } + else + { this.m_recordQueued = false; } - } else { + } + else + { this.stopRecord(); this.m_recordPlaying = false; } @@ -161,42 +190,49 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory // IInventory implementation @Override - public int size() { + public int size() + { return 1; } @Override - public boolean isEmpty() { + public boolean isEmpty() + { return this.m_diskStack.isEmpty(); } @Nonnull @Override - public ItemStack getStack(int slot) { + public ItemStack getStack( int slot ) + { return this.m_diskStack; } @Nonnull @Override - public ItemStack removeStack(int slot, int count) { - if (this.m_diskStack.isEmpty()) { + public ItemStack removeStack( int slot, int count ) + { + if( this.m_diskStack.isEmpty() ) + { return ItemStack.EMPTY; } - if (this.m_diskStack.getCount() <= count) { + if( this.m_diskStack.getCount() <= count ) + { ItemStack disk = this.m_diskStack; - this.setStack(slot, ItemStack.EMPTY); + this.setStack( slot, ItemStack.EMPTY ); return disk; } - ItemStack part = this.m_diskStack.split(count); - this.setStack(slot, this.m_diskStack.isEmpty() ? ItemStack.EMPTY : this.m_diskStack); + ItemStack part = this.m_diskStack.split( count ); + this.setStack( slot, this.m_diskStack.isEmpty() ? ItemStack.EMPTY : this.m_diskStack ); return part; } @Nonnull @Override - public ItemStack removeStack(int slot) { + public ItemStack removeStack( int slot ) + { ItemStack result = this.m_diskStack; this.m_diskStack = ItemStack.EMPTY; this.m_diskMount = null; @@ -205,31 +241,38 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory } @Override - public void setStack(int slot, @Nonnull ItemStack stack) { - if (this.getWorld().isClient) { + public void setStack( int slot, @Nonnull ItemStack stack ) + { + if( this.getWorld().isClient ) + { this.m_diskStack = stack; this.m_diskMount = null; this.markDirty(); return; } - synchronized (this) { - if (InventoryUtil.areItemsStackable(stack, this.m_diskStack)) { + synchronized( this ) + { + if( InventoryUtil.areItemsStackable( stack, this.m_diskStack ) ) + { this.m_diskStack = stack; return; } // Unmount old disk - if (!this.m_diskStack.isEmpty()) { + if( !this.m_diskStack.isEmpty() ) + { // TODO: Is this iteration thread safe? Set computers = this.m_computers.keySet(); - for (IComputerAccess computer : computers) { - this.unmountDisk(computer); + for( IComputerAccess computer : computers ) + { + this.unmountDisk( computer ); } } // Stop music - if (this.m_recordPlaying) { + if( this.m_recordPlaying ) + { this.stopRecord(); this.m_recordPlaying = false; this.m_recordQueued = false; @@ -241,121 +284,155 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory this.markDirty(); // Mount new disk - if (!this.m_diskStack.isEmpty()) { + if( !this.m_diskStack.isEmpty() ) + { Set computers = this.m_computers.keySet(); - for (IComputerAccess computer : computers) { - this.mountDisk(computer); + for( IComputerAccess computer : computers ) + { + this.mountDisk( computer ); } } } } @Override - public boolean canPlayerUse(@Nonnull PlayerEntity player) { - return this.isUsable(player, false); + public boolean canPlayerUse( @Nonnull PlayerEntity player ) + { + return this.isUsable( player, false ); } @Override - public void clear() { - this.setStack(0, ItemStack.EMPTY); + public void clear() + { + this.setStack( 0, ItemStack.EMPTY ); } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { - return new DiskDrivePeripheral(this); + public IPeripheral getPeripheral( Direction side ) + { + return new DiskDrivePeripheral( this ); } - String getDiskMountPath(IComputerAccess computer) { - synchronized (this) { - MountInfo info = this.m_computers.get(computer); + String getDiskMountPath( IComputerAccess computer ) + { + synchronized( this ) + { + MountInfo info = this.m_computers.get( computer ); return info != null ? info.mountPath : null; } } - void mount(IComputerAccess computer) { - synchronized (this) { - this.m_computers.put(computer, new MountInfo()); - this.mountDisk(computer); + void mount( IComputerAccess computer ) + { + synchronized( this ) + { + this.m_computers.put( computer, new MountInfo() ); + this.mountDisk( computer ); } } - private synchronized void mountDisk(IComputerAccess computer) { - if (!this.m_diskStack.isEmpty()) { - MountInfo info = this.m_computers.get(computer); + private synchronized void mountDisk( IComputerAccess computer ) + { + if( !this.m_diskStack.isEmpty() ) + { + MountInfo info = this.m_computers.get( computer ); IMedia contents = this.getDiskMedia(); - if (contents != null) { - if (this.m_diskMount == null) { - this.m_diskMount = contents.createDataMount(this.m_diskStack, this.getWorld()); + if( contents != null ) + { + if( this.m_diskMount == null ) + { + this.m_diskMount = contents.createDataMount( this.m_diskStack, this.getWorld() ); } - if (this.m_diskMount != null) { - if (this.m_diskMount instanceof IWritableMount) { + if( this.m_diskMount != null ) + { + if( this.m_diskMount instanceof IWritableMount ) + { // Try mounting at the lowest numbered "disk" name we can int n = 1; - while (info.mountPath == null) { - info.mountPath = computer.mountWritable(n == 1 ? "disk" : "disk" + n, (IWritableMount) this.m_diskMount); - n++; - } - } else { - // Try mounting at the lowest numbered "disk" name we can - int n = 1; - while (info.mountPath == null) { - info.mountPath = computer.mount(n == 1 ? "disk" : "disk" + n, this.m_diskMount); + while( info.mountPath == null ) + { + info.mountPath = computer.mountWritable( n == 1 ? "disk" : "disk" + n, (IWritableMount) this.m_diskMount ); n++; } } - } else { + else + { + // Try mounting at the lowest numbered "disk" name we can + int n = 1; + while( info.mountPath == null ) + { + info.mountPath = computer.mount( n == 1 ? "disk" : "disk" + n, this.m_diskMount ); + n++; + } + } + } + else + { info.mountPath = null; } } - computer.queueEvent("disk", computer.getAttachmentName()); + computer.queueEvent( "disk", computer.getAttachmentName() ); } } - private IMedia getDiskMedia() { - return MediaProviders.get(this.getDiskStack()); + private IMedia getDiskMedia() + { + return MediaProviders.get( this.getDiskStack() ); } @Nonnull - ItemStack getDiskStack() { - return this.getStack(0); + ItemStack getDiskStack() + { + return this.getStack( 0 ); } - void setDiskStack(@Nonnull ItemStack stack) { - this.setStack(0, stack); + void setDiskStack( @Nonnull ItemStack stack ) + { + this.setStack( 0, stack ); } - void unmount(IComputerAccess computer) { - synchronized (this) { - this.unmountDisk(computer); - this.m_computers.remove(computer); + void unmount( IComputerAccess computer ) + { + synchronized( this ) + { + this.unmountDisk( computer ); + this.m_computers.remove( computer ); } } - private synchronized void unmountDisk(IComputerAccess computer) { - if (!this.m_diskStack.isEmpty()) { - MountInfo info = this.m_computers.get(computer); + private synchronized void unmountDisk( IComputerAccess computer ) + { + if( !this.m_diskStack.isEmpty() ) + { + MountInfo info = this.m_computers.get( computer ); assert info != null; - if (info.mountPath != null) { - computer.unmount(info.mountPath); + if( info.mountPath != null ) + { + computer.unmount( info.mountPath ); info.mountPath = null; } - computer.queueEvent("disk_eject", computer.getAttachmentName()); + computer.queueEvent( "disk_eject", computer.getAttachmentName() ); } } - void playDiskAudio() { - synchronized (this) { + void playDiskAudio() + { + synchronized( this ) + { IMedia media = this.getDiskMedia(); - if (media != null && media.getAudioTitle(this.m_diskStack) != null) { + if( media != null && media.getAudioTitle( this.m_diskStack ) != null ) + { this.m_recordQueued = true; this.m_restartRecord = this.m_recordPlaying; } } } - void stopDiskAudio() { - synchronized (this) { + void stopDiskAudio() + { + synchronized( this ) + { this.m_recordQueued = false; this.m_restartRecord = false; } @@ -363,47 +440,59 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory // private methods - void ejectDisk() { - synchronized (this) { + void ejectDisk() + { + synchronized( this ) + { this.m_ejectQueued = true; } } - private void updateBlockState() { - if (this.removed) { + private void updateBlockState() + { + if( this.removed ) + { return; } - if (!this.m_diskStack.isEmpty()) { + if( !this.m_diskStack.isEmpty() ) + { IMedia contents = this.getDiskMedia(); - this.updateBlockState(contents != null ? DiskDriveState.FULL : DiskDriveState.INVALID); - } else { - this.updateBlockState(DiskDriveState.EMPTY); + this.updateBlockState( contents != null ? DiskDriveState.FULL : DiskDriveState.INVALID ); + } + else + { + this.updateBlockState( DiskDriveState.EMPTY ); } } - private void updateBlockState(DiskDriveState state) { + private void updateBlockState( DiskDriveState state ) + { BlockState blockState = this.getCachedState(); - if (blockState.get(BlockDiskDrive.STATE) == state) { + if( blockState.get( BlockDiskDrive.STATE ) == state ) + { return; } - this.getWorld().setBlockState(this.getPos(), blockState.with(BlockDiskDrive.STATE, state)); + this.getWorld().setBlockState( this.getPos(), blockState.with( BlockDiskDrive.STATE, state ) ); } - private synchronized void ejectContents(boolean destroyed) { - if (this.getWorld().isClient || this.m_diskStack.isEmpty()) { + private synchronized void ejectContents( boolean destroyed ) + { + if( this.getWorld().isClient || this.m_diskStack.isEmpty() ) + { return; } // Remove the disks from the inventory ItemStack disks = this.m_diskStack; - this.setDiskStack(ItemStack.EMPTY); + this.setDiskStack( ItemStack.EMPTY ); // Spawn the item in the world int xOff = 0; int zOff = 0; - if (!destroyed) { + if( !destroyed ) + { Direction dir = this.getDirection(); xOff = dir.getOffsetX(); zOff = dir.getOffsetZ(); @@ -413,62 +502,74 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory double x = pos.getX() + 0.5 + xOff * 0.5; double y = pos.getY() + 0.75; double z = pos.getZ() + 0.5 + zOff * 0.5; - ItemEntity entityitem = new ItemEntity(this.getWorld(), x, y, z, disks); - entityitem.setVelocity(xOff * 0.15, 0, zOff * 0.15); + ItemEntity entityitem = new ItemEntity( this.getWorld(), x, y, z, disks ); + entityitem.setVelocity( xOff * 0.15, 0, zOff * 0.15 ); - this.getWorld().spawnEntity(entityitem); - if (!destroyed) { - this.getWorld().syncGlobalEvent(1000, this.getPos(), 0); + this.getWorld().spawnEntity( entityitem ); + if( !destroyed ) + { + this.getWorld().syncGlobalEvent( 1000, this.getPos(), 0 ); } } - private void playRecord() { + private void playRecord() + { IMedia contents = this.getDiskMedia(); - SoundEvent record = contents != null ? contents.getAudio(this.m_diskStack) : null; - if (record != null) { - RecordUtil.playRecord(record, contents.getAudioTitle(this.m_diskStack), this.getWorld(), this.getPos()); - } else { - RecordUtil.playRecord(null, null, this.getWorld(), this.getPos()); + SoundEvent record = contents != null ? contents.getAudio( this.m_diskStack ) : null; + if( record != null ) + { + RecordUtil.playRecord( record, contents.getAudioTitle( this.m_diskStack ), this.getWorld(), this.getPos() ); + } + else + { + RecordUtil.playRecord( null, null, this.getWorld(), this.getPos() ); } } // Private methods - private void stopRecord() { - RecordUtil.playRecord(null, null, this.getWorld(), this.getPos()); + private void stopRecord() + { + RecordUtil.playRecord( null, null, this.getWorld(), this.getPos() ); } @Nonnull @Override - public Text getName() { - return this.customName != null ? this.customName : new TranslatableText(this.getCachedState().getBlock() - .getTranslationKey()); + public Text getName() + { + return this.customName != null ? this.customName : new TranslatableText( this.getCachedState().getBlock() + .getTranslationKey() ); } @Override - public boolean hasCustomName() { + public boolean hasCustomName() + { return this.customName != null; } @Nonnull @Override - public Text getDisplayName() { + public Text getDisplayName() + { return Nameable.super.getDisplayName(); } @Nullable @Override - public Text getCustomName() { + public Text getCustomName() + { return this.customName; } @Nonnull @Override - public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player) { - return new ContainerDiskDrive(id, inventory, this); + public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player ) + { + return new ContainerDiskDrive( id, inventory, this ); } - private static class MountInfo { + private static class MountInfo + { String mountPath; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java index 15ae9320d..c4c59ee4a 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java @@ -5,22 +5,20 @@ */ package dan200.computercraft.shared.peripheral.generic; -import dan200.computercraft.api.lua.*; +import dan200.computercraft.api.lua.IArguments; +import dan200.computercraft.api.lua.ILuaContext; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IDynamicPeripheral; import dan200.computercraft.api.peripheral.IPeripheral; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.block.entity.LockableContainerBlockEntity; -import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import net.minecraft.util.Nameable; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; -import java.util.Objects; -import java.util.concurrent.locks.Lock; class GenericPeripheral implements IDynamicPeripheral { @@ -30,7 +28,7 @@ class GenericPeripheral implements IDynamicPeripheral GenericPeripheral( BlockEntity tile, List methods ) { - Identifier type = BlockEntityType.getId(tile.getType()); + Identifier type = BlockEntityType.getId( tile.getType() ); this.tile = tile; this.type = type == null ? "unknown" : type.toString(); this.methods = methods; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/BlockData.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/BlockData.java index 2d7038b29..4b9a9e0ed 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/BlockData.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/BlockData.java @@ -18,14 +18,15 @@ public class BlockData @Nonnull public static > T fill( @Nonnull T data, @Nonnull BlockState state ) { - data.put("name", DataHelpers.getId( state.getBlock() ) ); + data.put( "name", DataHelpers.getId( state.getBlock() ) ); Map stateTable = new HashMap<>(); - for (ImmutableMap.Entry, ? extends Comparable> entry : state.getEntries().entrySet()) { + for( ImmutableMap.Entry, ? extends Comparable> entry : state.getEntries().entrySet() ) + { Property property = entry.getKey(); - stateTable.put(property.getName(), getPropertyValue(property, entry.getValue())); + stateTable.put( property.getName(), getPropertyValue( property, entry.getValue() ) ); } - data.put("state", stateTable); + data.put( "state", stateTable ); return data; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java index 3d69d2849..210aa5b5a 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java @@ -5,7 +5,6 @@ */ package dan200.computercraft.shared.peripheral.generic.data; -import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; import net.minecraft.item.Item; @@ -34,21 +33,21 @@ public final class DataHelpers @Nullable public static String getId( @Nonnull Block block ) { - Identifier id = Registry.BLOCK.getId(block); + Identifier id = Registry.BLOCK.getId( block ); return id == null ? null : id.toString(); } @Nullable public static String getId( @Nonnull Item item ) { - Identifier id = Registry.ITEM.getId(item); + Identifier id = Registry.ITEM.getId( item ); return id == null ? null : id.toString(); } @Nullable - public static String getId( @Nonnull Enchantment enchantment) + public static String getId( @Nonnull Enchantment enchantment ) { - Identifier id = Registry.ENCHANTMENT.getId(enchantment); + Identifier id = Registry.ENCHANTMENT.getId( enchantment ); return id == null ? null : id.toString(); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/ItemData.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/ItemData.java index b88570bb9..bf002abac 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/ItemData.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/ItemData.java @@ -7,24 +7,22 @@ package dan200.computercraft.shared.peripheral.generic.data; import com.google.gson.JsonParseException; import dan200.computercraft.shared.util.NBTUtil; -import net.fabricmc.fabric.api.tag.TagRegistry; -import net.fabricmc.fabric.impl.tag.extension.TagDelegate; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.item.EnchantedBookItem; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.tag.ServerTagManagerHolder; import net.minecraft.tag.Tag; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Data providers for items. @@ -68,7 +66,7 @@ public class ItemData if( stack.isDamaged() ) { - data.put( "durability", 1.0 - ( stack.getDamage() / stack.getMaxDamage() ) ); + data.put( "durability", 1.0 - (stack.getDamage() / stack.getMaxDamage()) ); } /* @@ -87,7 +85,7 @@ public class ItemData data.put( "unbreakable", true ); } - data.put("tags", DataHelpers.getTags( ServerTagManagerHolder.getTagManager().getItems().getTagsFor(stack.getItem()) )); // chaos + data.put( "tags", DataHelpers.getTags( ServerTagManagerHolder.getTagManager().getItems().getTagsFor( stack.getItem() ) ) ); // chaos return data; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java index 86267a3ba..421f75492 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java @@ -51,7 +51,7 @@ public class InventoryMethods implements GenericSource @LuaFunction( mainThread = true ) public static int size( Inventory inventory ) { - return extractHandler(inventory).size(); + return extractHandler( inventory ).size(); } /** @@ -63,8 +63,9 @@ public class InventoryMethods implements GenericSource @LuaFunction( mainThread = true ) public static String name( Inventory inventory ) { - if ( inventory instanceof Nameable ) { - Nameable i = (Nameable)inventory; + if( inventory instanceof Nameable ) + { + Nameable i = (Nameable) inventory; return i.hasCustomName() ? i.getName().asString() : null; } return null; @@ -96,7 +97,7 @@ public class InventoryMethods implements GenericSource @LuaFunction( mainThread = true ) public static Map> list( Inventory inventory ) { - ItemStorage itemStorage = extractHandler(inventory); + ItemStorage itemStorage = extractHandler( inventory ); Map> result = new HashMap<>(); int size = itemStorage.size(); @@ -143,7 +144,7 @@ public class InventoryMethods implements GenericSource @LuaFunction( mainThread = true ) public static Map getItemDetail( Inventory inventory, int slot ) throws LuaException { - ItemStorage itemStorage = extractHandler(inventory); + ItemStorage itemStorage = extractHandler( inventory ); assertBetween( slot, 1, itemStorage.size(), "Slot out of range (%s)" ); @@ -281,10 +282,12 @@ public class InventoryMethods implements GenericSource @Nullable private static ItemStorage extractHandler( @Nullable Object object ) { - if ( object instanceof BlockEntity ) { - Inventory inventory = InventoryUtil.getInventory((BlockEntity) object); - if ( inventory != null ) { - return ItemStorage.wrap(inventory); + if( object instanceof BlockEntity ) + { + Inventory inventory = InventoryUtil.getInventory( (BlockEntity) object ); + if( inventory != null ) + { + return ItemStorage.wrap( inventory ); } } @@ -304,31 +307,37 @@ public class InventoryMethods implements GenericSource private static int moveItem( ItemStorage from, int fromSlot, ItemStorage to, int toSlot, final int limit ) { // Moving nothing is easy - if (limit == 0) { + if( limit == 0 ) + { return 0; } // Get stack to move - ItemStack stack = InventoryUtil.takeItems(limit, from, fromSlot, 1, fromSlot); - if (stack.isEmpty()) { + ItemStack stack = InventoryUtil.takeItems( limit, from, fromSlot, 1, fromSlot ); + if( stack.isEmpty() ) + { return 0; } int stackCount = stack.getCount(); // Move items in ItemStack remainder; - if (toSlot < 0) { - remainder = InventoryUtil.storeItems(stack, to); - } else { - remainder = InventoryUtil.storeItems(stack, to, toSlot, 1, toSlot); + if( toSlot < 0 ) + { + remainder = InventoryUtil.storeItems( stack, to ); + } + else + { + remainder = InventoryUtil.storeItems( stack, to, toSlot, 1, toSlot ); } // Calculate items moved int count = stackCount - remainder.getCount(); - if (!remainder.isEmpty()) { + if( !remainder.isEmpty() ) + { // Put the remainder back - InventoryUtil.storeItems(remainder, from, fromSlot, 1, fromSlot); + InventoryUtil.storeItems( remainder, from, fromSlot, 1, fromSlot ); } return count; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java index d87094f37..c73c966ae 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.peripheral.modem; -import java.util.HashSet; -import java.util.Set; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.network.IPacketNetwork; @@ -19,109 +14,134 @@ import dan200.computercraft.api.network.IPacketSender; import dan200.computercraft.api.network.Packet; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import java.util.HashSet; +import java.util.Set; + /** * The modem peripheral allows you to send messages between computers. * * @cc.module modem */ -public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver { - private final Set m_computers = new HashSet<>(1); +public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver +{ + private final Set m_computers = new HashSet<>( 1 ); private final ModemState m_state; private IPacketNetwork m_network; - protected ModemPeripheral(ModemState state) { + protected ModemPeripheral( ModemState state ) + { this.m_state = state; } - public ModemState getModemState() { + public ModemState getModemState() + { return this.m_state; } - public void destroy() { - this.setNetwork(null); + public void destroy() + { + this.setNetwork( null ); } @Override - public void receiveSameDimension(@Nonnull Packet packet, double distance) { - if (packet.getSender() == this || !this.m_state.isOpen(packet.getChannel())) { + public void receiveSameDimension( @Nonnull Packet packet, double distance ) + { + if( packet.getSender() == this || !this.m_state.isOpen( packet.getChannel() ) ) + { return; } - synchronized (this.m_computers) { - for (IComputerAccess computer : this.m_computers) { - computer.queueEvent("modem_message", - computer.getAttachmentName(), - packet.getChannel(), - packet.getReplyChannel(), - packet.getPayload(), - distance); + synchronized( this.m_computers ) + { + for( IComputerAccess computer : this.m_computers ) + { + computer.queueEvent( "modem_message", + computer.getAttachmentName(), + packet.getChannel(), + packet.getReplyChannel(), + packet.getPayload(), + distance ); } } } @Override - public void receiveDifferentDimension(@Nonnull Packet packet) { - if (packet.getSender() == this || !this.m_state.isOpen(packet.getChannel())) { + public void receiveDifferentDimension( @Nonnull Packet packet ) + { + if( packet.getSender() == this || !this.m_state.isOpen( packet.getChannel() ) ) + { return; } - synchronized (this.m_computers) { - for (IComputerAccess computer : this.m_computers) { - computer.queueEvent("modem_message", computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload()); + synchronized( this.m_computers ) + { + for( IComputerAccess computer : this.m_computers ) + { + computer.queueEvent( "modem_message", computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload() ); } } } @Nonnull @Override - public String getType() { + public String getType() + { return "modem"; } @Override - public synchronized void attach(@Nonnull IComputerAccess computer) { - synchronized (this.m_computers) { - this.m_computers.add(computer); + public synchronized void attach( @Nonnull IComputerAccess computer ) + { + synchronized( this.m_computers ) + { + this.m_computers.add( computer ); } - this.setNetwork(this.getNetwork()); + this.setNetwork( this.getNetwork() ); } protected abstract IPacketNetwork getNetwork(); - private synchronized void setNetwork(IPacketNetwork network) { - if (this.m_network == network) { + private synchronized void setNetwork( IPacketNetwork network ) + { + if( this.m_network == network ) + { return; } // Leave old network - if (this.m_network != null) { - this.m_network.removeReceiver(this); + if( this.m_network != null ) + { + this.m_network.removeReceiver( this ); } // Set new network this.m_network = network; // Join new network - if (this.m_network != null) { - this.m_network.addReceiver(this); + if( this.m_network != null ) + { + this.m_network.addReceiver( this ); } } @Override - public synchronized void detach(@Nonnull IComputerAccess computer) { + public synchronized void detach( @Nonnull IComputerAccess computer ) + { boolean empty; - synchronized (this.m_computers) { - this.m_computers.remove(computer); + synchronized( this.m_computers ) + { + this.m_computers.remove( computer ); empty = this.m_computers.isEmpty(); } - if (empty) { - this.setNetwork(null); + if( empty ) + { + this.setNetwork( null ); } } @@ -133,13 +153,16 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa * @throws LuaException If there are too many open channels. */ @LuaFunction - public final void open(int channel) throws LuaException { - this.m_state.open(parseChannel(channel)); + public final void open( int channel ) throws LuaException + { + this.m_state.open( parseChannel( channel ) ); } - private static int parseChannel(int channel) throws LuaException { - if (channel < 0 || channel > 65535) { - throw new LuaException("Expected number in range 0-65535"); + private static int parseChannel( int channel ) throws LuaException + { + if( channel < 0 || channel > 65535 ) + { + throw new LuaException( "Expected number in range 0-65535" ); } return channel; } @@ -152,8 +175,9 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa * @throws LuaException If the channel is out of range. */ @LuaFunction - public final boolean isOpen(int channel) throws LuaException { - return this.m_state.isOpen(parseChannel(channel)); + public final boolean isOpen( int channel ) throws LuaException + { + return this.m_state.isOpen( parseChannel( channel ) ); } /** @@ -163,15 +187,17 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa * @throws LuaException If the channel is out of range. */ @LuaFunction - public final void close(int channel) throws LuaException { - this.m_state.close(parseChannel(channel)); + public final void close( int channel ) throws LuaException + { + this.m_state.close( parseChannel( channel ) ); } /** * Close all open channels. */ @LuaFunction - public final void closeAll() { + public final void closeAll() + { this.m_state.closeAll(); } @@ -180,29 +206,34 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa * *
    Note: The channel does not need be open to send a message.
    * - * @param channel The channel to send messages on. + * @param channel The channel to send messages on. * @param replyChannel The channel that responses to this message should be sent on. - * @param payload The object to send. This can be a string, number, or table. + * @param payload The object to send. This can be a string, number, or table. * @throws LuaException If the channel is out of range. */ @LuaFunction - public final void transmit(int channel, int replyChannel, Object payload) throws LuaException { - parseChannel(channel); - parseChannel(replyChannel); + public final void transmit( int channel, int replyChannel, Object payload ) throws LuaException + { + parseChannel( channel ); + parseChannel( replyChannel ); World world = this.getWorld(); Vec3d position = this.getPosition(); IPacketNetwork network = this.m_network; - if (world == null || position == null || network == null) { + if( world == null || position == null || network == null ) + { return; } - Packet packet = new Packet(channel, replyChannel, payload, this); - if (this.isInterdimensional()) { - network.transmitInterdimensional(packet); - } else { - network.transmitSameDimension(packet, this.getRange()); + Packet packet = new Packet( channel, replyChannel, payload, this ); + if( this.isInterdimensional() ) + { + network.transmitInterdimensional( packet ); + } + else + { + network.transmitSameDimension( packet, this.getRange() ); } } @@ -214,20 +245,26 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa * @return {@code true} if this is a wireless modem. */ @LuaFunction - public final boolean isWireless() { + public final boolean isWireless() + { IPacketNetwork network = this.m_network; return network != null && network.isWireless(); } @Nonnull @Override - public String getSenderID() { - synchronized (this.m_computers) { - if (this.m_computers.size() != 1) { + public String getSenderID() + { + synchronized( this.m_computers ) + { + if( this.m_computers.size() != 1 ) + { return "unknown"; - } else { + } + else + { IComputerAccess computer = this.m_computers.iterator() - .next(); + .next(); return computer.getID() + "_" + computer.getAttachmentName(); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemShapes.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemShapes.java index 548b010b9..1cf37fe63 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemShapes.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemShapes.java @@ -6,30 +6,32 @@ package dan200.computercraft.shared.peripheral.modem; -import javax.annotation.Nonnull; - import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; -public final class ModemShapes { +import javax.annotation.Nonnull; + +public final class ModemShapes +{ private static final VoxelShape[] BOXES = new VoxelShape[] { - VoxelShapes.cuboid(0.125, 0.0, 0.125, 0.875, 0.1875, 0.875), + VoxelShapes.cuboid( 0.125, 0.0, 0.125, 0.875, 0.1875, 0.875 ), // Down - VoxelShapes.cuboid(0.125, 0.8125, 0.125, 0.875, 1.0, 0.875), + VoxelShapes.cuboid( 0.125, 0.8125, 0.125, 0.875, 1.0, 0.875 ), // Up - VoxelShapes.cuboid(0.125, 0.125, 0.0, 0.875, 0.875, 0.1875), + VoxelShapes.cuboid( 0.125, 0.125, 0.0, 0.875, 0.875, 0.1875 ), // North - VoxelShapes.cuboid(0.125, 0.125, 0.8125, 0.875, 0.875, 1.0), + VoxelShapes.cuboid( 0.125, 0.125, 0.8125, 0.875, 0.875, 1.0 ), // South - VoxelShapes.cuboid(0.0, 0.125, 0.125, 0.1875, 0.875, 0.875), + VoxelShapes.cuboid( 0.0, 0.125, 0.125, 0.1875, 0.875, 0.875 ), // West - VoxelShapes.cuboid(0.8125, 0.125, 0.125, 1.0, 0.875, 0.875), + VoxelShapes.cuboid( 0.8125, 0.125, 0.125, 1.0, 0.875, 0.875 ), // East }; @Nonnull - public static VoxelShape getBounds(Direction facing) { + public static VoxelShape getBounds( Direction facing ) + { int direction = facing.ordinal(); return direction < BOXES.length ? BOXES[direction] : VoxelShapes.fullCube(); } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java index 883498f27..5d56ef3ae 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java @@ -6,75 +6,94 @@ package dan200.computercraft.shared.peripheral.modem; -import java.util.concurrent.atomic.AtomicBoolean; - import dan200.computercraft.api.lua.LuaException; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; -public class ModemState { +import java.util.concurrent.atomic.AtomicBoolean; + +public class ModemState +{ private final Runnable onChanged; - private final AtomicBoolean changed = new AtomicBoolean(true); + private final AtomicBoolean changed = new AtomicBoolean( true ); private final IntSet channels = new IntOpenHashSet(); private boolean open = false; - public ModemState() { + public ModemState() + { this.onChanged = null; } - public ModemState(Runnable onChanged) { + public ModemState( Runnable onChanged ) + { this.onChanged = onChanged; } - public boolean pollChanged() { - return this.changed.getAndSet(false); + public boolean pollChanged() + { + return this.changed.getAndSet( false ); } - public boolean isOpen() { + public boolean isOpen() + { return this.open; } - private void setOpen(boolean open) { - if (this.open == open) { + private void setOpen( boolean open ) + { + if( this.open == open ) + { return; } this.open = open; - if (!this.changed.getAndSet(true) && this.onChanged != null) { + if( !this.changed.getAndSet( true ) && this.onChanged != null ) + { this.onChanged.run(); } } - public boolean isOpen(int channel) { - synchronized (this.channels) { - return this.channels.contains(channel); + public boolean isOpen( int channel ) + { + synchronized( this.channels ) + { + return this.channels.contains( channel ); } } - public void open(int channel) throws LuaException { - synchronized (this.channels) { - if (!this.channels.contains(channel)) { - if (this.channels.size() >= 128) { - throw new LuaException("Too many open channels"); + public void open( int channel ) throws LuaException + { + synchronized( this.channels ) + { + if( !this.channels.contains( channel ) ) + { + if( this.channels.size() >= 128 ) + { + throw new LuaException( "Too many open channels" ); } - this.channels.add(channel); - this.setOpen(true); + this.channels.add( channel ); + this.setOpen( true ); } } } - public void close(int channel) { - synchronized (this.channels) { - this.channels.remove(channel); - if (this.channels.isEmpty()) { - this.setOpen(false); + public void close( int channel ) + { + synchronized( this.channels ) + { + this.channels.remove( channel ); + if( this.channels.isEmpty() ) + { + this.setOpen( false ); } } } - public void closeAll() { - synchronized (this.channels) { + public void closeAll() + { + synchronized( this.channels ) + { this.channels.clear(); - this.setOpen(false); + this.setOpen( false ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockCable.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockCable.java index 7b6fde27d..4e958b69c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockCable.java @@ -6,21 +6,10 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED; -import static dan200.computercraft.shared.util.WaterloggableHelpers.getWaterloggedFluidState; -import static dan200.computercraft.shared.util.WaterloggableHelpers.getWaterloggedStateForPlacement; -import static dan200.computercraft.shared.util.WaterloggableHelpers.updateWaterloggedPostPlacement; - -import java.util.EnumMap; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.collect.ImmutableMap; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.BlockGeneric; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; @@ -41,81 +30,96 @@ import net.minecraft.world.World; import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldView; -public class BlockCable extends BlockGeneric implements Waterloggable { - public static final EnumProperty MODEM = EnumProperty.of("modem", CableModemVariant.class); - public static final BooleanProperty CABLE = BooleanProperty.of("cable"); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.EnumMap; - private static final BooleanProperty NORTH = BooleanProperty.of("north"); - private static final BooleanProperty SOUTH = BooleanProperty.of("south"); - private static final BooleanProperty EAST = BooleanProperty.of("east"); - private static final BooleanProperty WEST = BooleanProperty.of("west"); - private static final BooleanProperty UP = BooleanProperty.of("up"); - private static final BooleanProperty DOWN = BooleanProperty.of("down"); +import static dan200.computercraft.shared.util.WaterloggableHelpers.*; - static final EnumMap CONNECTIONS = new EnumMap<>(new ImmutableMap.Builder().put(Direction.DOWN, - DOWN) - .put(Direction.UP, - UP) - .put(Direction.NORTH, - NORTH) - .put(Direction.SOUTH, - SOUTH) - .put(Direction.WEST, - WEST) - .put(Direction.EAST, - EAST) - .build()); +public class BlockCable extends BlockGeneric implements Waterloggable +{ + public static final EnumProperty MODEM = EnumProperty.of( "modem", CableModemVariant.class ); + public static final BooleanProperty CABLE = BooleanProperty.of( "cable" ); - public BlockCable(Settings settings) { - super(settings, ComputerCraftRegistry.ModTiles.CABLE); + private static final BooleanProperty NORTH = BooleanProperty.of( "north" ); + private static final BooleanProperty SOUTH = BooleanProperty.of( "south" ); + private static final BooleanProperty EAST = BooleanProperty.of( "east" ); + private static final BooleanProperty WEST = BooleanProperty.of( "west" ); + private static final BooleanProperty UP = BooleanProperty.of( "up" ); + private static final BooleanProperty DOWN = BooleanProperty.of( "down" ); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(MODEM, CableModemVariant.None) - .with(CABLE, false) - .with(NORTH, false) - .with(SOUTH, false) - .with(EAST, false) - .with(WEST, false) - .with(UP, false) - .with(DOWN, false) - .with(WATERLOGGED, false)); + static final EnumMap CONNECTIONS = new EnumMap<>( new ImmutableMap.Builder().put( Direction.DOWN, + DOWN ) + .put( Direction.UP, + UP ) + .put( Direction.NORTH, + NORTH ) + .put( Direction.SOUTH, + SOUTH ) + .put( Direction.WEST, + WEST ) + .put( Direction.EAST, + EAST ) + .build() ); + + public BlockCable( Settings settings ) + { + super( settings, ComputerCraftRegistry.ModTiles.CABLE ); + + this.setDefaultState( this.getStateManager().getDefaultState() + .with( MODEM, CableModemVariant.None ) + .with( CABLE, false ) + .with( NORTH, false ) + .with( SOUTH, false ) + .with( EAST, false ) + .with( WEST, false ) + .with( UP, false ) + .with( DOWN, false ) + .with( WATERLOGGED, false ) ); } - public static boolean canConnectIn(BlockState state, Direction direction) { - return state.get(BlockCable.CABLE) && state.get(BlockCable.MODEM) - .getFacing() != direction; + public static boolean canConnectIn( BlockState state, Direction direction ) + { + return state.get( BlockCable.CABLE ) && state.get( BlockCable.MODEM ) + .getFacing() != direction; } @Nonnull @Override @Deprecated - public BlockState getStateForNeighborUpdate(@Nonnull BlockState state, @Nonnull Direction side, @Nonnull BlockState otherState, - @Nonnull WorldAccess world, @Nonnull BlockPos pos, @Nonnull BlockPos otherPos) { - updateWaterloggedPostPlacement(state, world, pos); + public BlockState getStateForNeighborUpdate( @Nonnull BlockState state, @Nonnull Direction side, @Nonnull BlockState otherState, + @Nonnull WorldAccess world, @Nonnull BlockPos pos, @Nonnull BlockPos otherPos ) + { + updateWaterloggedPostPlacement( state, world, pos ); // Should never happen, but handle the case where we've no modem or cable. - if (!state.get(CABLE) && state.get(MODEM) == CableModemVariant.None) { - return this.getFluidState(state).getBlockState(); + if( !state.get( CABLE ) && state.get( MODEM ) == CableModemVariant.None ) + { + return this.getFluidState( state ).getBlockState(); } - return state.with(CONNECTIONS.get(side), doesConnectVisually(state, world, pos, side)); + return state.with( CONNECTIONS.get( side ), doesConnectVisually( state, world, pos, side ) ); } - public static boolean doesConnectVisually(BlockState state, BlockView world, BlockPos pos, Direction direction) { - if (!state.get(CABLE)) { + public static boolean doesConnectVisually( BlockState state, BlockView world, BlockPos pos, Direction direction ) + { + if( !state.get( CABLE ) ) + { return false; } - if (state.get(MODEM) - .getFacing() == direction) { + if( state.get( MODEM ) + .getFacing() == direction ) + { return true; } - return ComputerCraftAPI.getWiredElementAt(world, pos.offset(direction), direction.getOpposite()) != null; + return ComputerCraftAPI.getWiredElementAt( world, pos.offset( direction ), direction.getOpposite() ) != null; } @Nonnull @Override @Deprecated - public FluidState getFluidState(@Nonnull BlockState state) { - return getWaterloggedFluidState(state); + public FluidState getFluidState( @Nonnull BlockState state ) + { + return getWaterloggedFluidState( state ); } // @Override @@ -183,73 +187,88 @@ public class BlockCable extends BlockGeneric implements Waterloggable { @Override @Deprecated - public boolean canPlaceAt(BlockState state, @Nonnull WorldView world, @Nonnull BlockPos pos) { - Direction facing = state.get(MODEM) - .getFacing(); - if (facing == null) { + public boolean canPlaceAt( BlockState state, @Nonnull WorldView world, @Nonnull BlockPos pos ) + { + Direction facing = state.get( MODEM ) + .getFacing(); + if( facing == null ) + { return true; } - return sideCoversSmallSquare(world, pos.offset(facing), facing.getOpposite()); + return sideCoversSmallSquare( world, pos.offset( facing ), facing.getOpposite() ); } @Nonnull @Override @Deprecated - public VoxelShape getOutlineShape(@Nonnull BlockState state, @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull ShapeContext context) { - return CableShapes.getShape(state); + public VoxelShape getOutlineShape( @Nonnull BlockState state, @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull ShapeContext context ) + { + return CableShapes.getShape( state ); } @Nullable @Override - public BlockState getPlacementState(@Nonnull ItemPlacementContext context) { - BlockState state = this.getDefaultState().with(WATERLOGGED, getWaterloggedStateForPlacement(context)); + public BlockState getPlacementState( @Nonnull ItemPlacementContext context ) + { + BlockState state = this.getDefaultState().with( WATERLOGGED, getWaterloggedStateForPlacement( context ) ); - if (context.getStack() - .getItem() instanceof ItemBlockCable.Cable) { + if( context.getStack() + .getItem() instanceof ItemBlockCable.Cable ) + { World world = context.getWorld(); BlockPos pos = context.getBlockPos(); - return correctConnections(world, pos, state.with(CABLE, true)); - } else { - return state.with(MODEM, - CableModemVariant.from(context.getSide() - .getOpposite())); + return correctConnections( world, pos, state.with( CABLE, true ) ); + } + else + { + return state.with( MODEM, + CableModemVariant.from( context.getSide() + .getOpposite() ) ); } } @Override - public void onPlaced(World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, @Nonnull ItemStack stack) { - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileCable) { + public void onPlaced( World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, @Nonnull ItemStack stack ) + { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileCable ) + { TileCable cable = (TileCable) tile; - if (cable.hasCable()) { + if( cable.hasCable() ) + { cable.connectionsChanged(); } } - super.onPlaced(world, pos, state, placer, stack); + super.onPlaced( world, pos, state, placer, stack ); } @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(MODEM, CABLE, NORTH, SOUTH, EAST, WEST, UP, DOWN, WATERLOGGED); + protected void appendProperties( StateManager.Builder builder ) + { + builder.add( MODEM, CABLE, NORTH, SOUTH, EAST, WEST, UP, DOWN, WATERLOGGED ); } - public static BlockState correctConnections(World world, BlockPos pos, BlockState state) { - if (state.get(CABLE)) { - return state.with(NORTH, doesConnectVisually(state, world, pos, Direction.NORTH)) - .with(SOUTH, doesConnectVisually(state, world, pos, Direction.SOUTH)) - .with(EAST, doesConnectVisually(state, world, pos, Direction.EAST)) - .with(WEST, doesConnectVisually(state, world, pos, Direction.WEST)) - .with(UP, doesConnectVisually(state, world, pos, Direction.UP)) - .with(DOWN, doesConnectVisually(state, world, pos, Direction.DOWN)); - } else { - return state.with(NORTH, false) - .with(SOUTH, false) - .with(EAST, false) - .with(WEST, false) - .with(UP, false) - .with(DOWN, false); + public static BlockState correctConnections( World world, BlockPos pos, BlockState state ) + { + if( state.get( CABLE ) ) + { + return state.with( NORTH, doesConnectVisually( state, world, pos, Direction.NORTH ) ) + .with( SOUTH, doesConnectVisually( state, world, pos, Direction.SOUTH ) ) + .with( EAST, doesConnectVisually( state, world, pos, Direction.EAST ) ) + .with( WEST, doesConnectVisually( state, world, pos, Direction.WEST ) ) + .with( UP, doesConnectVisually( state, world, pos, Direction.UP ) ) + .with( DOWN, doesConnectVisually( state, world, pos, Direction.DOWN ) ); + } + else + { + return state.with( NORTH, false ) + .with( SOUTH, false ) + .with( EAST, false ) + .with( WEST, false ) + .with( UP, false ) + .with( DOWN, false ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockWiredModemFull.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockWiredModemFull.java index fa801daf1..fc6572cc3 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockWiredModemFull.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/BlockWiredModemFull.java @@ -7,26 +7,28 @@ package dan200.computercraft.shared.peripheral.modem.wired; import dan200.computercraft.shared.common.BlockGeneric; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; -public class BlockWiredModemFull extends BlockGeneric { - public static final BooleanProperty MODEM_ON = BooleanProperty.of("modem"); - public static final BooleanProperty PERIPHERAL_ON = BooleanProperty.of("peripheral"); +public class BlockWiredModemFull extends BlockGeneric +{ + public static final BooleanProperty MODEM_ON = BooleanProperty.of( "modem" ); + public static final BooleanProperty PERIPHERAL_ON = BooleanProperty.of( "peripheral" ); - public BlockWiredModemFull(Settings settings, BlockEntityType type) { - super(settings, type); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(MODEM_ON, false) - .with(PERIPHERAL_ON, false)); + public BlockWiredModemFull( Settings settings, BlockEntityType type ) + { + super( settings, type ); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( MODEM_ON, false ) + .with( PERIPHERAL_ON, false ) ); } @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(MODEM_ON, PERIPHERAL_ON); + protected void appendProperties( StateManager.Builder builder ) + { + builder.add( MODEM_ON, PERIPHERAL_ON ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java index 0c3c16e8c..5c6fc398d 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java @@ -6,73 +6,80 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import net.minecraft.util.StringIdentifiable; import net.minecraft.util.math.Direction; -public enum CableModemVariant implements StringIdentifiable { - None("none", null), - DownOff("down_off", Direction.DOWN), - UpOff("up_off", Direction.UP), - NorthOff("north_off", Direction.NORTH), - SouthOff("south_off", Direction.SOUTH), - WestOff("west_off", Direction.WEST), - EastOff("east_off", Direction.EAST), - DownOn("down_on", Direction.DOWN), - UpOn("up_on", Direction.UP), - NorthOn("north_on", Direction.NORTH), - SouthOn("south_on", Direction.SOUTH), - WestOn("west_on", Direction.WEST), - EastOn("east_on", Direction.EAST), - DownOffPeripheral("down_off_peripheral", Direction.DOWN), - UpOffPeripheral("up_off_peripheral", Direction.UP), - NorthOffPeripheral("north_off_peripheral", Direction.NORTH), - SouthOffPeripheral("south_off_peripheral", Direction.SOUTH), - WestOffPeripheral("west_off_peripheral", Direction.WEST), - EastOffPeripheral("east_off_peripheral", Direction.EAST), - DownOnPeripheral("down_on_peripheral", Direction.DOWN), - UpOnPeripheral("up_on_peripheral", Direction.UP), - NorthOnPeripheral("north_on_peripheral", Direction.NORTH), - SouthOnPeripheral("south_on_peripheral", Direction.SOUTH), - WestOnPeripheral("west_on_peripheral", Direction.WEST), - EastOnPeripheral("east_on_peripheral", Direction.EAST); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public enum CableModemVariant implements StringIdentifiable +{ + None( "none", null ), + DownOff( "down_off", Direction.DOWN ), + UpOff( "up_off", Direction.UP ), + NorthOff( "north_off", Direction.NORTH ), + SouthOff( "south_off", Direction.SOUTH ), + WestOff( "west_off", Direction.WEST ), + EastOff( "east_off", Direction.EAST ), + DownOn( "down_on", Direction.DOWN ), + UpOn( "up_on", Direction.UP ), + NorthOn( "north_on", Direction.NORTH ), + SouthOn( "south_on", Direction.SOUTH ), + WestOn( "west_on", Direction.WEST ), + EastOn( "east_on", Direction.EAST ), + DownOffPeripheral( "down_off_peripheral", Direction.DOWN ), + UpOffPeripheral( "up_off_peripheral", Direction.UP ), + NorthOffPeripheral( "north_off_peripheral", Direction.NORTH ), + SouthOffPeripheral( "south_off_peripheral", Direction.SOUTH ), + WestOffPeripheral( "west_off_peripheral", Direction.WEST ), + EastOffPeripheral( "east_off_peripheral", Direction.EAST ), + DownOnPeripheral( "down_on_peripheral", Direction.DOWN ), + UpOnPeripheral( "up_on_peripheral", Direction.UP ), + NorthOnPeripheral( "north_on_peripheral", Direction.NORTH ), + SouthOnPeripheral( "south_on_peripheral", Direction.SOUTH ), + WestOnPeripheral( "west_on_peripheral", Direction.WEST ), + EastOnPeripheral( "east_on_peripheral", Direction.EAST ); private static final CableModemVariant[] VALUES = values(); private final String name; private final Direction facing; - CableModemVariant(String name, Direction facing) { + CableModemVariant( String name, Direction facing ) + { this.name = name; this.facing = facing; } @Nonnull - public static CableModemVariant from(Direction facing) { + public static CableModemVariant from( Direction facing ) + { return facing == null ? None : VALUES[1 + facing.getId()]; } @Nonnull - public static CableModemVariant from(Direction facing, boolean modem, boolean peripheral) { + public static CableModemVariant from( Direction facing, boolean modem, boolean peripheral ) + { int state = (modem ? 2 : 0) + (peripheral ? 1 : 0); return facing == null ? None : VALUES[1 + 6 * state + facing.getId()]; } @Nonnull @Override - public String asString() { + public String asString() + { return this.name; } @Nullable - public Direction getFacing() { + public Direction getFacing() + { return this.facing; } @Override - public String toString() { + public String toString() + { return this.name; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableShapes.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableShapes.java index 85a6112fc..12bd696cb 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableShapes.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableShapes.java @@ -6,110 +6,118 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.CABLE; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.CONNECTIONS; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.MODEM; - -import java.util.EnumMap; - import com.google.common.collect.ImmutableMap; import dan200.computercraft.shared.peripheral.modem.ModemShapes; import dan200.computercraft.shared.util.DirectionUtil; - import net.minecraft.block.BlockState; import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; -public final class CableShapes { +import java.util.EnumMap; + +import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.*; + +public final class CableShapes +{ private static final double MIN = 0.375; private static final double MAX = 1 - MIN; - private static final VoxelShape SHAPE_CABLE_CORE = VoxelShapes.cuboid(MIN, MIN, MIN, MAX, MAX, MAX); + private static final VoxelShape SHAPE_CABLE_CORE = VoxelShapes.cuboid( MIN, MIN, MIN, MAX, MAX, MAX ); private static final EnumMap SHAPE_CABLE_ARM = - new EnumMap<>(new ImmutableMap.Builder().put(Direction.DOWN, - VoxelShapes.cuboid( - MIN, - 0, - MIN, - MAX, - MIN, - MAX)) - .put(Direction.UP, - VoxelShapes.cuboid( - MIN, - MAX, - MIN, - MAX, - 1, - MAX)) - .put(Direction.NORTH, - VoxelShapes.cuboid( - MIN, - MIN, - 0, - MAX, - MAX, - MIN)) - .put(Direction.SOUTH, - VoxelShapes.cuboid( - MIN, - MIN, - MAX, - MAX, - MAX, - 1)) - .put(Direction.WEST, - VoxelShapes.cuboid( - 0, - MIN, - MIN, - MIN, - MAX, - MAX)) - .put(Direction.EAST, - VoxelShapes.cuboid( - MAX, - MIN, - MIN, - 1, - MAX, - MAX)) - .build()); + new EnumMap<>( new ImmutableMap.Builder().put( Direction.DOWN, + VoxelShapes.cuboid( + MIN, + 0, + MIN, + MAX, + MIN, + MAX ) ) + .put( Direction.UP, + VoxelShapes.cuboid( + MIN, + MAX, + MIN, + MAX, + 1, + MAX ) ) + .put( Direction.NORTH, + VoxelShapes.cuboid( + MIN, + MIN, + 0, + MAX, + MAX, + MIN ) ) + .put( Direction.SOUTH, + VoxelShapes.cuboid( + MIN, + MIN, + MAX, + MAX, + MAX, + 1 ) ) + .put( Direction.WEST, + VoxelShapes.cuboid( + 0, + MIN, + MIN, + MIN, + MAX, + MAX ) ) + .put( Direction.EAST, + VoxelShapes.cuboid( + MAX, + MIN, + MIN, + 1, + MAX, + MAX ) ) + .build() ); private static final VoxelShape[] SHAPES = new VoxelShape[(1 << 6) * 7]; private static final VoxelShape[] CABLE_SHAPES = new VoxelShape[1 << 6]; - private CableShapes() { + private CableShapes() + { } - public static VoxelShape getCableShape(BlockState state) { - if (!state.get(CABLE)) { + public static VoxelShape getCableShape( BlockState state ) + { + if( !state.get( CABLE ) ) + { return VoxelShapes.empty(); } - return getCableShape(getCableIndex(state)); + return getCableShape( getCableIndex( state ) ); } - private static VoxelShape getCableShape(int index) { + private static VoxelShape getCableShape( int index ) + { VoxelShape shape = CABLE_SHAPES[index]; - if (shape != null) { + if( shape != null ) + { return shape; } shape = SHAPE_CABLE_CORE; - for (Direction facing : DirectionUtil.FACINGS) { - if ((index & (1 << facing.ordinal())) != 0) { - shape = VoxelShapes.union(shape, SHAPE_CABLE_ARM.get(facing)); + for( Direction facing : DirectionUtil.FACINGS ) + { + if( (index & (1 << facing.ordinal())) != 0 ) + { + shape = VoxelShapes.union( shape, SHAPE_CABLE_ARM.get( facing ) ); } } return CABLE_SHAPES[index] = shape; } - private static int getCableIndex(BlockState state) { + private static int getCableIndex( BlockState state ) + { int index = 0; - for (Direction facing : DirectionUtil.FACINGS) { - if (state.get(CONNECTIONS.get(facing))) { + for( Direction facing : DirectionUtil.FACINGS ) + { + if( state.get( CONNECTIONS.get( facing ) ) ) + { index |= 1 << facing.ordinal(); } } @@ -117,31 +125,36 @@ public final class CableShapes { return index; } - public static VoxelShape getShape(BlockState state) { - Direction facing = state.get(MODEM) - .getFacing(); - if (!state.get(CABLE)) { - return getModemShape(state); + public static VoxelShape getShape( BlockState state ) + { + Direction facing = state.get( MODEM ) + .getFacing(); + if( !state.get( CABLE ) ) + { + return getModemShape( state ); } - int cableIndex = getCableIndex(state); + int cableIndex = getCableIndex( state ); int index = cableIndex + ((facing == null ? 0 : facing.ordinal() + 1) << 6); VoxelShape shape = SHAPES[index]; - if (shape != null) { + if( shape != null ) + { return shape; } - shape = getCableShape(cableIndex); - if (facing != null) { - shape = VoxelShapes.union(shape, ModemShapes.getBounds(facing)); + shape = getCableShape( cableIndex ); + if( facing != null ) + { + shape = VoxelShapes.union( shape, ModemShapes.getBounds( facing ) ); } return SHAPES[index] = shape; } - public static VoxelShape getModemShape(BlockState state) { - Direction facing = state.get(MODEM) - .getFacing(); - return facing == null ? VoxelShapes.empty() : ModemShapes.getBounds(facing); + public static VoxelShape getModemShape( BlockState state ) + { + Direction facing = state.get( MODEM ) + .getFacing(); + return facing == null ? VoxelShapes.empty() : ModemShapes.getBounds( facing ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/ItemBlockCable.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/ItemBlockCable.java index 4685c18a3..d866b41c7 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/ItemBlockCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/ItemBlockCable.java @@ -6,15 +6,7 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.CABLE; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.CONNECTIONS; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.MODEM; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.correctConnections; - -import javax.annotation.Nonnull; - import dan200.computercraft.shared.ComputerCraftRegistry; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; @@ -32,30 +24,40 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; -public abstract class ItemBlockCable extends BlockItem { +import javax.annotation.Nonnull; + +import static dan200.computercraft.shared.peripheral.modem.wired.BlockCable.*; + +public abstract class ItemBlockCable extends BlockItem +{ private String translationKey; - public ItemBlockCable(BlockCable block, Settings settings) { - super(block, settings); + public ItemBlockCable( BlockCable block, Settings settings ) + { + super( block, settings ); } - boolean placeAtCorrected(World world, BlockPos pos, BlockState state) { - return this.placeAt(world, pos, correctConnections(world, pos, state), null); + boolean placeAtCorrected( World world, BlockPos pos, BlockState state ) + { + return this.placeAt( world, pos, correctConnections( world, pos, state ), null ); } - boolean placeAt(World world, BlockPos pos, BlockState state, PlayerEntity player) { + boolean placeAt( World world, BlockPos pos, BlockState state, PlayerEntity player ) + { // TODO: Check entity collision. - if (!state.canPlaceAt(world, pos)) { + if( !state.canPlaceAt( world, pos ) ) + { return false; } - world.setBlockState(pos, state, 3); + world.setBlockState( pos, state, 3 ); BlockSoundGroup soundType = state.getBlock() - .getSoundGroup(state); - world.playSound(null, pos, soundType.getPlaceSound(), SoundCategory.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, soundType.getPitch() * 0.8F); + .getSoundGroup( state ); + world.playSound( null, pos, soundType.getPlaceSound(), SoundCategory.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, soundType.getPitch() * 0.8F ); - BlockEntity tile = world.getBlockEntity(pos); - if (tile instanceof TileCable) { + BlockEntity tile = world.getBlockEntity( pos ); + if( tile instanceof TileCable ) + { TileCable cable = (TileCable) tile; cable.modemChanged(); cable.connectionsChanged(); @@ -66,63 +68,77 @@ public abstract class ItemBlockCable extends BlockItem { @Nonnull @Override - public String getTranslationKey() { - if (this.translationKey == null) { - this.translationKey = Util.createTranslationKey("block", Registry.ITEM.getId(this)); + public String getTranslationKey() + { + if( this.translationKey == null ) + { + this.translationKey = Util.createTranslationKey( "block", Registry.ITEM.getId( this ) ); } return this.translationKey; } @Override - public void appendStacks(@Nonnull ItemGroup group, @Nonnull DefaultedList list) { - if (this.isIn(group)) { - list.add(new ItemStack(this)); + public void appendStacks( @Nonnull ItemGroup group, @Nonnull DefaultedList list ) + { + if( this.isIn( group ) ) + { + list.add( new ItemStack( this ) ); } } - public static class WiredModem extends ItemBlockCable { - public WiredModem(BlockCable block, Settings settings) { - super(block, settings); + public static class WiredModem extends ItemBlockCable + { + public WiredModem( BlockCable block, Settings settings ) + { + super( block, settings ); } @Nonnull @Override - public ActionResult place(ItemPlacementContext context) { + public ActionResult place( ItemPlacementContext context ) + { ItemStack stack = context.getStack(); - if (stack.isEmpty()) { + if( stack.isEmpty() ) + { return ActionResult.FAIL; } World world = context.getWorld(); BlockPos pos = context.getBlockPos(); - BlockState existingState = world.getBlockState(pos); + BlockState existingState = world.getBlockState( pos ); // Try to add a modem to a cable - if (existingState.getBlock() == ComputerCraftRegistry.ModBlocks.CABLE && existingState.get(MODEM) == CableModemVariant.None) { + if( existingState.getBlock() == ComputerCraftRegistry.ModBlocks.CABLE && existingState.get( MODEM ) == CableModemVariant.None ) + { Direction side = context.getSide() - .getOpposite(); - BlockState newState = existingState.with(MODEM, CableModemVariant.from(side)) - .with(CONNECTIONS.get(side), existingState.get(CABLE)); - if (this.placeAt(world, pos, newState, context.getPlayer())) { - stack.decrement(1); + .getOpposite(); + BlockState newState = existingState.with( MODEM, CableModemVariant.from( side ) ) + .with( CONNECTIONS.get( side ), existingState.get( CABLE ) ); + if( this.placeAt( world, pos, newState, context.getPlayer() ) ) + { + stack.decrement( 1 ); return ActionResult.SUCCESS; } } - return super.place(context); + return super.place( context ); } } - public static class Cable extends ItemBlockCable { - public Cable(BlockCable block, Settings settings) { - super(block, settings); + public static class Cable extends ItemBlockCable + { + public Cable( BlockCable block, Settings settings ) + { + super( block, settings ); } @Nonnull @Override - public ActionResult place(ItemPlacementContext context) { + public ActionResult place( ItemPlacementContext context ) + { ItemStack stack = context.getStack(); - if (stack.isEmpty()) { + if( stack.isEmpty() ) + { return ActionResult.FAIL; } @@ -130,30 +146,32 @@ public abstract class ItemBlockCable extends BlockItem { BlockPos pos = context.getBlockPos(); // Try to add a cable to a modem inside the block we're clicking on. - BlockPos insidePos = pos.offset(context.getSide() - .getOpposite()); - BlockState insideState = world.getBlockState(insidePos); - if (insideState.getBlock() == ComputerCraftRegistry.ModBlocks.CABLE && !insideState.get(BlockCable.CABLE) && this.placeAtCorrected(world, - insidePos, - insideState.with( - BlockCable.CABLE, - true))) { - stack.decrement(1); + BlockPos insidePos = pos.offset( context.getSide() + .getOpposite() ); + BlockState insideState = world.getBlockState( insidePos ); + if( insideState.getBlock() == ComputerCraftRegistry.ModBlocks.CABLE && !insideState.get( BlockCable.CABLE ) && this.placeAtCorrected( world, + insidePos, + insideState.with( + BlockCable.CABLE, + true ) ) ) + { + stack.decrement( 1 ); return ActionResult.SUCCESS; } // Try to add a cable to a modem adjacent to this block - BlockState existingState = world.getBlockState(pos); - if (existingState.getBlock() == ComputerCraftRegistry.ModBlocks.CABLE && !existingState.get(BlockCable.CABLE) && this.placeAtCorrected(world, - pos, - existingState.with( - BlockCable.CABLE, - true))) { - stack.decrement(1); + BlockState existingState = world.getBlockState( pos ); + if( existingState.getBlock() == ComputerCraftRegistry.ModBlocks.CABLE && !existingState.get( BlockCable.CABLE ) && this.placeAtCorrected( world, + pos, + existingState.with( + BlockCable.CABLE, + true ) ) ) + { + stack.decrement( 1 ); return ActionResult.SUCCESS; } - return super.place(context); + return super.place( context ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java index 9b23eaed7..fe4440f24 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileCable.java @@ -6,12 +6,6 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import java.util.Collections; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.base.Objects; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.network.wired.IWiredElement; @@ -24,7 +18,6 @@ import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.TickScheduler; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; @@ -40,7 +33,13 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class TileCable extends TileGeneric implements IPeripheralTile { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.Map; + +public class TileCable extends TileGeneric implements IPeripheralTile +{ private static final String NBT_PERIPHERAL_ENABLED = "PeirpheralAccess"; private final WiredModemLocalPeripheral m_peripheral = new WiredModemLocalPeripheral(); private final WiredModemElement m_cable = new CableElement(); @@ -48,35 +47,43 @@ public class TileCable extends TileGeneric implements IPeripheralTile { private boolean m_peripheralAccessAllowed; private boolean m_destroyed = false; private Direction modemDirection = Direction.NORTH; - private final WiredModemPeripheral m_modem = new WiredModemPeripheral(new ModemState(() -> TickScheduler.schedule(this)), this.m_cable) { + private final WiredModemPeripheral m_modem = new WiredModemPeripheral( new ModemState( () -> TickScheduler.schedule( this ) ), this.m_cable ) + { @Nonnull @Override - protected WiredModemLocalPeripheral getLocalPeripheral() { + protected WiredModemLocalPeripheral getLocalPeripheral() + { return TileCable.this.m_peripheral; } @Nonnull @Override - public Vec3d getPosition() { - BlockPos pos = TileCable.this.getPos().offset(TileCable.this.modemDirection); - return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + public Vec3d getPosition() + { + BlockPos pos = TileCable.this.getPos().offset( TileCable.this.modemDirection ); + return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ); } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return TileCable.this; } }; private boolean hasModemDirection = false; private boolean m_connectionsFormed = false; - public TileCable(BlockEntityType type) { - super(type); + + public TileCable( BlockEntityType type ) + { + super( type ); } @Override - public void destroy() { - if (!this.m_destroyed) { + public void destroy() + { + if( !this.m_destroyed ) + { this.m_destroyed = true; this.m_modem.destroy(); this.onRemove(); @@ -90,8 +97,10 @@ public class TileCable extends TileGeneric implements IPeripheralTile { onRemove(); } - private void onRemove() { - if (this.world == null || !this.world.isClient) { + private void onRemove() + { + if( this.world == null || !this.world.isClient ) + { this.m_node.remove(); this.m_connectionsFormed = false; } @@ -99,29 +108,36 @@ public class TileCable extends TileGeneric implements IPeripheralTile { @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { - if (player.isInSneakingPose()) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { + if( player.isInSneakingPose() ) + { return ActionResult.PASS; } - if (!this.canAttachPeripheral()) { + if( !this.canAttachPeripheral() ) + { return ActionResult.FAIL; } - if (this.getWorld().isClient) { + if( this.getWorld().isClient ) + { return ActionResult.SUCCESS; } String oldName = this.m_peripheral.getConnectedName(); this.togglePeripheralAccess(); String newName = this.m_peripheral.getConnectedName(); - if (!Objects.equal(newName, oldName)) { - if (oldName != null) { - player.sendMessage(new TranslatableText("chat.computercraft.wired_modem.peripheral_disconnected", - ChatHelpers.copy(oldName)), false); + if( !Objects.equal( newName, oldName ) ) + { + if( oldName != null ) + { + player.sendMessage( new TranslatableText( "chat.computercraft.wired_modem.peripheral_disconnected", + ChatHelpers.copy( oldName ) ), false ); } - if (newName != null) { - player.sendMessage(new TranslatableText("chat.computercraft.wired_modem.peripheral_connected", - ChatHelpers.copy(newName)), false); + if( newName != null ) + { + player.sendMessage( new TranslatableText( "chat.computercraft.wired_modem.peripheral_connected", + ChatHelpers.copy( newName ) ), false ); } } @@ -129,264 +145,320 @@ public class TileCable extends TileGeneric implements IPeripheralTile { } @Override - public void onNeighbourChange(@Nonnull BlockPos neighbour) { + public void onNeighbourChange( @Nonnull BlockPos neighbour ) + { Direction dir = this.getDirection(); - if (neighbour.equals(this.getPos().offset(dir)) && this.hasModem() && !this.getCachedState().canPlaceAt(this.getWorld(), this.getPos())) { - if (this.hasCable()) { + if( neighbour.equals( this.getPos().offset( dir ) ) && this.hasModem() && !this.getCachedState().canPlaceAt( this.getWorld(), this.getPos() ) ) + { + if( this.hasCable() ) + { // Drop the modem and convert to cable - Block.dropStack(this.getWorld(), this.getPos(), new ItemStack(ComputerCraftRegistry.ModItems.WIRED_MODEM)); - this.getWorld().setBlockState(this.getPos(), - this.getCachedState().with(BlockCable.MODEM, CableModemVariant.None)); + Block.dropStack( this.getWorld(), this.getPos(), new ItemStack( ComputerCraftRegistry.ModItems.WIRED_MODEM ) ); + this.getWorld().setBlockState( this.getPos(), + this.getCachedState().with( BlockCable.MODEM, CableModemVariant.None ) ); this.modemChanged(); this.connectionsChanged(); - } else { + } + else + { // Drop everything and remove block - Block.dropStack(this.getWorld(), this.getPos(), new ItemStack(ComputerCraftRegistry.ModItems.WIRED_MODEM)); - this.getWorld().removeBlock(this.getPos(), false); + Block.dropStack( this.getWorld(), this.getPos(), new ItemStack( ComputerCraftRegistry.ModItems.WIRED_MODEM ) ); + this.getWorld().removeBlock( this.getPos(), false ); // This'll call #destroy(), so we don't need to reset the network here. } return; } - this.onNeighbourTileEntityChange(neighbour); + this.onNeighbourTileEntityChange( neighbour ); } @Nonnull - private Direction getDirection() { + private Direction getDirection() + { this.refreshDirection(); return this.modemDirection == null ? Direction.NORTH : this.modemDirection; } - public boolean hasModem() { - return this.getCachedState().get(BlockCable.MODEM) != CableModemVariant.None; + public boolean hasModem() + { + return this.getCachedState().get( BlockCable.MODEM ) != CableModemVariant.None; } - boolean hasCable() { - return this.getCachedState().get(BlockCable.CABLE); + boolean hasCable() + { + return this.getCachedState().get( BlockCable.CABLE ); } - void modemChanged() { + void modemChanged() + { // Tell anyone who cares that the connection state has changed - if (this.getWorld().isClient) { + if( this.getWorld().isClient ) + { return; } // If we can no longer attach peripherals, then detach any // which may have existed - if (!this.canAttachPeripheral() && this.m_peripheralAccessAllowed) { + if( !this.canAttachPeripheral() && this.m_peripheralAccessAllowed ) + { this.m_peripheralAccessAllowed = false; this.m_peripheral.detach(); - this.m_node.updatePeripherals(Collections.emptyMap()); + this.m_node.updatePeripherals( Collections.emptyMap() ); this.markDirty(); this.updateBlockState(); } } - void connectionsChanged() { - if (this.getWorld().isClient) { + void connectionsChanged() + { + if( this.getWorld().isClient ) + { return; } BlockState state = this.getCachedState(); World world = this.getWorld(); BlockPos current = this.getPos(); - for (Direction facing : DirectionUtil.FACINGS) { - BlockPos offset = current.offset(facing); - if (!world.isChunkLoaded(offset)) { + for( Direction facing : DirectionUtil.FACINGS ) + { + BlockPos offset = current.offset( facing ); + if( !world.isChunkLoaded( offset ) ) + { continue; } - IWiredElement element = ComputerCraftAPI.getWiredElementAt(world, offset, facing.getOpposite()); - if (element != null) { + IWiredElement element = ComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() ); + if( element != null ) + { // TODO Figure out why this crashes. IWiredNode node = element.getNode(); - if (node != null && this.m_node != null) { - if (BlockCable.canConnectIn(state, facing)) { + if( node != null && this.m_node != null ) + { + if( BlockCable.canConnectIn( state, facing ) ) + { // If we can connect to it then do so - this.m_node.connectTo(node); - } else if (this.m_node.getNetwork() == node.getNetwork()) { + this.m_node.connectTo( node ); + } + else if( this.m_node.getNetwork() == node.getNetwork() ) + { // Otherwise if we're on the same network then attempt to void it. - this.m_node.disconnectFrom(node); + this.m_node.disconnectFrom( node ); } } } } } - private boolean canAttachPeripheral() { + private boolean canAttachPeripheral() + { return this.hasCable() && this.hasModem(); } - private void updateBlockState() { + private void updateBlockState() + { BlockState state = this.getCachedState(); - CableModemVariant oldVariant = state.get(BlockCable.MODEM); - CableModemVariant newVariant = CableModemVariant.from(oldVariant.getFacing(), this.m_modem.getModemState() - .isOpen(), this.m_peripheralAccessAllowed); + CableModemVariant oldVariant = state.get( BlockCable.MODEM ); + CableModemVariant newVariant = CableModemVariant.from( oldVariant.getFacing(), this.m_modem.getModemState() + .isOpen(), this.m_peripheralAccessAllowed ); - if (oldVariant != newVariant) { - this.world.setBlockState(this.getPos(), state.with(BlockCable.MODEM, newVariant)); + if( oldVariant != newVariant ) + { + this.world.setBlockState( this.getPos(), state.with( BlockCable.MODEM, newVariant ) ); } } - private void refreshPeripheral() { - if (this.world != null && !this.isRemoved() && this.m_peripheral.attach(this.world, this.getPos(), this.getDirection())) { + private void refreshPeripheral() + { + if( this.world != null && !this.isRemoved() && this.m_peripheral.attach( this.world, this.getPos(), this.getDirection() ) ) + { this.updateConnectedPeripherals(); } } - private void updateConnectedPeripherals() { + private void updateConnectedPeripherals() + { Map peripherals = this.m_peripheral.toMap(); - if (peripherals.isEmpty()) { + if( peripherals.isEmpty() ) + { // If there are no peripherals then disable access and update the display state. this.m_peripheralAccessAllowed = false; this.updateBlockState(); } - this.m_node.updatePeripherals(peripherals); + this.m_node.updatePeripherals( peripherals ); } @Override - public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) { - super.onNeighbourTileEntityChange(neighbour); - if (!this.world.isClient && this.m_peripheralAccessAllowed) { + public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour ) + { + super.onNeighbourTileEntityChange( neighbour ); + if( !this.world.isClient && this.m_peripheralAccessAllowed ) + { Direction facing = this.getDirection(); - if (this.getPos().offset(facing) - .equals(neighbour)) { + if( this.getPos().offset( facing ) + .equals( neighbour ) ) + { this.refreshPeripheral(); } } } @Override - public void blockTick() { - if (this.getWorld().isClient) { + public void blockTick() + { + if( this.getWorld().isClient ) + { return; } this.refreshDirection(); - if (this.m_modem.getModemState() - .pollChanged()) { + if( this.m_modem.getModemState() + .pollChanged() ) + { this.updateBlockState(); } - if (!this.m_connectionsFormed) { + if( !this.m_connectionsFormed ) + { this.m_connectionsFormed = true; this.connectionsChanged(); - if (this.m_peripheralAccessAllowed) { - this.m_peripheral.attach(this.world, this.pos, this.modemDirection); + if( this.m_peripheralAccessAllowed ) + { + this.m_peripheral.attach( this.world, this.pos, this.modemDirection ); this.updateConnectedPeripherals(); } } } - private void togglePeripheralAccess() { - if (!this.m_peripheralAccessAllowed) { - this.m_peripheral.attach(this.world, this.getPos(), this.getDirection()); - if (!this.m_peripheral.hasPeripheral()) { + private void togglePeripheralAccess() + { + if( !this.m_peripheralAccessAllowed ) + { + this.m_peripheral.attach( this.world, this.getPos(), this.getDirection() ); + if( !this.m_peripheral.hasPeripheral() ) + { return; } this.m_peripheralAccessAllowed = true; - this.m_node.updatePeripherals(this.m_peripheral.toMap()); - } else { + this.m_node.updatePeripherals( this.m_peripheral.toMap() ); + } + else + { this.m_peripheral.detach(); this.m_peripheralAccessAllowed = false; - this.m_node.updatePeripherals(Collections.emptyMap()); + this.m_node.updatePeripherals( Collections.emptyMap() ); } this.updateBlockState(); } @Nullable - private Direction getMaybeDirection() { + private Direction getMaybeDirection() + { this.refreshDirection(); return this.modemDirection; } - private void refreshDirection() { - if (this.hasModemDirection) { + private void refreshDirection() + { + if( this.hasModemDirection ) + { return; } this.hasModemDirection = true; - this.modemDirection = this.getCachedState().get(BlockCable.MODEM) - .getFacing(); + this.modemDirection = this.getCachedState().get( BlockCable.MODEM ) + .getFacing(); } @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); - this.m_peripheralAccessAllowed = nbt.getBoolean(NBT_PERIPHERAL_ENABLED); - this.m_peripheral.read(nbt, ""); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); + this.m_peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED ); + this.m_peripheral.read( nbt, "" ); } @Nonnull @Override - public CompoundTag toTag(CompoundTag nbt) { - nbt.putBoolean(NBT_PERIPHERAL_ENABLED, this.m_peripheralAccessAllowed); - this.m_peripheral.write(nbt, ""); - return super.toTag(nbt); + public CompoundTag toTag( CompoundTag nbt ) + { + nbt.putBoolean( NBT_PERIPHERAL_ENABLED, this.m_peripheralAccessAllowed ); + this.m_peripheral.write( nbt, "" ); + return super.toTag( nbt ); } @Override - public void markRemoved() { + public void markRemoved() + { super.markRemoved(); this.onRemove(); } @Override - public void cancelRemoval() { + public void cancelRemoval() + { super.cancelRemoval(); - TickScheduler.schedule(this); + TickScheduler.schedule( this ); } @Override - public void resetBlock() { + public void resetBlock() + { super.resetBlock(); this.hasModemDirection = false; - if (!this.world.isClient) { + if( !this.world.isClient ) + { this.world.getBlockTickScheduler() - .schedule(this.pos, - this.getCachedState().getBlock(), 0); + .schedule( this.pos, + this.getCachedState().getBlock(), 0 ); } } - public IWiredElement getElement(Direction facing) { - return BlockCable.canConnectIn(this.getCachedState(), facing) ? this.m_cable : null; + public IWiredElement getElement( Direction facing ) + { + return BlockCable.canConnectIn( this.getCachedState(), facing ) ? this.m_cable : null; } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { + public IPeripheral getPeripheral( Direction side ) + { return !this.m_destroyed && this.hasModem() && side == this.getDirection() ? this.m_modem : null; } - private class CableElement extends WiredModemElement { + private class CableElement extends WiredModemElement + { @Nonnull @Override - public World getWorld() { + public World getWorld() + { return TileCable.this.getWorld(); } @Nonnull @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { BlockPos pos = TileCable.this.getPos(); - return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ); } @Override - protected void attachPeripheral(String name, IPeripheral peripheral) { - TileCable.this.m_modem.attachPeripheral(name, peripheral); + protected void attachPeripheral( String name, IPeripheral peripheral ) + { + TileCable.this.m_modem.attachPeripheral( name, peripheral ); } @Override - protected void detachPeripheral(String name) { - TileCable.this.m_modem.detachPeripheral(name); + protected void detachPeripheral( String name ) + { + TileCable.this.m_modem.detachPeripheral( name ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java index d258877ca..886585ebc 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/TileWiredModemFull.java @@ -6,21 +6,6 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull.MODEM_ON; -import static dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull.PERIPHERAL_ON; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nonnull; - import com.google.common.base.Objects; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.network.wired.IWiredElement; @@ -32,7 +17,6 @@ import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.TickScheduler; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; @@ -47,27 +31,39 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class TileWiredModemFull extends TileGeneric implements IPeripheralTile { +import javax.annotation.Nonnull; +import java.util.*; + +import static dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull.MODEM_ON; +import static dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull.PERIPHERAL_ON; + +public class TileWiredModemFull extends TileGeneric implements IPeripheralTile +{ private static final String NBT_PERIPHERAL_ENABLED = "PeripheralAccess"; private final WiredModemPeripheral[] modems = new WiredModemPeripheral[6]; private final WiredModemLocalPeripheral[] m_peripherals = new WiredModemLocalPeripheral[6]; - private final ModemState m_modemState = new ModemState(() -> TickScheduler.schedule(this)); - private final WiredModemElement m_element = new FullElement(this); + private final ModemState m_modemState = new ModemState( () -> TickScheduler.schedule( this ) ); + private final WiredModemElement m_element = new FullElement( this ); private final IWiredNode m_node = this.m_element.getNode(); private boolean m_peripheralAccessAllowed = false; private boolean m_destroyed = false; private boolean m_connectionsFormed = false; - public TileWiredModemFull(BlockEntityType type) { - super(type); - for (int i = 0; i < this.m_peripherals.length; i++) { - Direction facing = Direction.byId(i); + + public TileWiredModemFull( BlockEntityType type ) + { + super( type ); + for( int i = 0; i < this.m_peripherals.length; i++ ) + { + Direction facing = Direction.byId( i ); this.m_peripherals[i] = new WiredModemLocalPeripheral(); } } @Override - public void destroy() { - if (!this.m_destroyed) { + public void destroy() + { + if( !this.m_destroyed ) + { this.m_destroyed = true; this.doRemove(); } @@ -81,8 +77,10 @@ public class TileWiredModemFull extends TileGeneric implements IPeripheralTile { doRemove(); } - private void doRemove() { - if (this.world == null || !this.world.isClient) { + private void doRemove() + { + if( this.world == null || !this.world.isClient ) + { this.m_node.remove(); this.m_connectionsFormed = false; } @@ -90,8 +88,10 @@ public class TileWiredModemFull extends TileGeneric implements IPeripheralTile { @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { - if (this.getWorld().isClient) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { + if( this.getWorld().isClient ) + { return ActionResult.SUCCESS; } @@ -100,283 +100,347 @@ public class TileWiredModemFull extends TileGeneric implements IPeripheralTile { this.togglePeripheralAccess(); Set periphNames = this.getConnectedPeripheralNames(); - if (!Objects.equal(periphNames, oldPeriphNames)) { - sendPeripheralChanges(player, "chat.computercraft.wired_modem.peripheral_disconnected", oldPeriphNames); - sendPeripheralChanges(player, "chat.computercraft.wired_modem.peripheral_connected", periphNames); + if( !Objects.equal( periphNames, oldPeriphNames ) ) + { + sendPeripheralChanges( player, "chat.computercraft.wired_modem.peripheral_disconnected", oldPeriphNames ); + sendPeripheralChanges( player, "chat.computercraft.wired_modem.peripheral_connected", periphNames ); } return ActionResult.SUCCESS; } @Override - public void onNeighbourChange(@Nonnull BlockPos neighbour) { - this.onNeighbourTileEntityChange(neighbour); + public void onNeighbourChange( @Nonnull BlockPos neighbour ) + { + this.onNeighbourTileEntityChange( neighbour ); } @Override - public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) { - if (!this.world.isClient && this.m_peripheralAccessAllowed) { - for (Direction facing : DirectionUtil.FACINGS) { - if (this.getPos().offset(facing) - .equals(neighbour)) { - this.refreshPeripheral(facing); + public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour ) + { + if( !this.world.isClient && this.m_peripheralAccessAllowed ) + { + for( Direction facing : DirectionUtil.FACINGS ) + { + if( this.getPos().offset( facing ) + .equals( neighbour ) ) + { + this.refreshPeripheral( facing ); } } } } @Override - public void blockTick() { - if (this.getWorld().isClient) { + public void blockTick() + { + if( this.getWorld().isClient ) + { return; } - if (this.m_modemState.pollChanged()) { + if( this.m_modemState.pollChanged() ) + { this.updateBlockState(); } - if (!this.m_connectionsFormed) { + if( !this.m_connectionsFormed ) + { this.m_connectionsFormed = true; this.connectionsChanged(); - if (this.m_peripheralAccessAllowed) { - for (Direction facing : DirectionUtil.FACINGS) { - this.m_peripherals[facing.ordinal()].attach(this.world, this.getPos(), facing); + if( this.m_peripheralAccessAllowed ) + { + for( Direction facing : DirectionUtil.FACINGS ) + { + this.m_peripherals[facing.ordinal()].attach( this.world, this.getPos(), facing ); } this.updateConnectedPeripherals(); } } } - private void connectionsChanged() { - if (this.getWorld().isClient) { + private void connectionsChanged() + { + if( this.getWorld().isClient ) + { return; } World world = this.getWorld(); BlockPos current = this.getPos(); - for (Direction facing : DirectionUtil.FACINGS) { - BlockPos offset = current.offset(facing); - if (!world.isChunkLoaded(offset)) { + for( Direction facing : DirectionUtil.FACINGS ) + { + BlockPos offset = current.offset( facing ); + if( !world.isChunkLoaded( offset ) ) + { continue; } - IWiredElement element = ComputerCraftAPI.getWiredElementAt(world, offset, facing.getOpposite()); - if (element == null) { + IWiredElement element = ComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() ); + if( element == null ) + { continue; } - this.m_node.connectTo(element.getNode()); + this.m_node.connectTo( element.getNode() ); } } - private void refreshPeripheral(@Nonnull Direction facing) { + private void refreshPeripheral( @Nonnull Direction facing ) + { WiredModemLocalPeripheral peripheral = this.m_peripherals[facing.ordinal()]; - if (this.world != null && !this.isRemoved() && peripheral.attach(this.world, this.getPos(), facing)) { + if( this.world != null && !this.isRemoved() && peripheral.attach( this.world, this.getPos(), facing ) ) + { this.updateConnectedPeripherals(); } } - private void updateConnectedPeripherals() { + private void updateConnectedPeripherals() + { Map peripherals = this.getConnectedPeripherals(); - if (peripherals.isEmpty()) { + if( peripherals.isEmpty() ) + { // If there are no peripherals then disable access and update the display state. this.m_peripheralAccessAllowed = false; this.updateBlockState(); } - this.m_node.updatePeripherals(peripherals); + this.m_node.updatePeripherals( peripherals ); } - private Map getConnectedPeripherals() { - if (!this.m_peripheralAccessAllowed) { + private Map getConnectedPeripherals() + { + if( !this.m_peripheralAccessAllowed ) + { return Collections.emptyMap(); } - Map peripherals = new HashMap<>(6); - for (WiredModemLocalPeripheral peripheral : this.m_peripherals) { - peripheral.extendMap(peripherals); + Map peripherals = new HashMap<>( 6 ); + for( WiredModemLocalPeripheral peripheral : this.m_peripherals ) + { + peripheral.extendMap( peripherals ); } return peripherals; } - private void updateBlockState() { + private void updateBlockState() + { BlockState state = this.getCachedState(); boolean modemOn = this.m_modemState.isOpen(), peripheralOn = this.m_peripheralAccessAllowed; - if (state.get(MODEM_ON) == modemOn && state.get(PERIPHERAL_ON) == peripheralOn) { + if( state.get( MODEM_ON ) == modemOn && state.get( PERIPHERAL_ON ) == peripheralOn ) + { return; } - this.getWorld().setBlockState(this.getPos(), - state.with(MODEM_ON, modemOn) - .with(PERIPHERAL_ON, peripheralOn)); + this.getWorld().setBlockState( this.getPos(), + state.with( MODEM_ON, modemOn ) + .with( PERIPHERAL_ON, peripheralOn ) ); } - private Set getConnectedPeripheralNames() { - if (!this.m_peripheralAccessAllowed) { + private Set getConnectedPeripheralNames() + { + if( !this.m_peripheralAccessAllowed ) + { return Collections.emptySet(); } - Set peripherals = new HashSet<>(6); - for (WiredModemLocalPeripheral peripheral : this.m_peripherals) { + Set peripherals = new HashSet<>( 6 ); + for( WiredModemLocalPeripheral peripheral : this.m_peripherals ) + { String name = peripheral.getConnectedName(); - if (name != null) { - peripherals.add(name); + if( name != null ) + { + peripherals.add( name ); } } return peripherals; } - private void togglePeripheralAccess() { - if (!this.m_peripheralAccessAllowed) { + private void togglePeripheralAccess() + { + if( !this.m_peripheralAccessAllowed ) + { boolean hasAny = false; - for (Direction facing : DirectionUtil.FACINGS) { + for( Direction facing : DirectionUtil.FACINGS ) + { WiredModemLocalPeripheral peripheral = this.m_peripherals[facing.ordinal()]; - peripheral.attach(this.world, this.getPos(), facing); + peripheral.attach( this.world, this.getPos(), facing ); hasAny |= peripheral.hasPeripheral(); } - if (!hasAny) { + if( !hasAny ) + { return; } this.m_peripheralAccessAllowed = true; - this.m_node.updatePeripherals(this.getConnectedPeripherals()); - } else { + this.m_node.updatePeripherals( this.getConnectedPeripherals() ); + } + else + { this.m_peripheralAccessAllowed = false; - for (WiredModemLocalPeripheral peripheral : this.m_peripherals) { + for( WiredModemLocalPeripheral peripheral : this.m_peripherals ) + { peripheral.detach(); } - this.m_node.updatePeripherals(Collections.emptyMap()); + this.m_node.updatePeripherals( Collections.emptyMap() ); } this.updateBlockState(); } - private static void sendPeripheralChanges(PlayerEntity player, String kind, Collection peripherals) { - if (peripherals.isEmpty()) { + private static void sendPeripheralChanges( PlayerEntity player, String kind, Collection peripherals ) + { + if( peripherals.isEmpty() ) + { return; } - List names = new ArrayList<>(peripherals); - names.sort(Comparator.naturalOrder()); + List names = new ArrayList<>( peripherals ); + names.sort( Comparator.naturalOrder() ); - LiteralText base = new LiteralText(""); - for (int i = 0; i < names.size(); i++) { - if (i > 0) { - base.append(", "); + LiteralText base = new LiteralText( "" ); + for( int i = 0; i < names.size(); i++ ) + { + if( i > 0 ) + { + base.append( ", " ); } - base.append(ChatHelpers.copy(names.get(i))); + base.append( ChatHelpers.copy( names.get( i ) ) ); } - player.sendMessage(new TranslatableText(kind, base), false); + player.sendMessage( new TranslatableText( kind, base ), false ); } @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); - this.m_peripheralAccessAllowed = nbt.getBoolean(NBT_PERIPHERAL_ENABLED); - for (int i = 0; i < this.m_peripherals.length; i++) { - this.m_peripherals[i].read(nbt, Integer.toString(i)); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); + this.m_peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED ); + for( int i = 0; i < this.m_peripherals.length; i++ ) + { + this.m_peripherals[i].read( nbt, Integer.toString( i ) ); } } @Nonnull @Override - public CompoundTag toTag(CompoundTag nbt) { - nbt.putBoolean(NBT_PERIPHERAL_ENABLED, this.m_peripheralAccessAllowed); - for (int i = 0; i < this.m_peripherals.length; i++) { - this.m_peripherals[i].write(nbt, Integer.toString(i)); + public CompoundTag toTag( CompoundTag nbt ) + { + nbt.putBoolean( NBT_PERIPHERAL_ENABLED, this.m_peripheralAccessAllowed ); + for( int i = 0; i < this.m_peripherals.length; i++ ) + { + this.m_peripherals[i].write( nbt, Integer.toString( i ) ); } - return super.toTag(nbt); + return super.toTag( nbt ); } @Override - public void markRemoved() { + public void markRemoved() + { super.markRemoved(); this.doRemove(); } @Override - public void cancelRemoval() { + public void cancelRemoval() + { super.cancelRemoval(); - TickScheduler.schedule(this); + TickScheduler.schedule( this ); } - public IWiredElement getElement() { + public IWiredElement getElement() + { return this.m_element; } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { + public IPeripheral getPeripheral( Direction side ) + { WiredModemPeripheral peripheral = this.modems[side.ordinal()]; - if (peripheral != null) { + if( peripheral != null ) + { return peripheral; } WiredModemLocalPeripheral localPeripheral = this.m_peripherals[side.ordinal()]; - return this.modems[side.ordinal()] = new WiredModemPeripheral(this.m_modemState, this.m_element) { + return this.modems[side.ordinal()] = new WiredModemPeripheral( this.m_modemState, this.m_element ) + { @Nonnull @Override - protected WiredModemLocalPeripheral getLocalPeripheral() { + protected WiredModemLocalPeripheral getLocalPeripheral() + { return localPeripheral; } @Nonnull @Override - public Vec3d getPosition() { - BlockPos pos = TileWiredModemFull.this.getPos().offset(side); - return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + public Vec3d getPosition() + { + BlockPos pos = TileWiredModemFull.this.getPos().offset( side ); + return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ); } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return TileWiredModemFull.this; } }; } - private static final class FullElement extends WiredModemElement { + private static final class FullElement extends WiredModemElement + { private final TileWiredModemFull m_entity; - private FullElement(TileWiredModemFull entity) { + private FullElement( TileWiredModemFull entity ) + { this.m_entity = entity; } @Override - protected void detachPeripheral(String name) { - for (int i = 0; i < 6; i++) { + protected void detachPeripheral( String name ) + { + for( int i = 0; i < 6; i++ ) + { WiredModemPeripheral modem = this.m_entity.modems[i]; - if (modem != null) { - modem.detachPeripheral(name); + if( modem != null ) + { + modem.detachPeripheral( name ); } } } @Override - protected void attachPeripheral(String name, IPeripheral peripheral) { - for (int i = 0; i < 6; i++) { + protected void attachPeripheral( String name, IPeripheral peripheral ) + { + for( int i = 0; i < 6; i++ ) + { WiredModemPeripheral modem = this.m_entity.modems[i]; - if (modem != null) { - modem.attachPeripheral(name, peripheral); + if( modem != null ) + { + modem.attachPeripheral( name, peripheral ); } } } @Nonnull @Override - public World getWorld() { + public World getWorld() + { return this.m_entity.getWorld(); } @Nonnull @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { BlockPos pos = this.m_entity.getPos(); - return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemElement.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemElement.java index dae2cdcd1..3eb19e6d6 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemElement.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemElement.java @@ -6,57 +6,64 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.network.wired.IWiredElement; import dan200.computercraft.api.network.wired.IWiredNetworkChange; import dan200.computercraft.api.network.wired.IWiredNode; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.wired.WiredNode; -public abstract class WiredModemElement implements IWiredElement { - private final IWiredNode node = new WiredNode(this); +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.Map; + +public abstract class WiredModemElement implements IWiredElement +{ + private final IWiredNode node = new WiredNode( this ); private final Map remotePeripherals = new HashMap<>(); @Nonnull @Override - public IWiredNode getNode() { + public IWiredNode getNode() + { return this.node; } @Nonnull @Override - public String getSenderID() { + public String getSenderID() + { return "modem"; } @Override - public void networkChanged(@Nonnull IWiredNetworkChange change) { - synchronized (this.remotePeripherals) { + public void networkChanged( @Nonnull IWiredNetworkChange change ) + { + synchronized( this.remotePeripherals ) + { this.remotePeripherals.keySet() - .removeAll(change.peripheralsRemoved() - .keySet()); - for (String name : change.peripheralsRemoved() - .keySet()) { - this.detachPeripheral(name); + .removeAll( change.peripheralsRemoved() + .keySet() ); + for( String name : change.peripheralsRemoved() + .keySet() ) + { + this.detachPeripheral( name ); } - for (Map.Entry peripheral : change.peripheralsAdded() - .entrySet()) { - this.attachPeripheral(peripheral.getKey(), peripheral.getValue()); + for( Map.Entry peripheral : change.peripheralsAdded() + .entrySet() ) + { + this.attachPeripheral( peripheral.getKey(), peripheral.getValue() ); } - this.remotePeripherals.putAll(change.peripheralsAdded()); + this.remotePeripherals.putAll( change.peripheralsAdded() ); } } - protected abstract void detachPeripheral(String name); + protected abstract void detachPeripheral( String name ); - protected abstract void attachPeripheral(String name, IPeripheral peripheral); + protected abstract void attachPeripheral( String name, IPeripheral peripheral ); - public Map getRemotePeripherals() { + public Map getRemotePeripherals() + { return this.remotePeripherals; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java index 2ef294fcb..271a10ed5 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java @@ -6,30 +6,29 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import java.util.Collections; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.Peripherals; import dan200.computercraft.shared.util.IDAssigner; import dan200.computercraft.shared.util.NBTUtil; - import net.minecraft.block.Block; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.Map; + /** * Represents a local peripheral exposed on the wired network. * * This is responsible for getting the peripheral in world, tracking id and type and determining whether it has changed. */ -public final class WiredModemLocalPeripheral { +public final class WiredModemLocalPeripheral +{ private static final String NBT_PERIPHERAL_TYPE = "PeripheralType"; private static final String NBT_PERIPHERAL_ID = "PeripheralId"; @@ -41,44 +40,53 @@ public final class WiredModemLocalPeripheral { /** * Attach a new peripheral from the world. * - * @param world The world to search in - * @param origin The position to search from + * @param world The world to search in + * @param origin The position to search from * @param direction The direction so search in * @return Whether the peripheral changed. */ - public boolean attach(@Nonnull World world, @Nonnull BlockPos origin, @Nonnull Direction direction) { + public boolean attach( @Nonnull World world, @Nonnull BlockPos origin, @Nonnull Direction direction ) + { IPeripheral oldPeripheral = this.peripheral; - IPeripheral peripheral = this.peripheral = this.getPeripheralFrom(world, origin, direction); + IPeripheral peripheral = this.peripheral = this.getPeripheralFrom( world, origin, direction ); - if (peripheral == null) { + if( peripheral == null ) + { return oldPeripheral != null; - } else { + } + else + { String type = peripheral.getType(); int id = this.id; - if (id > 0 && this.type == null) { + if( id > 0 && this.type == null ) + { // If we had an ID but no type, then just set the type. this.type = type; - } else if (id < 0 || !type.equals(this.type)) { + } + else if( id < 0 || !type.equals( this.type ) ) + { this.type = type; - this.id = IDAssigner.getNextId("peripheral." + type); + this.id = IDAssigner.getNextId( "peripheral." + type ); } - return oldPeripheral == null || !oldPeripheral.equals(peripheral); + return oldPeripheral == null || !oldPeripheral.equals( peripheral ); } } @Nullable - private IPeripheral getPeripheralFrom(World world, BlockPos pos, Direction direction) { - BlockPos offset = pos.offset(direction); + private IPeripheral getPeripheralFrom( World world, BlockPos pos, Direction direction ) + { + BlockPos offset = pos.offset( direction ); - Block block = world.getBlockState(offset) - .getBlock(); - if (block == ComputerCraftRegistry.ModBlocks.WIRED_MODEM_FULL || block == ComputerCraftRegistry.ModBlocks.CABLE) { + Block block = world.getBlockState( offset ) + .getBlock(); + if( block == ComputerCraftRegistry.ModBlocks.WIRED_MODEM_FULL || block == ComputerCraftRegistry.ModBlocks.CABLE ) + { return null; } - IPeripheral peripheral = Peripherals.getPeripheral(world, offset, direction.getOpposite()); + IPeripheral peripheral = Peripherals.getPeripheral( world, offset, direction.getOpposite() ); return peripheral instanceof WiredModemPeripheral ? null : peripheral; } @@ -87,8 +95,10 @@ public final class WiredModemLocalPeripheral { * * @return Whether the peripheral changed */ - public boolean detach() { - if (this.peripheral == null) { + public boolean detach() + { + if( this.peripheral == null ) + { return false; } this.peripheral = null; @@ -96,41 +106,51 @@ public final class WiredModemLocalPeripheral { } @Nullable - public String getConnectedName() { + public String getConnectedName() + { return this.peripheral != null ? this.type + "_" + this.id : null; } @Nullable - public IPeripheral getPeripheral() { + public IPeripheral getPeripheral() + { return this.peripheral; } - public boolean hasPeripheral() { + public boolean hasPeripheral() + { return this.peripheral != null; } - public void extendMap(@Nonnull Map peripherals) { - if (this.peripheral != null) { - peripherals.put(this.type + "_" + this.id, this.peripheral); + public void extendMap( @Nonnull Map peripherals ) + { + if( this.peripheral != null ) + { + peripherals.put( this.type + "_" + this.id, this.peripheral ); } } - public Map toMap() { - return this.peripheral == null ? Collections.emptyMap() : Collections.singletonMap(this.type + "_" + this.id, this.peripheral); + public Map toMap() + { + return this.peripheral == null ? Collections.emptyMap() : Collections.singletonMap( this.type + "_" + this.id, this.peripheral ); } - public void write(@Nonnull CompoundTag tag, @Nonnull String suffix) { - if (this.id >= 0) { - tag.putInt(NBT_PERIPHERAL_ID + suffix, this.id); + public void write( @Nonnull CompoundTag tag, @Nonnull String suffix ) + { + if( this.id >= 0 ) + { + tag.putInt( NBT_PERIPHERAL_ID + suffix, this.id ); } - if (this.type != null) { - tag.putString(NBT_PERIPHERAL_TYPE + suffix, this.type); + if( this.type != null ) + { + tag.putString( NBT_PERIPHERAL_TYPE + suffix, this.type ); } } - public void read(@Nonnull CompoundTag tag, @Nonnull String suffix) { - this.id = tag.contains(NBT_PERIPHERAL_ID + suffix, NBTUtil.TAG_ANY_NUMERIC) ? tag.getInt(NBT_PERIPHERAL_ID + suffix) : -1; + public void read( @Nonnull CompoundTag tag, @Nonnull String suffix ) + { + this.id = tag.contains( NBT_PERIPHERAL_ID + suffix, NBTUtil.TAG_ANY_NUMERIC ) ? tag.getInt( NBT_PERIPHERAL_ID + suffix ) : -1; - this.type = tag.contains(NBT_PERIPHERAL_TYPE + suffix, NBTUtil.TAG_STRING) ? tag.getString(NBT_PERIPHERAL_TYPE + suffix) : null; + this.type = tag.contains( NBT_PERIPHERAL_TYPE + suffix, NBTUtil.TAG_STRING ) ? tag.getString( NBT_PERIPHERAL_TYPE + suffix ) : null; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java index fb6b08b77..147e956dd 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java @@ -6,24 +6,10 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.collect.ImmutableMap; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; -import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.lua.*; import dan200.computercraft.api.network.IPacketNetwork; import dan200.computercraft.api.network.wired.IWiredNode; import dan200.computercraft.api.network.wired.IWiredSender; @@ -34,86 +20,111 @@ import dan200.computercraft.core.apis.PeripheralAPI; import dan200.computercraft.core.asm.PeripheralMethod; import dan200.computercraft.shared.peripheral.modem.ModemPeripheral; import dan200.computercraft.shared.peripheral.modem.ModemState; - import net.minecraft.world.World; -public abstract class WiredModemPeripheral extends ModemPeripheral implements IWiredSender { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public abstract class WiredModemPeripheral extends ModemPeripheral implements IWiredSender +{ private final WiredModemElement modem; - private final Map> peripheralWrappers = new HashMap<>(1); + private final Map> peripheralWrappers = new HashMap<>( 1 ); - public WiredModemPeripheral(ModemState state, WiredModemElement modem) { - super(state); + public WiredModemPeripheral( ModemState state, WiredModemElement modem ) + { + super( state ); this.modem = modem; } @Override - public double getRange() { + public double getRange() + { return 256.0; } //region IPacketSender implementation @Override - public boolean isInterdimensional() { + public boolean isInterdimensional() + { return false; } @Override - protected IPacketNetwork getNetwork() { + protected IPacketNetwork getNetwork() + { return this.modem.getNode(); } @Override - public void attach(@Nonnull IComputerAccess computer) { - super.attach(computer); + public void attach( @Nonnull IComputerAccess computer ) + { + super.attach( computer ); ConcurrentMap wrappers; - synchronized (this.peripheralWrappers) { - wrappers = this.peripheralWrappers.get(computer); - if (wrappers == null) { - this.peripheralWrappers.put(computer, wrappers = new ConcurrentHashMap<>()); + synchronized( this.peripheralWrappers ) + { + wrappers = this.peripheralWrappers.get( computer ); + if( wrappers == null ) + { + this.peripheralWrappers.put( computer, wrappers = new ConcurrentHashMap<>() ); } } - synchronized (this.modem.getRemotePeripherals()) { - for (Map.Entry entry : this.modem.getRemotePeripherals() - .entrySet()) { - this.attachPeripheralImpl(computer, wrappers, entry.getKey(), entry.getValue()); + synchronized( this.modem.getRemotePeripherals() ) + { + for( Map.Entry entry : this.modem.getRemotePeripherals() + .entrySet() ) + { + this.attachPeripheralImpl( computer, wrappers, entry.getKey(), entry.getValue() ); } } } @Override - public void detach(@Nonnull IComputerAccess computer) { + public void detach( @Nonnull IComputerAccess computer ) + { Map wrappers; - synchronized (this.peripheralWrappers) { - wrappers = this.peripheralWrappers.remove(computer); + synchronized( this.peripheralWrappers ) + { + wrappers = this.peripheralWrappers.remove( computer ); } - if (wrappers != null) { - for (RemotePeripheralWrapper wrapper : wrappers.values()) { + if( wrappers != null ) + { + for( RemotePeripheralWrapper wrapper : wrappers.values() ) + { wrapper.detach(); } wrappers.clear(); } - super.detach(computer); + super.detach( computer ); } //endregion //region Peripheral methods - private void attachPeripheralImpl(IComputerAccess computer, ConcurrentMap peripherals, String periphName, - IPeripheral peripheral) { - if (!peripherals.containsKey(periphName) && !periphName.equals(this.getLocalPeripheral().getConnectedName())) { - RemotePeripheralWrapper wrapper = new RemotePeripheralWrapper(this.modem, peripheral, computer, periphName); - peripherals.put(periphName, wrapper); + private void attachPeripheralImpl( IComputerAccess computer, ConcurrentMap peripherals, String periphName, + IPeripheral peripheral ) + { + if( !peripherals.containsKey( periphName ) && !periphName.equals( this.getLocalPeripheral().getConnectedName() ) ) + { + RemotePeripheralWrapper wrapper = new RemotePeripheralWrapper( this.modem, peripheral, computer, periphName ); + peripherals.put( periphName, wrapper ); wrapper.attach(); } } @Nonnull @Override - public World getWorld() { + public World getWorld() + { return this.modem.getWorld(); } @@ -129,13 +140,16 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW * @return Remote peripheral names on the network. */ @LuaFunction - public final Collection getNamesRemote(IComputerAccess computer) { - return this.getWrappers(computer).keySet(); + public final Collection getNamesRemote( IComputerAccess computer ) + { + return this.getWrappers( computer ).keySet(); } - private ConcurrentMap getWrappers(IComputerAccess computer) { - synchronized (this.peripheralWrappers) { - return this.peripheralWrappers.get(computer); + private ConcurrentMap getWrappers( IComputerAccess computer ) + { + synchronized( this.peripheralWrappers ) + { + return this.peripheralWrappers.get( computer ); } } @@ -146,18 +160,20 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW * returns false before calling it. * * @param computer The calling computer. - * @param name The peripheral's name. + * @param name The peripheral's name. * @return boolean If a peripheral is present with the given name. * @see PeripheralAPI#isPresent */ @LuaFunction - public final boolean isPresentRemote(IComputerAccess computer, String name) { - return this.getWrapper(computer, name) != null; + public final boolean isPresentRemote( IComputerAccess computer, String name ) + { + return this.getWrapper( computer, name ) != null; } - private RemotePeripheralWrapper getWrapper(IComputerAccess computer, String remoteName) { - ConcurrentMap wrappers = this.getWrappers(computer); - return wrappers == null ? null : wrappers.get(remoteName); + private RemotePeripheralWrapper getWrapper( IComputerAccess computer, String remoteName ) + { + ConcurrentMap wrappers = this.getWrappers( computer ); + return wrappers == null ? null : wrappers.get( remoteName ); } /** @@ -167,15 +183,16 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW * returns false before calling it. * * @param computer The calling computer. - * @param name The peripheral's name. + * @param name The peripheral's name. * @return The peripheral's name. * @cc.treturn string|nil The peripheral's type, or {@code nil} if it is not present. * @see PeripheralAPI#getType */ @LuaFunction - public final Object[] getTypeRemote(IComputerAccess computer, String name) { - RemotePeripheralWrapper wrapper = this.getWrapper(computer, name); - return wrapper != null ? new Object[] {wrapper.getType()} : null; + public final Object[] getTypeRemote( IComputerAccess computer, String name ) + { + RemotePeripheralWrapper wrapper = this.getWrapper( computer, name ); + return wrapper != null ? new Object[] { wrapper.getType() } : null; } /** @@ -185,19 +202,21 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW * returns false before calling it. * * @param computer The calling computer. - * @param name The peripheral's name. + * @param name The peripheral's name. * @return A list of methods provided by this peripheral, or {@code nil} if it is not present. * @cc.treturn { string... }|nil A list of methods provided by this peripheral, or {@code nil} if it is not present. * @see PeripheralAPI#getMethods */ @LuaFunction - public final Object[] getMethodsRemote(IComputerAccess computer, String name) { - RemotePeripheralWrapper wrapper = this.getWrapper(computer, name); - if (wrapper == null) { + public final Object[] getMethodsRemote( IComputerAccess computer, String name ) + { + RemotePeripheralWrapper wrapper = this.getWrapper( computer, name ); + if( wrapper == null ) + { return null; } - return new Object[] {wrapper.getMethodNames()}; + return new Object[] { wrapper.getMethodNames() }; } /** @@ -206,8 +225,8 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW *
    Important: This function only appears on wired modems. Check {@link #isWireless} * returns false before calling it.
    * - * @param computer The calling computer. - * @param context The Lua context we're executing in. + * @param computer The calling computer. + * @param context The Lua context we're executing in. * @param arguments Arguments to this computer. * @return The peripheral's result. * @throws LuaException (hidden) If the method throws an error. @@ -218,15 +237,17 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW * @see PeripheralAPI#call */ @LuaFunction - public final MethodResult callRemote(IComputerAccess computer, ILuaContext context, IArguments arguments) throws LuaException { - String remoteName = arguments.getString(0); - String methodName = arguments.getString(1); - RemotePeripheralWrapper wrapper = this.getWrapper(computer, remoteName); - if (wrapper == null) { - throw new LuaException("No peripheral: " + remoteName); + public final MethodResult callRemote( IComputerAccess computer, ILuaContext context, IArguments arguments ) throws LuaException + { + String remoteName = arguments.getString( 0 ); + String methodName = arguments.getString( 1 ); + RemotePeripheralWrapper wrapper = this.getWrapper( computer, remoteName ); + if( wrapper == null ) + { + throw new LuaException( "No peripheral: " + remoteName ); } - return wrapper.callMethod(context, methodName, arguments.drop(2)); + return wrapper.callMethod( context, methodName, arguments.drop( 2 ) ); } //endregion @@ -241,17 +262,20 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW * @cc.treturn string|nil The current computer's name on the wired network. */ @LuaFunction - public final Object[] getNameLocal() { + public final Object[] getNameLocal() + { String local = this.getLocalPeripheral().getConnectedName(); - return local == null ? null : new Object[] {local}; + return local == null ? null : new Object[] { local }; } @Nonnull protected abstract WiredModemLocalPeripheral getLocalPeripheral(); @Override - public boolean equals(IPeripheral other) { - if (other instanceof WiredModemPeripheral) { + public boolean equals( IPeripheral other ) + { + if( other instanceof WiredModemPeripheral ) + { WiredModemPeripheral otherModem = (WiredModemPeripheral) other; return otherModem.modem == this.modem; } @@ -260,23 +284,31 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW @Nonnull @Override - public IWiredNode getNode() { + public IWiredNode getNode() + { return this.modem.getNode(); } - public void attachPeripheral(String name, IPeripheral peripheral) { - synchronized (this.peripheralWrappers) { - for (Map.Entry> entry : this.peripheralWrappers.entrySet()) { - this.attachPeripheralImpl(entry.getKey(), entry.getValue(), name, peripheral); + public void attachPeripheral( String name, IPeripheral peripheral ) + { + synchronized( this.peripheralWrappers ) + { + for( Map.Entry> entry : this.peripheralWrappers.entrySet() ) + { + this.attachPeripheralImpl( entry.getKey(), entry.getValue(), name, peripheral ); } } } - public void detachPeripheral(String name) { - synchronized (this.peripheralWrappers) { - for (ConcurrentMap wrappers : this.peripheralWrappers.values()) { - RemotePeripheralWrapper wrapper = wrappers.remove(name); - if (wrapper != null) { + public void detachPeripheral( String name ) + { + synchronized( this.peripheralWrappers ) + { + for( ConcurrentMap wrappers : this.peripheralWrappers.values() ) + { + RemotePeripheralWrapper wrapper = wrappers.remove( name ); + if( wrapper != null ) + { wrapper.detach(); } } @@ -284,7 +316,8 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW } } - private static class RemotePeripheralWrapper implements IComputerAccess { + private static class RemotePeripheralWrapper implements IComputerAccess + { private final WiredModemElement element; private final IPeripheral peripheral; private final IComputerAccess computer; @@ -293,105 +326,125 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW private final String type; private final Map methodMap; - RemotePeripheralWrapper(WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name) { + RemotePeripheralWrapper( WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name ) + { this.element = element; this.peripheral = peripheral; this.computer = computer; this.name = name; - this.type = Objects.requireNonNull(peripheral.getType(), "Peripheral type cannot be null"); - this.methodMap = PeripheralAPI.getMethods(peripheral); + this.type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" ); + this.methodMap = PeripheralAPI.getMethods( peripheral ); } - public void attach() { - this.peripheral.attach(this); - this.computer.queueEvent("peripheral", this.getAttachmentName()); + public void attach() + { + this.peripheral.attach( this ); + this.computer.queueEvent( "peripheral", this.getAttachmentName() ); } - public void detach() { - this.peripheral.detach(this); - this.computer.queueEvent("peripheral_detach", this.getAttachmentName()); + public void detach() + { + this.peripheral.detach( this ); + this.computer.queueEvent( "peripheral_detach", this.getAttachmentName() ); } - public String getType() { + public String getType() + { return this.type; } - public Collection getMethodNames() { + public Collection getMethodNames() + { return this.methodMap.keySet(); } - public MethodResult callMethod(ILuaContext context, String methodName, IArguments arguments) throws LuaException { - PeripheralMethod method = this.methodMap.get(methodName); - if (method == null) { - throw new LuaException("No such method " + methodName); + public MethodResult callMethod( ILuaContext context, String methodName, IArguments arguments ) throws LuaException + { + PeripheralMethod method = this.methodMap.get( methodName ); + if( method == null ) + { + throw new LuaException( "No such method " + methodName ); } - return method.apply(this.peripheral, context, this, arguments); + return method.apply( this.peripheral, context, this, arguments ); } // IComputerAccess implementation @Override - public String mount(@Nonnull String desiredLocation, @Nonnull IMount mount) { - return this.computer.mount(desiredLocation, mount, this.name); + public String mount( @Nonnull String desiredLocation, @Nonnull IMount mount ) + { + return this.computer.mount( desiredLocation, mount, this.name ); } @Override - public String mount(@Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName) { - return this.computer.mount(desiredLocation, mount, driveName); + public String mount( @Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName ) + { + return this.computer.mount( desiredLocation, mount, driveName ); } @Nonnull @Override - public String getAttachmentName() { + public String getAttachmentName() + { return this.name; } @Override - public String mountWritable(@Nonnull String desiredLocation, @Nonnull IWritableMount mount) { - return this.computer.mountWritable(desiredLocation, mount, this.name); + public String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount ) + { + return this.computer.mountWritable( desiredLocation, mount, this.name ); } @Override - public String mountWritable(@Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName) { - return this.computer.mountWritable(desiredLocation, mount, driveName); + public String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName ) + { + return this.computer.mountWritable( desiredLocation, mount, driveName ); } @Override - public void unmount(String location) { - this.computer.unmount(location); + public void unmount( String location ) + { + this.computer.unmount( location ); } @Override - public int getID() { + public int getID() + { return this.computer.getID(); } @Override - public void queueEvent(@Nonnull String event, Object... arguments) { - this.computer.queueEvent(event, arguments); + public void queueEvent( @Nonnull String event, Object... arguments ) + { + this.computer.queueEvent( event, arguments ); } @Nonnull @Override - public Map getAvailablePeripherals() { - synchronized (this.element.getRemotePeripherals()) { - return ImmutableMap.copyOf(this.element.getRemotePeripherals()); + public Map getAvailablePeripherals() + { + synchronized( this.element.getRemotePeripherals() ) + { + return ImmutableMap.copyOf( this.element.getRemotePeripherals() ); } } @Nullable @Override - public IPeripheral getAvailablePeripheral(@Nonnull String name) { - synchronized (this.element.getRemotePeripherals()) { + public IPeripheral getAvailablePeripheral( @Nonnull String name ) + { + synchronized( this.element.getRemotePeripherals() ) + { return this.element.getRemotePeripherals() - .get(name); + .get( name ); } } @Nonnull @Override - public IWorkMonitor getMainThreadMonitor() { + public IWorkMonitor getMainThreadMonitor() + { return this.computer.getMainThreadMonitor(); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/BlockWirelessModem.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/BlockWirelessModem.java index b2fb5db29..abdf324d5 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/BlockWirelessModem.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/BlockWirelessModem.java @@ -6,17 +6,8 @@ package dan200.computercraft.shared.peripheral.modem.wireless; -import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED; -import static dan200.computercraft.shared.util.WaterloggableHelpers.getWaterloggedFluidState; -import static dan200.computercraft.shared.util.WaterloggableHelpers.getWaterloggedStateForPlacement; -import static dan200.computercraft.shared.util.WaterloggableHelpers.updateWaterloggedPostPlacement; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.common.BlockGeneric; import dan200.computercraft.shared.peripheral.modem.ModemShapes; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; @@ -35,60 +26,73 @@ import net.minecraft.world.BlockView; import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldView; -public class BlockWirelessModem extends BlockGeneric implements Waterloggable { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import static dan200.computercraft.shared.util.WaterloggableHelpers.*; + +public class BlockWirelessModem extends BlockGeneric implements Waterloggable +{ public static final DirectionProperty FACING = Properties.FACING; - public static final BooleanProperty ON = BooleanProperty.of("on"); + public static final BooleanProperty ON = BooleanProperty.of( "on" ); - public BlockWirelessModem(Settings settings, BlockEntityType type) { - super(settings, type); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(FACING, Direction.NORTH) - .with(ON, false) - .with(WATERLOGGED, false)); + public BlockWirelessModem( Settings settings, BlockEntityType type ) + { + super( settings, type ); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( FACING, Direction.NORTH ) + .with( ON, false ) + .with( WATERLOGGED, false ) ); } @Nonnull @Override @Deprecated - public BlockState getStateForNeighborUpdate(@Nonnull BlockState state, @Nonnull Direction side, @Nonnull BlockState otherState, - @Nonnull WorldAccess world, @Nonnull BlockPos pos, @Nonnull BlockPos otherPos) { - updateWaterloggedPostPlacement(state, world, pos); - return side == state.get(FACING) && !state.canPlaceAt(world, pos) ? state.getFluidState() - .getBlockState() : state; + public BlockState getStateForNeighborUpdate( @Nonnull BlockState state, @Nonnull Direction side, @Nonnull BlockState otherState, + @Nonnull WorldAccess world, @Nonnull BlockPos pos, @Nonnull BlockPos otherPos ) + { + updateWaterloggedPostPlacement( state, world, pos ); + return side == state.get( FACING ) && !state.canPlaceAt( world, pos ) ? state.getFluidState() + .getBlockState() : state; } @Nonnull @Override @Deprecated - public FluidState getFluidState(@Nonnull BlockState state) { - return getWaterloggedFluidState(state); + public FluidState getFluidState( @Nonnull BlockState state ) + { + return getWaterloggedFluidState( state ); } @Override @Deprecated - public boolean canPlaceAt(BlockState state, @Nonnull WorldView world, BlockPos pos) { - Direction facing = state.get(FACING); - return sideCoversSmallSquare(world, pos.offset(facing), facing.getOpposite()); + public boolean canPlaceAt( BlockState state, @Nonnull WorldView world, BlockPos pos ) + { + Direction facing = state.get( FACING ); + return sideCoversSmallSquare( world, pos.offset( facing ), facing.getOpposite() ); } @Nonnull @Override @Deprecated - public VoxelShape getOutlineShape(BlockState blockState, @Nonnull BlockView blockView, @Nonnull BlockPos blockPos, @Nonnull ShapeContext context) { - return ModemShapes.getBounds(blockState.get(FACING)); + public VoxelShape getOutlineShape( BlockState blockState, @Nonnull BlockView blockView, @Nonnull BlockPos blockPos, @Nonnull ShapeContext context ) + { + return ModemShapes.getBounds( blockState.get( FACING ) ); } @Nullable @Override - public BlockState getPlacementState(ItemPlacementContext placement) { - return this.getDefaultState().with(FACING, - placement.getSide() - .getOpposite()) - .with(WATERLOGGED, getWaterloggedStateForPlacement(placement)); + public BlockState getPlacementState( ItemPlacementContext placement ) + { + return this.getDefaultState().with( FACING, + placement.getSide() + .getOpposite() ) + .with( WATERLOGGED, getWaterloggedStateForPlacement( placement ) ); } @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(FACING, ON, WATERLOGGED); + protected void appendProperties( StateManager.Builder builder ) + { + builder.add( FACING, ON, WATERLOGGED ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/TileWirelessModem.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/TileWirelessModem.java index 247a3b256..1f761a583 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/TileWirelessModem.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/TileWirelessModem.java @@ -6,15 +6,12 @@ package dan200.computercraft.shared.peripheral.modem.wireless; -import javax.annotation.Nonnull; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralTile; import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.peripheral.modem.ModemPeripheral; import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.util.TickScheduler; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.math.BlockPos; @@ -22,109 +19,131 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class TileWirelessModem extends TileGeneric implements IPeripheralTile { +import javax.annotation.Nonnull; + +public class TileWirelessModem extends TileGeneric implements IPeripheralTile +{ private final boolean advanced; private final ModemPeripheral modem; private boolean hasModemDirection = false; private Direction modemDirection = Direction.DOWN; private boolean destroyed = false; - public TileWirelessModem(BlockEntityType type, boolean advanced) { - super(type); + + public TileWirelessModem( BlockEntityType type, boolean advanced ) + { + super( type ); this.advanced = advanced; - this.modem = new Peripheral(this); + this.modem = new Peripheral( this ); } @Override - public void cancelRemoval() { + public void cancelRemoval() + { super.cancelRemoval(); - TickScheduler.schedule(this); + TickScheduler.schedule( this ); } @Override - public void resetBlock() { + public void resetBlock() + { super.resetBlock(); this.hasModemDirection = false; this.world.getBlockTickScheduler() - .schedule(this.getPos(), - this.getCachedState().getBlock(), 0); + .schedule( this.getPos(), + this.getCachedState().getBlock(), 0 ); } @Override - public void destroy() { - if (!this.destroyed) { + public void destroy() + { + if( !this.destroyed ) + { this.modem.destroy(); this.destroyed = true; } } @Override - public void blockTick() { + public void blockTick() + { Direction currentDirection = this.modemDirection; this.refreshDirection(); // Invalidate the capability if the direction has changed. I'm not 100% happy with this implementation // - ideally we'd do it within refreshDirection or updateContainingBlockInfo, but this seems the _safest_ // place. - if (this.modem.getModemState() - .pollChanged()) { + if( this.modem.getModemState() + .pollChanged() ) + { this.updateBlockState(); } } - private void refreshDirection() { - if (this.hasModemDirection) { + private void refreshDirection() + { + if( this.hasModemDirection ) + { return; } this.hasModemDirection = true; - this.modemDirection = this.getCachedState().get(BlockWirelessModem.FACING); + this.modemDirection = this.getCachedState().get( BlockWirelessModem.FACING ); } - private void updateBlockState() { + private void updateBlockState() + { boolean on = this.modem.getModemState() - .isOpen(); + .isOpen(); BlockState state = this.getCachedState(); - if (state.get(BlockWirelessModem.ON) != on) { - this.getWorld().setBlockState(this.getPos(), state.with(BlockWirelessModem.ON, on)); + if( state.get( BlockWirelessModem.ON ) != on ) + { + this.getWorld().setBlockState( this.getPos(), state.with( BlockWirelessModem.ON, on ) ); } } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { + public IPeripheral getPeripheral( Direction side ) + { this.refreshDirection(); return side == this.modemDirection ? this.modem : null; } - private static class Peripheral extends WirelessModemPeripheral { + private static class Peripheral extends WirelessModemPeripheral + { private final TileWirelessModem entity; - Peripheral(TileWirelessModem entity) { - super(new ModemState(() -> TickScheduler.schedule(entity)), entity.advanced); + Peripheral( TileWirelessModem entity ) + { + super( new ModemState( () -> TickScheduler.schedule( entity ) ), entity.advanced ); this.entity = entity; } @Nonnull @Override - public World getWorld() { + public World getWorld() + { return this.entity.getWorld(); } @Nonnull @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { BlockPos pos = this.entity.getPos() - .offset(this.entity.modemDirection); - return new Vec3d(pos.getX(), pos.getY(), pos.getZ()); + .offset( this.entity.modemDirection ); + return new Vec3d( pos.getX(), pos.getY(), pos.getZ() ); } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return this.entity; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return this == other || (other instanceof Peripheral && this.entity == ((Peripheral) other).entity); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java index 514264047..0d69b8e11 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java @@ -10,33 +10,41 @@ import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.network.IPacketNetwork; import dan200.computercraft.shared.peripheral.modem.ModemPeripheral; import dan200.computercraft.shared.peripheral.modem.ModemState; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public abstract class WirelessModemPeripheral extends ModemPeripheral { +public abstract class WirelessModemPeripheral extends ModemPeripheral +{ private final boolean m_advanced; - public WirelessModemPeripheral(ModemState state, boolean advanced) { - super(state); + public WirelessModemPeripheral( ModemState state, boolean advanced ) + { + super( state ); this.m_advanced = advanced; } @Override - public double getRange() { - if (this.m_advanced) { + public double getRange() + { + if( this.m_advanced ) + { return Integer.MAX_VALUE; - } else { + } + else + { World world = this.getWorld(); - if (world != null) { + if( world != null ) + { Vec3d position = this.getPosition(); double minRange = ComputerCraft.modemRange; double maxRange = ComputerCraft.modemHighAltitudeRange; - if (world.isRaining() && world.isThundering()) { + if( world.isRaining() && world.isThundering() ) + { minRange = ComputerCraft.modemRangeDuringStorm; maxRange = ComputerCraft.modemHighAltitudeRangeDuringStorm; } - if (position.y > 96.0 && maxRange > minRange) { + if( position.y > 96.0 && maxRange > minRange ) + { return minRange + (position.y - 96.0) * ((maxRange - minRange) / ((world.getHeight() - 1) - 96.0)); } return minRange; @@ -46,12 +54,14 @@ public abstract class WirelessModemPeripheral extends ModemPeripheral { } @Override - public boolean isInterdimensional() { + public boolean isInterdimensional() + { return this.m_advanced; } @Override - protected IPacketNetwork getNetwork() { + protected IPacketNetwork getNetwork() + { return WirelessNetwork.getUniversal(); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessNetwork.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessNetwork.java index ecb583802..4c0200ffe 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessNetwork.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessNetwork.java @@ -6,78 +6,94 @@ package dan200.computercraft.shared.peripheral.modem.wireless; -import java.util.Collections; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.network.IPacketNetwork; import dan200.computercraft.api.network.IPacketReceiver; import dan200.computercraft.api.network.IPacketSender; import dan200.computercraft.api.network.Packet; -public class WirelessNetwork implements IPacketNetwork { - private static WirelessNetwork s_universalNetwork = null; - private final Set m_receivers = Collections.newSetFromMap(new ConcurrentHashMap<>()); +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; - public static WirelessNetwork getUniversal() { - if (s_universalNetwork == null) { +public class WirelessNetwork implements IPacketNetwork +{ + private static WirelessNetwork s_universalNetwork = null; + private final Set m_receivers = Collections.newSetFromMap( new ConcurrentHashMap<>() ); + + public static WirelessNetwork getUniversal() + { + if( s_universalNetwork == null ) + { s_universalNetwork = new WirelessNetwork(); } return s_universalNetwork; } - public static void resetNetworks() { + public static void resetNetworks() + { s_universalNetwork = null; } @Override - public void addReceiver(@Nonnull IPacketReceiver receiver) { - Objects.requireNonNull(receiver, "device cannot be null"); - this.m_receivers.add(receiver); + public void addReceiver( @Nonnull IPacketReceiver receiver ) + { + Objects.requireNonNull( receiver, "device cannot be null" ); + this.m_receivers.add( receiver ); } @Override - public void removeReceiver(@Nonnull IPacketReceiver receiver) { - Objects.requireNonNull(receiver, "device cannot be null"); - this.m_receivers.remove(receiver); + public void removeReceiver( @Nonnull IPacketReceiver receiver ) + { + Objects.requireNonNull( receiver, "device cannot be null" ); + this.m_receivers.remove( receiver ); } @Override - public boolean isWireless() { + public boolean isWireless() + { return true; } @Override - public void transmitSameDimension(@Nonnull Packet packet, double range) { - Objects.requireNonNull(packet, "packet cannot be null"); - for (IPacketReceiver device : this.m_receivers) { - tryTransmit(device, packet, range, false); + public void transmitSameDimension( @Nonnull Packet packet, double range ) + { + Objects.requireNonNull( packet, "packet cannot be null" ); + for( IPacketReceiver device : this.m_receivers ) + { + tryTransmit( device, packet, range, false ); } } @Override - public void transmitInterdimensional(@Nonnull Packet packet) { - Objects.requireNonNull(packet, "packet cannot be null"); - for (IPacketReceiver device : this.m_receivers) { - tryTransmit(device, packet, 0, true); + public void transmitInterdimensional( @Nonnull Packet packet ) + { + Objects.requireNonNull( packet, "packet cannot be null" ); + for( IPacketReceiver device : this.m_receivers ) + { + tryTransmit( device, packet, 0, true ); } } - private static void tryTransmit(IPacketReceiver receiver, Packet packet, double range, boolean interdimensional) { + private static void tryTransmit( IPacketReceiver receiver, Packet packet, double range, boolean interdimensional ) + { IPacketSender sender = packet.getSender(); - if (receiver.getWorld() == sender.getWorld()) { - double receiveRange = Math.max(range, receiver.getRange()); // Ensure range is symmetrical + if( receiver.getWorld() == sender.getWorld() ) + { + double receiveRange = Math.max( range, receiver.getRange() ); // Ensure range is symmetrical double distanceSq = receiver.getPosition() - .squaredDistanceTo(sender.getPosition()); - if (interdimensional || receiver.isInterdimensional() || distanceSq <= receiveRange * receiveRange) { - receiver.receiveSameDimension(packet, Math.sqrt(distanceSq)); + .squaredDistanceTo( sender.getPosition() ); + if( interdimensional || receiver.isInterdimensional() || distanceSq <= receiveRange * receiveRange ) + { + receiver.receiveSameDimension( packet, Math.sqrt( distanceSq ) ); } - } else { - if (interdimensional || receiver.isInterdimensional()) { - receiver.receiveDifferentDimension(packet); + } + else + { + if( interdimensional || receiver.isInterdimensional() ) + { + receiver.receiveDifferentDimension( packet ); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/BlockMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/BlockMonitor.java index ebd2799bb..897ea62e0 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/BlockMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/BlockMonitor.java @@ -6,12 +6,8 @@ package dan200.computercraft.shared.peripheral.monitor; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.shared.common.BlockGeneric; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -27,53 +23,66 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class BlockMonitor extends BlockGeneric { - public static final DirectionProperty ORIENTATION = DirectionProperty.of("orientation", Direction.UP, Direction.DOWN, Direction.NORTH); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class BlockMonitor extends BlockGeneric +{ + public static final DirectionProperty ORIENTATION = DirectionProperty.of( "orientation", Direction.UP, Direction.DOWN, Direction.NORTH ); public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - static final EnumProperty STATE = EnumProperty.of("state", MonitorEdgeState.class); + static final EnumProperty STATE = EnumProperty.of( "state", MonitorEdgeState.class ); - public BlockMonitor(Settings settings, BlockEntityType type) { - super(settings, type); + public BlockMonitor( Settings settings, BlockEntityType type ) + { + super( settings, type ); // TODO: Test underwater - do we need isSolid at all? - this.setDefaultState(this.getStateManager().getDefaultState() - .with(ORIENTATION, Direction.NORTH) - .with(FACING, Direction.NORTH) - .with(STATE, MonitorEdgeState.NONE)); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( ORIENTATION, Direction.NORTH ) + .with( FACING, Direction.NORTH ) + .with( STATE, MonitorEdgeState.NONE ) ); } @Override @Nullable - public BlockState getPlacementState(ItemPlacementContext context) { + public BlockState getPlacementState( ItemPlacementContext context ) + { float pitch = context.getPlayer() == null ? 0 : context.getPlayer().pitch; Direction orientation; - if (pitch > 66.5f) { + if( pitch > 66.5f ) + { // If the player is looking down, place it facing upwards orientation = Direction.UP; - } else if (pitch < -66.5f) { + } + else if( pitch < -66.5f ) + { // If they're looking up, place it down. orientation = Direction.DOWN; - } else { + } + else + { orientation = Direction.NORTH; } - return this.getDefaultState().with(FACING, - context.getPlayerFacing() - .getOpposite()) - .with(ORIENTATION, orientation); + return this.getDefaultState().with( FACING, + context.getPlayerFacing() + .getOpposite() ) + .with( ORIENTATION, orientation ); } @Override - public void onPlaced(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState blockState, @Nullable LivingEntity livingEntity, - @Nonnull ItemStack itemStack) { - super.onPlaced(world, pos, blockState, livingEntity, itemStack); + public void onPlaced( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState blockState, @Nullable LivingEntity livingEntity, + @Nonnull ItemStack itemStack ) + { + super.onPlaced( world, pos, blockState, livingEntity, itemStack ); - BlockEntity entity = world.getBlockEntity(pos); - if (entity instanceof TileMonitor && !world.isClient) { + BlockEntity entity = world.getBlockEntity( pos ); + if( entity instanceof TileMonitor && !world.isClient ) + { TileMonitor monitor = (TileMonitor) entity; // Defer the block update if we're being placed by another TE. See #691 - if ( livingEntity == null || livingEntity instanceof FakePlayer ) + if( livingEntity == null || livingEntity instanceof FakePlayer ) { monitor.updateNeighborsDeferred(); return; @@ -84,7 +93,8 @@ public class BlockMonitor extends BlockGeneric { } @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(ORIENTATION, FACING, STATE); + protected void appendProperties( StateManager.Builder builder ) + { + builder.add( ORIENTATION, FACING, STATE ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java index 7ad6d90c8..d7b682f84 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java @@ -6,27 +6,26 @@ package dan200.computercraft.shared.peripheral.monitor; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.shared.common.ClientTerminal; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gl.VertexBuffer; +import net.minecraft.util.math.BlockPos; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL31; -import net.minecraft.client.gl.VertexBuffer; -import net.minecraft.util.math.BlockPos; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment (EnvType.CLIENT) -public final class ClientMonitor extends ClientTerminal { +@Environment( EnvType.CLIENT ) +public final class ClientMonitor extends ClientTerminal +{ private static final Set allMonitors = new HashSet<>(); private final TileMonitor origin; @@ -38,15 +37,19 @@ public final class ClientMonitor extends ClientTerminal { public int tboTexture; public VertexBuffer buffer; - public ClientMonitor(boolean colour, TileMonitor origin) { - super(colour); + public ClientMonitor( boolean colour, TileMonitor origin ) + { + super( colour ); this.origin = origin; } - @Environment (EnvType.CLIENT) - public static void destroyAll() { - synchronized (allMonitors) { - for (Iterator iterator = allMonitors.iterator(); iterator.hasNext(); ) { + @Environment( EnvType.CLIENT ) + public static void destroyAll() + { + synchronized( allMonitors ) + { + for( Iterator iterator = allMonitors.iterator(); iterator.hasNext(); ) + { ClientMonitor monitor = iterator.next(); monitor.deleteBuffers(); @@ -55,7 +58,8 @@ public final class ClientMonitor extends ClientTerminal { } } - public TileMonitor getOrigin() { + public TileMonitor getOrigin() + { return this.origin; } @@ -65,74 +69,88 @@ public final class ClientMonitor extends ClientTerminal { * @param renderer The renderer to use. This can be fetched from {@link MonitorRenderer#current()}. * @return If a buffer was created. This will return {@code false} if we already have an appropriate buffer, or this mode does not require one. */ - @Environment (EnvType.CLIENT) - public boolean createBuffer(MonitorRenderer renderer) { - switch (renderer) { - case TBO: { - if (this.tboBuffer != 0) { - return false; + @Environment( EnvType.CLIENT ) + public boolean createBuffer( MonitorRenderer renderer ) + { + switch( renderer ) + { + case TBO: + { + if( this.tboBuffer != 0 ) + { + return false; + } + + this.deleteBuffers(); + + this.tboBuffer = GlStateManager.genBuffers(); + GlStateManager.bindBuffers( GL31.GL_TEXTURE_BUFFER, this.tboBuffer ); + GL15.glBufferData( GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW ); + this.tboTexture = GlStateManager.genTextures(); + GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, this.tboTexture ); + GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, this.tboBuffer ); + GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, 0 ); + + GlStateManager.bindBuffers( GL31.GL_TEXTURE_BUFFER, 0 ); + + this.addMonitor(); + return true; } - this.deleteBuffers(); + case VBO: + if( this.buffer != null ) + { + return false; + } - this.tboBuffer = GlStateManager.genBuffers(); - GlStateManager.bindBuffers(GL31.GL_TEXTURE_BUFFER, this.tboBuffer); - GL15.glBufferData(GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW); - this.tboTexture = GlStateManager.genTextures(); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, this.tboTexture); - GL31.glTexBuffer(GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, this.tboBuffer); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, 0); + this.deleteBuffers(); + this.buffer = new VertexBuffer( FixedWidthFontRenderer.TYPE.getVertexFormat() ); + this.addMonitor(); + return true; - GlStateManager.bindBuffers(GL31.GL_TEXTURE_BUFFER, 0); - - this.addMonitor(); - return true; - } - - case VBO: - if (this.buffer != null) { + default: return false; - } - - this.deleteBuffers(); - this.buffer = new VertexBuffer(FixedWidthFontRenderer.TYPE.getVertexFormat()); - this.addMonitor(); - return true; - - default: - return false; } } - private void deleteBuffers() { + private void deleteBuffers() + { - if (this.tboBuffer != 0) { - RenderSystem.glDeleteBuffers(this.tboBuffer); + if( this.tboBuffer != 0 ) + { + RenderSystem.glDeleteBuffers( this.tboBuffer ); this.tboBuffer = 0; } - if (this.tboTexture != 0) { - GlStateManager.deleteTexture(this.tboTexture); + if( this.tboTexture != 0 ) + { + GlStateManager.deleteTexture( this.tboTexture ); this.tboTexture = 0; } - if (this.buffer != null) { + if( this.buffer != null ) + { this.buffer.close(); this.buffer = null; } } - private void addMonitor() { - synchronized (allMonitors) { - allMonitors.add(this); + private void addMonitor() + { + synchronized( allMonitors ) + { + allMonitors.add( this ); } } - @Environment (EnvType.CLIENT) - public void destroy() { - if (this.tboBuffer != 0 || this.buffer != null) { - synchronized (allMonitors) { - allMonitors.remove(this); + @Environment( EnvType.CLIENT ) + public void destroy() + { + if( this.tboBuffer != 0 || this.buffer != null ) + { + synchronized( allMonitors ) + { + allMonitors.remove( this ); } this.deleteBuffers(); diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorEdgeState.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorEdgeState.java index af5600f58..6e2e83bbd 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorEdgeState.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorEdgeState.java @@ -6,40 +6,40 @@ package dan200.computercraft.shared.peripheral.monitor; -import static dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState.Flags.DOWN; -import static dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState.Flags.LEFT; -import static dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState.Flags.RIGHT; -import static dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState.Flags.UP; +import net.minecraft.util.StringIdentifiable; import javax.annotation.Nonnull; -import net.minecraft.util.StringIdentifiable; +import static dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState.Flags.*; -public enum MonitorEdgeState implements StringIdentifiable { - NONE("none", 0), +public enum MonitorEdgeState implements StringIdentifiable +{ + NONE( "none", 0 ), - L("l", LEFT), - R("r", RIGHT), - LR("lr", LEFT | RIGHT), - U("u", UP), - D("d", DOWN), + L( "l", LEFT ), + R( "r", RIGHT ), + LR( "lr", LEFT | RIGHT ), + U( "u", UP ), + D( "d", DOWN ), - UD("ud", UP | DOWN), - RD("rd", RIGHT | DOWN), - LD("ld", LEFT | DOWN), - RU("ru", RIGHT | UP), - LU("lu", LEFT | UP), + UD( "ud", UP | DOWN ), + RD( "rd", RIGHT | DOWN ), + LD( "ld", LEFT | DOWN ), + RU( "ru", RIGHT | UP ), + LU( "lu", LEFT | UP ), - LRD("lrd", LEFT | RIGHT | DOWN), - RUD("rud", RIGHT | UP | DOWN), - LUD("lud", LEFT | UP | DOWN), - LRU("lru", LEFT | RIGHT | UP), - LRUD("lrud", LEFT | RIGHT | UP | DOWN); + LRD( "lrd", LEFT | RIGHT | DOWN ), + RUD( "rud", RIGHT | UP | DOWN ), + LUD( "lud", LEFT | UP | DOWN ), + LRU( "lru", LEFT | RIGHT | UP ), + LRUD( "lrud", LEFT | RIGHT | UP | DOWN ); private static final MonitorEdgeState[] BY_FLAG = new MonitorEdgeState[16]; - static { - for (MonitorEdgeState state : values()) { + static + { + for( MonitorEdgeState state : values() ) + { BY_FLAG[state.flags] = state; } } @@ -47,22 +47,26 @@ public enum MonitorEdgeState implements StringIdentifiable { private final String name; private final int flags; - MonitorEdgeState(String name, int flags) { + MonitorEdgeState( String name, int flags ) + { this.name = name; this.flags = flags; } - public static MonitorEdgeState fromConnections(boolean up, boolean down, boolean left, boolean right) { + public static MonitorEdgeState fromConnections( boolean up, boolean down, boolean left, boolean right ) + { return BY_FLAG[(up ? UP : 0) | (down ? DOWN : 0) | (left ? LEFT : 0) | (right ? RIGHT : 0)]; } @Nonnull @Override - public String asString() { + public String asString() + { return this.name; } - static final class Flags { + static final class Flags + { static final int UP = 1 << 0; static final int DOWN = 1 << 1; static final int LEFT = 1 << 2; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java index 83e76c796..ee0191b03 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java @@ -6,9 +6,6 @@ package dan200.computercraft.shared.peripheral.monitor; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaValues; @@ -17,6 +14,9 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.apis.TermMethods; import dan200.computercraft.core.terminal.Terminal; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * Monitors are a block which act as a terminal, displaying information on one side. This allows them to be read and interacted with in-world without * opening a GUI. @@ -28,43 +28,50 @@ import dan200.computercraft.core.terminal.Terminal; * @cc.module monitor * @cc.usage Write "Hello, world!" to an adjacent monitor: * - *
    + * 
      *     local monitor = peripheral.find("monitor")
      *     monitor.setCursorPos(1, 1)
      *     monitor.write("Hello, world!")
      *     
    */ -public class MonitorPeripheral extends TermMethods implements IPeripheral { +public class MonitorPeripheral extends TermMethods implements IPeripheral +{ private final TileMonitor monitor; - public MonitorPeripheral(TileMonitor monitor) { + public MonitorPeripheral( TileMonitor monitor ) + { this.monitor = monitor; } @Nonnull @Override - public String getType() { + public String getType() + { return "monitor"; } @Override - public void attach(@Nonnull IComputerAccess computer) { - this.monitor.addComputer(computer); + public void attach( @Nonnull IComputerAccess computer ) + { + this.monitor.addComputer( computer ); } @Override - public void detach(@Nonnull IComputerAccess computer) { - this.monitor.removeComputer(computer); + public void detach( @Nonnull IComputerAccess computer ) + { + this.monitor.removeComputer( computer ); } @Nullable @Override - public Object getTarget() { + public Object getTarget() + { return this.monitor; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other instanceof MonitorPeripheral && this.monitor == ((MonitorPeripheral) other).monitor; } @@ -75,7 +82,8 @@ public class MonitorPeripheral extends TermMethods implements IPeripheral { * @throws LuaException If the monitor cannot be found. */ @LuaFunction - public final double getTextScale() throws LuaException { + public final double getTextScale() throws LuaException + { return this.getMonitor().getTextScale() / 2.0; } @@ -87,35 +95,42 @@ public class MonitorPeripheral extends TermMethods implements IPeripheral { * @see #getTextScale() */ @LuaFunction - public final void setTextScale(double scaleArg) throws LuaException { - int scale = (int) (LuaValues.checkFinite(0, scaleArg) * 2.0); - if (scale < 1 || scale > 10) { - throw new LuaException("Expected number in range 0.5-5"); + public final void setTextScale( double scaleArg ) throws LuaException + { + int scale = (int) (LuaValues.checkFinite( 0, scaleArg ) * 2.0); + if( scale < 1 || scale > 10 ) + { + throw new LuaException( "Expected number in range 0.5-5" ); } - this.getMonitor().setTextScale(scale); + this.getMonitor().setTextScale( scale ); } @Nonnull - private ServerMonitor getMonitor() throws LuaException { + private ServerMonitor getMonitor() throws LuaException + { ServerMonitor monitor = this.monitor.getCachedServerMonitor(); - if (monitor == null) { - throw new LuaException("Monitor has been detached"); + if( monitor == null ) + { + throw new LuaException( "Monitor has been detached" ); } return monitor; } @Nonnull @Override - public Terminal getTerminal() throws LuaException { + public Terminal getTerminal() throws LuaException + { Terminal terminal = this.getMonitor().getTerminal(); - if (terminal == null) { - throw new LuaException("Monitor has been detached"); + if( terminal == null ) + { + throw new LuaException( "Monitor has been detached" ); } return terminal; } @Override - public boolean isColour() throws LuaException { + public boolean isColour() throws LuaException + { return this.getMonitor().isColour(); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java index c30d3a4d5..6d0dc360f 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java @@ -5,19 +5,20 @@ */ package dan200.computercraft.shared.peripheral.monitor; -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.render.TileEntityMonitorRenderer; import org.lwjgl.opengl.GL; +import javax.annotation.Nonnull; + /** * The render type to use for monitors. * * @see TileEntityMonitorRenderer * @see ClientMonitor */ -public enum MonitorRenderer { +public enum MonitorRenderer +{ /** * Determine the best monitor backend. */ @@ -44,32 +45,38 @@ public enum MonitorRenderer { * @return The current renderer. Will not return {@link MonitorRenderer#BEST}. */ @Nonnull - public static MonitorRenderer current() { + public static MonitorRenderer current() + { MonitorRenderer current = ComputerCraft.monitorRenderer; - switch (current) { - case BEST: - return best(); - case TBO: - checkCapabilities(); - if (!textureBuffer) { - ComputerCraft.log.warn("Texture buffers are not supported on your graphics card. Falling back to default."); - ComputerCraft.monitorRenderer = BEST; + switch( current ) + { + case BEST: return best(); - } + case TBO: + checkCapabilities(); + if( !textureBuffer ) + { + ComputerCraft.log.warn( "Texture buffers are not supported on your graphics card. Falling back to default." ); + ComputerCraft.monitorRenderer = BEST; + return best(); + } - return TBO; - default: - return current; + return TBO; + default: + return current; } } - private static MonitorRenderer best() { + private static MonitorRenderer best() + { checkCapabilities(); return textureBuffer ? TBO : VBO; } - private static void checkCapabilities() { - if (initialised) { + private static void checkCapabilities() + { + if( initialised ) + { return; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java index 6914f2a0d..fb338fc27 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java @@ -6,77 +6,90 @@ package dan200.computercraft.shared.peripheral.monitor; -import java.util.concurrent.atomic.AtomicBoolean; - import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.common.ServerTerminal; import dan200.computercraft.shared.util.TickScheduler; -public class ServerMonitor extends ServerTerminal { +import java.util.concurrent.atomic.AtomicBoolean; + +public class ServerMonitor extends ServerTerminal +{ private final TileMonitor origin; - private final AtomicBoolean resized = new AtomicBoolean(false); - private final AtomicBoolean changed = new AtomicBoolean(false); + private final AtomicBoolean resized = new AtomicBoolean( false ); + private final AtomicBoolean changed = new AtomicBoolean( false ); private int textScale = 2; - public ServerMonitor(boolean colour, TileMonitor origin) { - super(colour); + public ServerMonitor( boolean colour, TileMonitor origin ) + { + super( colour ); this.origin = origin; } @Override - protected void markTerminalChanged() { + protected void markTerminalChanged() + { super.markTerminalChanged(); this.markChanged(); } - private void markChanged() { - if (!this.changed.getAndSet(true)) { - TickScheduler.schedule(this.origin); + private void markChanged() + { + if( !this.changed.getAndSet( true ) ) + { + TickScheduler.schedule( this.origin ); } } - protected void clearChanged() { - this.changed.set(false); + protected void clearChanged() + { + this.changed.set( false ); } - public int getTextScale() { + public int getTextScale() + { return this.textScale; } - public synchronized void setTextScale(int textScale) { - if (this.textScale == textScale) { + public synchronized void setTextScale( int textScale ) + { + if( this.textScale == textScale ) + { return; } this.textScale = textScale; this.rebuild(); } - public synchronized void rebuild() { + public synchronized void rebuild() + { Terminal oldTerm = this.getTerminal(); int oldWidth = oldTerm == null ? -1 : oldTerm.getWidth(); int oldHeight = oldTerm == null ? -1 : oldTerm.getHeight(); double textScale = this.textScale * 0.5; int termWidth = - (int) Math.max(Math.round((this.origin.getWidth() - 2.0 * (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN)) / (textScale * 6.0 * TileMonitor.RENDER_PIXEL_SCALE)), - 1.0); + (int) Math.max( Math.round( (this.origin.getWidth() - 2.0 * (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN)) / (textScale * 6.0 * TileMonitor.RENDER_PIXEL_SCALE) ), + 1.0 ); int termHeight = - (int) Math.max(Math.round((this.origin.getHeight() - 2.0 * (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN)) / (textScale * 9.0 * TileMonitor.RENDER_PIXEL_SCALE)), - 1.0); + (int) Math.max( Math.round( (this.origin.getHeight() - 2.0 * (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN)) / (textScale * 9.0 * TileMonitor.RENDER_PIXEL_SCALE) ), + 1.0 ); - this.resize(termWidth, termHeight); - if (oldWidth != termWidth || oldHeight != termHeight) { + this.resize( termWidth, termHeight ); + if( oldWidth != termWidth || oldHeight != termHeight ) + { this.getTerminal().clear(); - this.resized.set(true); + this.resized.set( true ); this.markChanged(); } } - public boolean pollResized() { - return this.resized.getAndSet(false); + public boolean pollResized() + { + return this.resized.getAndSet( false ); } - public boolean pollTerminalChanged() { + public boolean pollTerminalChanged() + { this.update(); return this.hasTerminalChanged(); } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java index d7331f5df..ee328608c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.peripheral.monitor; -import java.util.HashSet; -import java.util.Set; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; @@ -20,7 +15,6 @@ import dan200.computercraft.shared.common.ServerTerminal; import dan200.computercraft.shared.common.TileGeneric; import dan200.computercraft.shared.network.client.TerminalState; import dan200.computercraft.shared.util.TickScheduler; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; @@ -33,10 +27,12 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; +import java.util.HashSet; +import java.util.Set; -public class TileMonitor extends TileGeneric implements IPeripheralTile { +public class TileMonitor extends TileGeneric implements IPeripheralTile +{ public static final double RENDER_BORDER = 2.0 / 16.0; public static final double RENDER_MARGIN = 0.5 / 16.0; public static final double RENDER_PIXEL_SCALE = 1.0 / 64.0; @@ -62,35 +58,43 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { private int m_xIndex = 0; private int m_yIndex = 0; - public TileMonitor(BlockEntityType type, boolean advanced) { - super(type); + public TileMonitor( BlockEntityType type, boolean advanced ) + { + super( type ); this.advanced = advanced; } @Override - public void destroy() { + public void destroy() + { // TODO: Call this before using the block - if (this.m_destroyed) { + if( this.m_destroyed ) + { return; } this.m_destroyed = true; - if (!this.getWorld().isClient) { + if( !this.getWorld().isClient ) + { this.contractNeighbours(); } } @Override - public void markRemoved() { + public void markRemoved() + { super.markRemoved(); - if (this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0) { + if( this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0 ) + { this.m_clientMonitor.destroy(); } } @Override - public void onChunkUnloaded() { + public void onChunkUnloaded() + { super.onChunkUnloaded(); - if (this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0) { + if( this.m_clientMonitor != null && this.m_xIndex == 0 && this.m_yIndex == 0 ) + { this.m_clientMonitor.destroy(); } this.m_clientMonitor = null; @@ -98,15 +102,18 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { - if (!player.isInSneakingPose() && this.getFront() == hit.getSide()) { - if (!this.getWorld().isClient) { - this.monitorTouched((float) (hit.getPos().x - hit.getBlockPos() - .getX()), - (float) (hit.getPos().y - hit.getBlockPos() - .getY()), - (float) (hit.getPos().z - hit.getBlockPos() - .getZ())); + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { + if( !player.isInSneakingPose() && this.getFront() == hit.getSide() ) + { + if( !this.getWorld().isClient ) + { + this.monitorTouched( (float) (hit.getPos().x - hit.getBlockPos() + .getX()), + (float) (hit.getPos().y - hit.getBlockPos() + .getY()), + (float) (hit.getPos().z - hit.getBlockPos() + .getZ()) ); } return ActionResult.SUCCESS; } @@ -115,124 +122,148 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } @Override - public void blockTick() { - if ( needsUpdate ) + public void blockTick() + { + if( needsUpdate ) { needsUpdate = false; updateNeighbors(); } - if (this.m_xIndex != 0 || this.m_yIndex != 0 || this.m_serverMonitor == null) { + if( this.m_xIndex != 0 || this.m_yIndex != 0 || this.m_serverMonitor == null ) + { return; } this.m_serverMonitor.clearChanged(); - if (this.m_serverMonitor.pollResized()) { - for (int x = 0; x < this.m_width; x++) { - for (int y = 0; y < this.m_height; y++) { - TileMonitor monitor = this.getNeighbour(x, y); - if (monitor == null) { + if( this.m_serverMonitor.pollResized() ) + { + for( int x = 0; x < this.m_width; x++ ) + { + for( int y = 0; y < this.m_height; y++ ) + { + TileMonitor monitor = this.getNeighbour( x, y ); + if( monitor == null ) + { continue; } - for (IComputerAccess computer : monitor.m_computers) { - computer.queueEvent("monitor_resize", computer.getAttachmentName()); + for( IComputerAccess computer : monitor.m_computers ) + { + computer.queueEvent( "monitor_resize", computer.getAttachmentName() ); } } } } - if (this.m_serverMonitor.pollTerminalChanged()) { + if( this.m_serverMonitor.pollTerminalChanged() ) + { this.updateBlock(); } } @Override - protected final void readDescription(@Nonnull CompoundTag nbt) { - super.readDescription(nbt); + protected final void readDescription( @Nonnull CompoundTag nbt ) + { + super.readDescription( nbt ); int oldXIndex = this.m_xIndex; int oldYIndex = this.m_yIndex; int oldWidth = this.m_width; int oldHeight = this.m_height; - this.m_xIndex = nbt.getInt(NBT_X); - this.m_yIndex = nbt.getInt(NBT_Y); - this.m_width = nbt.getInt(NBT_WIDTH); - this.m_height = nbt.getInt(NBT_HEIGHT); + this.m_xIndex = nbt.getInt( NBT_X ); + this.m_yIndex = nbt.getInt( NBT_Y ); + this.m_width = nbt.getInt( NBT_WIDTH ); + this.m_height = nbt.getInt( NBT_HEIGHT ); - if (oldXIndex != this.m_xIndex || oldYIndex != this.m_yIndex) { + if( oldXIndex != this.m_xIndex || oldYIndex != this.m_yIndex ) + { // If our index has changed then it's possible the origin monitor has changed. Thus // we'll clear our cache. If we're the origin then we'll need to remove the glList as well. - if (oldXIndex == 0 && oldYIndex == 0 && this.m_clientMonitor != null) { + if( oldXIndex == 0 && oldYIndex == 0 && this.m_clientMonitor != null ) + { this.m_clientMonitor.destroy(); } this.m_clientMonitor = null; } - if (this.m_xIndex == 0 && this.m_yIndex == 0) { + if( this.m_xIndex == 0 && this.m_yIndex == 0 ) + { // If we're the origin terminal then create it. - if (this.m_clientMonitor == null) { - this.m_clientMonitor = new ClientMonitor(this.advanced, this); + if( this.m_clientMonitor == null ) + { + this.m_clientMonitor = new ClientMonitor( this.advanced, this ); } - this.m_clientMonitor.readDescription(nbt); + this.m_clientMonitor.readDescription( nbt ); } - if (oldXIndex != this.m_xIndex || oldYIndex != this.m_yIndex || oldWidth != this.m_width || oldHeight != this.m_height) { + if( oldXIndex != this.m_xIndex || oldYIndex != this.m_yIndex || oldWidth != this.m_width || oldHeight != this.m_height ) + { // One of our properties has changed, so ensure we redraw the block this.updateBlock(); } } @Override - protected void writeDescription(@Nonnull CompoundTag nbt) { - super.writeDescription(nbt); - nbt.putInt(NBT_X, this.m_xIndex); - nbt.putInt(NBT_Y, this.m_yIndex); - nbt.putInt(NBT_WIDTH, this.m_width); - nbt.putInt(NBT_HEIGHT, this.m_height); + protected void writeDescription( @Nonnull CompoundTag nbt ) + { + super.writeDescription( nbt ); + nbt.putInt( NBT_X, this.m_xIndex ); + nbt.putInt( NBT_Y, this.m_yIndex ); + nbt.putInt( NBT_WIDTH, this.m_width ); + nbt.putInt( NBT_HEIGHT, this.m_height ); - if (this.m_xIndex == 0 && this.m_yIndex == 0 && this.m_serverMonitor != null) { - this.m_serverMonitor.writeDescription(nbt); + if( this.m_xIndex == 0 && this.m_yIndex == 0 && this.m_serverMonitor != null ) + { + this.m_serverMonitor.writeDescription( nbt ); } } - private TileMonitor getNeighbour(int x, int y) { + private TileMonitor getNeighbour( int x, int y ) + { BlockPos pos = this.getPos(); Direction right = this.getRight(); Direction down = this.getDown(); int xOffset = -this.m_xIndex + x; int yOffset = -this.m_yIndex + y; - return this.getSimilarMonitorAt(pos.offset(right, xOffset) - .offset(down, yOffset)); + return this.getSimilarMonitorAt( pos.offset( right, xOffset ) + .offset( down, yOffset ) ); } - public Direction getRight() { + public Direction getRight() + { return this.getDirection().rotateYCounterclockwise(); } - public Direction getDown() { + public Direction getDown() + { Direction orientation = this.getOrientation(); - if (orientation == Direction.NORTH) { + if( orientation == Direction.NORTH ) + { return Direction.UP; } return orientation == Direction.DOWN ? this.getDirection() : this.getDirection().getOpposite(); } - private TileMonitor getSimilarMonitorAt(BlockPos pos) { - if (pos.equals(this.getPos())) { + private TileMonitor getSimilarMonitorAt( BlockPos pos ) + { + if( pos.equals( this.getPos() ) ) + { return this; } int y = pos.getY(); World world = this.getWorld(); - if (world == null || !world.isChunkLoaded(pos)) { + if( world == null || !world.isChunkLoaded( pos ) ) + { return null; } - BlockEntity tile = world.getBlockEntity(pos); - if (!(tile instanceof TileMonitor)) { + BlockEntity tile = world.getBlockEntity( pos ); + if( !(tile instanceof TileMonitor) ) + { return null; } @@ -241,107 +272,128 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } // region Sizing and placement stuff - public Direction getDirection() { + public Direction getDirection() + { // Ensure we're actually a monitor block. This _should_ always be the case, but sometimes there's // fun problems with the block being missing on the client. BlockState state = getCachedState(); return state.contains( BlockMonitor.FACING ) ? state.get( BlockMonitor.FACING ) : Direction.NORTH; } - public Direction getOrientation() { - return this.getCachedState().get(BlockMonitor.ORIENTATION); + public Direction getOrientation() + { + return this.getCachedState().get( BlockMonitor.ORIENTATION ); } @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); - this.m_xIndex = nbt.getInt(NBT_X); - this.m_yIndex = nbt.getInt(NBT_Y); - this.m_width = nbt.getInt(NBT_WIDTH); - this.m_height = nbt.getInt(NBT_HEIGHT); + this.m_xIndex = nbt.getInt( NBT_X ); + this.m_yIndex = nbt.getInt( NBT_Y ); + this.m_width = nbt.getInt( NBT_WIDTH ); + this.m_height = nbt.getInt( NBT_HEIGHT ); } // Networking stuff @Nonnull @Override - public CompoundTag toTag(CompoundTag tag) { - tag.putInt(NBT_X, this.m_xIndex); - tag.putInt(NBT_Y, this.m_yIndex); - tag.putInt(NBT_WIDTH, this.m_width); - tag.putInt(NBT_HEIGHT, this.m_height); - return super.toTag(tag); + public CompoundTag toTag( CompoundTag tag ) + { + tag.putInt( NBT_X, this.m_xIndex ); + tag.putInt( NBT_Y, this.m_yIndex ); + tag.putInt( NBT_WIDTH, this.m_width ); + tag.putInt( NBT_HEIGHT, this.m_height ); + return super.toTag( tag ); } @Override - public double getRenderDistance() { + public double getRenderDistance() + { return ComputerCraft.monitorDistanceSq; } // Sizing and placement stuff @Override - public void cancelRemoval() { + public void cancelRemoval() + { super.cancelRemoval(); - TickScheduler.schedule(this); + TickScheduler.schedule( this ); } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { + public IPeripheral getPeripheral( Direction side ) + { this.createServerMonitor(); // Ensure the monitor is created before doing anything else. - if (this.peripheral == null) { - this.peripheral = new MonitorPeripheral(this); + if( this.peripheral == null ) + { + this.peripheral = new MonitorPeripheral( this ); } return this.peripheral; } - public ServerMonitor getCachedServerMonitor() { + public ServerMonitor getCachedServerMonitor() + { return this.m_serverMonitor; } - private ServerMonitor getServerMonitor() { - if (this.m_serverMonitor != null) { + private ServerMonitor getServerMonitor() + { + if( this.m_serverMonitor != null ) + { return this.m_serverMonitor; } TileMonitor origin = this.getOrigin(); - if (origin == null) { + if( origin == null ) + { return null; } return this.m_serverMonitor = origin.m_serverMonitor; } - private ServerMonitor createServerMonitor() { - if (this.m_serverMonitor != null) { + private ServerMonitor createServerMonitor() + { + if( this.m_serverMonitor != null ) + { return this.m_serverMonitor; } - if (this.m_xIndex == 0 && this.m_yIndex == 0) { + if( this.m_xIndex == 0 && this.m_yIndex == 0 ) + { // If we're the origin, set up the new monitor - this.m_serverMonitor = new ServerMonitor(this.advanced, this); + this.m_serverMonitor = new ServerMonitor( this.advanced, this ); this.m_serverMonitor.rebuild(); // And propagate it to child monitors - for (int x = 0; x < this.m_width; x++) { - for (int y = 0; y < this.m_height; y++) { - TileMonitor monitor = this.getNeighbour(x, y); - if (monitor != null) { + for( int x = 0; x < this.m_width; x++ ) + { + for( int y = 0; y < this.m_height; y++ ) + { + TileMonitor monitor = this.getNeighbour( x, y ); + if( monitor != null ) + { monitor.m_serverMonitor = this.m_serverMonitor; } } } return this.m_serverMonitor; - } else { + } + else + { // Otherwise fetch the origin and attempt to get its monitor // Note this may load chunks, but we don't really have a choice here. BlockPos pos = this.getPos(); - BlockEntity te = this.world.getBlockEntity(pos.offset(this.getRight(), -this.m_xIndex) - .offset(this.getDown(), -this.m_yIndex)); - if (!(te instanceof TileMonitor)) { + BlockEntity te = this.world.getBlockEntity( pos.offset( this.getRight(), -this.m_xIndex ) + .offset( this.getDown(), -this.m_yIndex ) ); + if( !(te instanceof TileMonitor) ) + { return null; } @@ -349,69 +401,84 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } } - public ClientMonitor getClientMonitor() { - if (this.m_clientMonitor != null) { + public ClientMonitor getClientMonitor() + { + if( this.m_clientMonitor != null ) + { return this.m_clientMonitor; } BlockPos pos = this.getPos(); - BlockEntity te = this.world.getBlockEntity(pos.offset(this.getRight(), -this.m_xIndex) - .offset(this.getDown(), -this.m_yIndex)); - if (!(te instanceof TileMonitor)) { + BlockEntity te = this.world.getBlockEntity( pos.offset( this.getRight(), -this.m_xIndex ) + .offset( this.getDown(), -this.m_yIndex ) ); + if( !(te instanceof TileMonitor) ) + { return null; } return this.m_clientMonitor = ((TileMonitor) te).m_clientMonitor; } - public final void read(TerminalState state) { - if (this.m_xIndex != 0 || this.m_yIndex != 0) { - ComputerCraft.log.warn("Receiving monitor state for non-origin terminal at {}", this.getPos()); + public final void read( TerminalState state ) + { + if( this.m_xIndex != 0 || this.m_yIndex != 0 ) + { + ComputerCraft.log.warn( "Receiving monitor state for non-origin terminal at {}", this.getPos() ); return; } - if (this.m_clientMonitor == null) { - this.m_clientMonitor = new ClientMonitor(this.advanced, this); + if( this.m_clientMonitor == null ) + { + this.m_clientMonitor = new ClientMonitor( this.advanced, this ); } - this.m_clientMonitor.read(state); + this.m_clientMonitor.read( state ); } - private void updateBlockState() { - this.getWorld().setBlockState(this.getPos(), - this.getCachedState().with(BlockMonitor.STATE, - MonitorEdgeState.fromConnections(this.m_yIndex < this.m_height - 1, - this.m_yIndex > 0, this.m_xIndex > 0, this.m_xIndex < this.m_width - 1)), - 2); + private void updateBlockState() + { + this.getWorld().setBlockState( this.getPos(), + this.getCachedState().with( BlockMonitor.STATE, + MonitorEdgeState.fromConnections( this.m_yIndex < this.m_height - 1, + this.m_yIndex > 0, this.m_xIndex > 0, this.m_xIndex < this.m_width - 1 ) ), + 2 ); } - public Direction getFront() { + public Direction getFront() + { Direction orientation = this.getOrientation(); return orientation == Direction.NORTH ? this.getDirection() : orientation; } - public int getWidth() { + public int getWidth() + { return this.m_width; } - public int getHeight() { + public int getHeight() + { return this.m_height; } - public int getXIndex() { + public int getXIndex() + { return this.m_xIndex; } - public int getYIndex() { + public int getYIndex() + { return this.m_yIndex; } - private TileMonitor getOrigin() { - return this.getNeighbour(0, 0); + private TileMonitor getOrigin() + { + return this.getNeighbour( 0, 0 ); } - private void resize(int width, int height) { + private void resize( int width, int height ) + { // If we're not already the origin then we'll need to generate a new terminal. - if (this.m_xIndex != 0 || this.m_yIndex != 0) { + if( this.m_xIndex != 0 || this.m_yIndex != 0 ) + { this.m_serverMonitor = null; } @@ -425,10 +492,13 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { // out of date, boolean needsTerminal = false; terminalCheck: - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - TileMonitor monitor = this.getNeighbour(x, y); - if (monitor != null && monitor.peripheral != null) { + for( int x = 0; x < width; x++ ) + { + for( int y = 0; y < height; y++ ) + { + TileMonitor monitor = this.getNeighbour( x, y ); + if( monitor != null && monitor.peripheral != null ) + { needsTerminal = true; break terminalCheck; } @@ -436,25 +506,33 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } // Either delete the current monitor or sync a new one. - if (needsTerminal) { - if (this.m_serverMonitor == null) { - this.m_serverMonitor = new ServerMonitor(this.advanced, this); + if( needsTerminal ) + { + if( this.m_serverMonitor == null ) + { + this.m_serverMonitor = new ServerMonitor( this.advanced, this ); } - } else { + } + else + { this.m_serverMonitor = null; } // Update the terminal's width and height and rebuild it. This ensures the monitor // is consistent when syncing it to other monitors. - if (this.m_serverMonitor != null) { + if( this.m_serverMonitor != null ) + { this.m_serverMonitor.rebuild(); } // Update the other monitors, setting coordinates, dimensions and the server terminal - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - TileMonitor monitor = this.getNeighbour(x, y); - if (monitor == null) { + for( int x = 0; x < width; x++ ) + { + for( int y = 0; y < height; y++ ) + { + TileMonitor monitor = this.getNeighbour( x, y ); + if( monitor == null ) + { continue; } @@ -469,77 +547,93 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } } - private boolean mergeLeft() { - TileMonitor left = this.getNeighbour(-1, 0); - if (left == null || left.m_yIndex != 0 || left.m_height != this.m_height) { + private boolean mergeLeft() + { + TileMonitor left = this.getNeighbour( -1, 0 ); + if( left == null || left.m_yIndex != 0 || left.m_height != this.m_height ) + { return false; } int width = left.m_width + this.m_width; - if (width > ComputerCraft.monitorWidth) { + if( width > ComputerCraft.monitorWidth ) + { return false; } TileMonitor origin = left.getOrigin(); - if (origin != null) { - origin.resize(width, this.m_height); + if( origin != null ) + { + origin.resize( width, this.m_height ); } left.expand(); return true; } - private boolean mergeRight() { - TileMonitor right = this.getNeighbour(this.m_width, 0); - if (right == null || right.m_yIndex != 0 || right.m_height != this.m_height) { + private boolean mergeRight() + { + TileMonitor right = this.getNeighbour( this.m_width, 0 ); + if( right == null || right.m_yIndex != 0 || right.m_height != this.m_height ) + { return false; } int width = this.m_width + right.m_width; - if (width > ComputerCraft.monitorWidth) { + if( width > ComputerCraft.monitorWidth ) + { return false; } TileMonitor origin = this.getOrigin(); - if (origin != null) { - origin.resize(width, this.m_height); + if( origin != null ) + { + origin.resize( width, this.m_height ); } this.expand(); return true; } - private boolean mergeUp() { - TileMonitor above = this.getNeighbour(0, this.m_height); - if (above == null || above.m_xIndex != 0 || above.m_width != this.m_width) { + private boolean mergeUp() + { + TileMonitor above = this.getNeighbour( 0, this.m_height ); + if( above == null || above.m_xIndex != 0 || above.m_width != this.m_width ) + { return false; } int height = above.m_height + this.m_height; - if (height > ComputerCraft.monitorHeight) { + if( height > ComputerCraft.monitorHeight ) + { return false; } TileMonitor origin = this.getOrigin(); - if (origin != null) { - origin.resize(this.m_width, height); + if( origin != null ) + { + origin.resize( this.m_width, height ); } this.expand(); return true; } - private boolean mergeDown() { - TileMonitor below = this.getNeighbour(0, -1); - if (below == null || below.m_xIndex != 0 || below.m_width != this.m_width) { + private boolean mergeDown() + { + TileMonitor below = this.getNeighbour( 0, -1 ); + if( below == null || below.m_xIndex != 0 || below.m_width != this.m_width ) + { return false; } int height = this.m_height + below.m_height; - if (height > ComputerCraft.monitorHeight) { + if( height > ComputerCraft.monitorHeight ) + { return false; } TileMonitor origin = below.getOrigin(); - if (origin != null) { - origin.resize(this.m_width, height); + if( origin != null ) + { + origin.resize( this.m_width, height ); } below.expand(); return true; @@ -557,70 +651,90 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { expand(); } - @SuppressWarnings ("StatementWithEmptyBody") - void expand() { - while (this.mergeLeft() || this.mergeRight() || this.mergeUp() || this.mergeDown()) { + @SuppressWarnings( "StatementWithEmptyBody" ) + void expand() + { + while( this.mergeLeft() || this.mergeRight() || this.mergeUp() || this.mergeDown() ) + { } } - void contractNeighbours() { + void contractNeighbours() + { this.visiting = true; - if (this.m_xIndex > 0) { - TileMonitor left = this.getNeighbour(this.m_xIndex - 1, this.m_yIndex); - if (left != null) { + if( this.m_xIndex > 0 ) + { + TileMonitor left = this.getNeighbour( this.m_xIndex - 1, this.m_yIndex ); + if( left != null ) + { left.contract(); } } - if (this.m_xIndex + 1 < this.m_width) { - TileMonitor right = this.getNeighbour(this.m_xIndex + 1, this.m_yIndex); - if (right != null) { + if( this.m_xIndex + 1 < this.m_width ) + { + TileMonitor right = this.getNeighbour( this.m_xIndex + 1, this.m_yIndex ); + if( right != null ) + { right.contract(); } } - if (this.m_yIndex > 0) { - TileMonitor below = this.getNeighbour(this.m_xIndex, this.m_yIndex - 1); - if (below != null) { + if( this.m_yIndex > 0 ) + { + TileMonitor below = this.getNeighbour( this.m_xIndex, this.m_yIndex - 1 ); + if( below != null ) + { below.contract(); } } - if (this.m_yIndex + 1 < this.m_height) { - TileMonitor above = this.getNeighbour(this.m_xIndex, this.m_yIndex + 1); - if (above != null) { + if( this.m_yIndex + 1 < this.m_height ) + { + TileMonitor above = this.getNeighbour( this.m_xIndex, this.m_yIndex + 1 ); + if( above != null ) + { above.contract(); } } this.visiting = false; } - void contract() { + void contract() + { int height = this.m_height; int width = this.m_width; TileMonitor origin = this.getOrigin(); - if (origin == null) { - TileMonitor right = width > 1 ? this.getNeighbour(1, 0) : null; - TileMonitor below = height > 1 ? this.getNeighbour(0, 1) : null; + if( origin == null ) + { + TileMonitor right = width > 1 ? this.getNeighbour( 1, 0 ) : null; + TileMonitor below = height > 1 ? this.getNeighbour( 0, 1 ) : null; - if (right != null) { - right.resize(width - 1, 1); + if( right != null ) + { + right.resize( width - 1, 1 ); } - if (below != null) { - below.resize(width, height - 1); + if( below != null ) + { + below.resize( width, height - 1 ); } - if (right != null) { + if( right != null ) + { right.expand(); } - if (below != null) { + if( below != null ) + { below.expand(); } return; } - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - TileMonitor monitor = origin.getNeighbour(x, y); - if (monitor != null) { + for( int y = 0; y < height; y++ ) + { + for( int x = 0; x < width; x++ ) + { + TileMonitor monitor = origin.getNeighbour( x, y ); + if( monitor != null ) + { continue; } @@ -630,34 +744,42 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { TileMonitor right = null; TileMonitor below = null; - if (y > 0) { + if( y > 0 ) + { above = origin; - above.resize(width, y); + above.resize( width, y ); } - if (x > 0) { - left = origin.getNeighbour(0, y); - left.resize(x, 1); + if( x > 0 ) + { + left = origin.getNeighbour( 0, y ); + left.resize( x, 1 ); } - if (x + 1 < width) { - right = origin.getNeighbour(x + 1, y); - right.resize(width - (x + 1), 1); + if( x + 1 < width ) + { + right = origin.getNeighbour( x + 1, y ); + right.resize( width - (x + 1), 1 ); } - if (y + 1 < height) { - below = origin.getNeighbour(0, y + 1); - below.resize(width, height - (y + 1)); + if( y + 1 < height ) + { + below = origin.getNeighbour( 0, y + 1 ); + below.resize( width, height - (y + 1) ); } // Re-expand - if (above != null) { + if( above != null ) + { above.expand(); } - if (left != null) { + if( left != null ) + { left.expand(); } - if (right != null) { + if( right != null ) + { right.expand(); } - if (below != null) { + if( below != null ) + { below.expand(); } return; @@ -666,46 +788,55 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { } // endregion - private void monitorTouched(float xPos, float yPos, float zPos) { - XYPair pair = XYPair.of(xPos, yPos, zPos, this.getDirection(), this.getOrientation()) - .add(this.m_xIndex, this.m_height - this.m_yIndex - 1); + private void monitorTouched( float xPos, float yPos, float zPos ) + { + XYPair pair = XYPair.of( xPos, yPos, zPos, this.getDirection(), this.getOrientation() ) + .add( this.m_xIndex, this.m_height - this.m_yIndex - 1 ); - if (pair.x > this.m_width - RENDER_BORDER || pair.y > this.m_height - RENDER_BORDER || pair.x < RENDER_BORDER || pair.y < RENDER_BORDER) { + if( pair.x > this.m_width - RENDER_BORDER || pair.y > this.m_height - RENDER_BORDER || pair.x < RENDER_BORDER || pair.y < RENDER_BORDER ) + { return; } ServerTerminal serverTerminal = this.getServerMonitor(); - if (serverTerminal == null || !serverTerminal.isColour()) { + if( serverTerminal == null || !serverTerminal.isColour() ) + { return; } Terminal originTerminal = serverTerminal.getTerminal(); - if (originTerminal == null) { + if( originTerminal == null ) + { return; } double xCharWidth = (this.m_width - (RENDER_BORDER + RENDER_MARGIN) * 2.0) / originTerminal.getWidth(); double yCharHeight = (this.m_height - (RENDER_BORDER + RENDER_MARGIN) * 2.0) / originTerminal.getHeight(); - int xCharPos = (int) Math.min(originTerminal.getWidth(), Math.max((pair.x - RENDER_BORDER - RENDER_MARGIN) / xCharWidth + 1.0, 1.0)); - int yCharPos = (int) Math.min(originTerminal.getHeight(), Math.max((pair.y - RENDER_BORDER - RENDER_MARGIN) / yCharHeight + 1.0, 1.0)); + int xCharPos = (int) Math.min( originTerminal.getWidth(), Math.max( (pair.x - RENDER_BORDER - RENDER_MARGIN) / xCharWidth + 1.0, 1.0 ) ); + int yCharPos = (int) Math.min( originTerminal.getHeight(), Math.max( (pair.y - RENDER_BORDER - RENDER_MARGIN) / yCharHeight + 1.0, 1.0 ) ); - for (int y = 0; y < this.m_height; y++) { - for (int x = 0; x < this.m_width; x++) { - TileMonitor monitor = this.getNeighbour(x, y); - if (monitor == null) { + for( int y = 0; y < this.m_height; y++ ) + { + for( int x = 0; x < this.m_width; x++ ) + { + TileMonitor monitor = this.getNeighbour( x, y ); + if( monitor == null ) + { continue; } - for (IComputerAccess computer : monitor.m_computers) { - computer.queueEvent("monitor_touch", computer.getAttachmentName(), xCharPos, yCharPos); + for( IComputerAccess computer : monitor.m_computers ) + { + computer.queueEvent( "monitor_touch", computer.getAttachmentName(), xCharPos, yCharPos ); } } } } - void addComputer(IComputerAccess computer) { - this.m_computers.add(computer); + void addComputer( IComputerAccess computer ) + { + this.m_computers.add( computer ); } // @Nonnull @@ -733,7 +864,8 @@ public class TileMonitor extends TileGeneric implements IPeripheralTile { // } // } - void removeComputer(IComputerAccess computer) { - this.m_computers.remove(computer); + void removeComputer( IComputerAccess computer ) + { + this.m_computers.remove( computer ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/XYPair.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/XYPair.java index 894333766..8aa24a4b3 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/XYPair.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/XYPair.java @@ -8,59 +8,67 @@ package dan200.computercraft.shared.peripheral.monitor; import net.minecraft.util.math.Direction; -public class XYPair { +public class XYPair +{ public final float x; public final float y; - public XYPair(float x, float y) { + public XYPair( float x, float y ) + { this.x = x; this.y = y; } - public static XYPair of(float xPos, float yPos, float zPos, Direction facing, Direction orientation) { - switch (orientation) { - case NORTH: - switch (facing) { + public static XYPair of( float xPos, float yPos, float zPos, Direction facing, Direction orientation ) + { + switch( orientation ) + { case NORTH: - return new XYPair(1 - xPos, 1 - yPos); - case SOUTH: - return new XYPair(xPos, 1 - yPos); - case WEST: - return new XYPair(zPos, 1 - yPos); - case EAST: - return new XYPair(1 - zPos, 1 - yPos); - } - break; - case DOWN: - switch (facing) { - case NORTH: - return new XYPair(1 - xPos, zPos); - case SOUTH: - return new XYPair(xPos, 1 - zPos); - case WEST: - return new XYPair(zPos, xPos); - case EAST: - return new XYPair(1 - zPos, 1 - xPos); - } - break; - case UP: - switch (facing) { - case NORTH: - return new XYPair(1 - xPos, 1 - zPos); - case SOUTH: - return new XYPair(xPos, zPos); - case WEST: - return new XYPair(zPos, 1 - xPos); - case EAST: - return new XYPair(1 - zPos, xPos); - } - break; + switch( facing ) + { + case NORTH: + return new XYPair( 1 - xPos, 1 - yPos ); + case SOUTH: + return new XYPair( xPos, 1 - yPos ); + case WEST: + return new XYPair( zPos, 1 - yPos ); + case EAST: + return new XYPair( 1 - zPos, 1 - yPos ); + } + break; + case DOWN: + switch( facing ) + { + case NORTH: + return new XYPair( 1 - xPos, zPos ); + case SOUTH: + return new XYPair( xPos, 1 - zPos ); + case WEST: + return new XYPair( zPos, xPos ); + case EAST: + return new XYPair( 1 - zPos, 1 - xPos ); + } + break; + case UP: + switch( facing ) + { + case NORTH: + return new XYPair( 1 - xPos, 1 - zPos ); + case SOUTH: + return new XYPair( xPos, zPos ); + case WEST: + return new XYPair( zPos, 1 - xPos ); + case EAST: + return new XYPair( 1 - zPos, xPos ); + } + break; } - return new XYPair(xPos, zPos); + return new XYPair( xPos, zPos ); } - public XYPair add(float x, float y) { - return new XYPair(this.x + x, this.y + y); + public XYPair add( float x, float y ) + { + return new XYPair( this.x + x, this.y + y ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/BlockPrinter.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/BlockPrinter.java index 59e4cbb78..a9f91b35b 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/BlockPrinter.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/BlockPrinter.java @@ -6,12 +6,8 @@ package dan200.computercraft.shared.peripheral.printer; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.BlockGeneric; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -29,54 +25,68 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class BlockPrinter extends BlockGeneric { - static final BooleanProperty TOP = BooleanProperty.of("top"); - static final BooleanProperty BOTTOM = BooleanProperty.of("bottom"); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class BlockPrinter extends BlockGeneric +{ + static final BooleanProperty TOP = BooleanProperty.of( "top" ); + static final BooleanProperty BOTTOM = BooleanProperty.of( "bottom" ); private static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - public BlockPrinter(Settings settings) { - super(settings, ComputerCraftRegistry.ModTiles.PRINTER); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(FACING, Direction.NORTH) - .with(TOP, false) - .with(BOTTOM, false)); + public BlockPrinter( Settings settings ) + { + super( settings, ComputerCraftRegistry.ModTiles.PRINTER ); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( FACING, Direction.NORTH ) + .with( TOP, false ) + .with( BOTTOM, false ) ); } @Nullable @Override - public BlockState getPlacementState(ItemPlacementContext placement) { - return this.getDefaultState().with(FACING, - placement.getPlayerFacing() - .getOpposite()); + public BlockState getPlacementState( ItemPlacementContext placement ) + { + return this.getDefaultState().with( FACING, + placement.getPlayerFacing() + .getOpposite() ); } @Override - public void afterBreak(@Nonnull World world, @Nonnull PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity te - , @Nonnull ItemStack stack) { - if (te instanceof Nameable && ((Nameable) te).hasCustomName()) { - player.incrementStat(Stats.MINED.getOrCreateStat(this)); - player.addExhaustion(0.005F); + public void afterBreak( @Nonnull World world, @Nonnull PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity te + , @Nonnull ItemStack stack ) + { + if( te instanceof Nameable && ((Nameable) te).hasCustomName() ) + { + player.incrementStat( Stats.MINED.getOrCreateStat( this ) ); + player.addExhaustion( 0.005F ); - ItemStack result = new ItemStack(this); - result.setCustomName(((Nameable) te).getCustomName()); - dropStack(world, pos, result); - } else { - super.afterBreak(world, player, pos, state, te, stack); + ItemStack result = new ItemStack( this ); + result.setCustomName( ((Nameable) te).getCustomName() ); + dropStack( world, pos, result ); + } + else + { + super.afterBreak( world, player, pos, state, te, stack ); } } @Override - public void onPlaced(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, ItemStack stack) { - if (stack.hasCustomName()) { - BlockEntity tileentity = world.getBlockEntity(pos); - if (tileentity instanceof TilePrinter) { + public void onPlaced( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, LivingEntity placer, ItemStack stack ) + { + if( stack.hasCustomName() ) + { + BlockEntity tileentity = world.getBlockEntity( pos ); + if( tileentity instanceof TilePrinter ) + { ((TilePrinter) tileentity).customName = stack.getName(); } } } @Override - protected void appendProperties(StateManager.Builder properties) { - properties.add(FACING, TOP, BOTTOM); + protected void appendProperties( StateManager.Builder properties ) + { + properties.add( FACING, TOP, BOTTOM ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/ContainerPrinter.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/ContainerPrinter.java index 03f234f6b..f2f322e7e 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/ContainerPrinter.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/ContainerPrinter.java @@ -6,11 +6,8 @@ package dan200.computercraft.shared.peripheral.printer; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.util.SingleIntArray; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; @@ -21,99 +18,126 @@ import net.minecraft.screen.PropertyDelegate; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.Slot; -public class ContainerPrinter extends ScreenHandler { +import javax.annotation.Nonnull; + +public class ContainerPrinter extends ScreenHandler +{ private final Inventory inventory; private final PropertyDelegate properties; - public ContainerPrinter(int id, PlayerInventory player) { - this(id, player, new SimpleInventory(TilePrinter.SLOTS), new ArrayPropertyDelegate(1)); + public ContainerPrinter( int id, PlayerInventory player ) + { + this( id, player, new SimpleInventory( TilePrinter.SLOTS ), new ArrayPropertyDelegate( 1 ) ); } - private ContainerPrinter(int id, PlayerInventory player, Inventory inventory, PropertyDelegate properties) { - super(ComputerCraftRegistry.ModContainers.PRINTER, id); + private ContainerPrinter( int id, PlayerInventory player, Inventory inventory, PropertyDelegate properties ) + { + super( ComputerCraftRegistry.ModContainers.PRINTER, id ); this.properties = properties; this.inventory = inventory; - this.addProperties(properties); + this.addProperties( properties ); // Ink slot - this.addSlot(new Slot(inventory, 0, 13, 35)); + this.addSlot( new Slot( inventory, 0, 13, 35 ) ); // In-tray - for (int x = 0; x < 6; x++) { - this.addSlot(new Slot(inventory, x + 1, 61 + x * 18, 22)); + for( int x = 0; x < 6; x++ ) + { + this.addSlot( new Slot( inventory, x + 1, 61 + x * 18, 22 ) ); } // Out-tray - for (int x = 0; x < 6; x++) { - this.addSlot(new Slot(inventory, x + 7, 61 + x * 18, 49)); + for( int x = 0; x < 6; x++ ) + { + this.addSlot( new Slot( inventory, x + 7, 61 + x * 18, 49 ) ); } // Player inv - for (int y = 0; y < 3; y++) { - for (int x = 0; x < 9; x++) { - this.addSlot(new Slot(player, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); + for( int y = 0; y < 3; y++ ) + { + for( int x = 0; x < 9; x++ ) + { + this.addSlot( new Slot( player, x + y * 9 + 9, 8 + x * 18, 84 + y * 18 ) ); } } // Player hotbar - for (int x = 0; x < 9; x++) { - this.addSlot(new Slot(player, x, 8 + x * 18, 142)); + for( int x = 0; x < 9; x++ ) + { + this.addSlot( new Slot( player, x, 8 + x * 18, 142 ) ); } } - public ContainerPrinter(int id, PlayerInventory player, TilePrinter printer) { - this(id, player, printer, (SingleIntArray) (() -> printer.isPrinting() ? 1 : 0)); + public ContainerPrinter( int id, PlayerInventory player, TilePrinter printer ) + { + this( id, player, printer, (SingleIntArray) (() -> printer.isPrinting() ? 1 : 0) ); } - public boolean isPrinting() { - return this.properties.get(0) != 0; + public boolean isPrinting() + { + return this.properties.get( 0 ) != 0; } @Nonnull @Override - public ItemStack transferSlot(@Nonnull PlayerEntity player, int index) { - Slot slot = this.slots.get(index); - if (slot == null || !slot.hasStack()) { + public ItemStack transferSlot( @Nonnull PlayerEntity player, int index ) + { + Slot slot = this.slots.get( index ); + if( slot == null || !slot.hasStack() ) + { return ItemStack.EMPTY; } ItemStack stack = slot.getStack(); ItemStack result = stack.copy(); - if (index < 13) { + if( index < 13 ) + { // Transfer from printer to inventory - if (!this.insertItem(stack, 13, 49, true)) { + if( !this.insertItem( stack, 13, 49, true ) ) + { return ItemStack.EMPTY; } - } else { + } + else + { // Transfer from inventory to printer - if( TilePrinter.isInk( stack ) ) { - if (!this.insertItem(stack, 0, 1, false)) { + if( TilePrinter.isInk( stack ) ) + { + if( !this.insertItem( stack, 0, 1, false ) ) + { return ItemStack.EMPTY; } - } else //if is paper + } + else //if is paper { - if (!this.insertItem(stack, 1, 13, false)) { + if( !this.insertItem( stack, 1, 13, false ) ) + { return ItemStack.EMPTY; } } } - if (stack.isEmpty()) { - slot.setStack(ItemStack.EMPTY); - } else { + if( stack.isEmpty() ) + { + slot.setStack( ItemStack.EMPTY ); + } + else + { slot.markDirty(); } - if (stack.getCount() == result.getCount()) { + if( stack.getCount() == result.getCount() ) + { return ItemStack.EMPTY; } - slot.onTakeItem(player, stack); + slot.onTakeItem( player, stack ); return result; } @Override - public boolean canUse(@Nonnull PlayerEntity player) { - return this.inventory.canPlayerUse(player); + public boolean canUse( @Nonnull PlayerEntity player ) + { + return this.inventory.canPlayerUse( player ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java index aa3c2248a..e0cb64942 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.peripheral.printer; -import java.util.Optional; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; @@ -17,21 +13,27 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.util.StringUtil; +import javax.annotation.Nonnull; +import java.util.Optional; + /** * The printer peripheral allows pages and books to be printed. * * @cc.module printer */ -public class PrinterPeripheral implements IPeripheral { +public class PrinterPeripheral implements IPeripheral +{ private final TilePrinter printer; - public PrinterPeripheral(TilePrinter printer) { + public PrinterPeripheral( TilePrinter printer ) + { this.printer = printer; } @Nonnull @Override - public String getType() { + public String getType() + { return "printer"; } @@ -43,12 +45,14 @@ public class PrinterPeripheral implements IPeripheral { @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return this.printer; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other instanceof PrinterPeripheral && ((PrinterPeripheral) other).printer == this.printer; } @@ -60,18 +64,21 @@ public class PrinterPeripheral implements IPeripheral { * @cc.tparam string|number ... The values to write to the page. */ @LuaFunction - public final void write(IArguments arguments) throws LuaException { - String text = StringUtil.toString(arguments.get(0)); + public final void write( IArguments arguments ) throws LuaException + { + String text = StringUtil.toString( arguments.get( 0 ) ); Terminal page = this.getCurrentPage(); - page.write(text); - page.setCursorPos(page.getCursorX() + text.length(), page.getCursorY()); + page.write( text ); + page.setCursorPos( page.getCursorX() + text.length(), page.getCursorY() ); } @Nonnull - private Terminal getCurrentPage() throws LuaException { + private Terminal getCurrentPage() throws LuaException + { Terminal currentPage = this.printer.getCurrentPage(); - if (currentPage == null) { - throw new LuaException("Page not started"); + if( currentPage == null ) + { + throw new LuaException( "Page not started" ); } return currentPage; } @@ -85,7 +92,8 @@ public class PrinterPeripheral implements IPeripheral { * @cc.treturn number The Y position of the cursor. */ @LuaFunction - public final Object[] getCursorPos() throws LuaException { + public final Object[] getCursorPos() throws LuaException + { Terminal page = this.getCurrentPage(); int x = page.getCursorX(); int y = page.getCursorY(); @@ -103,9 +111,10 @@ public class PrinterPeripheral implements IPeripheral { * @throws LuaException If a page isn't being printed. */ @LuaFunction - public final void setCursorPos(int x, int y) throws LuaException { + public final void setCursorPos( int x, int y ) throws LuaException + { Terminal page = this.getCurrentPage(); - page.setCursorPos(x - 1, y - 1); + page.setCursorPos( x - 1, y - 1 ); } /** @@ -117,7 +126,8 @@ public class PrinterPeripheral implements IPeripheral { * @cc.treturn number The height of the page. */ @LuaFunction - public final Object[] getPageSize() throws LuaException { + public final Object[] getPageSize() throws LuaException + { Terminal page = this.getCurrentPage(); int width = page.getWidth(); int height = page.getHeight(); @@ -132,8 +142,9 @@ public class PrinterPeripheral implements IPeripheral { * * @return Whether a new page could be started. */ - @LuaFunction (mainThread = true) - public final boolean newPage() { + @LuaFunction( mainThread = true ) + public final boolean newPage() + { return this.printer.startNewPage(); } @@ -143,8 +154,9 @@ public class PrinterPeripheral implements IPeripheral { * @return Whether the page could be successfully finished. * @throws LuaException If a page isn't being printed. */ - @LuaFunction (mainThread = true) - public final boolean endPage() throws LuaException { + @LuaFunction( mainThread = true ) + public final boolean endPage() throws LuaException + { this.getCurrentPage(); return this.printer.endCurrentPage(); } @@ -156,9 +168,10 @@ public class PrinterPeripheral implements IPeripheral { * @throws LuaException If a page isn't being printed. */ @LuaFunction - public final void setPageTitle(Optional title) throws LuaException { + public final void setPageTitle( Optional title ) throws LuaException + { this.getCurrentPage(); - this.printer.setPageTitle(StringUtil.normaliseLabel(title.orElse(""))); + this.printer.setPageTitle( StringUtil.normaliseLabel( title.orElse( "" ) ) ); } /** @@ -167,7 +180,8 @@ public class PrinterPeripheral implements IPeripheral { * @return The amount of ink available to print with. */ @LuaFunction - public final int getInkLevel() { + public final int getInkLevel() + { return this.printer.getInkLevel(); } @@ -177,7 +191,8 @@ public class PrinterPeripheral implements IPeripheral { * @return The amount of paper available to print with. */ @LuaFunction - public final int getPaperLevel() { + public final int getPaperLevel() + { return this.printer.getPaperLevel(); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java index 0cbe6c45e..a5198248d 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java @@ -6,9 +6,6 @@ package dan200.computercraft.shared.peripheral.printer; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralTile; import dan200.computercraft.core.terminal.Terminal; @@ -18,13 +15,11 @@ import dan200.computercraft.shared.util.ColourUtils; import dan200.computercraft.shared.util.DefaultSidedInventory; import dan200.computercraft.shared.util.ItemStorage; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventories; -import net.minecraft.item.DyeItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -42,7 +37,11 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; -public final class TilePrinter extends TileGeneric implements DefaultSidedInventory, IPeripheralTile, Nameable, NamedScreenHandlerFactory { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public final class TilePrinter extends TileGeneric implements DefaultSidedInventory, IPeripheralTile, Nameable, NamedScreenHandlerFactory +{ static final int SLOTS = 13; private static final String NBT_NAME = "CustomName"; private static final String NBT_PRINTING = "Printing"; @@ -63,142 +62,169 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent 5, 6 }; - private static final int[] SIDE_SLOTS = new int[] {0}; - private final DefaultedList m_inventory = DefaultedList.ofSize(SLOTS, ItemStack.EMPTY); - private final ItemStorage m_itemHandlerAll = ItemStorage.wrap(this); - private final Terminal m_page = new Terminal(ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE); + private static final int[] SIDE_SLOTS = new int[] { 0 }; + private final DefaultedList m_inventory = DefaultedList.ofSize( SLOTS, ItemStack.EMPTY ); + private final ItemStorage m_itemHandlerAll = ItemStorage.wrap( this ); + private final Terminal m_page = new Terminal( ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE ); Text customName; private String m_pageTitle = ""; private boolean m_printing = false; - public TilePrinter(BlockEntityType type) { - super(type); + public TilePrinter( BlockEntityType type ) + { + super( type ); } @Override - public void destroy() { + public void destroy() + { this.ejectContents(); } @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { - if (player.isInSneakingPose()) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { + if( player.isInSneakingPose() ) + { return ActionResult.PASS; } - if (!this.getWorld().isClient) { - player.openHandledScreen(this); + if( !this.getWorld().isClient ) + { + player.openHandledScreen( this ); } return ActionResult.SUCCESS; } - private void ejectContents() { - for (int i = 0; i < 13; i++) { - ItemStack stack = this.m_inventory.get(i); - if (!stack.isEmpty()) { + private void ejectContents() + { + for( int i = 0; i < 13; i++ ) + { + ItemStack stack = this.m_inventory.get( i ); + if( !stack.isEmpty() ) + { // Remove the stack from the inventory - this.setStack(i, ItemStack.EMPTY); + this.setStack( i, ItemStack.EMPTY ); // Spawn the item in the world - WorldUtil.dropItemStack(stack, this.getWorld(), - Vec3d.of(this.getPos()) - .add(0.5, 0.75, 0.5)); + WorldUtil.dropItemStack( stack, this.getWorld(), + Vec3d.of( this.getPos() ) + .add( 0.5, 0.75, 0.5 ) ); } } } - private void updateBlockState() { + private void updateBlockState() + { boolean top = false, bottom = false; - for (int i = 1; i < 7; i++) { - ItemStack stack = this.m_inventory.get(i); - if (!stack.isEmpty() && isPaper(stack)) { + for( int i = 1; i < 7; i++ ) + { + ItemStack stack = this.m_inventory.get( i ); + if( !stack.isEmpty() && isPaper( stack ) ) + { top = true; break; } } - for (int i = 7; i < 13; i++) { - ItemStack stack = this.m_inventory.get(i); - if (!stack.isEmpty() && isPaper(stack)) { + for( int i = 7; i < 13; i++ ) + { + ItemStack stack = this.m_inventory.get( i ); + if( !stack.isEmpty() && isPaper( stack ) ) + { bottom = true; break; } } - this.updateBlockState(top, bottom); + this.updateBlockState( top, bottom ); } - private static boolean isPaper(@Nonnull ItemStack stack) { + private static boolean isPaper( @Nonnull ItemStack stack ) + { Item item = stack.getItem(); return item == Items.PAPER || (item instanceof ItemPrintout && ((ItemPrintout) item).getType() == ItemPrintout.Type.PAGE); } - private void updateBlockState(boolean top, boolean bottom) { - if (this.removed) { + private void updateBlockState( boolean top, boolean bottom ) + { + if( this.removed ) + { return; } BlockState state = this.getCachedState(); - if (state.get(BlockPrinter.TOP) == top & state.get(BlockPrinter.BOTTOM) == bottom) { + if( state.get( BlockPrinter.TOP ) == top & state.get( BlockPrinter.BOTTOM ) == bottom ) + { return; } - this.getWorld().setBlockState(this.getPos(), - state.with(BlockPrinter.TOP, top) - .with(BlockPrinter.BOTTOM, bottom)); + this.getWorld().setBlockState( this.getPos(), + state.with( BlockPrinter.TOP, top ) + .with( BlockPrinter.BOTTOM, bottom ) ); } @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); - this.customName = nbt.contains(NBT_NAME) ? Text.Serializer.fromJson(nbt.getString(NBT_NAME)) : null; + this.customName = nbt.contains( NBT_NAME ) ? Text.Serializer.fromJson( nbt.getString( NBT_NAME ) ) : null; // Read page - synchronized (this.m_page) { - this.m_printing = nbt.getBoolean(NBT_PRINTING); - this.m_pageTitle = nbt.getString(NBT_PAGE_TITLE); - this.m_page.readFromNBT(nbt); + synchronized( this.m_page ) + { + this.m_printing = nbt.getBoolean( NBT_PRINTING ); + this.m_pageTitle = nbt.getString( NBT_PAGE_TITLE ); + this.m_page.readFromNBT( nbt ); } // Read inventory - Inventories.fromTag(nbt, this.m_inventory); + Inventories.fromTag( nbt, this.m_inventory ); } @Nonnull @Override - public CompoundTag toTag(@Nonnull CompoundTag nbt) { - if (this.customName != null) { - nbt.putString(NBT_NAME, Text.Serializer.toJson(this.customName)); + public CompoundTag toTag( @Nonnull CompoundTag nbt ) + { + if( this.customName != null ) + { + nbt.putString( NBT_NAME, Text.Serializer.toJson( this.customName ) ); } // Write page - synchronized (this.m_page) { - nbt.putBoolean(NBT_PRINTING, this.m_printing); - nbt.putString(NBT_PAGE_TITLE, this.m_pageTitle); - this.m_page.writeToNBT(nbt); + synchronized( this.m_page ) + { + nbt.putBoolean( NBT_PRINTING, this.m_printing ); + nbt.putString( NBT_PAGE_TITLE, this.m_pageTitle ); + this.m_page.writeToNBT( nbt ); } // Write inventory - Inventories.toTag(nbt, this.m_inventory); + Inventories.toTag( nbt, this.m_inventory ); - return super.toTag(nbt); + return super.toTag( nbt ); } - boolean isPrinting() { + boolean isPrinting() + { return this.m_printing; } // IInventory implementation @Override - public int size() { + public int size() + { return this.m_inventory.size(); } @Override - public boolean isEmpty() { - for (ItemStack stack : this.m_inventory) { - if (!stack.isEmpty()) { + public boolean isEmpty() + { + for( ItemStack stack : this.m_inventory ) + { + if( !stack.isEmpty() ) + { return false; } } @@ -207,27 +233,32 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent @Nonnull @Override - public ItemStack getStack(int slot) { - return this.m_inventory.get(slot); + public ItemStack getStack( int slot ) + { + return this.m_inventory.get( slot ); } @Nonnull @Override - public ItemStack removeStack(int slot, int count) { - ItemStack stack = this.m_inventory.get(slot); - if (stack.isEmpty()) { + public ItemStack removeStack( int slot, int count ) + { + ItemStack stack = this.m_inventory.get( slot ); + if( stack.isEmpty() ) + { return ItemStack.EMPTY; } - if (stack.getCount() <= count) { - this.setStack(slot, ItemStack.EMPTY); + if( stack.getCount() <= count ) + { + this.setStack( slot, ItemStack.EMPTY ); return stack; } - ItemStack part = stack.split(count); - if (this.m_inventory.get(slot) - .isEmpty()) { - this.m_inventory.set(slot, ItemStack.EMPTY); + ItemStack part = stack.split( count ); + if( this.m_inventory.get( slot ) + .isEmpty() ) + { + this.m_inventory.set( slot, ItemStack.EMPTY ); this.updateBlockState(); } this.markDirty(); @@ -236,9 +267,10 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent @Nonnull @Override - public ItemStack removeStack(int slot) { - ItemStack result = this.m_inventory.get(slot); - this.m_inventory.set(slot, ItemStack.EMPTY); + public ItemStack removeStack( int slot ) + { + ItemStack result = this.m_inventory.get( slot ); + this.m_inventory.set( slot, ItemStack.EMPTY ); this.markDirty(); this.updateBlockState(); return result; @@ -247,101 +279,127 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent // ISidedInventory implementation @Override - public void setStack(int slot, @Nonnull ItemStack stack) { - this.m_inventory.set(slot, stack); + public void setStack( int slot, @Nonnull ItemStack stack ) + { + this.m_inventory.set( slot, stack ); this.markDirty(); this.updateBlockState(); } @Override - public boolean canPlayerUse(@Nonnull PlayerEntity playerEntity) { - return this.isUsable(playerEntity, false); + public boolean canPlayerUse( @Nonnull PlayerEntity playerEntity ) + { + return this.isUsable( playerEntity, false ); } @Override - public void clear() { - for (int i = 0; i < this.m_inventory.size(); i++) { - this.m_inventory.set(i, ItemStack.EMPTY); + public void clear() + { + for( int i = 0; i < this.m_inventory.size(); i++ ) + { + this.m_inventory.set( i, ItemStack.EMPTY ); } this.markDirty(); this.updateBlockState(); } @Override - public boolean isValid(int slot, @Nonnull ItemStack stack) { - if (slot == 0) { - return isInk(stack); - } else if (slot >= TOP_SLOTS[0] && slot <= TOP_SLOTS[TOP_SLOTS.length - 1]) { - return isPaper(stack); - } else { + public boolean isValid( int slot, @Nonnull ItemStack stack ) + { + if( slot == 0 ) + { + return isInk( stack ); + } + else if( slot >= TOP_SLOTS[0] && slot <= TOP_SLOTS[TOP_SLOTS.length - 1] ) + { + return isPaper( stack ); + } + else + { return false; } } - static boolean isInk(@Nonnull ItemStack stack) { + static boolean isInk( @Nonnull ItemStack stack ) + { return ColourUtils.getStackColour( stack ) != null; } @Nonnull @Override - public int[] getAvailableSlots(@Nonnull Direction side) { - switch (side) { - case DOWN: // Bottom (Out tray) - return BOTTOM_SLOTS; - case UP: // Top (In tray) - return TOP_SLOTS; - default: // Sides (Ink) - return SIDE_SLOTS; + public int[] getAvailableSlots( @Nonnull Direction side ) + { + switch( side ) + { + case DOWN: // Bottom (Out tray) + return BOTTOM_SLOTS; + case UP: // Top (In tray) + return TOP_SLOTS; + default: // Sides (Ink) + return SIDE_SLOTS; } } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { - return new PrinterPeripheral(this); + public IPeripheral getPeripheral( Direction side ) + { + return new PrinterPeripheral( this ); } @Nullable - Terminal getCurrentPage() { - synchronized (this.m_page) { + Terminal getCurrentPage() + { + synchronized( this.m_page ) + { return this.m_printing ? this.m_page : null; } } - boolean startNewPage() { - synchronized (this.m_page) { - if (!this.canInputPage()) { + boolean startNewPage() + { + synchronized( this.m_page ) + { + if( !this.canInputPage() ) + { return false; } - if (this.m_printing && !this.outputPage()) { + if( this.m_printing && !this.outputPage() ) + { return false; } return this.inputPage(); } } - boolean endCurrentPage() { - synchronized (this.m_page) { + boolean endCurrentPage() + { + synchronized( this.m_page ) + { return this.m_printing && this.outputPage(); } } - private boolean outputPage() { + private boolean outputPage() + { int height = this.m_page.getHeight(); String[] lines = new String[height]; String[] colours = new String[height]; - for (int i = 0; i < height; i++) { - lines[i] = this.m_page.getLine(i) - .toString(); - colours[i] = this.m_page.getTextColourLine(i) - .toString(); + for( int i = 0; i < height; i++ ) + { + lines[i] = this.m_page.getLine( i ) + .toString(); + colours[i] = this.m_page.getTextColourLine( i ) + .toString(); } - ItemStack stack = ItemPrintout.createSingleFromTitleAndText(this.m_pageTitle, lines, colours); - for (int slot : BOTTOM_SLOTS) { - if (this.m_inventory.get(slot) - .isEmpty()) { - this.setStack(slot, stack); + ItemStack stack = ItemPrintout.createSingleFromTitleAndText( this.m_pageTitle, lines, colours ); + for( int slot : BOTTOM_SLOTS ) + { + if( this.m_inventory.get( slot ) + .isEmpty() ) + { + this.setStack( slot, stack ); this.m_printing = false; return true; } @@ -349,43 +407,54 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent return false; } - int getInkLevel() { - ItemStack inkStack = this.m_inventory.get(0); - return isInk(inkStack) ? inkStack.getCount() : 0; + int getInkLevel() + { + ItemStack inkStack = this.m_inventory.get( 0 ); + return isInk( inkStack ) ? inkStack.getCount() : 0; } - int getPaperLevel() { + int getPaperLevel() + { int count = 0; - for (int i = 1; i < 7; i++) { - ItemStack paperStack = this.m_inventory.get(i); - if (isPaper(paperStack)) { + for( int i = 1; i < 7; i++ ) + { + ItemStack paperStack = this.m_inventory.get( i ); + if( isPaper( paperStack ) ) + { count += paperStack.getCount(); } } return count; } - void setPageTitle(String title) { - synchronized (this.m_page) { - if (this.m_printing) { + void setPageTitle( String title ) + { + synchronized( this.m_page ) + { + if( this.m_printing ) + { this.m_pageTitle = title; } } } - private boolean canInputPage() { - ItemStack inkStack = this.m_inventory.get(0); - return !inkStack.isEmpty() && isInk(inkStack) && this.getPaperLevel() > 0; + private boolean canInputPage() + { + ItemStack inkStack = this.m_inventory.get( 0 ); + return !inkStack.isEmpty() && isInk( inkStack ) && this.getPaperLevel() > 0; } - private boolean inputPage() { - ItemStack inkStack = this.m_inventory.get(0); + private boolean inputPage() + { + ItemStack inkStack = this.m_inventory.get( 0 ); DyeColor dye = ColourUtils.getStackColour( inkStack ); if( dye == null ) return false; - for (int i = 1; i < 7; i++) { - ItemStack paperStack = this.m_inventory.get(i); - if (paperStack.isEmpty() || !isPaper(paperStack)) { + for( int i = 1; i < 7; i++ ) + { + ItemStack paperStack = this.m_inventory.get( i ); + if( paperStack.isEmpty() || !isPaper( paperStack ) ) + { continue; } @@ -393,28 +462,34 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent m_page.setTextColour( dye.getId() ); this.m_page.clear(); - if (paperStack.getItem() instanceof ItemPrintout) { - this.m_pageTitle = ItemPrintout.getTitle(paperStack); - String[] text = ItemPrintout.getText(paperStack); - String[] textColour = ItemPrintout.getColours(paperStack); - for (int y = 0; y < this.m_page.getHeight(); y++) { - this.m_page.setLine(y, text[y], textColour[y], ""); + if( paperStack.getItem() instanceof ItemPrintout ) + { + this.m_pageTitle = ItemPrintout.getTitle( paperStack ); + String[] text = ItemPrintout.getText( paperStack ); + String[] textColour = ItemPrintout.getColours( paperStack ); + for( int y = 0; y < this.m_page.getHeight(); y++ ) + { + this.m_page.setLine( y, text[y], textColour[y], "" ); } - } else { + } + else + { this.m_pageTitle = ""; } - this.m_page.setCursorPos(0, 0); + this.m_page.setCursorPos( 0, 0 ); // Decrement ink - inkStack.decrement(1); - if (inkStack.isEmpty()) { - this.m_inventory.set(0, ItemStack.EMPTY); + inkStack.decrement( 1 ); + if( inkStack.isEmpty() ) + { + this.m_inventory.set( 0, ItemStack.EMPTY ); } // Decrement paper - paperStack.decrement(1); - if (paperStack.isEmpty()) { - this.m_inventory.set(i, ItemStack.EMPTY); + paperStack.decrement( 1 ); + if( paperStack.isEmpty() ) + { + this.m_inventory.set( i, ItemStack.EMPTY ); this.updateBlockState(); } @@ -427,30 +502,35 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent @Nonnull @Override - public Text getName() { - return this.customName != null ? this.customName : new TranslatableText(this.getCachedState().getBlock() - .getTranslationKey()); + public Text getName() + { + return this.customName != null ? this.customName : new TranslatableText( this.getCachedState().getBlock() + .getTranslationKey() ); } @Override - public boolean hasCustomName() { + public boolean hasCustomName() + { return this.customName != null; } @Override - public Text getDisplayName() { + public Text getDisplayName() + { return Nameable.super.getDisplayName(); } @Nullable @Override - public Text getCustomName() { + public Text getCustomName() + { return this.customName; } @Nonnull @Override - public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player) { - return new ContainerPrinter(id, inventory, this); + public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player ) + { + return new ContainerPrinter( id, inventory, this ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/BlockSpeaker.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/BlockSpeaker.java index 9b076a19e..366d82d76 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/BlockSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/BlockSpeaker.java @@ -6,11 +6,8 @@ package dan200.computercraft.shared.peripheral.speaker; -import javax.annotation.Nullable; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.common.BlockGeneric; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.item.ItemPlacementContext; @@ -19,25 +16,31 @@ import net.minecraft.state.property.DirectionProperty; import net.minecraft.state.property.Properties; import net.minecraft.util.math.Direction; -public class BlockSpeaker extends BlockGeneric { +import javax.annotation.Nullable; + +public class BlockSpeaker extends BlockGeneric +{ private static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - public BlockSpeaker(Settings settings) { - super(settings, ComputerCraftRegistry.ModTiles.SPEAKER); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(FACING, Direction.NORTH)); + public BlockSpeaker( Settings settings ) + { + super( settings, ComputerCraftRegistry.ModTiles.SPEAKER ); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( FACING, Direction.NORTH ) ); } @Nullable @Override - public BlockState getPlacementState(ItemPlacementContext placement) { - return this.getDefaultState().with(FACING, - placement.getPlayerFacing() - .getOpposite()); + public BlockState getPlacementState( ItemPlacementContext placement ) + { + return this.getDefaultState().with( FACING, + placement.getPlayerFacing() + .getOpposite() ); } @Override - protected void appendProperties(StateManager.Builder properties) { - properties.add(FACING); + protected void appendProperties( StateManager.Builder properties ) + { + properties.add( FACING ); } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index c39a750a5..2e9ffe3b5 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -6,20 +6,12 @@ package dan200.computercraft.shared.peripheral.speaker; -import static dan200.computercraft.api.lua.LuaValues.checkFinite; - -import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.fabric.mixin.SoundEventAccess; - import net.minecraft.block.enums.Instrument; import net.minecraft.network.packet.s2c.play.PlaySoundIdS2CPacket; import net.minecraft.server.MinecraftServer; @@ -29,28 +21,38 @@ import net.minecraft.util.InvalidIdentifierException; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import javax.annotation.Nonnull; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; + +import static dan200.computercraft.api.lua.LuaValues.checkFinite; + /** * Speakers allow playing notes and other sounds. * * @cc.module speaker */ -public abstract class SpeakerPeripheral implements IPeripheral { +public abstract class SpeakerPeripheral implements IPeripheral +{ private final AtomicInteger m_notesThisTick = new AtomicInteger(); private long m_clock = 0; private long m_lastPlayTime = 0; - public void update() { + public void update() + { this.m_clock++; - this.m_notesThisTick.set(0); + this.m_notesThisTick.set( 0 ); } - public boolean madeSound(long ticks) { + public boolean madeSound( long ticks ) + { return this.m_clock - this.m_lastPlayTime <= ticks; } @Nonnull @Override - public String getType() { + public String getType() + { return "speaker"; } @@ -61,29 +63,35 @@ public abstract class SpeakerPeripheral implements IPeripheral { * minecraft:block.note_block.harp}) with an optional volume and speed multiplier, and plays it through the speaker. * * @param context The Lua context - * @param name The name of the sound to play. + * @param name The name of the sound to play. * @param volumeA The volume to play the sound at, from 0.0 to 3.0. Defaults to 1.0. - * @param pitchA The speed to play the sound at, from 0.5 to 2.0. Defaults to 1.0. + * @param pitchA The speed to play the sound at, from 0.5 to 2.0. Defaults to 1.0. * @return Whether the sound could be played. * @throws LuaException If the sound name couldn't be decoded. */ @LuaFunction - public final boolean playSound(ILuaContext context, String name, Optional volumeA, Optional pitchA) throws LuaException { - float volume = (float) checkFinite(1, volumeA.orElse(1.0)); - float pitch = (float) checkFinite(2, pitchA.orElse(1.0)); + public final boolean playSound( ILuaContext context, String name, Optional volumeA, Optional pitchA ) throws LuaException + { + float volume = (float) checkFinite( 1, volumeA.orElse( 1.0 ) ); + float pitch = (float) checkFinite( 2, pitchA.orElse( 1.0 ) ); Identifier identifier; - try { - identifier = new Identifier(name); - } catch (InvalidIdentifierException e) { - throw new LuaException("Malformed sound name '" + name + "' "); + try + { + identifier = new Identifier( name ); + } + catch( InvalidIdentifierException e ) + { + throw new LuaException( "Malformed sound name '" + name + "' " ); } - return this.playSound(context, identifier, volume, pitch, false); + return this.playSound( context, identifier, volume, pitch, false ); } - private synchronized boolean playSound(ILuaContext context, Identifier name, float volume, float pitch, boolean isNote) throws LuaException { - if (this.m_clock - this.m_lastPlayTime < TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS && (!isNote || this.m_clock - this.m_lastPlayTime != 0 || this.m_notesThisTick.get() >= ComputerCraft.maxNotesPerTick)) { + private synchronized boolean playSound( ILuaContext context, Identifier name, float volume, float pitch, boolean isNote ) throws LuaException + { + if( this.m_clock - this.m_lastPlayTime < TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS && (!isNote || this.m_clock - this.m_lastPlayTime != 0 || this.m_notesThisTick.get() >= ComputerCraft.maxNotesPerTick) ) + { // Rate limiting occurs when we've already played a sound within the last tick, or we've // played more notes than allowable within the current tick. return false; @@ -92,23 +100,24 @@ public abstract class SpeakerPeripheral implements IPeripheral { World world = this.getWorld(); Vec3d pos = this.getPosition(); - context.issueMainThreadTask(() -> { + context.issueMainThreadTask( () -> { MinecraftServer server = world.getServer(); - if (server == null) { + if( server == null ) + { return null; } - float adjVolume = Math.min(volume, 3.0f); + float adjVolume = Math.min( volume, 3.0f ); server.getPlayerManager() - .sendToAround(null, + .sendToAround( null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.getRegistryKey(), - new PlaySoundIdS2CPacket(name, SoundCategory.RECORDS, pos, adjVolume, pitch)); + new PlaySoundIdS2CPacket( name, SoundCategory.RECORDS, pos, adjVolume, pitch ) ); return null; - }); + } ); this.m_lastPlayTime = this.m_clock; return true; @@ -127,38 +136,43 @@ public abstract class SpeakerPeripheral implements IPeripheral { * and 6 and 18 map to C. * * @param context The Lua context - * @param name The name of the note to play. + * @param name The name of the note to play. * @param volumeA The volume to play the note at, from 0.0 to 3.0. Defaults to 1.0. - * @param pitchA The pitch to play the note at in semitones, from 0 to 24. Defaults to 12. + * @param pitchA The pitch to play the note at in semitones, from 0 to 24. Defaults to 12. * @return Whether the note could be played. * @throws LuaException If the instrument doesn't exist. */ @LuaFunction - public final synchronized boolean playNote(ILuaContext context, String name, Optional volumeA, Optional pitchA) throws LuaException { - float volume = (float) checkFinite(1, volumeA.orElse(1.0)); - float pitch = (float) checkFinite(2, pitchA.orElse(1.0)); + public final synchronized boolean playNote( ILuaContext context, String name, Optional volumeA, Optional pitchA ) throws LuaException + { + float volume = (float) checkFinite( 1, volumeA.orElse( 1.0 ) ); + float pitch = (float) checkFinite( 2, pitchA.orElse( 1.0 ) ); Instrument instrument = null; - for (Instrument testInstrument : Instrument.values()) { - if (testInstrument.asString() - .equalsIgnoreCase(name)) { + for( Instrument testInstrument : Instrument.values() ) + { + if( testInstrument.asString() + .equalsIgnoreCase( name ) ) + { instrument = testInstrument; break; } } // Check if the note exists - if (instrument == null) { - throw new LuaException("Invalid instrument, \"" + name + "\"!"); + if( instrument == null ) + { + throw new LuaException( "Invalid instrument, \"" + name + "\"!" ); } // If the resource location for note block notes changes, this method call will need to be updated - boolean success = this.playSound(context, - ((SoundEventAccess)instrument.getSound()).getId(), + boolean success = this.playSound( context, + ((SoundEventAccess) instrument.getSound()).getId(), volume, - (float) Math.pow(2.0, (pitch - 12.0) / 12.0), - true); - if (success) { + (float) Math.pow( 2.0, (pitch - 12.0) / 12.0 ), + true ); + if( success ) + { this.m_notesThisTick.incrementAndGet(); } return success; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java index 5c5578b7c..9b0bda5a3 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/TileSpeaker.java @@ -6,13 +6,9 @@ package dan200.computercraft.shared.peripheral.speaker; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralTile; import dan200.computercraft.shared.common.TileGeneric; - import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.Tickable; import net.minecraft.util.math.BlockPos; @@ -20,47 +16,59 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class TileSpeaker extends TileGeneric implements Tickable, IPeripheralTile { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class TileSpeaker extends TileGeneric implements Tickable, IPeripheralTile +{ public static final int MIN_TICKS_BETWEEN_SOUNDS = 1; private final SpeakerPeripheral peripheral; - public TileSpeaker(BlockEntityType type) { - super(type); - this.peripheral = new Peripheral(this); + public TileSpeaker( BlockEntityType type ) + { + super( type ); + this.peripheral = new Peripheral( this ); } @Override - public void tick() { + public void tick() + { this.peripheral.update(); } @Nonnull @Override - public IPeripheral getPeripheral(Direction side) { + public IPeripheral getPeripheral( Direction side ) + { return this.peripheral; } - private static final class Peripheral extends SpeakerPeripheral { + private static final class Peripheral extends SpeakerPeripheral + { private final TileSpeaker speaker; - private Peripheral(TileSpeaker speaker) { + private Peripheral( TileSpeaker speaker ) + { this.speaker = speaker; } @Override - public World getWorld() { + public World getWorld() + { return this.speaker.getWorld(); } @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { BlockPos pos = this.speaker.getPos(); - return new Vec3d(pos.getX(), pos.getY(), pos.getZ()); + return new Vec3d( pos.getX(), pos.getY(), pos.getZ() ); } @Override - public boolean equals(@Nullable IPeripheral other) { + public boolean equals( @Nullable IPeripheral other ) + { return this == other || (other instanceof Peripheral && this.speaker == ((Peripheral) other).speaker); } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java index b2c3a8f36..55b9168b6 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java +++ b/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java @@ -14,7 +14,6 @@ import dan200.computercraft.shared.pocket.core.PocketServerComputer; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.ItemStorage; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; @@ -36,16 +35,19 @@ import net.minecraft.util.collection.DefaultedList; * * @cc.module pocket */ -public class PocketAPI implements ILuaAPI { +public class PocketAPI implements ILuaAPI +{ private final PocketServerComputer computer; - public PocketAPI(PocketServerComputer computer) { + public PocketAPI( PocketServerComputer computer ) + { this.computer = computer; } @Override - public String[] getNames() { - return new String[] {"pocket"}; + public String[] getNames() + { + return new String[] { "pocket" }; } /** @@ -57,10 +59,12 @@ public class PocketAPI implements ILuaAPI { * @cc.treturn boolean If an item was equipped. * @cc.treturn string|nil The reason an item was not equipped. */ - @LuaFunction (mainThread = true) - public final Object[] equipBack() { + @LuaFunction( mainThread = true ) + public final Object[] equipBack() + { Entity entity = this.computer.getEntity(); - if (!(entity instanceof PlayerEntity)) { + if( !(entity instanceof PlayerEntity) ) + { return new Object[] { false, "Cannot find player" @@ -72,11 +76,13 @@ public class PocketAPI implements ILuaAPI { // Attempt to find the upgrade, starting in the main segment, and then looking in the opposite // one. We start from the position the item is currently in and loop round to the start. - IPocketUpgrade newUpgrade = findUpgrade(inventory.main, inventory.selectedSlot, previousUpgrade); - if (newUpgrade == null) { - newUpgrade = findUpgrade(inventory.offHand, 0, previousUpgrade); + IPocketUpgrade newUpgrade = findUpgrade( inventory.main, inventory.selectedSlot, previousUpgrade ); + if( newUpgrade == null ) + { + newUpgrade = findUpgrade( inventory.offHand, 0, previousUpgrade ); } - if (newUpgrade == null) { + if( newUpgrade == null ) + { return new Object[] { false, "Cannot find a valid upgrade" @@ -84,33 +90,40 @@ public class PocketAPI implements ILuaAPI { } // Remove the current upgrade - if (previousUpgrade != null) { + if( previousUpgrade != null ) + { ItemStack stack = previousUpgrade.getCraftingItem(); - if (!stack.isEmpty()) { - stack = InventoryUtil.storeItems(stack, ItemStorage.wrap(inventory), inventory.selectedSlot); - if (!stack.isEmpty()) { - WorldUtil.dropItemStack(stack, player.getEntityWorld(), player.getPos()); + if( !stack.isEmpty() ) + { + stack = InventoryUtil.storeItems( stack, ItemStorage.wrap( inventory ), inventory.selectedSlot ); + if( !stack.isEmpty() ) + { + WorldUtil.dropItemStack( stack, player.getEntityWorld(), player.getPos() ); } } } // Set the new upgrade - this.computer.setUpgrade(newUpgrade); + this.computer.setUpgrade( newUpgrade ); - return new Object[] {true}; + return new Object[] { true }; } - private static IPocketUpgrade findUpgrade(DefaultedList inv, int start, IPocketUpgrade previous) { - for (int i = 0; i < inv.size(); i++) { - ItemStack invStack = inv.get((i + start) % inv.size()); - if (!invStack.isEmpty()) { - IPocketUpgrade newUpgrade = PocketUpgrades.get(invStack); + private static IPocketUpgrade findUpgrade( DefaultedList inv, int start, IPocketUpgrade previous ) + { + for( int i = 0; i < inv.size(); i++ ) + { + ItemStack invStack = inv.get( (i + start) % inv.size() ); + if( !invStack.isEmpty() ) + { + IPocketUpgrade newUpgrade = PocketUpgrades.get( invStack ); - if (newUpgrade != null && newUpgrade != previous) { + if( newUpgrade != null && newUpgrade != previous ) + { // Consume an item from this stack and exit the loop invStack = invStack.copy(); - invStack.decrement(1); - inv.set((i + start) % inv.size(), invStack.isEmpty() ? ItemStack.EMPTY : invStack); + invStack.decrement( 1 ); + inv.set( (i + start) % inv.size(), invStack.isEmpty() ? ItemStack.EMPTY : invStack ); return newUpgrade; } @@ -127,10 +140,12 @@ public class PocketAPI implements ILuaAPI { * @cc.treturn boolean If the upgrade was unequipped. * @cc.treturn string|nil The reason an upgrade was not unequipped. */ - @LuaFunction (mainThread = true) - public final Object[] unequipBack() { + @LuaFunction( mainThread = true ) + public final Object[] unequipBack() + { Entity entity = this.computer.getEntity(); - if (!(entity instanceof PlayerEntity)) { + if( !(entity instanceof PlayerEntity) ) + { return new Object[] { false, "Cannot find player" @@ -140,23 +155,26 @@ public class PocketAPI implements ILuaAPI { PlayerInventory inventory = player.inventory; IPocketUpgrade previousUpgrade = this.computer.getUpgrade(); - if (previousUpgrade == null) { + if( previousUpgrade == null ) + { return new Object[] { false, "Nothing to unequip" }; } - this.computer.setUpgrade(null); + this.computer.setUpgrade( null ); ItemStack stack = previousUpgrade.getCraftingItem(); - if (!stack.isEmpty()) { - stack = InventoryUtil.storeItems(stack, ItemStorage.wrap(inventory), inventory.selectedSlot); - if (stack.isEmpty()) { - WorldUtil.dropItemStack(stack, player.getEntityWorld(), player.getPos()); + if( !stack.isEmpty() ) + { + stack = InventoryUtil.storeItems( stack, ItemStorage.wrap( inventory ), inventory.selectedSlot ); + if( stack.isEmpty() ) + { + WorldUtil.dropItemStack( stack, player.getEntityWorld(), player.getPos() ); } } - return new Object[] {true}; + return new Object[] { true }; } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index c6eeafde3..bc28daa9a 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -6,14 +6,6 @@ package dan200.computercraft.shared.pocket.core; -import static dan200.computercraft.shared.pocket.items.ItemPocketComputer.NBT_LIGHT; - -import java.util.Collections; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.IPocketAccess; @@ -25,7 +17,6 @@ import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.util.NBTUtil; - import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; @@ -36,91 +27,121 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import net.minecraft.world.World; -public class PocketServerComputer extends ServerComputer implements IPocketAccess { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.Map; + +import static dan200.computercraft.shared.pocket.items.ItemPocketComputer.NBT_LIGHT; + +public class PocketServerComputer extends ServerComputer implements IPocketAccess +{ private IPocketUpgrade m_upgrade; private Entity m_entity; private ItemStack m_stack; - public PocketServerComputer(World world, int computerID, String label, int instanceID, ComputerFamily family) { - super(world, computerID, label, instanceID, family, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight); + public PocketServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family ) + { + super( world, computerID, label, instanceID, family, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight ); } @Nullable @Override - public Entity getEntity() { + public Entity getEntity() + { Entity entity = this.m_entity; - if (entity == null || this.m_stack == null || !entity.isAlive()) { + if( entity == null || this.m_stack == null || !entity.isAlive() ) + { return null; } - if (entity instanceof PlayerEntity) { + if( entity instanceof PlayerEntity ) + { PlayerInventory inventory = ((PlayerEntity) entity).inventory; - return inventory.main.contains(this.m_stack) || inventory.offHand.contains(this.m_stack) ? entity : null; - } else if (entity instanceof LivingEntity) { + return inventory.main.contains( this.m_stack ) || inventory.offHand.contains( this.m_stack ) ? entity : null; + } + else if( entity instanceof LivingEntity ) + { LivingEntity living = (LivingEntity) entity; return living.getMainHandStack() == this.m_stack || living.getOffHandStack() == this.m_stack ? entity : null; - } else { + } + else + { return null; } } @Override - public int getColour() { - return IColouredItem.getColourBasic(this.m_stack); + public int getColour() + { + return IColouredItem.getColourBasic( this.m_stack ); } @Override - public void setColour(int colour) { - IColouredItem.setColourBasic(this.m_stack, colour); + public void setColour( int colour ) + { + IColouredItem.setColourBasic( this.m_stack, colour ); this.updateUpgradeNBTData(); } @Override - public int getLight() { + public int getLight() + { CompoundTag tag = this.getUserData(); - return tag.contains(NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC) ? tag.getInt(NBT_LIGHT) : -1; + return tag.contains( NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC ) ? tag.getInt( NBT_LIGHT ) : -1; } @Override - public void setLight(int colour) { + public void setLight( int colour ) + { CompoundTag tag = this.getUserData(); - if (colour >= 0 && colour <= 0xFFFFFF) { - if (!tag.contains(NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC) || tag.getInt(NBT_LIGHT) != colour) { - tag.putInt(NBT_LIGHT, colour); + if( colour >= 0 && colour <= 0xFFFFFF ) + { + if( !tag.contains( NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC ) || tag.getInt( NBT_LIGHT ) != colour ) + { + tag.putInt( NBT_LIGHT, colour ); this.updateUserData(); } - } else if (tag.contains(NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC)) { - tag.remove(NBT_LIGHT); + } + else if( tag.contains( NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC ) ) + { + tag.remove( NBT_LIGHT ); this.updateUserData(); } } @Nonnull @Override - public CompoundTag getUpgradeNBTData() { - return ItemPocketComputer.getUpgradeInfo(this.m_stack); + public CompoundTag getUpgradeNBTData() + { + return ItemPocketComputer.getUpgradeInfo( this.m_stack ); } @Override - public void updateUpgradeNBTData() { - if (this.m_entity instanceof PlayerEntity) { + public void updateUpgradeNBTData() + { + if( this.m_entity instanceof PlayerEntity ) + { ((PlayerEntity) this.m_entity).inventory.markDirty(); } } @Override - public void invalidatePeripheral() { - IPeripheral peripheral = this.m_upgrade == null ? null : this.m_upgrade.createPeripheral(this); - this.setPeripheral(ComputerSide.BACK, peripheral); + public void invalidatePeripheral() + { + IPeripheral peripheral = this.m_upgrade == null ? null : this.m_upgrade.createPeripheral( this ); + this.setPeripheral( ComputerSide.BACK, peripheral ); } @Nonnull @Override - public Map getUpgrades() { - return this.m_upgrade == null ? Collections.emptyMap() : Collections.singletonMap(this.m_upgrade.getUpgradeID(), this.getPeripheral(ComputerSide.BACK)); + public Map getUpgrades() + { + return this.m_upgrade == null ? Collections.emptyMap() : Collections.singletonMap( this.m_upgrade.getUpgradeID(), this.getPeripheral( ComputerSide.BACK ) ); } - public IPocketUpgrade getUpgrade() { + public IPocketUpgrade getUpgrade() + { return this.m_upgrade; } @@ -131,48 +152,58 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces * * @param upgrade The new upgrade to set it to, may be {@code null}. */ - public void setUpgrade(IPocketUpgrade upgrade) { - if (this.m_upgrade == upgrade) { + public void setUpgrade( IPocketUpgrade upgrade ) + { + if( this.m_upgrade == upgrade ) + { return; } - synchronized (this) { - ItemPocketComputer.setUpgrade(this.m_stack, upgrade); + synchronized( this ) + { + ItemPocketComputer.setUpgrade( this.m_stack, upgrade ); this.updateUpgradeNBTData(); this.m_upgrade = upgrade; this.invalidatePeripheral(); } } - public synchronized void updateValues(Entity entity, @Nonnull ItemStack stack, IPocketUpgrade upgrade) { - if (entity != null) { - this.setWorld(entity.getEntityWorld()); - this.setPosition(entity.getBlockPos()); + public synchronized void updateValues( Entity entity, @Nonnull ItemStack stack, IPocketUpgrade upgrade ) + { + if( entity != null ) + { + this.setWorld( entity.getEntityWorld() ); + this.setPosition( entity.getBlockPos() ); } // If a new entity has picked it up then rebroadcast the terminal to them - if (entity != this.m_entity && entity instanceof ServerPlayerEntity) { + if( entity != this.m_entity && entity instanceof ServerPlayerEntity ) + { this.markTerminalChanged(); } this.m_entity = entity; this.m_stack = stack; - if (this.m_upgrade != upgrade) { + if( this.m_upgrade != upgrade ) + { this.m_upgrade = upgrade; this.invalidatePeripheral(); } } @Override - public void broadcastState(boolean force) { - super.broadcastState(force); + public void broadcastState( boolean force ) + { + super.broadcastState( force ); - if ((this.hasTerminalChanged() || force) && this.m_entity instanceof ServerPlayerEntity) { + if( (this.hasTerminalChanged() || force) && this.m_entity instanceof ServerPlayerEntity ) + { // Broadcast the state to the current entity if they're not already interacting with it. ServerPlayerEntity player = (ServerPlayerEntity) this.m_entity; - if (player.networkHandler != null && !this.isInteracting(player)) { - NetworkHandler.sendToPlayer(player, this.createTerminalPacket()); + if( player.networkHandler != null && !this.isInteracting( player ) ) + { + NetworkHandler.sendToPlayer( player, this.createTerminalPacket() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java index c0a136e47..9a41f3a5a 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java @@ -6,14 +6,11 @@ package dan200.computercraft.shared.pocket.inventory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.inventory.ContainerComputerBase; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; - +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; @@ -24,27 +21,33 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Hand; -import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; -public final class ContainerPocketComputer extends ContainerComputerBase { - private ContainerPocketComputer(int id, ServerComputer computer, ItemPocketComputer item, Hand hand) { - super(ComputerCraftRegistry.ModContainers.POCKET_COMPUTER, id, p -> { - ItemStack stack = p.getStackInHand(hand); - return stack.getItem() == item && ItemPocketComputer.getServerComputer(stack) == computer; - }, computer, item.getFamily()); +public final class ContainerPocketComputer extends ContainerComputerBase +{ + private ContainerPocketComputer( int id, ServerComputer computer, ItemPocketComputer item, Hand hand ) + { + super( ComputerCraftRegistry.ModContainers.POCKET_COMPUTER, id, p -> { + ItemStack stack = p.getStackInHand( hand ); + return stack.getItem() == item && ItemPocketComputer.getServerComputer( stack ) == computer; + }, computer, item.getFamily() ); } - public ContainerPocketComputer(int id, PlayerInventory player, PacketByteBuf packetByteBuf) { - super(ComputerCraftRegistry.ModContainers.POCKET_COMPUTER, id, player, packetByteBuf); + public ContainerPocketComputer( int id, PlayerInventory player, PacketByteBuf packetByteBuf ) + { + super( ComputerCraftRegistry.ModContainers.POCKET_COMPUTER, id, player, packetByteBuf ); } - public static class Factory implements NamedScreenHandlerFactory, ExtendedScreenHandlerFactory { + public static class Factory implements NamedScreenHandlerFactory, ExtendedScreenHandlerFactory + { private final ServerComputer computer; private final Text name; private final ItemPocketComputer item; private final Hand hand; - public Factory(ServerComputer computer, ItemStack stack, ItemPocketComputer item, Hand hand) { + public Factory( ServerComputer computer, ItemStack stack, ItemPocketComputer item, Hand hand ) + { this.computer = computer; this.name = stack.getName(); this.item = item; @@ -54,20 +57,23 @@ public final class ContainerPocketComputer extends ContainerComputerBase { @Nonnull @Override - public Text getDisplayName() { + public Text getDisplayName() + { return this.name; } @Nullable @Override - public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity entity) { - return new ContainerPocketComputer(id, this.computer, this.item, this.hand); + public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity entity ) + { + return new ContainerPocketComputer( id, this.computer, this.item, this.hand ); } @Override - public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf) { - packetByteBuf.writeInt(this.computer.getInstanceID()); - packetByteBuf.writeEnumConstant(this.computer.getFamily()); + public void writeScreenOpeningData( ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf ) + { + packetByteBuf.writeInt( this.computer.getInstanceID() ); + packetByteBuf.writeEnumConstant( this.computer.getFamily() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index b3c4ad312..7eda82a58 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.pocket.items; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.base.Objects; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.ComputerCraftAPI; @@ -29,7 +24,8 @@ import dan200.computercraft.shared.network.container.ComputerContainerData; import dan200.computercraft.shared.pocket.apis.PocketAPI; import dan200.computercraft.shared.pocket.core.PocketServerComputer; import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; @@ -48,10 +44,12 @@ import net.minecraft.util.TypedActionResult; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; -public class ItemPocketComputer extends Item implements IComputerItem, IMedia, IColouredItem { +public class ItemPocketComputer extends Item implements IComputerItem, IMedia, IColouredItem +{ public static final String NBT_LIGHT = "Light"; private static final String NBT_UPGRADE = "Upgrade"; private static final String NBT_UPGRADE_INFO = "UpgradeInfo"; @@ -60,58 +58,70 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I private final ComputerFamily family; - public ItemPocketComputer(Settings settings, ComputerFamily family) { - super(settings); + public ItemPocketComputer( Settings settings, ComputerFamily family ) + { + super( settings ); this.family = family; } - public static ServerComputer getServerComputer(@Nonnull ItemStack stack) { + public static ServerComputer getServerComputer( @Nonnull ItemStack stack ) + { int session = getSessionID( stack ); if( session != ComputerCraft.serverComputerRegistry.getSessionID() ) return null; - int instanceID = getInstanceID(stack); - return instanceID >= 0 ? ComputerCraft.serverComputerRegistry.get(instanceID) : null; + int instanceID = getInstanceID( stack ); + return instanceID >= 0 ? ComputerCraft.serverComputerRegistry.get( instanceID ) : null; } - @Environment (EnvType.CLIENT) - public static ComputerState getState(@Nonnull ItemStack stack) { - ClientComputer computer = getClientComputer(stack); + @Environment( EnvType.CLIENT ) + public static ComputerState getState( @Nonnull ItemStack stack ) + { + ClientComputer computer = getClientComputer( stack ); return computer == null ? ComputerState.OFF : computer.getState(); } - private static ClientComputer getClientComputer(@Nonnull ItemStack stack) { - int instanceID = getInstanceID(stack); - return instanceID >= 0 ? ComputerCraft.clientComputerRegistry.get(instanceID) : null; + private static ClientComputer getClientComputer( @Nonnull ItemStack stack ) + { + int instanceID = getInstanceID( stack ); + return instanceID >= 0 ? ComputerCraft.clientComputerRegistry.get( instanceID ) : null; } - @Environment (EnvType.CLIENT) - public static int getLightState(@Nonnull ItemStack stack) { - ClientComputer computer = getClientComputer(stack); - if (computer != null && computer.isOn()) { + @Environment( EnvType.CLIENT ) + public static int getLightState( @Nonnull ItemStack stack ) + { + ClientComputer computer = getClientComputer( stack ); + if( computer != null && computer.isOn() ) + { CompoundTag computerNBT = computer.getUserData(); - if (computerNBT != null && computerNBT.contains(NBT_LIGHT)) { - return computerNBT.getInt(NBT_LIGHT); + if( computerNBT != null && computerNBT.contains( NBT_LIGHT ) ) + { + return computerNBT.getInt( NBT_LIGHT ); } } return -1; } - public static void setUpgrade(@Nonnull ItemStack stack, IPocketUpgrade upgrade) { + public static void setUpgrade( @Nonnull ItemStack stack, IPocketUpgrade upgrade ) + { CompoundTag compound = stack.getOrCreateTag(); - if (upgrade == null) { - compound.remove(NBT_UPGRADE); - } else { - compound.putString(NBT_UPGRADE, - upgrade.getUpgradeID() - .toString()); + if( upgrade == null ) + { + compound.remove( NBT_UPGRADE ); + } + else + { + compound.putString( NBT_UPGRADE, + upgrade.getUpgradeID() + .toString() ); } - compound.remove(NBT_UPGRADE_INFO); + compound.remove( NBT_UPGRADE_INFO ); } - public static CompoundTag getUpgradeInfo(@Nonnull ItemStack stack) { - return stack.getOrCreateSubTag(NBT_UPGRADE_INFO); + public static CompoundTag getUpgradeInfo( @Nonnull ItemStack stack ) + { + return stack.getOrCreateSubTag( NBT_UPGRADE_INFO ); } // @Nullable @@ -132,239 +142,295 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I @Nonnull @Override - public TypedActionResult use(World world, PlayerEntity player, @Nonnull Hand hand) { - ItemStack stack = player.getStackInHand(hand); - if (!world.isClient) { - PocketServerComputer computer = this.createServerComputer(world, player.inventory, player, stack); + public TypedActionResult use( World world, PlayerEntity player, @Nonnull Hand hand ) + { + ItemStack stack = player.getStackInHand( hand ); + if( !world.isClient ) + { + PocketServerComputer computer = this.createServerComputer( world, player.inventory, player, stack ); boolean stop = false; - if (computer != null) { + if( computer != null ) + { computer.turnOn(); - IPocketUpgrade upgrade = getUpgrade(stack); - if (upgrade != null) { - computer.updateValues(player, stack, upgrade); - stop = upgrade.onRightClick(world, computer, computer.getPeripheral(ComputerSide.BACK)); + IPocketUpgrade upgrade = getUpgrade( stack ); + if( upgrade != null ) + { + computer.updateValues( player, stack, upgrade ); + stop = upgrade.onRightClick( world, computer, computer.getPeripheral( ComputerSide.BACK ) ); } } - if (!stop && computer != null) { - computer.sendTerminalState(player); - new ComputerContainerData(computer).open(player, new ContainerPocketComputer.Factory(computer, stack, this, hand)); + if( !stop && computer != null ) + { + computer.sendTerminalState( player ); + new ComputerContainerData( computer ).open( player, new ContainerPocketComputer.Factory( computer, stack, this, hand ) ); } } - return new TypedActionResult<>(ActionResult.SUCCESS, stack); + return new TypedActionResult<>( ActionResult.SUCCESS, stack ); } @Override - public void inventoryTick(@Nonnull ItemStack stack, World world, @Nonnull Entity entity, int slotNum, boolean selected) { - if (!world.isClient) { + public void inventoryTick( @Nonnull ItemStack stack, World world, @Nonnull Entity entity, int slotNum, boolean selected ) + { + if( !world.isClient ) + { // Server side Inventory inventory = entity instanceof PlayerEntity ? ((PlayerEntity) entity).inventory : null; - PocketServerComputer computer = this.createServerComputer(world, inventory, entity, stack); - if (computer != null) { - IPocketUpgrade upgrade = getUpgrade(stack); + PocketServerComputer computer = this.createServerComputer( world, inventory, entity, stack ); + if( computer != null ) + { + IPocketUpgrade upgrade = getUpgrade( stack ); // Ping computer computer.keepAlive(); - computer.setWorld(world); - computer.updateValues(entity, stack, upgrade); + computer.setWorld( world ); + computer.updateValues( entity, stack, upgrade ); // Sync ID int id = computer.getID(); - if (id != this.getComputerID(stack)) { - setComputerID(stack, id); - if (inventory != null) { + if( id != this.getComputerID( stack ) ) + { + setComputerID( stack, id ); + if( inventory != null ) + { inventory.markDirty(); } } // Sync label String label = computer.getLabel(); - if (!Objects.equal(label, this.getLabel(stack))) { - this.setLabel(stack, label); - if (inventory != null) { + if( !Objects.equal( label, this.getLabel( stack ) ) ) + { + this.setLabel( stack, label ); + if( inventory != null ) + { inventory.markDirty(); } } // Update pocket upgrade - if (upgrade != null) { - upgrade.update(computer, computer.getPeripheral(ComputerSide.BACK)); + if( upgrade != null ) + { + upgrade.update( computer, computer.getPeripheral( ComputerSide.BACK ) ); } } - } else { + } + else + { // Client side - createClientComputer(stack); + createClientComputer( stack ); } } @Override - public void appendTooltip(@Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, TooltipContext flag) { - if (flag.isAdvanced() || this.getLabel(stack) == null) { - int id = this.getComputerID(stack); - if (id >= 0) { - list.add(new TranslatableText("gui.computercraft.tooltip.computer_id", id).formatted(Formatting.GRAY)); + public void appendTooltip( @Nonnull ItemStack stack, @Nullable World world, @Nonnull List list, TooltipContext flag ) + { + if( flag.isAdvanced() || this.getLabel( stack ) == null ) + { + int id = this.getComputerID( stack ); + if( id >= 0 ) + { + list.add( new TranslatableText( "gui.computercraft.tooltip.computer_id", id ).formatted( Formatting.GRAY ) ); } } } @Nonnull @Override - public Text getName(@Nonnull ItemStack stack) { - String baseString = this.getTranslationKey(stack); - IPocketUpgrade upgrade = getUpgrade(stack); - if (upgrade != null) { - return new TranslatableText(baseString + ".upgraded", new TranslatableText(upgrade.getUnlocalisedAdjective())); - } else { - return super.getName(stack); + public Text getName( @Nonnull ItemStack stack ) + { + String baseString = this.getTranslationKey( stack ); + IPocketUpgrade upgrade = getUpgrade( stack ); + if( upgrade != null ) + { + return new TranslatableText( baseString + ".upgraded", new TranslatableText( upgrade.getUnlocalisedAdjective() ) ); + } + else + { + return super.getName( stack ); } } // IComputerItem implementation @Override - public void appendStacks(@Nonnull ItemGroup group, @Nonnull DefaultedList stacks) { - if (!this.isIn(group)) { + public void appendStacks( @Nonnull ItemGroup group, @Nonnull DefaultedList stacks ) + { + if( !this.isIn( group ) ) + { return; } - stacks.add(this.create(-1, null, -1, null)); - for (IPocketUpgrade upgrade : PocketUpgrades.getVanillaUpgrades()) { - stacks.add(this.create(-1, null, -1, upgrade)); + stacks.add( this.create( -1, null, -1, null ) ); + for( IPocketUpgrade upgrade : PocketUpgrades.getVanillaUpgrades() ) + { + stacks.add( this.create( -1, null, -1, upgrade ) ); } } - public ItemStack create(int id, String label, int colour, IPocketUpgrade upgrade) { - ItemStack result = new ItemStack(this); - if (id >= 0) { + public ItemStack create( int id, String label, int colour, IPocketUpgrade upgrade ) + { + ItemStack result = new ItemStack( this ); + if( id >= 0 ) + { result.getOrCreateTag() - .putInt(NBT_ID, id); + .putInt( NBT_ID, id ); } - if (label != null) { - result.setCustomName(new LiteralText(label)); + if( label != null ) + { + result.setCustomName( new LiteralText( label ) ); } - if (upgrade != null) { + if( upgrade != null ) + { result.getOrCreateTag() - .putString(NBT_UPGRADE, - upgrade.getUpgradeID() - .toString()); + .putString( NBT_UPGRADE, + upgrade.getUpgradeID() + .toString() ); } - if (colour != -1) { + if( colour != -1 ) + { result.getOrCreateTag() - .putInt(NBT_COLOUR, colour); + .putInt( NBT_COLOUR, colour ); } return result; } - public PocketServerComputer createServerComputer(final World world, Inventory inventory, Entity entity, @Nonnull ItemStack stack) { - if (world.isClient) { + public PocketServerComputer createServerComputer( final World world, Inventory inventory, Entity entity, @Nonnull ItemStack stack ) + { + if( world.isClient ) + { return null; } PocketServerComputer computer; - int instanceID = getInstanceID(stack); - int sessionID = getSessionID(stack); + int instanceID = getInstanceID( stack ); + int sessionID = getSessionID( stack ); int correctSessionID = ComputerCraft.serverComputerRegistry.getSessionID(); - if (instanceID >= 0 && sessionID == correctSessionID && ComputerCraft.serverComputerRegistry.contains(instanceID)) { - computer = (PocketServerComputer) ComputerCraft.serverComputerRegistry.get(instanceID); - } else { - if (instanceID < 0 || sessionID != correctSessionID) { + if( instanceID >= 0 && sessionID == correctSessionID && ComputerCraft.serverComputerRegistry.contains( instanceID ) ) + { + computer = (PocketServerComputer) ComputerCraft.serverComputerRegistry.get( instanceID ); + } + else + { + if( instanceID < 0 || sessionID != correctSessionID ) + { instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID(); - setInstanceID(stack, instanceID); - setSessionID(stack, correctSessionID); + setInstanceID( stack, instanceID ); + setSessionID( stack, correctSessionID ); } - int computerID = this.getComputerID(stack); - if (computerID < 0) { - computerID = ComputerCraftAPI.createUniqueNumberedSaveDir(world, "computer"); - setComputerID(stack, computerID); + int computerID = this.getComputerID( stack ); + if( computerID < 0 ) + { + computerID = ComputerCraftAPI.createUniqueNumberedSaveDir( world, "computer" ); + setComputerID( stack, computerID ); } - computer = new PocketServerComputer(world, computerID, this.getLabel(stack), instanceID, this.getFamily()); - computer.updateValues(entity, stack, getUpgrade(stack)); - computer.addAPI(new PocketAPI(computer)); - ComputerCraft.serverComputerRegistry.add(instanceID, computer); - if (inventory != null) { + computer = new PocketServerComputer( world, computerID, this.getLabel( stack ), instanceID, this.getFamily() ); + computer.updateValues( entity, stack, getUpgrade( stack ) ); + computer.addAPI( new PocketAPI( computer ) ); + ComputerCraft.serverComputerRegistry.add( instanceID, computer ); + if( inventory != null ) + { inventory.markDirty(); } } - computer.setWorld(world); + computer.setWorld( world ); return computer; } - public static IPocketUpgrade getUpgrade(@Nonnull ItemStack stack) { + public static IPocketUpgrade getUpgrade( @Nonnull ItemStack stack ) + { CompoundTag compound = stack.getTag(); - return compound != null && compound.contains(NBT_UPGRADE) ? PocketUpgrades.get(compound.getString(NBT_UPGRADE)) : null; + return compound != null && compound.contains( NBT_UPGRADE ) ? PocketUpgrades.get( compound.getString( NBT_UPGRADE ) ) : null; } // IMedia - private static void setComputerID(@Nonnull ItemStack stack, int computerID) { + private static void setComputerID( @Nonnull ItemStack stack, int computerID ) + { stack.getOrCreateTag() - .putInt(NBT_ID, computerID); + .putInt( NBT_ID, computerID ); } @Override - public String getLabel(@Nonnull ItemStack stack) { - return IComputerItem.super.getLabel(stack); + public String getLabel( @Nonnull ItemStack stack ) + { + return IComputerItem.super.getLabel( stack ); } @Override - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.family; } @Override - public ItemStack withFamily(@Nonnull ItemStack stack, @Nonnull ComputerFamily family) { - return PocketComputerItemFactory.create(this.getComputerID(stack), this.getLabel(stack), this.getColour(stack), family, getUpgrade(stack)); + public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ) + { + return PocketComputerItemFactory.create( this.getComputerID( stack ), this.getLabel( stack ), this.getColour( stack ), family, getUpgrade( stack ) ); } @Override - public boolean setLabel(@Nonnull ItemStack stack, String label) { - if (label != null) { - stack.setCustomName(new LiteralText(label)); - } else { + public boolean setLabel( @Nonnull ItemStack stack, String label ) + { + if( label != null ) + { + stack.setCustomName( new LiteralText( label ) ); + } + else + { stack.removeCustomName(); } return true; } - public static ClientComputer createClientComputer(@Nonnull ItemStack stack) { - int instanceID = getInstanceID(stack); - if (instanceID >= 0) { - if (!ComputerCraft.clientComputerRegistry.contains(instanceID)) { - ComputerCraft.clientComputerRegistry.add(instanceID, new ClientComputer(instanceID)); + public static ClientComputer createClientComputer( @Nonnull ItemStack stack ) + { + int instanceID = getInstanceID( stack ); + if( instanceID >= 0 ) + { + if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) ) + { + ComputerCraft.clientComputerRegistry.add( instanceID, new ClientComputer( instanceID ) ); } - return ComputerCraft.clientComputerRegistry.get(instanceID); + return ComputerCraft.clientComputerRegistry.get( instanceID ); } return null; } - private static int getInstanceID(@Nonnull ItemStack stack) { + private static int getInstanceID( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_INSTANCE) ? nbt.getInt(NBT_INSTANCE) : -1; + return nbt != null && nbt.contains( NBT_INSTANCE ) ? nbt.getInt( NBT_INSTANCE ) : -1; } - private static int getSessionID(@Nonnull ItemStack stack) { + private static int getSessionID( @Nonnull ItemStack stack ) + { CompoundTag nbt = stack.getTag(); - return nbt != null && nbt.contains(NBT_SESSION) ? nbt.getInt(NBT_SESSION) : -1; + return nbt != null && nbt.contains( NBT_SESSION ) ? nbt.getInt( NBT_SESSION ) : -1; } - private static void setInstanceID(@Nonnull ItemStack stack, int instanceID) { + private static void setInstanceID( @Nonnull ItemStack stack, int instanceID ) + { stack.getOrCreateTag() - .putInt(NBT_INSTANCE, instanceID); + .putInt( NBT_INSTANCE, instanceID ); } - private static void setSessionID(@Nonnull ItemStack stack, int sessionID) { + private static void setSessionID( @Nonnull ItemStack stack, int sessionID ) + { stack.getOrCreateTag() - .putInt(NBT_SESSION, sessionID); + .putInt( NBT_SESSION, sessionID ); } @Override - public IMount createDataMount(@Nonnull ItemStack stack, @Nonnull World world) { - int id = this.getComputerID(stack); - if (id >= 0) { - return ComputerCraftAPI.createSaveDirMount(world, "computer/" + id, ComputerCraft.computerSpaceLimit); + public IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world ) + { + int id = this.getComputerID( stack ); + if( id >= 0 ) + { + return ComputerCraftAPI.createSaveDirMount( world, "computer/" + id, ComputerCraft.computerSpaceLimit ); } return null; } diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java b/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java index e2f4b1a43..ac2d7303d 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItemFactory.java @@ -6,26 +6,28 @@ package dan200.computercraft.shared.pocket.items; -import javax.annotation.Nonnull; - import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.core.ComputerFamily; - import net.minecraft.item.ItemStack; -public final class PocketComputerItemFactory { +import javax.annotation.Nonnull; + +public final class PocketComputerItemFactory +{ private PocketComputerItemFactory() {} @Nonnull - public static ItemStack create(int id, String label, int colour, ComputerFamily family, IPocketUpgrade upgrade) { - switch (family) { - case NORMAL: - return ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL.create(id, label, colour, upgrade); - case ADVANCED: - return ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED.create(id, label, colour, upgrade); - default: - return ItemStack.EMPTY; + public static ItemStack create( int id, String label, int colour, ComputerFamily family, IPocketUpgrade upgrade ) + { + switch( family ) + { + case NORMAL: + return ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL.create( id, label, colour, upgrade ); + case ADVANCED: + return ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED.create( id, label, colour, upgrade ); + default: + return ItemStack.EMPTY; } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java index 7c649807a..d4e9e1929 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java @@ -6,36 +6,40 @@ package dan200.computercraft.shared.pocket.peripherals; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.AbstractPocketUpgrade; import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.peripheral.modem.ModemState; - import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; -public class PocketModem extends AbstractPocketUpgrade { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class PocketModem extends AbstractPocketUpgrade +{ private final boolean advanced; - public PocketModem(boolean advanced) { - super(new Identifier("computercraft", advanced ? "wireless_modem_advanced" : "wireless_modem_normal"), - advanced ? ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_ADVANCED : ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_NORMAL); + public PocketModem( boolean advanced ) + { + super( new Identifier( "computercraft", advanced ? "wireless_modem_advanced" : "wireless_modem_normal" ), + advanced ? ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_ADVANCED : ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_NORMAL ); this.advanced = advanced; } @Nullable @Override - public IPeripheral createPeripheral(@Nonnull IPocketAccess access) { - return new PocketModemPeripheral(this.advanced); + public IPeripheral createPeripheral( @Nonnull IPocketAccess access ) + { + return new PocketModemPeripheral( this.advanced ); } @Override - public void update(@Nonnull IPocketAccess access, @Nullable IPeripheral peripheral) { - if (!(peripheral instanceof PocketModemPeripheral)) { + public void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) + { + if( !(peripheral instanceof PocketModemPeripheral) ) + { return; } @@ -43,13 +47,15 @@ public class PocketModem extends AbstractPocketUpgrade { PocketModemPeripheral modem = (PocketModemPeripheral) peripheral; - if (entity != null) { - modem.setLocation(entity.getEntityWorld(), entity.getCameraPosVec(1)); + if( entity != null ) + { + modem.setLocation( entity.getEntityWorld(), entity.getCameraPosVec( 1 ) ); } ModemState state = modem.getModemState(); - if (state.pollChanged()) { - access.setLight(state.isOpen() ? 0xBA0000 : -1); + if( state.pollChanged() ) + { + access.setLight( state.isOpen() ? 0xBA0000 : -1 ); } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java index 75a8cf013..e4a9c1ff8 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java @@ -6,42 +6,47 @@ package dan200.computercraft.shared.pocket.peripherals; -import javax.annotation.Nonnull; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class PocketModemPeripheral extends WirelessModemPeripheral { +import javax.annotation.Nonnull; + +public class PocketModemPeripheral extends WirelessModemPeripheral +{ private World world = null; private Vec3d position = Vec3d.ZERO; - public PocketModemPeripheral(boolean advanced) { - super(new ModemState(), advanced); + public PocketModemPeripheral( boolean advanced ) + { + super( new ModemState(), advanced ); } - void setLocation(World world, Vec3d position) { + void setLocation( World world, Vec3d position ) + { this.position = position; this.world = world; } @Nonnull @Override - public World getWorld() { + public World getWorld() + { return this.world; } @Nonnull @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { return this.position; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other instanceof PocketModemPeripheral; } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java index 31fadf87a..b5c98c7ad 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java @@ -6,42 +6,47 @@ package dan200.computercraft.shared.pocket.peripherals; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.AbstractPocketUpgrade; import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.shared.ComputerCraftRegistry; - import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; -public class PocketSpeaker extends AbstractPocketUpgrade { - public PocketSpeaker() { - super(new Identifier("computercraft", "speaker"), ComputerCraftRegistry.ModBlocks.SPEAKER); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class PocketSpeaker extends AbstractPocketUpgrade +{ + public PocketSpeaker() + { + super( new Identifier( "computercraft", "speaker" ), ComputerCraftRegistry.ModBlocks.SPEAKER ); } @Nullable @Override - public IPeripheral createPeripheral(@Nonnull IPocketAccess access) { + public IPeripheral createPeripheral( @Nonnull IPocketAccess access ) + { return new PocketSpeakerPeripheral(); } @Override - public void update(@Nonnull IPocketAccess access, @Nullable IPeripheral peripheral) { - if (!(peripheral instanceof PocketSpeakerPeripheral)) { + public void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral ) + { + if( !(peripheral instanceof PocketSpeakerPeripheral) ) + { return; } PocketSpeakerPeripheral speaker = (PocketSpeakerPeripheral) peripheral; Entity entity = access.getEntity(); - if (entity != null) { - speaker.setLocation(entity.getEntityWorld(), entity.getCameraPosVec(1)); + if( entity != null ) + { + speaker.setLocation( entity.getEntityWorld(), entity.getCameraPosVec( 1 ) ); } speaker.update(); - access.setLight(speaker.madeSound(20) ? 0x3320fc : -1); + access.setLight( speaker.madeSound( 20 ) ? 0x3320fc : -1 ); } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java index 901c509ac..b1a451b78 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java @@ -8,31 +8,35 @@ package dan200.computercraft.shared.pocket.peripherals; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class PocketSpeakerPeripheral extends SpeakerPeripheral { +public class PocketSpeakerPeripheral extends SpeakerPeripheral +{ private World world = null; private Vec3d position = Vec3d.ZERO; - void setLocation(World world, Vec3d position) { + void setLocation( World world, Vec3d position ) + { this.position = position; this.world = world; } @Override - public World getWorld() { + public World getWorld() + { return this.world; } @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { return this.world != null ? this.position : null; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other instanceof PocketSpeakerPeripheral; } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java b/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java index c9693c509..79faf31e1 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java +++ b/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java @@ -6,14 +6,11 @@ package dan200.computercraft.shared.pocket.recipes; -import javax.annotation.Nonnull; - import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.PocketUpgrades; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.recipe.RecipeSerializer; @@ -22,36 +19,46 @@ import net.minecraft.recipe.SpecialRecipeSerializer; import net.minecraft.util.Identifier; import net.minecraft.world.World; -public final class PocketComputerUpgradeRecipe extends SpecialCraftingRecipe { - public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>(PocketComputerUpgradeRecipe::new); +import javax.annotation.Nonnull; - private PocketComputerUpgradeRecipe(Identifier identifier) { - super(identifier); +public final class PocketComputerUpgradeRecipe extends SpecialCraftingRecipe +{ + public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>( PocketComputerUpgradeRecipe::new ); + + private PocketComputerUpgradeRecipe( Identifier identifier ) + { + super( identifier ); } @Nonnull @Override - public ItemStack getOutput() { - return PocketComputerItemFactory.create(-1, null, -1, ComputerFamily.NORMAL, null); + public ItemStack getOutput() + { + return PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.NORMAL, null ); } @Override - public boolean matches(@Nonnull CraftingInventory inventory, @Nonnull World world) { - return !this.craft(inventory).isEmpty(); + public boolean matches( @Nonnull CraftingInventory inventory, @Nonnull World world ) + { + return !this.craft( inventory ).isEmpty(); } @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inventory) { + public ItemStack craft( @Nonnull CraftingInventory inventory ) + { // Scan the grid for a pocket computer ItemStack computer = ItemStack.EMPTY; int computerX = -1; int computerY = -1; computer: - for (int y = 0; y < inventory.getHeight(); y++) { - for (int x = 0; x < inventory.getWidth(); x++) { - ItemStack item = inventory.getStack(x + y * inventory.getWidth()); - if (!item.isEmpty() && item.getItem() instanceof ItemPocketComputer) { + for( int y = 0; y < inventory.getHeight(); y++ ) + { + for( int x = 0; x < inventory.getWidth(); x++ ) + { + ItemStack item = inventory.getStack( x + y * inventory.getWidth() ); + if( !item.isEmpty() && item.getItem() instanceof ItemPocketComputer ) + { computer = item; computerX = x; computerY = y; @@ -60,55 +67,67 @@ public final class PocketComputerUpgradeRecipe extends SpecialCraftingRecipe { } } - if (computer.isEmpty()) { + if( computer.isEmpty() ) + { return ItemStack.EMPTY; } ItemPocketComputer itemComputer = (ItemPocketComputer) computer.getItem(); - if (ItemPocketComputer.getUpgrade(computer) != null) { + if( ItemPocketComputer.getUpgrade( computer ) != null ) + { return ItemStack.EMPTY; } // Check for upgrades around the item IPocketUpgrade upgrade = null; - for (int y = 0; y < inventory.getHeight(); y++) { - for (int x = 0; x < inventory.getWidth(); x++) { - ItemStack item = inventory.getStack(x + y * inventory.getWidth()); - if (x == computerX && y == computerY) { + for( int y = 0; y < inventory.getHeight(); y++ ) + { + for( int x = 0; x < inventory.getWidth(); x++ ) + { + ItemStack item = inventory.getStack( x + y * inventory.getWidth() ); + if( x == computerX && y == computerY ) + { continue; } - if (x == computerX && y == computerY - 1) { - upgrade = PocketUpgrades.get(item); - if (upgrade == null) { + if( x == computerX && y == computerY - 1 ) + { + upgrade = PocketUpgrades.get( item ); + if( upgrade == null ) + { return ItemStack.EMPTY; } - } else if (!item.isEmpty()) { + } + else if( !item.isEmpty() ) + { return ItemStack.EMPTY; } } } - if (upgrade == null) { + if( upgrade == null ) + { return ItemStack.EMPTY; } // Construct the new stack ComputerFamily family = itemComputer.getFamily(); - int computerID = itemComputer.getComputerID(computer); - String label = itemComputer.getLabel(computer); - int colour = itemComputer.getColour(computer); - return PocketComputerItemFactory.create(computerID, label, colour, family, upgrade); + int computerID = itemComputer.getComputerID( computer ); + String label = itemComputer.getLabel( computer ); + int colour = itemComputer.getColour( computer ); + return PocketComputerItemFactory.create( computerID, label, colour, family, upgrade ); } @Override - public boolean fits(int x, int y) { + public boolean fits( int x, int y ) + { return x >= 2 && y >= 2; } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } } diff --git a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java index 09654af93..cf16b9904 100644 --- a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java +++ b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java @@ -30,8 +30,10 @@ import dan200.computercraft.shared.turtle.FurnaceRefuelHandler; import dan200.computercraft.shared.turtle.SignInspectHandler; import dan200.computercraft.shared.util.Config; import dan200.computercraft.shared.util.TickScheduler; - +import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.item.Item; @@ -41,14 +43,12 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; -import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; - -public final class ComputerCraftProxyCommon { +public final class ComputerCraftProxyCommon +{ private static MinecraftServer server; - public static void init() { + public static void init() + { NetworkHandler.setup(); registerProviders(); @@ -56,84 +56,91 @@ public final class ComputerCraftProxyCommon { ArgumentSerializers.register(); - ComputerCraftAPI.registerGenericSource(new InventoryMethods()); + ComputerCraftAPI.registerGenericSource( new InventoryMethods() ); } - private static void registerProviders() { - ComputerCraftAPI.registerPeripheralProvider((world, pos, side) -> { - BlockEntity tile = world.getBlockEntity(pos); - return tile instanceof IPeripheralTile ? ((IPeripheralTile) tile).getPeripheral(side) : null; - }); + private static void registerProviders() + { + ComputerCraftAPI.registerPeripheralProvider( ( world, pos, side ) -> { + BlockEntity tile = world.getBlockEntity( pos ); + return tile instanceof IPeripheralTile ? ((IPeripheralTile) tile).getPeripheral( side ) : null; + } ); - ComputerCraftAPI.registerPeripheralProvider((world, pos, side) -> { - BlockEntity tile = world.getBlockEntity(pos); + ComputerCraftAPI.registerPeripheralProvider( ( world, pos, side ) -> { + BlockEntity tile = world.getBlockEntity( pos ); return ComputerCraft.enableCommandBlock && tile instanceof CommandBlockBlockEntity ? - new CommandBlockPeripheral((CommandBlockBlockEntity) tile) : null; - }); + new CommandBlockPeripheral( (CommandBlockBlockEntity) tile ) : null; + } ); // Register bundled power providers - ComputerCraftAPI.registerBundledRedstoneProvider(new DefaultBundledRedstoneProvider()); + ComputerCraftAPI.registerBundledRedstoneProvider( new DefaultBundledRedstoneProvider() ); // Register media providers - ComputerCraftAPI.registerMediaProvider(stack -> { + ComputerCraftAPI.registerMediaProvider( stack -> { Item item = stack.getItem(); - if (item instanceof IMedia) { + if( item instanceof IMedia ) + { return (IMedia) item; } - if (item instanceof MusicDiscItem) { + if( item instanceof MusicDiscItem ) + { return RecordMedia.INSTANCE; } return null; - }); + } ); } - private static void registerHandlers() { - CommandRegistrationCallback.EVENT.register(CommandComputerCraft::register); + private static void registerHandlers() + { + CommandRegistrationCallback.EVENT.register( CommandComputerCraft::register ); - ServerTickEvents.START_SERVER_TICK.register(server -> { + ServerTickEvents.START_SERVER_TICK.register( server -> { MainThread.executePendingTasks(); ComputerCraft.serverComputerRegistry.update(); TickScheduler.tick(); - }); + } ); - ServerLifecycleEvents.SERVER_STARTED.register(server -> { + ServerLifecycleEvents.SERVER_STARTED.register( server -> { ComputerCraftProxyCommon.server = server; ComputerCraft.serverComputerRegistry.reset(); WirelessNetwork.resetNetworks(); MainThread.reset(); Tracking.reset(); - }); + } ); - ServerLifecycleEvents.SERVER_STOPPING.register(server -> { + ServerLifecycleEvents.SERVER_STOPPING.register( server -> { ComputerCraft.serverComputerRegistry.reset(); WirelessNetwork.resetNetworks(); MainThread.reset(); Tracking.reset(); ComputerCraftProxyCommon.server = null; - }); + } ); ServerBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register( ( blockEntity, world ) -> { - if(blockEntity instanceof TileGeneric ) { - ((TileGeneric)blockEntity).onChunkUnloaded(); + if( blockEntity instanceof TileGeneric ) + { + ((TileGeneric) blockEntity).onChunkUnloaded(); } - }); + } ); // Config - ServerLifecycleEvents.SERVER_STARTING.register(Config::serverStarting); - ServerLifecycleEvents.SERVER_STOPPING.register(Config::serverStopping); + ServerLifecycleEvents.SERVER_STARTING.register( Config::serverStarting ); + ServerLifecycleEvents.SERVER_STOPPING.register( Config::serverStopping ); - TurtleEvent.EVENT_BUS.register(FurnaceRefuelHandler.INSTANCE); - TurtleEvent.EVENT_BUS.register(new TurtlePermissions()); - TurtleEvent.EVENT_BUS.register(new SignInspectHandler()); + TurtleEvent.EVENT_BUS.register( FurnaceRefuelHandler.INSTANCE ); + TurtleEvent.EVENT_BUS.register( new TurtlePermissions() ); + TurtleEvent.EVENT_BUS.register( new SignInspectHandler() ); } - public static void registerLoot() { - registerCondition("block_named", BlockNamedEntityLootCondition.TYPE); - registerCondition("player_creative", PlayerCreativeLootCondition.TYPE); - registerCondition("has_id", HasComputerIdLootCondition.TYPE); + public static void registerLoot() + { + registerCondition( "block_named", BlockNamedEntityLootCondition.TYPE ); + registerCondition( "player_creative", PlayerCreativeLootCondition.TYPE ); + registerCondition( "has_id", HasComputerIdLootCondition.TYPE ); } - private static void registerCondition(String name, LootConditionType serializer) { - Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, name), serializer); + private static void registerCondition( String name, LootConditionType serializer ) + { + Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, name ), serializer ); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java b/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java index 414613758..6ca4aaadd 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java +++ b/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java @@ -6,58 +6,65 @@ package dan200.computercraft.shared.turtle; -import javax.annotation.Nonnull; - import com.google.common.eventbus.Subscribe; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.event.TurtleRefuelEvent; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.ItemStorage; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.block.entity.FurnaceBlockEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler { +import javax.annotation.Nonnull; + +public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler +{ public static final FurnaceRefuelHandler INSTANCE = new FurnaceRefuelHandler(); - private FurnaceRefuelHandler() { + private FurnaceRefuelHandler() + { } @Subscribe - public static void onTurtleRefuel(TurtleRefuelEvent event) { - if (event.getHandler() == null && getFuelPerItem(event.getStack()) > 0) { - event.setHandler(INSTANCE); + public static void onTurtleRefuel( TurtleRefuelEvent event ) + { + if( event.getHandler() == null && getFuelPerItem( event.getStack() ) > 0 ) + { + event.setHandler( INSTANCE ); } } @Override - public int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack currentStack, int slot, int limit) { - ItemStorage storage = ItemStorage.wrap(turtle.getInventory()); - ItemStack stack = storage.take(slot, limit, ItemStack.EMPTY, false); - int fuelToGive = getFuelPerItem(stack) * stack.getCount(); + public int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack currentStack, int slot, int limit ) + { + ItemStorage storage = ItemStorage.wrap( turtle.getInventory() ); + ItemStack stack = storage.take( slot, limit, ItemStack.EMPTY, false ); + int fuelToGive = getFuelPerItem( stack ) * stack.getCount(); // Store the replacement item in the inventory Item replacementStack = stack.getItem() - .getRecipeRemainder(); - if (replacementStack != null) { - ItemStack remainder = InventoryUtil.storeItems(new ItemStack(replacementStack), storage, turtle.getSelectedSlot()); - if (!remainder.isEmpty()) { - WorldUtil.dropItemStack(remainder, - turtle.getWorld(), - turtle.getPosition(), - turtle.getDirection() - .getOpposite()); + .getRecipeRemainder(); + if( replacementStack != null ) + { + ItemStack remainder = InventoryUtil.storeItems( new ItemStack( replacementStack ), storage, turtle.getSelectedSlot() ); + if( !remainder.isEmpty() ) + { + WorldUtil.dropItemStack( remainder, + turtle.getWorld(), + turtle.getPosition(), + turtle.getDirection() + .getOpposite() ); } } return fuelToGive; } - private static int getFuelPerItem(@Nonnull ItemStack stack) { + private static int getFuelPerItem( @Nonnull ItemStack stack ) + { int burnTime = FurnaceBlockEntity.createFuelTimeMap() - .getOrDefault(stack.getItem(), 0); + .getOrDefault( stack.getItem(), 0 ); return (burnTime * 5) / 100; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/SignInspectHandler.java b/src/main/java/dan200/computercraft/shared/turtle/SignInspectHandler.java index 27bc2e98c..83308b347 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/SignInspectHandler.java +++ b/src/main/java/dan200/computercraft/shared/turtle/SignInspectHandler.java @@ -5,28 +5,30 @@ */ package dan200.computercraft.shared.turtle; -import java.util.HashMap; -import java.util.Map; - import com.google.common.eventbus.Subscribe; - import dan200.computercraft.api.turtle.event.TurtleBlockEvent; import dan200.computercraft.fabric.mixin.SignBlockEntityAccess; - import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.SignBlockEntity; -public class SignInspectHandler { +import java.util.HashMap; +import java.util.Map; + +public class SignInspectHandler +{ @Subscribe - public void onTurtleInspect(TurtleBlockEvent.Inspect event) { - BlockEntity be = event.getWorld().getBlockEntity(event.getPos()); - if (be instanceof SignBlockEntity) { - SignBlockEntity sbe = (SignBlockEntity)be; + public void onTurtleInspect( TurtleBlockEvent.Inspect event ) + { + BlockEntity be = event.getWorld().getBlockEntity( event.getPos() ); + if( be instanceof SignBlockEntity ) + { + SignBlockEntity sbe = (SignBlockEntity) be; Map textTable = new HashMap<>(); - for(int k = 0; k < 4; k++) { - textTable.put(k+1, ((SignBlockEntityAccess)sbe).getText()[k].asString()); + for( int k = 0; k < 4; k++ ) + { + textTable.put( k + 1, ((SignBlockEntityAccess) sbe).getText()[k].asString() ); } - event.getData().put("text", textTable); + event.getData().put( "text", textTable ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java b/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java index c10c2c1fd..f577bac63 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java +++ b/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java @@ -6,16 +6,7 @@ package dan200.computercraft.shared.turtle.apis; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.ILuaAPI; -import dan200.computercraft.api.lua.ILuaContext; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; -import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.lua.*; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleCommandResult; @@ -27,44 +18,33 @@ import dan200.computercraft.core.apis.IAPIEnvironment; import dan200.computercraft.core.asm.TaskCallback; import dan200.computercraft.core.tracking.TrackingField; import dan200.computercraft.shared.peripheral.generic.data.ItemData; -import dan200.computercraft.shared.turtle.core.InteractDirection; -import dan200.computercraft.shared.turtle.core.MoveDirection; -import dan200.computercraft.shared.turtle.core.TurnDirection; -import dan200.computercraft.shared.turtle.core.TurtleCompareCommand; -import dan200.computercraft.shared.turtle.core.TurtleCompareToCommand; -import dan200.computercraft.shared.turtle.core.TurtleDetectCommand; -import dan200.computercraft.shared.turtle.core.TurtleDropCommand; -import dan200.computercraft.shared.turtle.core.TurtleEquipCommand; -import dan200.computercraft.shared.turtle.core.TurtleInspectCommand; -import dan200.computercraft.shared.turtle.core.TurtleMoveCommand; -import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand; -import dan200.computercraft.shared.turtle.core.TurtleRefuelCommand; -import dan200.computercraft.shared.turtle.core.TurtleSuckCommand; -import dan200.computercraft.shared.turtle.core.TurtleToolCommand; -import dan200.computercraft.shared.turtle.core.TurtleTransferToCommand; -import dan200.computercraft.shared.turtle.core.TurtleTurnCommand; - -import net.minecraft.item.Item; +import dan200.computercraft.shared.turtle.core.*; import net.minecraft.item.ItemStack; -import net.minecraft.util.registry.Registry; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; /** * The turtle API allows you to control your turtle. * * @cc.module turtle */ -public class TurtleAPI implements ILuaAPI { +public class TurtleAPI implements ILuaAPI +{ private final IAPIEnvironment environment; private final ITurtleAccess turtle; - public TurtleAPI(IAPIEnvironment environment, ITurtleAccess turtle) { + public TurtleAPI( IAPIEnvironment environment, ITurtleAccess turtle ) + { this.environment = environment; this.turtle = turtle; } @Override - public String[] getNames() { - return new String[] {"turtle"}; + public String[] getNames() + { + return new String[] { "turtle" }; } /** @@ -75,13 +55,15 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the turtle could not move. */ @LuaFunction - public final MethodResult forward() { - return this.trackCommand(new TurtleMoveCommand(MoveDirection.FORWARD)); + public final MethodResult forward() + { + return this.trackCommand( new TurtleMoveCommand( MoveDirection.FORWARD ) ); } - private MethodResult trackCommand(ITurtleCommand command) { - this.environment.addTrackingChange(TrackingField.TURTLE_OPS); - return this.turtle.executeCommand(command); + private MethodResult trackCommand( ITurtleCommand command ) + { + this.environment.addTrackingChange( TrackingField.TURTLE_OPS ); + return this.turtle.executeCommand( command ); } /** @@ -92,8 +74,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the turtle could not move. */ @LuaFunction - public final MethodResult back() { - return this.trackCommand(new TurtleMoveCommand(MoveDirection.BACK)); + public final MethodResult back() + { + return this.trackCommand( new TurtleMoveCommand( MoveDirection.BACK ) ); } /** @@ -104,8 +87,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the turtle could not move. */ @LuaFunction - public final MethodResult up() { - return this.trackCommand(new TurtleMoveCommand(MoveDirection.UP)); + public final MethodResult up() + { + return this.trackCommand( new TurtleMoveCommand( MoveDirection.UP ) ); } /** @@ -116,8 +100,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the turtle could not move. */ @LuaFunction - public final MethodResult down() { - return this.trackCommand(new TurtleMoveCommand(MoveDirection.DOWN)); + public final MethodResult down() + { + return this.trackCommand( new TurtleMoveCommand( MoveDirection.DOWN ) ); } /** @@ -128,8 +113,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the turtle could not turn. */ @LuaFunction - public final MethodResult turnLeft() { - return this.trackCommand(new TurtleTurnCommand(TurnDirection.LEFT)); + public final MethodResult turnLeft() + { + return this.trackCommand( new TurtleTurnCommand( TurnDirection.LEFT ) ); } /** @@ -140,8 +126,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the turtle could not turn. */ @LuaFunction - public final MethodResult turnRight() { - return this.trackCommand(new TurtleTurnCommand(TurnDirection.RIGHT)); + public final MethodResult turnRight() + { + return this.trackCommand( new TurtleTurnCommand( TurnDirection.RIGHT ) ); } /** @@ -156,9 +143,10 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason no block was broken. */ @LuaFunction - public final MethodResult dig(Optional side) { - this.environment.addTrackingChange(TrackingField.TURTLE_OPS); - return this.trackCommand(TurtleToolCommand.dig(InteractDirection.FORWARD, side.orElse(null))); + public final MethodResult dig( Optional side ) + { + this.environment.addTrackingChange( TrackingField.TURTLE_OPS ); + return this.trackCommand( TurtleToolCommand.dig( InteractDirection.FORWARD, side.orElse( null ) ) ); } /** @@ -170,9 +158,10 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason no block was broken. */ @LuaFunction - public final MethodResult digUp(Optional side) { - this.environment.addTrackingChange(TrackingField.TURTLE_OPS); - return this.trackCommand(TurtleToolCommand.dig(InteractDirection.UP, side.orElse(null))); + public final MethodResult digUp( Optional side ) + { + this.environment.addTrackingChange( TrackingField.TURTLE_OPS ); + return this.trackCommand( TurtleToolCommand.dig( InteractDirection.UP, side.orElse( null ) ) ); } /** @@ -184,9 +173,10 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason no block was broken. */ @LuaFunction - public final MethodResult digDown(Optional side) { - this.environment.addTrackingChange(TrackingField.TURTLE_OPS); - return this.trackCommand(TurtleToolCommand.dig(InteractDirection.DOWN, side.orElse(null))); + public final MethodResult digDown( Optional side ) + { + this.environment.addTrackingChange( TrackingField.TURTLE_OPS ); + return this.trackCommand( TurtleToolCommand.dig( InteractDirection.DOWN, side.orElse( null ) ) ); } /** @@ -203,8 +193,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the block was not placed. */ @LuaFunction - public final MethodResult place(IArguments args) { - return this.trackCommand(new TurtlePlaceCommand(InteractDirection.FORWARD, args.getAll())); + public final MethodResult place( IArguments args ) + { + return this.trackCommand( new TurtlePlaceCommand( InteractDirection.FORWARD, args.getAll() ) ); } /** @@ -218,8 +209,9 @@ public class TurtleAPI implements ILuaAPI { * @see #place For more information about placing items. */ @LuaFunction - public final MethodResult placeUp(IArguments args) { - return this.trackCommand(new TurtlePlaceCommand(InteractDirection.UP, args.getAll())); + public final MethodResult placeUp( IArguments args ) + { + return this.trackCommand( new TurtlePlaceCommand( InteractDirection.UP, args.getAll() ) ); } /** @@ -233,8 +225,9 @@ public class TurtleAPI implements ILuaAPI { * @see #place For more information about placing items. */ @LuaFunction - public final MethodResult placeDown(IArguments args) { - return this.trackCommand(new TurtlePlaceCommand(InteractDirection.DOWN, args.getAll())); + public final MethodResult placeDown( IArguments args ) + { + return this.trackCommand( new TurtlePlaceCommand( InteractDirection.DOWN, args.getAll() ) ); } /** @@ -248,14 +241,17 @@ public class TurtleAPI implements ILuaAPI { * @see #select */ @LuaFunction - public final MethodResult drop(Optional count) throws LuaException { - return this.trackCommand(new TurtleDropCommand(InteractDirection.FORWARD, checkCount(count))); + public final MethodResult drop( Optional count ) throws LuaException + { + return this.trackCommand( new TurtleDropCommand( InteractDirection.FORWARD, checkCount( count ) ) ); } - private static int checkCount(Optional countArg) throws LuaException { - int count = countArg.orElse(64); - if (count < 0 || count > 64) { - throw new LuaException("Item count " + count + " out of range"); + private static int checkCount( Optional countArg ) throws LuaException + { + int count = countArg.orElse( 64 ); + if( count < 0 || count > 64 ) + { + throw new LuaException( "Item count " + count + " out of range" ); } return count; } @@ -271,8 +267,9 @@ public class TurtleAPI implements ILuaAPI { * @see #select */ @LuaFunction - public final MethodResult dropUp(Optional count) throws LuaException { - return this.trackCommand(new TurtleDropCommand(InteractDirection.UP, checkCount(count))); + public final MethodResult dropUp( Optional count ) throws LuaException + { + return this.trackCommand( new TurtleDropCommand( InteractDirection.UP, checkCount( count ) ) ); } /** @@ -286,8 +283,9 @@ public class TurtleAPI implements ILuaAPI { * @see #select */ @LuaFunction - public final MethodResult dropDown(Optional count) throws LuaException { - return this.trackCommand(new TurtleDropCommand(InteractDirection.DOWN, checkCount(count))); + public final MethodResult dropDown( Optional count ) throws LuaException + { + return this.trackCommand( new TurtleDropCommand( InteractDirection.DOWN, checkCount( count ) ) ); } /** @@ -303,17 +301,20 @@ public class TurtleAPI implements ILuaAPI { */ @LuaFunction - public final MethodResult select(int slot) throws LuaException { - int actualSlot = checkSlot(slot); - return this.turtle.executeCommand(turtle -> { - turtle.setSelectedSlot(actualSlot); + public final MethodResult select( int slot ) throws LuaException + { + int actualSlot = checkSlot( slot ); + return this.turtle.executeCommand( turtle -> { + turtle.setSelectedSlot( actualSlot ); return TurtleCommandResult.success(); - }); + } ); } - private static int checkSlot(int slot) throws LuaException { - if (slot < 1 || slot > 16) { - throw new LuaException("Slot number " + slot + " out of range"); + private static int checkSlot( int slot ) throws LuaException + { + if( slot < 1 || slot > 16 ) + { + throw new LuaException( "Slot number " + slot + " out of range" ); } return slot - 1; } @@ -326,15 +327,17 @@ public class TurtleAPI implements ILuaAPI { * @throws LuaException If the slot is out of range. */ @LuaFunction - public final int getItemCount(Optional slot) throws LuaException { - int actualSlot = checkSlot(slot).orElse(this.turtle.getSelectedSlot()); + public final int getItemCount( Optional slot ) throws LuaException + { + int actualSlot = checkSlot( slot ).orElse( this.turtle.getSelectedSlot() ); return this.turtle.getInventory() - .getStack(actualSlot) - .getCount(); + .getStack( actualSlot ) + .getCount(); } - private static Optional checkSlot(Optional slot) throws LuaException { - return slot.isPresent() ? Optional.of(checkSlot(slot.get())) : Optional.empty(); + private static Optional checkSlot( Optional slot ) throws LuaException + { + return slot.isPresent() ? Optional.of( checkSlot( slot.get() ) ) : Optional.empty(); } /** @@ -347,11 +350,12 @@ public class TurtleAPI implements ILuaAPI { * @throws LuaException If the slot is out of range. */ @LuaFunction - public final int getItemSpace(Optional slot) throws LuaException { - int actualSlot = checkSlot(slot).orElse(this.turtle.getSelectedSlot()); + public final int getItemSpace( Optional slot ) throws LuaException + { + int actualSlot = checkSlot( slot ).orElse( this.turtle.getSelectedSlot() ); ItemStack stack = this.turtle.getInventory() - .getStack(actualSlot); - return stack.isEmpty() ? 64 : Math.min(stack.getMaxCount(), 64) - stack.getCount(); + .getStack( actualSlot ); + return stack.isEmpty() ? 64 : Math.min( stack.getMaxCount(), 64 ) - stack.getCount(); } /** @@ -361,8 +365,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If there is a solid block in front. */ @LuaFunction - public final MethodResult detect() { - return this.trackCommand(new TurtleDetectCommand(InteractDirection.FORWARD)); + public final MethodResult detect() + { + return this.trackCommand( new TurtleDetectCommand( InteractDirection.FORWARD ) ); } /** @@ -372,8 +377,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If there is a solid block in front. */ @LuaFunction - public final MethodResult detectUp() { - return this.trackCommand(new TurtleDetectCommand(InteractDirection.UP)); + public final MethodResult detectUp() + { + return this.trackCommand( new TurtleDetectCommand( InteractDirection.UP ) ); } /** @@ -383,8 +389,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If there is a solid block in front. */ @LuaFunction - public final MethodResult detectDown() { - return this.trackCommand(new TurtleDetectCommand(InteractDirection.DOWN)); + public final MethodResult detectDown() + { + return this.trackCommand( new TurtleDetectCommand( InteractDirection.DOWN ) ); } /** @@ -394,8 +401,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If the block and item are equal. */ @LuaFunction - public final MethodResult compare() { - return this.trackCommand(new TurtleCompareCommand(InteractDirection.FORWARD)); + public final MethodResult compare() + { + return this.trackCommand( new TurtleCompareCommand( InteractDirection.FORWARD ) ); } /** @@ -405,8 +413,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If the block and item are equal. */ @LuaFunction - public final MethodResult compareUp() { - return this.trackCommand(new TurtleCompareCommand(InteractDirection.UP)); + public final MethodResult compareUp() + { + return this.trackCommand( new TurtleCompareCommand( InteractDirection.UP ) ); } /** @@ -416,8 +425,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If the block and item are equal. */ @LuaFunction - public final MethodResult compareDown() { - return this.trackCommand(new TurtleCompareCommand(InteractDirection.DOWN)); + public final MethodResult compareDown() + { + return this.trackCommand( new TurtleCompareCommand( InteractDirection.DOWN ) ); } /** @@ -429,8 +439,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason nothing was attacked. */ @LuaFunction - public final MethodResult attack(Optional side) { - return this.trackCommand(TurtleToolCommand.attack(InteractDirection.FORWARD, side.orElse(null))); + public final MethodResult attack( Optional side ) + { + return this.trackCommand( TurtleToolCommand.attack( InteractDirection.FORWARD, side.orElse( null ) ) ); } /** @@ -442,8 +453,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason nothing was attacked. */ @LuaFunction - public final MethodResult attackUp(Optional side) { - return this.trackCommand(TurtleToolCommand.attack(InteractDirection.UP, side.orElse(null))); + public final MethodResult attackUp( Optional side ) + { + return this.trackCommand( TurtleToolCommand.attack( InteractDirection.UP, side.orElse( null ) ) ); } /** @@ -455,8 +467,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason nothing was attacked. */ @LuaFunction - public final MethodResult attackDown(Optional side) { - return this.trackCommand(TurtleToolCommand.attack(InteractDirection.DOWN, side.orElse(null))); + public final MethodResult attackDown( Optional side ) + { + return this.trackCommand( TurtleToolCommand.attack( InteractDirection.DOWN, side.orElse( null ) ) ); } /** @@ -471,8 +484,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the no items were picked up. */ @LuaFunction - public final MethodResult suck(Optional count) throws LuaException { - return this.trackCommand(new TurtleSuckCommand(InteractDirection.FORWARD, checkCount(count))); + public final MethodResult suck( Optional count ) throws LuaException + { + return this.trackCommand( new TurtleSuckCommand( InteractDirection.FORWARD, checkCount( count ) ) ); } /** @@ -485,8 +499,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the no items were picked up. */ @LuaFunction - public final MethodResult suckUp(Optional count) throws LuaException { - return this.trackCommand(new TurtleSuckCommand(InteractDirection.UP, checkCount(count))); + public final MethodResult suckUp( Optional count ) throws LuaException + { + return this.trackCommand( new TurtleSuckCommand( InteractDirection.UP, checkCount( count ) ) ); } /** @@ -499,8 +514,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn string|nil The reason the no items were picked up. */ @LuaFunction - public final MethodResult suckDown(Optional count) throws LuaException { - return this.trackCommand(new TurtleSuckCommand(InteractDirection.DOWN, checkCount(count))); + public final MethodResult suckDown( Optional count ) throws LuaException + { + return this.trackCommand( new TurtleSuckCommand( InteractDirection.DOWN, checkCount( count ) ) ); } /** @@ -513,7 +529,8 @@ public class TurtleAPI implements ILuaAPI { * @see #refuel(Optional) */ @LuaFunction - public final Object getFuelLevel() { + public final Object getFuelLevel() + { return this.turtle.isFuelNeeded() ? this.turtle.getFuelLevel() : "unlimited"; } @@ -554,12 +571,14 @@ public class TurtleAPI implements ILuaAPI { * @see #getFuelLimit() */ @LuaFunction - public final MethodResult refuel(Optional countA) throws LuaException { - int count = countA.orElse(Integer.MAX_VALUE); - if (count < 0) { - throw new LuaException("Refuel count " + count + " out of range"); + public final MethodResult refuel( Optional countA ) throws LuaException + { + int count = countA.orElse( Integer.MAX_VALUE ); + if( count < 0 ) + { + throw new LuaException( "Refuel count " + count + " out of range" ); } - return this.trackCommand(new TurtleRefuelCommand(count)); + return this.trackCommand( new TurtleRefuelCommand( count ) ); } /** @@ -571,8 +590,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If the two items are equal. */ @LuaFunction - public final MethodResult compareTo(int slot) throws LuaException { - return this.trackCommand(new TurtleCompareToCommand(checkSlot(slot))); + public final MethodResult compareTo( int slot ) throws LuaException + { + return this.trackCommand( new TurtleCompareToCommand( checkSlot( slot ) ) ); } /** @@ -586,10 +606,11 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn boolean If some items were successfully moved. */ @LuaFunction - public final MethodResult transferTo(int slotArg, Optional countArg) throws LuaException { - int slot = checkSlot(slotArg); - int count = checkCount(countArg); - return this.trackCommand(new TurtleTransferToCommand(slot, count)); + public final MethodResult transferTo( int slotArg, Optional countArg ) throws LuaException + { + int slot = checkSlot( slotArg ); + int count = checkCount( countArg ); + return this.trackCommand( new TurtleTransferToCommand( slot, count ) ); } /** @@ -599,7 +620,8 @@ public class TurtleAPI implements ILuaAPI { * @see #select */ @LuaFunction - public final int getSelectedSlot() { + public final int getSelectedSlot() + { return this.turtle.getSelectedSlot() + 1; } @@ -615,7 +637,8 @@ public class TurtleAPI implements ILuaAPI { * @see #refuel(Optional) */ @LuaFunction - public final Object getFuelLimit() { + public final Object getFuelLimit() + { return this.turtle.isFuelNeeded() ? this.turtle.getFuelLimit() : "unlimited"; } @@ -633,8 +656,9 @@ public class TurtleAPI implements ILuaAPI { * @see #equipRight() */ @LuaFunction - public final MethodResult equipLeft() { - return this.trackCommand(new TurtleEquipCommand(TurtleSide.LEFT)); + public final MethodResult equipLeft() + { + return this.trackCommand( new TurtleEquipCommand( TurtleSide.LEFT ) ); } /** @@ -651,8 +675,9 @@ public class TurtleAPI implements ILuaAPI { * @see #equipRight() */ @LuaFunction - public final MethodResult equipRight() { - return this.trackCommand(new TurtleEquipCommand(TurtleSide.RIGHT)); + public final MethodResult equipRight() + { + return this.trackCommand( new TurtleEquipCommand( TurtleSide.RIGHT ) ); } /** @@ -675,8 +700,9 @@ public class TurtleAPI implements ILuaAPI { * end}
    */ @LuaFunction - public final MethodResult inspect() { - return this.trackCommand(new TurtleInspectCommand(InteractDirection.FORWARD)); + public final MethodResult inspect() + { + return this.trackCommand( new TurtleInspectCommand( InteractDirection.FORWARD ) ); } /** @@ -687,8 +713,9 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn table|string Information about the above below, or a message explaining that there is no block. */ @LuaFunction - public final MethodResult inspectUp() { - return this.trackCommand(new TurtleInspectCommand(InteractDirection.UP)); + public final MethodResult inspectUp() + { + return this.trackCommand( new TurtleInspectCommand( InteractDirection.UP ) ); } /** @@ -699,57 +726,62 @@ public class TurtleAPI implements ILuaAPI { * @cc.treturn table|string Information about the block below, or a message explaining that there is no block. */ @LuaFunction - public final MethodResult inspectDown() { - return this.trackCommand(new TurtleInspectCommand(InteractDirection.DOWN)); + public final MethodResult inspectDown() + { + return this.trackCommand( new TurtleInspectCommand( InteractDirection.DOWN ) ); } /** * Get detailed information about the items in the given slot. * - * @param context The Lua context - * @param slot The slot to get information about. Defaults to the {@link #select selected slot}. + * @param context The Lua context + * @param slot The slot to get information about. Defaults to the {@link #select selected slot}. * @param detailed Whether to include "detailed" information. When {@code true} the method will contain much more information about the item at the - * cost of taking longer to run. + * cost of taking longer to run. * @return The command result. * @throws LuaException If the slot is out of range. - * @see InventoryMethods#getItemDetail Describes the information returned by a detailed query. * @cc.treturn nil|table Information about the given slot, or {@code nil} if it is empty. * @cc.usage Print the current slot, assuming it contains 13 dirt. * - *
    {@code
    +     * 
    {@code
          *     print(textutils.serialize(turtle.getItemDetail()))
          *     -- => {
          *     --  name = "minecraft:dirt",
          *     --  count = 13,
          *     -- }
          *     }
    + * @see InventoryMethods#getItemDetail Describes the information returned by a detailed query. */ @LuaFunction - public final MethodResult getItemDetail(ILuaContext context, Optional slot, Optional detailed) throws LuaException { - int actualSlot = checkSlot(slot).orElse(this.turtle.getSelectedSlot()); - return detailed.orElse(false) ? TaskCallback.make(context, () -> this.getItemDetail(actualSlot, true)) : MethodResult.of(this.getItemDetail(actualSlot, - false)); + public final MethodResult getItemDetail( ILuaContext context, Optional slot, Optional detailed ) throws LuaException + { + int actualSlot = checkSlot( slot ).orElse( this.turtle.getSelectedSlot() ); + return detailed.orElse( false ) ? TaskCallback.make( context, () -> this.getItemDetail( actualSlot, true ) ) : MethodResult.of( this.getItemDetail( actualSlot, + false ) ); } - private Object[] getItemDetail(int slot, boolean detailed) { + private Object[] getItemDetail( int slot, boolean detailed ) + { ItemStack stack = this.turtle.getInventory() - .getStack(slot); - if (stack.isEmpty()) { - return new Object[] {null}; + .getStack( slot ); + if( stack.isEmpty() ) + { + return new Object[] { null }; } Map table = detailed ? ItemData.fill( new HashMap<>(), stack ) : ItemData.fillBasicSafe( new HashMap<>(), stack ); - TurtleActionEvent event = new TurtleInspectItemEvent(this.turtle, stack, table, detailed); - if (TurtleEvent.post(event)) { + TurtleActionEvent event = new TurtleInspectItemEvent( this.turtle, stack, table, detailed ); + if( TurtleEvent.post( event ) ) + { return new Object[] { false, event.getFailureMessage() }; } - return new Object[] {table}; + return new Object[] { table }; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java index 7abb6e687..cdecd21fd 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java @@ -6,14 +6,6 @@ package dan200.computercraft.shared.turtle.blocks; -import static dan200.computercraft.shared.util.WaterloggableHelpers.getWaterloggedFluidState; -import static dan200.computercraft.shared.util.WaterloggableHelpers.getWaterloggedStateForPlacement; -import static dan200.computercraft.shared.util.WaterloggableHelpers.updateWaterloggedPostPlacement; -import static net.minecraft.state.property.Properties.WATERLOGGED; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.computer.blocks.BlockComputerBase; import dan200.computercraft.shared.computer.blocks.TileComputerBase; @@ -21,12 +13,7 @@ import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.turtle.core.TurtleBrain; import dan200.computercraft.shared.turtle.items.ITurtleItem; import dan200.computercraft.shared.turtle.items.TurtleItemFactory; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockRenderType; -import net.minecraft.block.BlockState; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.Waterloggable; +import net.minecraft.block.*; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.LivingEntity; @@ -47,72 +34,88 @@ import net.minecraft.world.BlockView; import net.minecraft.world.World; import net.minecraft.world.WorldAccess; -public class BlockTurtle extends BlockComputerBase implements Waterloggable { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import static dan200.computercraft.shared.util.WaterloggableHelpers.*; +import static net.minecraft.state.property.Properties.WATERLOGGED; + +public class BlockTurtle extends BlockComputerBase implements Waterloggable +{ public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; - private static final VoxelShape DEFAULT_SHAPE = VoxelShapes.cuboid(0.125, 0.125, 0.125, 0.875, 0.875, 0.875); + private static final VoxelShape DEFAULT_SHAPE = VoxelShapes.cuboid( 0.125, 0.125, 0.125, 0.875, 0.875, 0.875 ); - public BlockTurtle(Settings settings, ComputerFamily family, BlockEntityType type) { - super(settings, family, type); - this.setDefaultState(this.getStateManager().getDefaultState() - .with(FACING, Direction.NORTH) - .with(WATERLOGGED, false)); + public BlockTurtle( Settings settings, ComputerFamily family, BlockEntityType type ) + { + super( settings, family, type ); + this.setDefaultState( this.getStateManager().getDefaultState() + .with( FACING, Direction.NORTH ) + .with( WATERLOGGED, false ) ); } @Nonnull @Override @Deprecated - public BlockRenderType getRenderType(@Nonnull BlockState state) { + public BlockRenderType getRenderType( @Nonnull BlockState state ) + { return BlockRenderType.ENTITYBLOCK_ANIMATED; } @Nonnull @Override @Deprecated - public BlockState getStateForNeighborUpdate(@Nonnull BlockState state, @Nonnull Direction side, @Nonnull BlockState otherState, - @Nonnull WorldAccess world, @Nonnull BlockPos pos, @Nonnull BlockPos otherPos) { - updateWaterloggedPostPlacement(state, world, pos); + public BlockState getStateForNeighborUpdate( @Nonnull BlockState state, @Nonnull Direction side, @Nonnull BlockState otherState, + @Nonnull WorldAccess world, @Nonnull BlockPos pos, @Nonnull BlockPos otherPos ) + { + updateWaterloggedPostPlacement( state, world, pos ); return state; } @Nonnull @Override @Deprecated - public FluidState getFluidState(@Nonnull BlockState state) { - return getWaterloggedFluidState(state); + public FluidState getFluidState( @Nonnull BlockState state ) + { + return getWaterloggedFluidState( state ); } @Nonnull @Override @Deprecated - public VoxelShape getOutlineShape(@Nonnull BlockState state, BlockView world, @Nonnull BlockPos pos, @Nonnull ShapeContext context) { - BlockEntity tile = world.getBlockEntity(pos); - Vec3d offset = tile instanceof TileTurtle ? ((TileTurtle) tile).getRenderOffset(1.0f) : Vec3d.ZERO; - return offset.equals(Vec3d.ZERO) ? DEFAULT_SHAPE : DEFAULT_SHAPE.offset(offset.x, offset.y, offset.z); + public VoxelShape getOutlineShape( @Nonnull BlockState state, BlockView world, @Nonnull BlockPos pos, @Nonnull ShapeContext context ) + { + BlockEntity tile = world.getBlockEntity( pos ); + Vec3d offset = tile instanceof TileTurtle ? ((TileTurtle) tile).getRenderOffset( 1.0f ) : Vec3d.ZERO; + return offset.equals( Vec3d.ZERO ) ? DEFAULT_SHAPE : DEFAULT_SHAPE.offset( offset.x, offset.y, offset.z ); } @Override - public float getBlastResistance() { + public float getBlastResistance() + { // TODO Implement below functionality return 2000; } @Nullable @Override - public BlockState getPlacementState(ItemPlacementContext placement) { - return this.getDefaultState().with(FACING, placement.getPlayerFacing()) - .with(WATERLOGGED, getWaterloggedStateForPlacement(placement)); + public BlockState getPlacementState( ItemPlacementContext placement ) + { + return this.getDefaultState().with( FACING, placement.getPlayerFacing() ) + .with( WATERLOGGED, getWaterloggedStateForPlacement( placement ) ); } @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(FACING, WATERLOGGED); + protected void appendProperties( StateManager.Builder builder ) + { + builder.add( FACING, WATERLOGGED ); } @Nonnull @Override - protected ItemStack getItem(TileComputerBase tile) { - return tile instanceof TileTurtle ? TurtleItemFactory.create((TileTurtle) tile) : ItemStack.EMPTY; + protected ItemStack getItem( TileComputerBase tile ) + { + return tile instanceof TileTurtle ? TurtleItemFactory.create( (TileTurtle) tile ) : ItemStack.EMPTY; } // @Override @@ -128,40 +131,47 @@ public class BlockTurtle extends BlockComputerBase implements Waterl // } @Override - public void onPlaced(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable LivingEntity player, @Nonnull ItemStack stack) { - super.onPlaced(world, pos, state, player, stack); + public void onPlaced( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable LivingEntity player, @Nonnull ItemStack stack ) + { + super.onPlaced( world, pos, state, player, stack ); - BlockEntity tile = world.getBlockEntity(pos); - if (!world.isClient && tile instanceof TileTurtle) { + BlockEntity tile = world.getBlockEntity( pos ); + if( !world.isClient && tile instanceof TileTurtle ) + { TileTurtle turtle = (TileTurtle) tile; - if (player instanceof PlayerEntity) { - ((TileTurtle) tile).setOwningPlayer(((PlayerEntity) player).getGameProfile()); + if( player instanceof PlayerEntity ) + { + ((TileTurtle) tile).setOwningPlayer( ((PlayerEntity) player).getGameProfile() ); } - if (stack.getItem() instanceof ITurtleItem) { + if( stack.getItem() instanceof ITurtleItem ) + { ITurtleItem item = (ITurtleItem) stack.getItem(); // Set Upgrades - for (TurtleSide side : TurtleSide.values()) { + for( TurtleSide side : TurtleSide.values() ) + { turtle.getAccess() - .setUpgrade(side, item.getUpgrade(stack, side)); + .setUpgrade( side, item.getUpgrade( stack, side ) ); } turtle.getAccess() - .setFuelLevel(item.getFuelLevel(stack)); + .setFuelLevel( item.getFuelLevel( stack ) ); // Set colour - int colour = item.getColour(stack); - if (colour != -1) { + int colour = item.getColour( stack ); + if( colour != -1 ) + { turtle.getAccess() - .setColour(colour); + .setColour( colour ); } // Set overlay - Identifier overlay = item.getOverlay(stack); - if (overlay != null) { - ((TurtleBrain) turtle.getAccess()).setOverlay(overlay); + Identifier overlay = item.getOverlay( stack ); + if( overlay != null ) + { + ((TurtleBrain) turtle.getAccess()).setOverlay( overlay ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/ITurtleTile.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/ITurtleTile.java index 894afcd8e..38224df84 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/ITurtleTile.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/ITurtleTile.java @@ -10,22 +10,22 @@ import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.computer.blocks.IComputerTile; - import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec3d; -public interface ITurtleTile extends IComputerTile { +public interface ITurtleTile extends IComputerTile +{ int getColour(); Identifier getOverlay(); - ITurtleUpgrade getUpgrade(TurtleSide side); + ITurtleUpgrade getUpgrade( TurtleSide side ); ITurtleAccess getAccess(); - Vec3d getRenderOffset(float f); + Vec3d getRenderOffset( float f ); - float getRenderYaw(float f); + float getRenderYaw( float f ); - float getToolRenderAngle(TurtleSide side, float f); + float getToolRenderAngle( TurtleSide side, float f ); } diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java index 118de826c..091d757f9 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.turtle.blocks; -import java.util.Collections; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.mojang.authlib.GameProfile; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.ITurtleAccess; @@ -26,13 +21,7 @@ import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.turtle.apis.TurtleAPI; import dan200.computercraft.shared.turtle.core.TurtleBrain; import dan200.computercraft.shared.turtle.inventory.ContainerTurtle; -import dan200.computercraft.shared.util.DefaultInventory; -import dan200.computercraft.shared.util.DirectionUtil; -import dan200.computercraft.shared.util.InventoryUtil; -import dan200.computercraft.shared.util.NBTUtil; -import dan200.computercraft.shared.util.RedstoneUtil; -import dan200.computercraft.shared.util.WorldUtil; - +import dan200.computercraft.shared.util.*; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; @@ -53,63 +42,85 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; -public class TileTurtle extends TileComputerBase implements ITurtleTile, DefaultInventory { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; + +public class TileTurtle extends TileComputerBase implements ITurtleTile, DefaultInventory +{ public static final int INVENTORY_SIZE = 16; public static final int INVENTORY_WIDTH = 4; public static final int INVENTORY_HEIGHT = 4; - private final DefaultedList m_inventory = DefaultedList.ofSize(INVENTORY_SIZE, ItemStack.EMPTY); - private final DefaultedList m_previousInventory = DefaultedList.ofSize(INVENTORY_SIZE, ItemStack.EMPTY); + private final DefaultedList m_inventory = DefaultedList.ofSize( INVENTORY_SIZE, ItemStack.EMPTY ); + private final DefaultedList m_previousInventory = DefaultedList.ofSize( INVENTORY_SIZE, ItemStack.EMPTY ); private boolean m_inventoryChanged = false; - private TurtleBrain m_brain = new TurtleBrain(this); + private TurtleBrain m_brain = new TurtleBrain( this ); private MoveState m_moveState = MoveState.NOT_MOVED; - public TileTurtle(BlockEntityType type, ComputerFamily family) { - super(type, family); + + public TileTurtle( BlockEntityType type, ComputerFamily family ) + { + super( type, family ); } @Override - protected void unload() { - if (!this.hasMoved()) { + protected void unload() + { + if( !this.hasMoved() ) + { super.unload(); } } @Override - public void destroy() { - if (!this.hasMoved()) { + public void destroy() + { + if( !this.hasMoved() ) + { // Stop computer super.destroy(); // Drop contents - if (!this.getWorld().isClient) { + if( !this.getWorld().isClient ) + { int size = this.size(); - for (int i = 0; i < size; i++) { - ItemStack stack = this.getStack(i); - if (!stack.isEmpty()) { - WorldUtil.dropItemStack(stack, this.getWorld(), this.getPos()); + for( int i = 0; i < size; i++ ) + { + ItemStack stack = this.getStack( i ); + if( !stack.isEmpty() ) + { + WorldUtil.dropItemStack( stack, this.getWorld(), this.getPos() ); } } } - } else { + } + else + { // Just turn off any redstone we had on - for (Direction dir : DirectionUtil.FACINGS) { - RedstoneUtil.propagateRedstoneOutput(this.getWorld(), this.getPos(), dir); + for( Direction dir : DirectionUtil.FACINGS ) + { + RedstoneUtil.propagateRedstoneOutput( this.getWorld(), this.getPos(), dir ); } } } - private boolean hasMoved() { + private boolean hasMoved() + { return this.m_moveState == MoveState.MOVED; } @Override - public int size() { + public int size() + { return INVENTORY_SIZE; } @Override - public boolean isEmpty() { - for (ItemStack stack : this.m_inventory) { - if (!stack.isEmpty()) { + public boolean isEmpty() + { + for( ItemStack stack : this.m_inventory ) + { + if( !stack.isEmpty() ) + { return false; } } @@ -118,88 +129,110 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default @Nonnull @Override - public ItemStack getStack(int slot) { - return slot >= 0 && slot < INVENTORY_SIZE ? this.m_inventory.get(slot) : ItemStack.EMPTY; + public ItemStack getStack( int slot ) + { + return slot >= 0 && slot < INVENTORY_SIZE ? this.m_inventory.get( slot ) : ItemStack.EMPTY; } @Nonnull @Override - public ItemStack removeStack(int slot, int count) { - if (count == 0) { + public ItemStack removeStack( int slot, int count ) + { + if( count == 0 ) + { return ItemStack.EMPTY; } - ItemStack stack = this.getStack(slot); - if (stack.isEmpty()) { + ItemStack stack = this.getStack( slot ); + if( stack.isEmpty() ) + { return ItemStack.EMPTY; } - if (stack.getCount() <= count) { - this.setStack(slot, ItemStack.EMPTY); + if( stack.getCount() <= count ) + { + this.setStack( slot, ItemStack.EMPTY ); return stack; } - ItemStack part = stack.split(count); + ItemStack part = stack.split( count ); this.onInventoryDefinitelyChanged(); return part; } @Nonnull @Override - public ItemStack removeStack(int slot) { - ItemStack result = this.getStack(slot); - this.setStack(slot, ItemStack.EMPTY); + public ItemStack removeStack( int slot ) + { + ItemStack result = this.getStack( slot ); + this.setStack( slot, ItemStack.EMPTY ); return result; } @Override - public void setStack(int i, @Nonnull ItemStack stack) { - if (i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual(stack, this.m_inventory.get(i))) { - this.m_inventory.set(i, stack); + public void setStack( int i, @Nonnull ItemStack stack ) + { + if( i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual( stack, this.m_inventory.get( i ) ) ) + { + this.m_inventory.set( i, stack ); this.onInventoryDefinitelyChanged(); } } @Override - public boolean canPlayerUse(@Nonnull PlayerEntity player) { - return this.isUsable(player, false); + public boolean canPlayerUse( @Nonnull PlayerEntity player ) + { + return this.isUsable( player, false ); } - private void onInventoryDefinitelyChanged() { + private void onInventoryDefinitelyChanged() + { super.markDirty(); this.m_inventoryChanged = true; } @Override - protected boolean canNameWithTag(PlayerEntity player) { + protected boolean canNameWithTag( PlayerEntity player ) + { return true; } @Nonnull @Override - public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) { + public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit ) + { // Apply dye - ItemStack currentItem = player.getStackInHand(hand); - if (!currentItem.isEmpty()) { - if (currentItem.getItem() instanceof DyeItem) { + ItemStack currentItem = player.getStackInHand( hand ); + if( !currentItem.isEmpty() ) + { + if( currentItem.getItem() instanceof DyeItem ) + { // Dye to change turtle colour - if (!this.getWorld().isClient) { + if( !this.getWorld().isClient ) + { DyeColor dye = ((DyeItem) currentItem.getItem()).getColor(); - if (this.m_brain.getDyeColour() != dye) { - this.m_brain.setDyeColour(dye); - if (!player.isCreative()) { - currentItem.decrement(1); + if( this.m_brain.getDyeColour() != dye ) + { + this.m_brain.setDyeColour( dye ); + if( !player.isCreative() ) + { + currentItem.decrement( 1 ); } } } return ActionResult.SUCCESS; - } else if (currentItem.getItem() == Items.WATER_BUCKET && this.m_brain.getColour() != -1) { + } + else if( currentItem.getItem() == Items.WATER_BUCKET && this.m_brain.getColour() != -1 ) + { // Water to remove turtle colour - if (!this.getWorld().isClient) { - if (this.m_brain.getColour() != -1) { - this.m_brain.setColour(-1); - if (!player.isCreative()) { - player.setStackInHand(hand, new ItemStack(Items.BUCKET)); + if( !this.getWorld().isClient ) + { + if( this.m_brain.getColour() != -1 ) + { + this.m_brain.setColour( -1 ); + if( !player.isCreative() ) + { + player.setStackInHand( hand, new ItemStack( Items.BUCKET ) ); player.inventory.markDirty(); } } @@ -209,233 +242,276 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default } // Open GUI or whatever - return super.onActivate(player, hand, hit); + return super.onActivate( player, hand, hit ); } @Override - public void onNeighbourChange(@Nonnull BlockPos neighbour) { - if (this.m_moveState == MoveState.NOT_MOVED) { - super.onNeighbourChange(neighbour); + public void onNeighbourChange( @Nonnull BlockPos neighbour ) + { + if( this.m_moveState == MoveState.NOT_MOVED ) + { + super.onNeighbourChange( neighbour ); } } @Override - public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) { - if (this.m_moveState == MoveState.NOT_MOVED) { - super.onNeighbourTileEntityChange(neighbour); + public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour ) + { + if( this.m_moveState == MoveState.NOT_MOVED ) + { + super.onNeighbourTileEntityChange( neighbour ); } } @Override - public void tick() { + public void tick() + { super.tick(); this.m_brain.update(); - if (!this.getWorld().isClient && this.m_inventoryChanged) { + if( !this.getWorld().isClient && this.m_inventoryChanged ) + { ServerComputer computer = this.getServerComputer(); - if (computer != null) { - computer.queueEvent("turtle_inventory"); + if( computer != null ) + { + computer.queueEvent( "turtle_inventory" ); } this.m_inventoryChanged = false; - for (int n = 0; n < this.size(); n++) { - this.m_previousInventory.set(n, - this.getStack(n).copy()); + for( int n = 0; n < this.size(); n++ ) + { + this.m_previousInventory.set( n, + this.getStack( n ).copy() ); } } } @Override - protected void updateBlockState(ComputerState newState) { + protected void updateBlockState( ComputerState newState ) + { } @Nonnull @Override - public CompoundTag toTag(@Nonnull CompoundTag nbt) { + public CompoundTag toTag( @Nonnull CompoundTag nbt ) + { // Write inventory ListTag nbttaglist = new ListTag(); - for (int i = 0; i < INVENTORY_SIZE; i++) { - if (!this.m_inventory.get(i) - .isEmpty()) { + for( int i = 0; i < INVENTORY_SIZE; i++ ) + { + if( !this.m_inventory.get( i ) + .isEmpty() ) + { CompoundTag tag = new CompoundTag(); - tag.putByte("Slot", (byte) i); - this.m_inventory.get(i) - .toTag(tag); - nbttaglist.add(tag); + tag.putByte( "Slot", (byte) i ); + this.m_inventory.get( i ) + .toTag( tag ); + nbttaglist.add( tag ); } } - nbt.put("Items", nbttaglist); + nbt.put( "Items", nbttaglist ); // Write brain - nbt = this.m_brain.writeToNBT(nbt); + nbt = this.m_brain.writeToNBT( nbt ); - return super.toTag(nbt); + return super.toTag( nbt ); } // IDirectionalTile @Override - public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) { - super.fromTag(state, nbt); + public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt ) + { + super.fromTag( state, nbt ); // Read inventory - ListTag nbttaglist = nbt.getList("Items", NBTUtil.TAG_COMPOUND); + ListTag nbttaglist = nbt.getList( "Items", NBTUtil.TAG_COMPOUND ); this.m_inventory.clear(); this.m_previousInventory.clear(); - for (int i = 0; i < nbttaglist.size(); i++) { - CompoundTag tag = nbttaglist.getCompound(i); - int slot = tag.getByte("Slot") & 0xff; - if (slot < this.size()) { - this.m_inventory.set(slot, ItemStack.fromTag(tag)); - this.m_previousInventory.set(slot, this.m_inventory.get(slot) - .copy()); + for( int i = 0; i < nbttaglist.size(); i++ ) + { + CompoundTag tag = nbttaglist.getCompound( i ); + int slot = tag.getByte( "Slot" ) & 0xff; + if( slot < this.size() ) + { + this.m_inventory.set( slot, ItemStack.fromTag( tag ) ); + this.m_previousInventory.set( slot, this.m_inventory.get( slot ) + .copy() ); } } // Read state - this.m_brain.readFromNBT(nbt); + this.m_brain.readFromNBT( nbt ); } @Override - protected boolean isPeripheralBlockedOnSide(ComputerSide localSide) { - return this.hasPeripheralUpgradeOnSide(localSide); + protected boolean isPeripheralBlockedOnSide( ComputerSide localSide ) + { + return this.hasPeripheralUpgradeOnSide( localSide ); } // ITurtleTile @Override - public Direction getDirection() { - return this.getCachedState().get(BlockTurtle.FACING); + public Direction getDirection() + { + return this.getCachedState().get( BlockTurtle.FACING ); } @Override - protected ServerComputer createComputer(int instanceID, int id) { - ServerComputer computer = new ServerComputer(this.getWorld(), - id, this.label, - instanceID, this.getFamily(), - ComputerCraft.turtleTermWidth, - ComputerCraft.turtleTermHeight); - computer.setPosition(this.getPos()); - computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), this.getAccess())); - this.m_brain.setupComputer(computer); + protected ServerComputer createComputer( int instanceID, int id ) + { + ServerComputer computer = new ServerComputer( this.getWorld(), + id, this.label, + instanceID, this.getFamily(), + ComputerCraft.turtleTermWidth, + ComputerCraft.turtleTermHeight ); + computer.setPosition( this.getPos() ); + computer.addAPI( new TurtleAPI( computer.getAPIEnvironment(), this.getAccess() ) ); + this.m_brain.setupComputer( computer ); return computer; } @Override - protected void writeDescription(@Nonnull CompoundTag nbt) { - super.writeDescription(nbt); - this.m_brain.writeDescription(nbt); + protected void writeDescription( @Nonnull CompoundTag nbt ) + { + super.writeDescription( nbt ); + this.m_brain.writeDescription( nbt ); } @Override - protected void readDescription(@Nonnull CompoundTag nbt) { - super.readDescription(nbt); - this.m_brain.readDescription(nbt); + protected void readDescription( @Nonnull CompoundTag nbt ) + { + super.readDescription( nbt ); + this.m_brain.readDescription( nbt ); } @Override - public ComputerProxy createProxy() { + public ComputerProxy createProxy() + { return this.m_brain.getProxy(); } - public void setDirection(Direction dir) { - if (dir.getAxis() == Direction.Axis.Y) { + public void setDirection( Direction dir ) + { + if( dir.getAxis() == Direction.Axis.Y ) + { dir = Direction.NORTH; } - this.world.setBlockState(this.pos, - this.getCachedState().with(BlockTurtle.FACING, dir)); + this.world.setBlockState( this.pos, + this.getCachedState().with( BlockTurtle.FACING, dir ) ); this.updateOutput(); this.updateInput(); this.onTileEntityChange(); } - public void onTileEntityChange() { + public void onTileEntityChange() + { super.markDirty(); } - private boolean hasPeripheralUpgradeOnSide(ComputerSide side) { + private boolean hasPeripheralUpgradeOnSide( ComputerSide side ) + { ITurtleUpgrade upgrade; - switch (side) { - case RIGHT: - upgrade = this.getUpgrade(TurtleSide.RIGHT); - break; - case LEFT: - upgrade = this.getUpgrade(TurtleSide.LEFT); - break; - default: - return false; + switch( side ) + { + case RIGHT: + upgrade = this.getUpgrade( TurtleSide.RIGHT ); + break; + case LEFT: + upgrade = this.getUpgrade( TurtleSide.LEFT ); + break; + default: + return false; } return upgrade != null && upgrade.getType() - .isPeripheral(); + .isPeripheral(); } // IInventory @Override - protected double getInteractRange(PlayerEntity player) { + protected double getInteractRange( PlayerEntity player ) + { return 12.0; } - public void notifyMoveStart() { - if (this.m_moveState == MoveState.NOT_MOVED) { + public void notifyMoveStart() + { + if( this.m_moveState == MoveState.NOT_MOVED ) + { this.m_moveState = MoveState.IN_PROGRESS; } } - public void notifyMoveEnd() { + public void notifyMoveEnd() + { // MoveState.MOVED is final - if (this.m_moveState == MoveState.IN_PROGRESS) { + if( this.m_moveState == MoveState.IN_PROGRESS ) + { this.m_moveState = MoveState.NOT_MOVED; } } @Override - public int getColour() { + public int getColour() + { return this.m_brain.getColour(); } @Override - public Identifier getOverlay() { + public Identifier getOverlay() + { return this.m_brain.getOverlay(); } @Override - public ITurtleUpgrade getUpgrade(TurtleSide side) { - return this.m_brain.getUpgrade(side); + public ITurtleUpgrade getUpgrade( TurtleSide side ) + { + return this.m_brain.getUpgrade( side ); } @Override - public ITurtleAccess getAccess() { + public ITurtleAccess getAccess() + { return this.m_brain; } @Override - public Vec3d getRenderOffset(float f) { - return this.m_brain.getRenderOffset(f); + public Vec3d getRenderOffset( float f ) + { + return this.m_brain.getRenderOffset( f ); } @Override - public float getRenderYaw(float f) { - return this.m_brain.getVisualYaw(f); + public float getRenderYaw( float f ) + { + return this.m_brain.getVisualYaw( f ); } @Override - public float getToolRenderAngle(TurtleSide side, float f) { - return this.m_brain.getToolRenderAngle(side, f); + public float getToolRenderAngle( TurtleSide side, float f ) + { + return this.m_brain.getToolRenderAngle( side, f ); } - void setOwningPlayer(GameProfile player) { - this.m_brain.setOwningPlayer(player); + void setOwningPlayer( GameProfile player ) + { + this.m_brain.setOwningPlayer( player ); this.markDirty(); } // Networking stuff @Override - public void markDirty() { + public void markDirty() + { super.markDirty(); - if (!this.m_inventoryChanged) { - for (int n = 0; n < this.size(); n++) { - if (!ItemStack.areEqual(this.getStack(n), this.m_previousInventory.get(n))) { + if( !this.m_inventoryChanged ) + { + for( int n = 0; n < this.size(); n++ ) + { + if( !ItemStack.areEqual( this.getStack( n ), this.m_previousInventory.get( n ) ) ) + { this.m_inventoryChanged = true; break; } @@ -444,30 +520,35 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default } @Override - public void clear() { + public void clear() + { boolean changed = false; - for (int i = 0; i < INVENTORY_SIZE; i++) { - if (!this.m_inventory.get(i) - .isEmpty()) { - this.m_inventory.set(i, ItemStack.EMPTY); + for( int i = 0; i < INVENTORY_SIZE; i++ ) + { + if( !this.m_inventory.get( i ) + .isEmpty() ) + { + this.m_inventory.set( i, ItemStack.EMPTY ); changed = true; } } - if (changed) { + if( changed ) + { this.onInventoryDefinitelyChanged(); } } // Privates - public void transferStateFrom(TileTurtle copy) { - super.transferStateFrom(copy); - Collections.copy(this.m_inventory, copy.m_inventory); - Collections.copy(this.m_previousInventory, copy.m_previousInventory); + public void transferStateFrom( TileTurtle copy ) + { + super.transferStateFrom( copy ); + Collections.copy( this.m_inventory, copy.m_inventory ); + Collections.copy( this.m_previousInventory, copy.m_previousInventory ); this.m_inventoryChanged = copy.m_inventoryChanged; this.m_brain = copy.m_brain; - this.m_brain.setOwner(this); + this.m_brain.setOwner( this ); // Mark the other turtle as having moved, and so its peripheral is dead. copy.m_moveState = MoveState.MOVED; @@ -475,11 +556,13 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default @Nullable @Override - public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player) { - return new ContainerTurtle(id, inventory, this.m_brain); + public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player ) + { + return new ContainerTurtle( id, inventory, this.m_brain ); } - enum MoveState { + enum MoveState + { NOT_MOVED, IN_PROGRESS, MOVED } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/InteractDirection.java b/src/main/java/dan200/computercraft/shared/turtle/core/InteractDirection.java index 00b58b318..2f22305e1 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/InteractDirection.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/InteractDirection.java @@ -7,21 +7,23 @@ package dan200.computercraft.shared.turtle.core; import dan200.computercraft.api.turtle.ITurtleAccess; - import net.minecraft.util.math.Direction; -public enum InteractDirection { +public enum InteractDirection +{ FORWARD, UP, DOWN; - public Direction toWorldDir(ITurtleAccess turtle) { - switch (this) { - case FORWARD: - default: - return turtle.getDirection(); - case UP: - return Direction.UP; - case DOWN: - return Direction.DOWN; + public Direction toWorldDir( ITurtleAccess turtle ) + { + switch( this ) + { + case FORWARD: + default: + return turtle.getDirection(); + case UP: + return Direction.UP; + case DOWN: + return Direction.DOWN; } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/MoveDirection.java b/src/main/java/dan200/computercraft/shared/turtle/core/MoveDirection.java index 60df15898..0364db549 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/MoveDirection.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/MoveDirection.java @@ -7,24 +7,26 @@ package dan200.computercraft.shared.turtle.core; import dan200.computercraft.api.turtle.ITurtleAccess; - import net.minecraft.util.math.Direction; -public enum MoveDirection { +public enum MoveDirection +{ FORWARD, BACK, UP, DOWN; - public Direction toWorldDir(ITurtleAccess turtle) { - switch (this) { - case FORWARD: - default: - return turtle.getDirection(); - case BACK: - return turtle.getDirection() - .getOpposite(); - case UP: - return Direction.UP; - case DOWN: - return Direction.DOWN; + public Direction toWorldDir( ITurtleAccess turtle ) + { + switch( this ) + { + case FORWARD: + default: + return turtle.getDirection(); + case BACK: + return turtle.getDirection() + .getOpposite(); + case UP: + return Direction.UP; + case DOWN: + return Direction.DOWN; } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurnDirection.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurnDirection.java index bcf7015c6..becb48380 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurnDirection.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurnDirection.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.turtle.core; -public enum TurnDirection { +public enum TurnDirection +{ LEFT, RIGHT, } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java index 3cbecea92..870fcb2a0 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java @@ -6,45 +6,20 @@ package dan200.computercraft.shared.turtle.core; -import static dan200.computercraft.shared.common.IColouredItem.NBT_COLOUR; -import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED; - -import java.util.ArrayDeque; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.base.Objects; import com.mojang.authlib.GameProfile; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.ILuaCallback; import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.peripheral.IPeripheral; -import dan200.computercraft.api.turtle.ITurtleAccess; -import dan200.computercraft.api.turtle.ITurtleCommand; -import dan200.computercraft.api.turtle.ITurtleUpgrade; -import dan200.computercraft.api.turtle.TurtleAnimation; -import dan200.computercraft.api.turtle.TurtleCommandResult; -import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.api.turtle.*; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.shared.TurtleUpgrades; import dan200.computercraft.shared.computer.blocks.ComputerProxy; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.turtle.blocks.TileTurtle; -import dan200.computercraft.shared.util.Colour; -import dan200.computercraft.shared.util.Holiday; -import dan200.computercraft.shared.util.HolidayUtil; -import dan200.computercraft.shared.util.InventoryDelegate; -import dan200.computercraft.shared.util.NBTUtil; - +import dan200.computercraft.shared.util.*; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -64,7 +39,16 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class TurtleBrain implements ITurtleAccess { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import static dan200.computercraft.shared.common.IColouredItem.NBT_COLOUR; +import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED; + +public class TurtleBrain implements ITurtleAccess +{ public static final String NBT_RIGHT_UPGRADE = "RightUpgrade"; public static final String NBT_RIGHT_UPGRADE_DATA = "RightUpgradeNbt"; public static final String NBT_LEFT_UPGRADE = "LeftUpgrade"; @@ -76,9 +60,9 @@ public class TurtleBrain implements ITurtleAccess { private static final int ANIM_DURATION = 8; private final Queue m_commandQueue = new ArrayDeque<>(); - private final Map m_upgrades = new EnumMap<>(TurtleSide.class); - private final Map peripherals = new EnumMap<>(TurtleSide.class); - private final Map m_upgradeNBTData = new EnumMap<>(TurtleSide.class); + private final Map m_upgrades = new EnumMap<>( TurtleSide.class ); + private final Map peripherals = new EnumMap<>( TurtleSide.class ); + private final Map m_upgradeNBTData = new EnumMap<>( TurtleSide.class ); TurtlePlayer m_cachedPlayer; private TileTurtle m_owner; private final Inventory m_inventory = (InventoryDelegate) () -> this.m_owner; @@ -93,74 +77,92 @@ public class TurtleBrain implements ITurtleAccess { private int m_animationProgress = 0; private int m_lastAnimationProgress = 0; - public TurtleBrain(TileTurtle turtle) { + public TurtleBrain( TileTurtle turtle ) + { this.m_owner = turtle; } - public TileTurtle getOwner() { + public TileTurtle getOwner() + { return this.m_owner; } - public void setOwner(TileTurtle owner) { + public void setOwner( TileTurtle owner ) + { this.m_owner = owner; } - public ComputerProxy getProxy() { - if (this.m_proxy == null) { - this.m_proxy = new ComputerProxy(() -> this.m_owner); + public ComputerProxy getProxy() + { + if( this.m_proxy == null ) + { + this.m_proxy = new ComputerProxy( () -> this.m_owner ); } return this.m_proxy; } - public ComputerFamily getFamily() { + public ComputerFamily getFamily() + { return this.m_owner.getFamily(); } - public void setupComputer(ServerComputer computer) { - this.updatePeripherals(computer); + public void setupComputer( ServerComputer computer ) + { + this.updatePeripherals( computer ); } - private void updatePeripherals(ServerComputer serverComputer) { - if (serverComputer == null) { + private void updatePeripherals( ServerComputer serverComputer ) + { + if( serverComputer == null ) + { return; } // Update peripherals - for (TurtleSide side : TurtleSide.values()) { - ITurtleUpgrade upgrade = this.getUpgrade(side); + for( TurtleSide side : TurtleSide.values() ) + { + ITurtleUpgrade upgrade = this.getUpgrade( side ); IPeripheral peripheral = null; - if (upgrade != null && upgrade.getType() - .isPeripheral()) { - peripheral = upgrade.createPeripheral(this, side); + if( upgrade != null && upgrade.getType() + .isPeripheral() ) + { + peripheral = upgrade.createPeripheral( this, side ); } - IPeripheral existing = this.peripherals.get(side); - if (existing == peripheral || (existing != null && peripheral != null && existing.equals(peripheral))) { + IPeripheral existing = this.peripherals.get( side ); + if( existing == peripheral || (existing != null && peripheral != null && existing.equals( peripheral )) ) + { // If the peripheral is the same, just use that. peripheral = existing; - } else { + } + else + { // Otherwise update our map - this.peripherals.put(side, peripheral); + this.peripherals.put( side, peripheral ); } // Always update the computer: it may not be the same computer as before! - serverComputer.setPeripheral(toDirection(side), peripheral); + serverComputer.setPeripheral( toDirection( side ), peripheral ); } } - private static ComputerSide toDirection(TurtleSide side) { - switch (side) { - case LEFT: - return ComputerSide.LEFT; - case RIGHT: - default: - return ComputerSide.RIGHT; + private static ComputerSide toDirection( TurtleSide side ) + { + switch( side ) + { + case LEFT: + return ComputerSide.LEFT; + case RIGHT: + default: + return ComputerSide.RIGHT; } } - public void update() { + public void update() + { World world = this.getWorld(); - if (!world.isClient) { + if( !world.isClient ) + { // Advance movement this.updateCommands(); @@ -173,30 +175,36 @@ public class TurtleBrain implements ITurtleAccess { this.updateAnimation(); // Advance upgrades - if (!this.m_upgrades.isEmpty()) { - for (Map.Entry entry : this.m_upgrades.entrySet()) { + if( !this.m_upgrades.isEmpty() ) + { + for( Map.Entry entry : this.m_upgrades.entrySet() ) + { entry.getValue() - .update(this, entry.getKey()); + .update( this, entry.getKey() ); } } } @Nonnull @Override - public World getWorld() { + public World getWorld() + { return this.m_owner.getWorld(); } @Nonnull @Override - public BlockPos getPosition() { + public BlockPos getPosition() + { return this.m_owner.getPos(); } @Override - public boolean teleportTo(@Nonnull World world, @Nonnull BlockPos pos) { - if (world.isClient || this.getWorld().isClient) { - throw new UnsupportedOperationException("Cannot teleport on the client"); + public boolean teleportTo( @Nonnull World world, @Nonnull BlockPos pos ) + { + if( world.isClient || this.getWorld().isClient ) + { + throw new UnsupportedOperationException( "Cannot teleport on the client" ); } // Cache info about the old turtle (so we don't access this after we delete ourselves) @@ -205,51 +213,58 @@ public class TurtleBrain implements ITurtleAccess { BlockPos oldPos = this.m_owner.getPos(); BlockState oldBlock = this.m_owner.getCachedState(); - if (oldWorld == world && oldPos.equals(pos)) { + if( oldWorld == world && oldPos.equals( pos ) ) + { // Teleporting to the current position is a no-op return true; } // Ensure the chunk is loaded - if (!world.isChunkLoaded(pos)) { + if( !world.isChunkLoaded( pos ) ) + { return false; } // Ensure we're inside the world border - if (!world.getWorldBorder() - .contains(pos)) { + if( !world.getWorldBorder() + .contains( pos ) ) + { return false; } - FluidState existingFluid = world.getBlockState(pos) - .getFluidState(); + FluidState existingFluid = world.getBlockState( pos ) + .getFluidState(); BlockState newState = oldBlock - // We only mark this as waterlogged when travelling into a source block. This prevents us from spreading - // fluid by creating a new source when moving into a block, causing the next block to be almost full and - // then moving into that. - .with(WATERLOGGED, existingFluid.isIn(FluidTags.WATER) && existingFluid.isStill()); + // We only mark this as waterlogged when travelling into a source block. This prevents us from spreading + // fluid by creating a new source when moving into a block, causing the next block to be almost full and + // then moving into that. + .with( WATERLOGGED, existingFluid.isIn( FluidTags.WATER ) && existingFluid.isStill() ); oldOwner.notifyMoveStart(); - try { + try + { // Create a new turtle - if (world.setBlockState(pos, newState, 0)) { - Block block = world.getBlockState(pos) - .getBlock(); - if (block == oldBlock.getBlock()) { - BlockEntity newTile = world.getBlockEntity(pos); - if (newTile instanceof TileTurtle) { + if( world.setBlockState( pos, newState, 0 ) ) + { + Block block = world.getBlockState( pos ) + .getBlock(); + if( block == oldBlock.getBlock() ) + { + BlockEntity newTile = world.getBlockEntity( pos ); + if( newTile instanceof TileTurtle ) + { // Copy the old turtle state into the new turtle TileTurtle newTurtle = (TileTurtle) newTile; - newTurtle.setLocation(world, pos); - newTurtle.transferStateFrom(oldOwner); + newTurtle.setLocation( world, pos ); + newTurtle.transferStateFrom( oldOwner ); newTurtle.createServerComputer() - .setWorld(world); + .setWorld( world ); newTurtle.createServerComputer() - .setPosition(pos); + .setPosition( pos ); // Remove the old turtle - oldWorld.removeBlock(oldPos, false); + oldWorld.removeBlock( oldPos, false ); // Make sure everybody knows about it newTurtle.updateBlock(); @@ -260,9 +275,11 @@ public class TurtleBrain implements ITurtleAccess { } // Something went wrong, remove the newly created turtle - world.removeBlock(pos, false); + world.removeBlock( pos, false ); } - } finally { + } + finally + { // whatever happens, unblock old turtle in case it's still in world oldOwner.notifyMoveEnd(); } @@ -272,75 +289,94 @@ public class TurtleBrain implements ITurtleAccess { @Nonnull @Override - public Vec3d getVisualPosition(float f) { - Vec3d offset = this.getRenderOffset(f); + public Vec3d getVisualPosition( float f ) + { + Vec3d offset = this.getRenderOffset( f ); BlockPos pos = this.m_owner.getPos(); - return new Vec3d(pos.getX() + 0.5 + offset.x, pos.getY() + 0.5 + offset.y, pos.getZ() + 0.5 + offset.z); + return new Vec3d( pos.getX() + 0.5 + offset.x, pos.getY() + 0.5 + offset.y, pos.getZ() + 0.5 + offset.z ); } @Override - public float getVisualYaw(float f) { + public float getVisualYaw( float f ) + { float yaw = this.getDirection().asRotation(); - switch (this.m_animation) { - case TURN_LEFT: { - yaw += 90.0f * (1.0f - this.getAnimationFraction(f)); - if (yaw >= 360.0f) { - yaw -= 360.0f; + switch( this.m_animation ) + { + case TURN_LEFT: + { + yaw += 90.0f * (1.0f - this.getAnimationFraction( f )); + if( yaw >= 360.0f ) + { + yaw -= 360.0f; + } + break; } - break; - } - case TURN_RIGHT: { - yaw += -90.0f * (1.0f - this.getAnimationFraction(f)); - if (yaw < 0.0f) { - yaw += 360.0f; + case TURN_RIGHT: + { + yaw += -90.0f * (1.0f - this.getAnimationFraction( f )); + if( yaw < 0.0f ) + { + yaw += 360.0f; + } + break; } - break; - } } return yaw; } @Nonnull @Override - public Direction getDirection() { + public Direction getDirection() + { return this.m_owner.getDirection(); } @Override - public void setDirection(@Nonnull Direction dir) { - this.m_owner.setDirection(dir); + public void setDirection( @Nonnull Direction dir ) + { + this.m_owner.setDirection( dir ); } @Override - public int getSelectedSlot() { + public int getSelectedSlot() + { return this.m_selectedSlot; } @Override - public void setSelectedSlot(int slot) { - if (this.getWorld().isClient) { - throw new UnsupportedOperationException("Cannot set the slot on the client"); + public void setSelectedSlot( int slot ) + { + if( this.getWorld().isClient ) + { + throw new UnsupportedOperationException( "Cannot set the slot on the client" ); } - if (slot >= 0 && slot < this.m_owner.size()) { + if( slot >= 0 && slot < this.m_owner.size() ) + { this.m_selectedSlot = slot; this.m_owner.onTileEntityChange(); } } @Override - public int getColour() { + public int getColour() + { return this.m_colourHex; } @Override - public void setColour(int colour) { - if (colour >= 0 && colour <= 0xFFFFFF) { - if (this.m_colourHex != colour) { + public void setColour( int colour ) + { + if( colour >= 0 && colour <= 0xFFFFFF ) + { + if( this.m_colourHex != colour ) + { this.m_colourHex = colour; this.m_owner.updateBlock(); } - } else if (this.m_colourHex != -1) { + } + else if( this.m_colourHex != -1 ) + { this.m_colourHex = -1; this.m_owner.updateBlock(); } @@ -348,91 +384,113 @@ public class TurtleBrain implements ITurtleAccess { @Nullable @Override - public GameProfile getOwningPlayer() { + public GameProfile getOwningPlayer() + { return this.m_owningPlayer; } @Override - public boolean isFuelNeeded() { + public boolean isFuelNeeded() + { return ComputerCraft.turtlesNeedFuel; } @Override - public int getFuelLevel() { - return Math.min(this.m_fuelLevel, this.getFuelLimit()); + public int getFuelLevel() + { + return Math.min( this.m_fuelLevel, this.getFuelLimit() ); } @Override - public void setFuelLevel(int level) { - this.m_fuelLevel = Math.min(level, this.getFuelLimit()); + public void setFuelLevel( int level ) + { + this.m_fuelLevel = Math.min( level, this.getFuelLimit() ); this.m_owner.onTileEntityChange(); } @Override - public int getFuelLimit() { - if (this.m_owner.getFamily() == ComputerFamily.ADVANCED) { + public int getFuelLimit() + { + if( this.m_owner.getFamily() == ComputerFamily.ADVANCED ) + { return ComputerCraft.advancedTurtleFuelLimit; - } else { + } + else + { return ComputerCraft.turtleFuelLimit; } } @Override - public boolean consumeFuel(int fuel) { - if (this.getWorld().isClient) { - throw new UnsupportedOperationException("Cannot consume fuel on the client"); + public boolean consumeFuel( int fuel ) + { + if( this.getWorld().isClient ) + { + throw new UnsupportedOperationException( "Cannot consume fuel on the client" ); } - if (!this.isFuelNeeded()) { + if( !this.isFuelNeeded() ) + { return true; } - int consumption = Math.max(fuel, 0); - if (this.getFuelLevel() >= consumption) { - this.setFuelLevel(this.getFuelLevel() - consumption); + int consumption = Math.max( fuel, 0 ); + if( this.getFuelLevel() >= consumption ) + { + this.setFuelLevel( this.getFuelLevel() - consumption ); return true; } return false; } @Override - public void addFuel(int fuel) { - if (this.getWorld().isClient) { - throw new UnsupportedOperationException("Cannot add fuel on the client"); + public void addFuel( int fuel ) + { + if( this.getWorld().isClient ) + { + throw new UnsupportedOperationException( "Cannot add fuel on the client" ); } - int addition = Math.max(fuel, 0); - this.setFuelLevel(this.getFuelLevel() + addition); + int addition = Math.max( fuel, 0 ); + this.setFuelLevel( this.getFuelLevel() + addition ); } @Nonnull @Override - public MethodResult executeCommand(@Nonnull ITurtleCommand command) { - if (this.getWorld().isClient) { - throw new UnsupportedOperationException("Cannot run commands on the client"); + public MethodResult executeCommand( @Nonnull ITurtleCommand command ) + { + if( this.getWorld().isClient ) + { + throw new UnsupportedOperationException( "Cannot run commands on the client" ); } // Issue command - int commandID = this.issueCommand(command); - return new CommandCallback(commandID).pull; + int commandID = this.issueCommand( command ); + return new CommandCallback( commandID ).pull; } - private int issueCommand(ITurtleCommand command) { - this.m_commandQueue.offer(new TurtleCommandQueueEntry(++this.m_commandsIssued, command)); + private int issueCommand( ITurtleCommand command ) + { + this.m_commandQueue.offer( new TurtleCommandQueueEntry( ++this.m_commandsIssued, command ) ); return this.m_commandsIssued; } @Override - public void playAnimation(@Nonnull TurtleAnimation animation) { - if (this.getWorld().isClient) { - throw new UnsupportedOperationException("Cannot play animations on the client"); + public void playAnimation( @Nonnull TurtleAnimation animation ) + { + if( this.getWorld().isClient ) + { + throw new UnsupportedOperationException( "Cannot play animations on the client" ); } this.m_animation = animation; - if (this.m_animation == TurtleAnimation.SHORT_WAIT) { + if( this.m_animation == TurtleAnimation.SHORT_WAIT ) + { this.m_animationProgress = ANIM_DURATION / 2; this.m_lastAnimationProgress = ANIM_DURATION / 2; - } else { + } + else + { this.m_animationProgress = 0; this.m_lastAnimationProgress = 0; } @@ -440,150 +498,182 @@ public class TurtleBrain implements ITurtleAccess { } @Override - public ITurtleUpgrade getUpgrade(@Nonnull TurtleSide side) { - return this.m_upgrades.get(side); + public ITurtleUpgrade getUpgrade( @Nonnull TurtleSide side ) + { + return this.m_upgrades.get( side ); } @Override - public void setUpgrade(@Nonnull TurtleSide side, ITurtleUpgrade upgrade) { + public void setUpgrade( @Nonnull TurtleSide side, ITurtleUpgrade upgrade ) + { // Remove old upgrade - if (this.m_upgrades.containsKey(side)) { - if (this.m_upgrades.get(side) == upgrade) { + if( this.m_upgrades.containsKey( side ) ) + { + if( this.m_upgrades.get( side ) == upgrade ) + { return; } - this.m_upgrades.remove(side); - } else { - if (upgrade == null) { + this.m_upgrades.remove( side ); + } + else + { + if( upgrade == null ) + { return; } } - this.m_upgradeNBTData.remove(side); + this.m_upgradeNBTData.remove( side ); // Set new upgrade - if (upgrade != null) { - this.m_upgrades.put(side, upgrade); + if( upgrade != null ) + { + this.m_upgrades.put( side, upgrade ); } // Notify clients and create peripherals - if (this.m_owner.getWorld() != null) { - this.updatePeripherals(this.m_owner.createServerComputer()); + if( this.m_owner.getWorld() != null ) + { + this.updatePeripherals( this.m_owner.createServerComputer() ); this.m_owner.updateBlock(); } } @Override - public IPeripheral getPeripheral(@Nonnull TurtleSide side) { - return this.peripherals.get(side); + public IPeripheral getPeripheral( @Nonnull TurtleSide side ) + { + return this.peripherals.get( side ); } @Nonnull @Override - public CompoundTag getUpgradeNBTData(TurtleSide side) { - CompoundTag nbt = this.m_upgradeNBTData.get(side); - if (nbt == null) { - this.m_upgradeNBTData.put(side, nbt = new CompoundTag()); + public CompoundTag getUpgradeNBTData( TurtleSide side ) + { + CompoundTag nbt = this.m_upgradeNBTData.get( side ); + if( nbt == null ) + { + this.m_upgradeNBTData.put( side, nbt = new CompoundTag() ); } return nbt; } @Override - public void updateUpgradeNBTData(@Nonnull TurtleSide side) { + public void updateUpgradeNBTData( @Nonnull TurtleSide side ) + { this.m_owner.updateBlock(); } @Nonnull @Override - public Inventory getInventory() { + public Inventory getInventory() + { return this.m_inventory; } - public void setOwningPlayer(GameProfile profile) { + public void setOwningPlayer( GameProfile profile ) + { this.m_owningPlayer = profile; } - private void updateCommands() { - if (this.m_animation != TurtleAnimation.NONE || this.m_commandQueue.isEmpty()) { + private void updateCommands() + { + if( this.m_animation != TurtleAnimation.NONE || this.m_commandQueue.isEmpty() ) + { return; } // If we've got a computer, ensure that we're allowed to perform work. ServerComputer computer = this.m_owner.getServerComputer(); - if (computer != null && !computer.getComputer() - .getMainThreadMonitor() - .canWork()) { + if( computer != null && !computer.getComputer() + .getMainThreadMonitor() + .canWork() ) + { return; } // Pull a new command TurtleCommandQueueEntry nextCommand = this.m_commandQueue.poll(); - if (nextCommand == null) { + if( nextCommand == null ) + { return; } // Execute the command long start = System.nanoTime(); - TurtleCommandResult result = nextCommand.command.execute(this); + TurtleCommandResult result = nextCommand.command.execute( this ); long end = System.nanoTime(); // Dispatch the callback - if (computer == null) { + if( computer == null ) + { return; } computer.getComputer() - .getMainThreadMonitor() - .trackWork(end - start, TimeUnit.NANOSECONDS); + .getMainThreadMonitor() + .trackWork( end - start, TimeUnit.NANOSECONDS ); int callbackID = nextCommand.callbackID; - if (callbackID < 0) { + if( callbackID < 0 ) + { return; } - if (result != null && result.isSuccess()) { + if( result != null && result.isSuccess() ) + { Object[] results = result.getResults(); - if (results != null) { + if( results != null ) + { Object[] arguments = new Object[results.length + 2]; arguments[0] = callbackID; arguments[1] = true; - System.arraycopy(results, 0, arguments, 2, results.length); - computer.queueEvent("turtle_response", arguments); - } else { - computer.queueEvent("turtle_response", new Object[] { + System.arraycopy( results, 0, arguments, 2, results.length ); + computer.queueEvent( "turtle_response", arguments ); + } + else + { + computer.queueEvent( "turtle_response", new Object[] { callbackID, true, - }); + } ); } - } else { - computer.queueEvent("turtle_response", new Object[] { + } + else + { + computer.queueEvent( "turtle_response", new Object[] { callbackID, false, result != null ? result.getErrorMessage() : null, - }); + } ); } } - private void updateAnimation() { - if (this.m_animation != TurtleAnimation.NONE) { + private void updateAnimation() + { + if( this.m_animation != TurtleAnimation.NONE ) + { World world = this.getWorld(); - if (ComputerCraft.turtlesCanPush) { + if( ComputerCraft.turtlesCanPush ) + { // Advance entity pushing - if (this.m_animation == TurtleAnimation.MOVE_FORWARD || this.m_animation == TurtleAnimation.MOVE_BACK || this.m_animation == TurtleAnimation.MOVE_UP || this.m_animation == TurtleAnimation.MOVE_DOWN) { + if( this.m_animation == TurtleAnimation.MOVE_FORWARD || this.m_animation == TurtleAnimation.MOVE_BACK || this.m_animation == TurtleAnimation.MOVE_UP || this.m_animation == TurtleAnimation.MOVE_DOWN ) + { BlockPos pos = this.getPosition(); Direction moveDir; - switch (this.m_animation) { - case MOVE_FORWARD: - default: - moveDir = this.getDirection(); - break; - case MOVE_BACK: - moveDir = this.getDirection().getOpposite(); - break; - case MOVE_UP: - moveDir = Direction.UP; - break; - case MOVE_DOWN: - moveDir = Direction.DOWN; - break; + switch( this.m_animation ) + { + case MOVE_FORWARD: + default: + moveDir = this.getDirection(); + break; + case MOVE_BACK: + moveDir = this.getDirection().getOpposite(); + break; + case MOVE_UP: + moveDir = Direction.UP; + break; + case MOVE_DOWN: + moveDir = Direction.DOWN; + break; } double minX = pos.getX(); @@ -594,63 +684,78 @@ public class TurtleBrain implements ITurtleAccess { double maxZ = minZ + 1.0; float pushFrac = 1.0f - (float) (this.m_animationProgress + 1) / ANIM_DURATION; - float push = Math.max(pushFrac + 0.0125f, 0.0f); - if (moveDir.getOffsetX() < 0) { + float push = Math.max( pushFrac + 0.0125f, 0.0f ); + if( moveDir.getOffsetX() < 0 ) + { minX += moveDir.getOffsetX() * push; - } else { + } + else + { maxX -= moveDir.getOffsetX() * push; } - if (moveDir.getOffsetY() < 0) { + if( moveDir.getOffsetY() < 0 ) + { minY += moveDir.getOffsetY() * push; - } else { + } + else + { maxY -= moveDir.getOffsetY() * push; } - if (moveDir.getOffsetZ() < 0) { + if( moveDir.getOffsetZ() < 0 ) + { minZ += moveDir.getOffsetZ() * push; - } else { + } + else + { maxZ -= moveDir.getOffsetZ() * push; } - Box aabb = new Box(minX, minY, minZ, maxX, maxY, maxZ); - List list = world.getEntitiesByClass(Entity.class, aabb, EntityPredicates.EXCEPT_SPECTATOR); - if (!list.isEmpty()) { + Box aabb = new Box( minX, minY, minZ, maxX, maxY, maxZ ); + List list = world.getEntitiesByClass( Entity.class, aabb, EntityPredicates.EXCEPT_SPECTATOR ); + if( !list.isEmpty() ) + { double pushStep = 1.0f / ANIM_DURATION; double pushStepX = moveDir.getOffsetX() * pushStep; double pushStepY = moveDir.getOffsetY() * pushStep; double pushStepZ = moveDir.getOffsetZ() * pushStep; - for (Entity entity : list) { - entity.move(MovementType.PISTON, new Vec3d(pushStepX, pushStepY, pushStepZ)); + for( Entity entity : list ) + { + entity.move( MovementType.PISTON, new Vec3d( pushStepX, pushStepY, pushStepZ ) ); } } } } // Advance valentines day easter egg - if (world.isClient && this.m_animation == TurtleAnimation.MOVE_FORWARD && this.m_animationProgress == 4) { + if( world.isClient && this.m_animation == TurtleAnimation.MOVE_FORWARD && this.m_animationProgress == 4 ) + { // Spawn love pfx if valentines day Holiday currentHoliday = HolidayUtil.getCurrentHoliday(); - if (currentHoliday == Holiday.VALENTINES) { - Vec3d position = this.getVisualPosition(1.0f); - if (position != null) { + if( currentHoliday == Holiday.VALENTINES ) + { + Vec3d position = this.getVisualPosition( 1.0f ); + if( position != null ) + { double x = position.x + world.random.nextGaussian() * 0.1; double y = position.y + 0.5 + world.random.nextGaussian() * 0.1; double z = position.z + world.random.nextGaussian() * 0.1; - world.addParticle(ParticleTypes.HEART, - x, - y, - z, - world.random.nextGaussian() * 0.02, - world.random.nextGaussian() * 0.02, - world.random.nextGaussian() * 0.02); + world.addParticle( ParticleTypes.HEART, + x, + y, + z, + world.random.nextGaussian() * 0.02, + world.random.nextGaussian() * 0.02, + world.random.nextGaussian() * 0.02 ); } } } // Wait for anim completion this.m_lastAnimationProgress = this.m_animationProgress; - if (++this.m_animationProgress >= ANIM_DURATION) { + if( ++this.m_animationProgress >= ANIM_DURATION ) + { this.m_animation = TurtleAnimation.NONE; this.m_animationProgress = 0; this.m_lastAnimationProgress = 0; @@ -658,56 +763,66 @@ public class TurtleBrain implements ITurtleAccess { } } - public Vec3d getRenderOffset(float f) { - switch (this.m_animation) { - case MOVE_FORWARD: - case MOVE_BACK: - case MOVE_UP: - case MOVE_DOWN: { - // Get direction - Direction dir; - switch (this.m_animation) { + public Vec3d getRenderOffset( float f ) + { + switch( this.m_animation ) + { case MOVE_FORWARD: - default: - dir = this.getDirection(); - break; case MOVE_BACK: - dir = this.getDirection().getOpposite(); - break; case MOVE_UP: - dir = Direction.UP; - break; case MOVE_DOWN: - dir = Direction.DOWN; - break; - } + { + // Get direction + Direction dir; + switch( this.m_animation ) + { + case MOVE_FORWARD: + default: + dir = this.getDirection(); + break; + case MOVE_BACK: + dir = this.getDirection().getOpposite(); + break; + case MOVE_UP: + dir = Direction.UP; + break; + case MOVE_DOWN: + dir = Direction.DOWN; + break; + } - double distance = -1.0 + this.getAnimationFraction(f); - return new Vec3d(distance * dir.getOffsetX(), distance * dir.getOffsetY(), distance * dir.getOffsetZ()); - } - default: { - return Vec3d.ZERO; - } + double distance = -1.0 + this.getAnimationFraction( f ); + return new Vec3d( distance * dir.getOffsetX(), distance * dir.getOffsetY(), distance * dir.getOffsetZ() ); + } + default: + { + return Vec3d.ZERO; + } } } - private float getAnimationFraction(float f) { + private float getAnimationFraction( float f ) + { float next = (float) this.m_animationProgress / ANIM_DURATION; float previous = (float) this.m_lastAnimationProgress / ANIM_DURATION; return previous + (next - previous) * f; } - public void readFromNBT(CompoundTag nbt) { - this.readCommon(nbt); + public void readFromNBT( CompoundTag nbt ) + { + this.readCommon( nbt ); // Read state - this.m_selectedSlot = nbt.getInt(NBT_SLOT); + this.m_selectedSlot = nbt.getInt( NBT_SLOT ); // Read owner - if (nbt.contains("Owner", NBTUtil.TAG_COMPOUND)) { - CompoundTag owner = nbt.getCompound("Owner"); - this.m_owningPlayer = new GameProfile(new UUID(owner.getLong("UpperId"), owner.getLong("LowerId")), owner.getString("Name")); - } else { + if( nbt.contains( "Owner", NBTUtil.TAG_COMPOUND ) ) + { + CompoundTag owner = nbt.getCompound( "Owner" ); + this.m_owningPlayer = new GameProfile( new UUID( owner.getLong( "UpperId" ), owner.getLong( "LowerId" ) ), owner.getString( "Name" ) ); + } + else + { this.m_owningPlayer = null; } } @@ -717,158 +832,188 @@ public class TurtleBrain implements ITurtleAccess { * * @param nbt The tag to read from */ - private void readCommon(CompoundTag nbt) { + private void readCommon( CompoundTag nbt ) + { // Read fields - this.m_colourHex = nbt.contains(NBT_COLOUR) ? nbt.getInt(NBT_COLOUR) : -1; - this.m_fuelLevel = nbt.contains(NBT_FUEL) ? nbt.getInt(NBT_FUEL) : 0; - this.m_overlay = nbt.contains(NBT_OVERLAY) ? new Identifier(nbt.getString(NBT_OVERLAY)) : null; + this.m_colourHex = nbt.contains( NBT_COLOUR ) ? nbt.getInt( NBT_COLOUR ) : -1; + this.m_fuelLevel = nbt.contains( NBT_FUEL ) ? nbt.getInt( NBT_FUEL ) : 0; + this.m_overlay = nbt.contains( NBT_OVERLAY ) ? new Identifier( nbt.getString( NBT_OVERLAY ) ) : null; // Read upgrades - this.setUpgrade(TurtleSide.LEFT, nbt.contains(NBT_LEFT_UPGRADE) ? TurtleUpgrades.get(nbt.getString(NBT_LEFT_UPGRADE)) : null); - this.setUpgrade(TurtleSide.RIGHT, nbt.contains(NBT_RIGHT_UPGRADE) ? TurtleUpgrades.get(nbt.getString(NBT_RIGHT_UPGRADE)) : null); + this.setUpgrade( TurtleSide.LEFT, nbt.contains( NBT_LEFT_UPGRADE ) ? TurtleUpgrades.get( nbt.getString( NBT_LEFT_UPGRADE ) ) : null ); + this.setUpgrade( TurtleSide.RIGHT, nbt.contains( NBT_RIGHT_UPGRADE ) ? TurtleUpgrades.get( nbt.getString( NBT_RIGHT_UPGRADE ) ) : null ); // NBT this.m_upgradeNBTData.clear(); - if (nbt.contains(NBT_LEFT_UPGRADE_DATA)) { - this.m_upgradeNBTData.put(TurtleSide.LEFT, - nbt.getCompound(NBT_LEFT_UPGRADE_DATA) - .copy()); + if( nbt.contains( NBT_LEFT_UPGRADE_DATA ) ) + { + this.m_upgradeNBTData.put( TurtleSide.LEFT, + nbt.getCompound( NBT_LEFT_UPGRADE_DATA ) + .copy() ); } - if (nbt.contains(NBT_RIGHT_UPGRADE_DATA)) { - this.m_upgradeNBTData.put(TurtleSide.RIGHT, - nbt.getCompound(NBT_RIGHT_UPGRADE_DATA) - .copy()); + if( nbt.contains( NBT_RIGHT_UPGRADE_DATA ) ) + { + this.m_upgradeNBTData.put( TurtleSide.RIGHT, + nbt.getCompound( NBT_RIGHT_UPGRADE_DATA ) + .copy() ); } } - public CompoundTag writeToNBT(CompoundTag nbt) { - this.writeCommon(nbt); + public CompoundTag writeToNBT( CompoundTag nbt ) + { + this.writeCommon( nbt ); // Write state - nbt.putInt(NBT_SLOT, this.m_selectedSlot); + nbt.putInt( NBT_SLOT, this.m_selectedSlot ); // Write owner - if (this.m_owningPlayer != null) { + if( this.m_owningPlayer != null ) + { CompoundTag owner = new CompoundTag(); - nbt.put("Owner", owner); + nbt.put( "Owner", owner ); - owner.putLong("UpperId", this.m_owningPlayer.getId() - .getMostSignificantBits()); - owner.putLong("LowerId", this.m_owningPlayer.getId() - .getLeastSignificantBits()); - owner.putString("Name", this.m_owningPlayer.getName()); + owner.putLong( "UpperId", this.m_owningPlayer.getId() + .getMostSignificantBits() ); + owner.putLong( "LowerId", this.m_owningPlayer.getId() + .getLeastSignificantBits() ); + owner.putString( "Name", this.m_owningPlayer.getName() ); } return nbt; } - private void writeCommon(CompoundTag nbt) { - nbt.putInt(NBT_FUEL, this.m_fuelLevel); - if (this.m_colourHex != -1) { - nbt.putInt(NBT_COLOUR, this.m_colourHex); + private void writeCommon( CompoundTag nbt ) + { + nbt.putInt( NBT_FUEL, this.m_fuelLevel ); + if( this.m_colourHex != -1 ) + { + nbt.putInt( NBT_COLOUR, this.m_colourHex ); } - if (this.m_overlay != null) { - nbt.putString(NBT_OVERLAY, this.m_overlay.toString()); + if( this.m_overlay != null ) + { + nbt.putString( NBT_OVERLAY, this.m_overlay.toString() ); } // Write upgrades - String leftUpgradeId = getUpgradeId(this.getUpgrade(TurtleSide.LEFT)); - if (leftUpgradeId != null) { - nbt.putString(NBT_LEFT_UPGRADE, leftUpgradeId); + String leftUpgradeId = getUpgradeId( this.getUpgrade( TurtleSide.LEFT ) ); + if( leftUpgradeId != null ) + { + nbt.putString( NBT_LEFT_UPGRADE, leftUpgradeId ); } - String rightUpgradeId = getUpgradeId(this.getUpgrade(TurtleSide.RIGHT)); - if (rightUpgradeId != null) { - nbt.putString(NBT_RIGHT_UPGRADE, rightUpgradeId); + String rightUpgradeId = getUpgradeId( this.getUpgrade( TurtleSide.RIGHT ) ); + if( rightUpgradeId != null ) + { + nbt.putString( NBT_RIGHT_UPGRADE, rightUpgradeId ); } // Write upgrade NBT - if (this.m_upgradeNBTData.containsKey(TurtleSide.LEFT)) { - nbt.put(NBT_LEFT_UPGRADE_DATA, - this.getUpgradeNBTData(TurtleSide.LEFT).copy()); + if( this.m_upgradeNBTData.containsKey( TurtleSide.LEFT ) ) + { + nbt.put( NBT_LEFT_UPGRADE_DATA, + this.getUpgradeNBTData( TurtleSide.LEFT ).copy() ); } - if (this.m_upgradeNBTData.containsKey(TurtleSide.RIGHT)) { - nbt.put(NBT_RIGHT_UPGRADE_DATA, - this.getUpgradeNBTData(TurtleSide.RIGHT).copy()); + if( this.m_upgradeNBTData.containsKey( TurtleSide.RIGHT ) ) + { + nbt.put( NBT_RIGHT_UPGRADE_DATA, + this.getUpgradeNBTData( TurtleSide.RIGHT ).copy() ); } } - private static String getUpgradeId(ITurtleUpgrade upgrade) { + private static String getUpgradeId( ITurtleUpgrade upgrade ) + { return upgrade != null ? upgrade.getUpgradeID() - .toString() : null; + .toString() : null; } - public void readDescription(CompoundTag nbt) { - this.readCommon(nbt); + public void readDescription( CompoundTag nbt ) + { + this.readCommon( nbt ); // Animation - TurtleAnimation anim = TurtleAnimation.values()[nbt.getInt("Animation")]; - if (anim != this.m_animation && anim != TurtleAnimation.WAIT && anim != TurtleAnimation.SHORT_WAIT && anim != TurtleAnimation.NONE) { + TurtleAnimation anim = TurtleAnimation.values()[nbt.getInt( "Animation" )]; + if( anim != this.m_animation && anim != TurtleAnimation.WAIT && anim != TurtleAnimation.SHORT_WAIT && anim != TurtleAnimation.NONE ) + { this.m_animation = anim; this.m_animationProgress = 0; this.m_lastAnimationProgress = 0; } } - public void writeDescription(CompoundTag nbt) { - this.writeCommon(nbt); - nbt.putInt("Animation", this.m_animation.ordinal()); + public void writeDescription( CompoundTag nbt ) + { + this.writeCommon( nbt ); + nbt.putInt( "Animation", this.m_animation.ordinal() ); } - public Identifier getOverlay() { + public Identifier getOverlay() + { return this.m_overlay; } - public void setOverlay(Identifier overlay) { - if (!Objects.equal(this.m_overlay, overlay)) { + public void setOverlay( Identifier overlay ) + { + if( !Objects.equal( this.m_overlay, overlay ) ) + { this.m_overlay = overlay; this.m_owner.updateBlock(); } } - public DyeColor getDyeColour() { - if (this.m_colourHex == -1) { + public DyeColor getDyeColour() + { + if( this.m_colourHex == -1 ) + { return null; } - Colour colour = Colour.fromHex(this.m_colourHex); - return colour == null ? null : DyeColor.byId(15 - colour.ordinal()); + Colour colour = Colour.fromHex( this.m_colourHex ); + return colour == null ? null : DyeColor.byId( 15 - colour.ordinal() ); } - public void setDyeColour(DyeColor dyeColour) { + public void setDyeColour( DyeColor dyeColour ) + { int newColour = -1; - if (dyeColour != null) { + if( dyeColour != null ) + { newColour = Colour.values()[15 - dyeColour.getId()].getHex(); } - if (this.m_colourHex != newColour) { + if( this.m_colourHex != newColour ) + { this.m_colourHex = newColour; this.m_owner.updateBlock(); } } - public float getToolRenderAngle(TurtleSide side, float f) { + public float getToolRenderAngle( TurtleSide side, float f ) + { return (side == TurtleSide.LEFT && this.m_animation == TurtleAnimation.SWING_LEFT_TOOL) || (side == TurtleSide.RIGHT && this.m_animation == TurtleAnimation.SWING_RIGHT_TOOL) ? 45.0f * (float) Math.sin( - this.getAnimationFraction(f) * Math.PI) : 0.0f; + this.getAnimationFraction( f ) * Math.PI ) : 0.0f; } - private static final class CommandCallback implements ILuaCallback { - final MethodResult pull = MethodResult.pullEvent("turtle_response", this); + private static final class CommandCallback implements ILuaCallback + { + final MethodResult pull = MethodResult.pullEvent( "turtle_response", this ); private final int command; - CommandCallback(int command) { + CommandCallback( int command ) + { this.command = command; } @Nonnull @Override - public MethodResult resume(Object[] response) { - if (response.length < 3 || !(response[1] instanceof Number) || !(response[2] instanceof Boolean)) { + public MethodResult resume( Object[] response ) + { + if( response.length < 3 || !(response[1] instanceof Number) || !(response[2] instanceof Boolean) ) + { return this.pull; } - if (((Number) response[1]).intValue() != this.command) { + if( ((Number) response[1]).intValue() != this.command ) + { return this.pull; } - return MethodResult.of(Arrays.copyOfRange(response, 2, response.length)); + return MethodResult.of( Arrays.copyOfRange( response, 2, response.length ) ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCommandQueueEntry.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCommandQueueEntry.java index 80c40edb3..17f203329 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCommandQueueEntry.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCommandQueueEntry.java @@ -8,11 +8,13 @@ package dan200.computercraft.shared.turtle.core; import dan200.computercraft.api.turtle.ITurtleCommand; -public class TurtleCommandQueueEntry { +public class TurtleCommandQueueEntry +{ public final int callbackID; public final ITurtleCommand command; - public TurtleCommandQueueEntry(int callbackID, ITurtleCommand command) { + public TurtleCommandQueueEntry( int callbackID, ITurtleCommand command ) + { this.callbackID = callbackID; this.command = command; } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java index dcf60d2b8..69fb115d3 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java @@ -6,14 +6,9 @@ package dan200.computercraft.shared.turtle.core; -import java.util.List; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleCommandResult; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; @@ -22,40 +17,52 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class TurtleCompareCommand implements ITurtleCommand { +import javax.annotation.Nonnull; +import java.util.List; + +public class TurtleCompareCommand implements ITurtleCommand +{ private final InteractDirection m_direction; - public TurtleCompareCommand(InteractDirection direction) { + public TurtleCompareCommand( InteractDirection direction ) + { this.m_direction = direction; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Get world direction from direction - Direction direction = this.m_direction.toWorldDir(turtle); + Direction direction = this.m_direction.toWorldDir( turtle ); // Get currently selected stack ItemStack selectedStack = turtle.getInventory() - .getStack(turtle.getSelectedSlot()); + .getStack( turtle.getSelectedSlot() ); // Get stack representing thing in front World world = turtle.getWorld(); BlockPos oldPosition = turtle.getPosition(); - BlockPos newPosition = oldPosition.offset(direction); + BlockPos newPosition = oldPosition.offset( direction ); ItemStack lookAtStack = ItemStack.EMPTY; - if (!world.isAir(newPosition)) { - BlockState lookAtState = world.getBlockState(newPosition); + if( !world.isAir( newPosition ) ) + { + BlockState lookAtState = world.getBlockState( newPosition ); Block lookAtBlock = lookAtState.getBlock(); - if (!lookAtState.isAir()) { + if( !lookAtState.isAir() ) + { // See if the block drops anything with the same ID as itself // (try 5 times to try and beat random number generators) - for (int i = 0; i < 5 && lookAtStack.isEmpty(); i++) { - List drops = Block.getDroppedStacks(lookAtState, (ServerWorld) world, newPosition, world.getBlockEntity(newPosition)); - if (!drops.isEmpty()) { - for (ItemStack drop : drops) { - if (drop.getItem() == lookAtBlock.asItem()) { + for( int i = 0; i < 5 && lookAtStack.isEmpty(); i++ ) + { + List drops = Block.getDroppedStacks( lookAtState, (ServerWorld) world, newPosition, world.getBlockEntity( newPosition ) ); + if( !drops.isEmpty() ) + { + for( ItemStack drop : drops ) + { + if( drop.getItem() == lookAtBlock.asItem() ) + { lookAtStack = drop; break; } @@ -64,8 +71,9 @@ public class TurtleCompareCommand implements ITurtleCommand { } // Last resort: roll our own (which will probably be wrong) - if (lookAtStack.isEmpty()) { - lookAtStack = new ItemStack(lookAtBlock); + if( lookAtStack.isEmpty() ) + { + lookAtStack = new ItemStack( lookAtBlock ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareToCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareToCommand.java index 139a06e34..c34cd8856 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareToCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareToCommand.java @@ -6,32 +6,37 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.shared.util.InventoryUtil; - import net.minecraft.item.ItemStack; -public class TurtleCompareToCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleCompareToCommand implements ITurtleCommand +{ private final int m_slot; - public TurtleCompareToCommand(int slot) { + public TurtleCompareToCommand( int slot ) + { this.m_slot = slot; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { ItemStack selectedStack = turtle.getInventory() - .getStack(turtle.getSelectedSlot()); + .getStack( turtle.getSelectedSlot() ); ItemStack stack = turtle.getInventory() - .getStack(this.m_slot); - if (InventoryUtil.areItemsStackable(selectedStack, stack)) { + .getStack( this.m_slot ); + if( InventoryUtil.areItemsStackable( selectedStack, stack ) ) + { return TurtleCommandResult.success(); - } else { + } + else + { return TurtleCommandResult.failure(); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java index 196a8bc5f..2cbfbedf4 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import java.util.List; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleAnimation; @@ -17,36 +13,45 @@ import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.shared.turtle.upgrades.TurtleInventoryCrafting; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.item.ItemStack; -public class TurtleCraftCommand implements ITurtleCommand { +import javax.annotation.Nonnull; +import java.util.List; + +public class TurtleCraftCommand implements ITurtleCommand +{ private final int limit; - public TurtleCraftCommand(int limit) { + public TurtleCraftCommand( int limit ) + { this.limit = limit; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Craft the item - TurtleInventoryCrafting crafting = new TurtleInventoryCrafting(turtle); - List results = crafting.doCrafting(turtle.getWorld(), this.limit); - if (results == null) { - return TurtleCommandResult.failure("No matching recipes"); + TurtleInventoryCrafting crafting = new TurtleInventoryCrafting( turtle ); + List results = crafting.doCrafting( turtle.getWorld(), this.limit ); + if( results == null ) + { + return TurtleCommandResult.failure( "No matching recipes" ); } // Store or drop any remainders - for (ItemStack stack : results) { - ItemStack remainder = InventoryUtil.storeItems(stack, turtle.getItemHandler(), turtle.getSelectedSlot()); - if (!remainder.isEmpty()) { - WorldUtil.dropItemStack(remainder, turtle.getWorld(), turtle.getPosition(), turtle.getDirection()); + for( ItemStack stack : results ) + { + ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() ); + if( !remainder.isEmpty() ) + { + WorldUtil.dropItemStack( remainder, turtle.getWorld(), turtle.getPosition(), turtle.getDirection() ); } } - if (!results.isEmpty()) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( !results.isEmpty() ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); } return TurtleCommandResult.success(); } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDetectCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDetectCommand.java index 9d4e239ea..269bb9388 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDetectCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDetectCommand.java @@ -6,35 +6,37 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class TurtleDetectCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleDetectCommand implements ITurtleCommand +{ private final InteractDirection m_direction; - public TurtleDetectCommand(InteractDirection direction) { + public TurtleDetectCommand( InteractDirection direction ) + { this.m_direction = direction; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Get world direction from direction - Direction direction = this.m_direction.toWorldDir(turtle); + Direction direction = this.m_direction.toWorldDir( turtle ); // Check if thing in front is air or not World world = turtle.getWorld(); BlockPos oldPosition = turtle.getPosition(); - BlockPos newPosition = oldPosition.offset(direction); + BlockPos newPosition = oldPosition.offset( direction ); - return !WorldUtil.isLiquidBlock(world, newPosition) && !world.isAir(newPosition) ? TurtleCommandResult.success() : TurtleCommandResult.failure(); + return !WorldUtil.isLiquidBlock( world, newPosition ) && !world.isAir( newPosition ) ? TurtleCommandResult.success() : TurtleCommandResult.failure(); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDropCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDropCommand.java index 5a0e000f7..611d63f1c 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDropCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleDropCommand.java @@ -6,8 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleAnimation; @@ -17,76 +15,90 @@ import dan200.computercraft.api.turtle.event.TurtleInventoryEvent; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.ItemStorage; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class TurtleDropCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleDropCommand implements ITurtleCommand +{ private final InteractDirection m_direction; private final int m_quantity; - public TurtleDropCommand(InteractDirection direction, int quantity) { + public TurtleDropCommand( InteractDirection direction, int quantity ) + { this.m_direction = direction; this.m_quantity = quantity; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Dropping nothing is easy - if (this.m_quantity == 0) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( this.m_quantity == 0 ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); } // Get world direction from direction - Direction direction = this.m_direction.toWorldDir(turtle); + Direction direction = this.m_direction.toWorldDir( turtle ); // Get things to drop - ItemStack stack = InventoryUtil.takeItems(this.m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot()); - if (stack.isEmpty()) { - return TurtleCommandResult.failure("No items to drop"); + ItemStack stack = InventoryUtil.takeItems( this.m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() ); + if( stack.isEmpty() ) + { + return TurtleCommandResult.failure( "No items to drop" ); } // Get inventory for thing in front World world = turtle.getWorld(); BlockPos oldPosition = turtle.getPosition(); - BlockPos newPosition = oldPosition.offset(direction); + BlockPos newPosition = oldPosition.offset( direction ); Direction side = direction.getOpposite(); - Inventory inventory = InventoryUtil.getInventory(world, newPosition, side); + Inventory inventory = InventoryUtil.getInventory( world, newPosition, side ); // Fire the event, restoring the inventory and exiting if it is cancelled. - TurtlePlayer player = TurtlePlaceCommand.createPlayer(turtle, oldPosition, direction); - TurtleInventoryEvent.Drop event = new TurtleInventoryEvent.Drop(turtle, player, world, newPosition, inventory, stack); - if (TurtleEvent.post(event)) { - InventoryUtil.storeItems(stack, turtle.getItemHandler(), turtle.getSelectedSlot()); - return TurtleCommandResult.failure(event.getFailureMessage()); + TurtlePlayer player = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction ); + TurtleInventoryEvent.Drop event = new TurtleInventoryEvent.Drop( turtle, player, world, newPosition, inventory, stack ); + if( TurtleEvent.post( event ) ) + { + InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() ); + return TurtleCommandResult.failure( event.getFailureMessage() ); } - if (inventory != null) { + if( inventory != null ) + { // Drop the item into the inventory - ItemStack remainder = InventoryUtil.storeItems(stack, ItemStorage.wrap(inventory, side)); - if (!remainder.isEmpty()) { + ItemStack remainder = InventoryUtil.storeItems( stack, ItemStorage.wrap( inventory, side ) ); + if( !remainder.isEmpty() ) + { // Put the remainder back in the turtle - InventoryUtil.storeItems(remainder, turtle.getItemHandler(), turtle.getSelectedSlot()); + InventoryUtil.storeItems( remainder, turtle.getItemHandler(), turtle.getSelectedSlot() ); } // Return true if we stored anything - if (remainder != stack) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( remainder != stack ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); - } else { - return TurtleCommandResult.failure("No space for items"); } - } else { + else + { + return TurtleCommandResult.failure( "No space for items" ); + } + } + else + { // Drop the item into the world - WorldUtil.dropItemStack(stack, world, oldPosition, direction); - world.syncGlobalEvent(1000, newPosition, 0); - turtle.playAnimation(TurtleAnimation.WAIT); + WorldUtil.dropItemStack( stack, world, oldPosition, direction ); + world.syncGlobalEvent( 1000, newPosition, 0 ); + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java index eafe02ebe..b8455962a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java @@ -6,14 +6,7 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.turtle.ITurtleAccess; -import dan200.computercraft.api.turtle.ITurtleCommand; -import dan200.computercraft.api.turtle.ITurtleUpgrade; -import dan200.computercraft.api.turtle.TurtleAnimation; -import dan200.computercraft.api.turtle.TurtleCommandResult; -import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.api.turtle.*; import dan200.computercraft.api.turtle.event.TurtleAction; import dan200.computercraft.api.turtle.event.TurtleActionEvent; import dan200.computercraft.api.turtle.event.TurtleEvent; @@ -21,71 +14,87 @@ import dan200.computercraft.shared.TurtleUpgrades; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.ItemStorage; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; -public class TurtleEquipCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleEquipCommand implements ITurtleCommand +{ private final TurtleSide m_side; - public TurtleEquipCommand(TurtleSide side) { + public TurtleEquipCommand( TurtleSide side ) + { this.m_side = side; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Determine the upgrade to equipLeft ITurtleUpgrade newUpgrade; ItemStack newUpgradeStack; Inventory inventory = turtle.getInventory(); - ItemStack selectedStack = inventory.getStack(turtle.getSelectedSlot()); - if (!selectedStack.isEmpty()) { + ItemStack selectedStack = inventory.getStack( turtle.getSelectedSlot() ); + if( !selectedStack.isEmpty() ) + { newUpgradeStack = selectedStack.copy(); - newUpgrade = TurtleUpgrades.get(newUpgradeStack); - if (newUpgrade == null || !TurtleUpgrades.suitableForFamily(((TurtleBrain) turtle).getFamily(), newUpgrade)) { - return TurtleCommandResult.failure("Not a valid upgrade"); + newUpgrade = TurtleUpgrades.get( newUpgradeStack ); + if( newUpgrade == null || !TurtleUpgrades.suitableForFamily( ((TurtleBrain) turtle).getFamily(), newUpgrade ) ) + { + return TurtleCommandResult.failure( "Not a valid upgrade" ); } - } else { + } + else + { newUpgradeStack = null; newUpgrade = null; } // Determine the upgrade to replace ItemStack oldUpgradeStack; - ITurtleUpgrade oldUpgrade = turtle.getUpgrade(this.m_side); - if (oldUpgrade != null) { + ITurtleUpgrade oldUpgrade = turtle.getUpgrade( this.m_side ); + if( oldUpgrade != null ) + { ItemStack craftingItem = oldUpgrade.getCraftingItem(); oldUpgradeStack = !craftingItem.isEmpty() ? craftingItem.copy() : null; - } else { + } + else + { oldUpgradeStack = null; } - TurtleActionEvent event = new TurtleActionEvent(turtle, TurtleAction.EQUIP); - if (TurtleEvent.post(event)) { - return TurtleCommandResult.failure(event.getFailureMessage()); + TurtleActionEvent event = new TurtleActionEvent( turtle, TurtleAction.EQUIP ); + if( TurtleEvent.post( event ) ) + { + return TurtleCommandResult.failure( event.getFailureMessage() ); } // Do the swapping: - if (newUpgradeStack != null) { + if( newUpgradeStack != null ) + { // Consume new upgrades item - InventoryUtil.takeItems(1, ItemStorage.wrap(inventory), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot()); + InventoryUtil.takeItems( 1, ItemStorage.wrap( inventory ), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() ); } - if (oldUpgradeStack != null) { + if( oldUpgradeStack != null ) + { // Store old upgrades item - ItemStack remainder = InventoryUtil.storeItems(oldUpgradeStack, ItemStorage.wrap(inventory), turtle.getSelectedSlot()); - if (!remainder.isEmpty()) { + ItemStack remainder = InventoryUtil.storeItems( oldUpgradeStack, ItemStorage.wrap( inventory ), turtle.getSelectedSlot() ); + if( !remainder.isEmpty() ) + { // If there's no room for the items, drop them BlockPos position = turtle.getPosition(); - WorldUtil.dropItemStack(remainder, turtle.getWorld(), position, turtle.getDirection()); + WorldUtil.dropItemStack( remainder, turtle.getWorld(), position, turtle.getDirection() ); } } - turtle.setUpgrade(this.m_side, newUpgrade); + turtle.setUpgrade( this.m_side, newUpgrade ); // Animate - if (newUpgrade != null || oldUpgrade != null) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( newUpgrade != null || oldUpgrade != null ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); } return TurtleCommandResult.success(); diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleInspectCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleInspectCommand.java index 0249ba6bd..5e781b23a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleInspectCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleInspectCommand.java @@ -6,70 +6,72 @@ package dan200.computercraft.shared.turtle.core; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nonnull; - -import com.google.common.collect.ImmutableMap; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.event.TurtleBlockEvent; import dan200.computercraft.api.turtle.event.TurtleEvent; - import dan200.computercraft.shared.peripheral.generic.data.BlockData; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.state.property.Property; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.registry.Registry; import net.minecraft.world.World; -public class TurtleInspectCommand implements ITurtleCommand { +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.Map; + +public class TurtleInspectCommand implements ITurtleCommand +{ private final InteractDirection direction; - public TurtleInspectCommand(InteractDirection direction) { + public TurtleInspectCommand( InteractDirection direction ) + { this.direction = direction; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Get world direction from direction - Direction direction = this.direction.toWorldDir(turtle); + Direction direction = this.direction.toWorldDir( turtle ); // Check if thing in front is air or not World world = turtle.getWorld(); BlockPos oldPosition = turtle.getPosition(); - BlockPos newPosition = oldPosition.offset(direction); + BlockPos newPosition = oldPosition.offset( direction ); - BlockState state = world.getBlockState(newPosition); - if (state.isAir()) { - return TurtleCommandResult.failure("No block to inspect"); + BlockState state = world.getBlockState( newPosition ); + if( state.isAir() ) + { + return TurtleCommandResult.failure( "No block to inspect" ); } Map table = BlockData.fill( new HashMap<>(), state ); // Fire the event, exiting if it is cancelled - TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer(turtle, oldPosition, direction); - TurtleBlockEvent.Inspect event = new TurtleBlockEvent.Inspect(turtle, turtlePlayer, world, newPosition, state, table); - if (TurtleEvent.post(event)) { - return TurtleCommandResult.failure(event.getFailureMessage()); + TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction ); + TurtleBlockEvent.Inspect event = new TurtleBlockEvent.Inspect( turtle, turtlePlayer, world, newPosition, state, table ); + if( TurtleEvent.post( event ) ) + { + return TurtleCommandResult.failure( event.getFailureMessage() ); } - return TurtleCommandResult.success(new Object[] {table}); + return TurtleCommandResult.success( new Object[] { table } ); } - @SuppressWarnings ({ + @SuppressWarnings( { "unchecked", "rawtypes" - }) - private static Object getPropertyValue(Property property, Comparable value) { - if (value instanceof String || value instanceof Number || value instanceof Boolean) { + } ) + private static Object getPropertyValue( Property property, Comparable value ) + { + if( value instanceof String || value instanceof Number || value instanceof Boolean ) + { return value; } - return property.name(value); + return property.name( value ); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleMoveCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleMoveCommand.java index 134dce9ca..a57bd841a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleMoveCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleMoveCommand.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import java.util.List; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; @@ -19,7 +15,6 @@ import dan200.computercraft.api.turtle.event.TurtleBlockEvent; import dan200.computercraft.api.turtle.event.TurtleEvent; import dan200.computercraft.shared.TurtlePermissions; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; @@ -29,120 +24,143 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.World; -public class TurtleMoveCommand implements ITurtleCommand { - private static final Box EMPTY_BOX = new Box(0, 0, 0, 0, 0, 0); +import javax.annotation.Nonnull; +import java.util.List; + +public class TurtleMoveCommand implements ITurtleCommand +{ + private static final Box EMPTY_BOX = new Box( 0, 0, 0, 0, 0, 0 ); private final MoveDirection m_direction; - public TurtleMoveCommand(MoveDirection direction) { + public TurtleMoveCommand( MoveDirection direction ) + { this.m_direction = direction; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Get world direction from direction - Direction direction = this.m_direction.toWorldDir(turtle); + Direction direction = this.m_direction.toWorldDir( turtle ); // Check if we can move World oldWorld = turtle.getWorld(); BlockPos oldPosition = turtle.getPosition(); - BlockPos newPosition = oldPosition.offset(direction); + BlockPos newPosition = oldPosition.offset( direction ); - TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer(turtle, oldPosition, direction); - TurtleCommandResult canEnterResult = canEnter(turtlePlayer, oldWorld, newPosition); - if (!canEnterResult.isSuccess()) { + TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction ); + TurtleCommandResult canEnterResult = canEnter( turtlePlayer, oldWorld, newPosition ); + if( !canEnterResult.isSuccess() ) + { return canEnterResult; } // Check existing block is air or replaceable - BlockState state = oldWorld.getBlockState(newPosition); - if (!oldWorld.isAir(newPosition) && !WorldUtil.isLiquidBlock(oldWorld, newPosition) && !state.getMaterial() - .isReplaceable()) { - return TurtleCommandResult.failure("Movement obstructed"); + BlockState state = oldWorld.getBlockState( newPosition ); + if( !oldWorld.isAir( newPosition ) && !WorldUtil.isLiquidBlock( oldWorld, newPosition ) && !state.getMaterial() + .isReplaceable() ) + { + return TurtleCommandResult.failure( "Movement obstructed" ); } // Check there isn't anything in the way - VoxelShape collision = state.getCollisionShape(oldWorld, oldPosition) - .offset(newPosition.getX(), newPosition.getY(), newPosition.getZ()); + VoxelShape collision = state.getCollisionShape( oldWorld, oldPosition ) + .offset( newPosition.getX(), newPosition.getY(), newPosition.getZ() ); - if (!oldWorld.intersectsEntities(null, collision)) { - if (!ComputerCraft.turtlesCanPush || this.m_direction == MoveDirection.UP || this.m_direction == MoveDirection.DOWN) { - return TurtleCommandResult.failure("Movement obstructed"); + if( !oldWorld.intersectsEntities( null, collision ) ) + { + if( !ComputerCraft.turtlesCanPush || this.m_direction == MoveDirection.UP || this.m_direction == MoveDirection.DOWN ) + { + return TurtleCommandResult.failure( "Movement obstructed" ); } // Check there is space for all the pushable entities to be pushed - List list = oldWorld.getEntitiesByClass(Entity.class, getBox(collision), x -> x != null && x.isAlive() && x.inanimate); - for (Entity entity : list) { + List list = oldWorld.getEntitiesByClass( Entity.class, getBox( collision ), x -> x != null && x.isAlive() && x.inanimate ); + for( Entity entity : list ) + { Box pushedBB = entity.getBoundingBox() - .offset(direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ()); - if (!oldWorld.intersectsEntities(null, VoxelShapes.cuboid(pushedBB))) { - return TurtleCommandResult.failure("Movement obstructed"); + .offset( direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ() ); + if( !oldWorld.intersectsEntities( null, VoxelShapes.cuboid( pushedBB ) ) ) + { + return TurtleCommandResult.failure( "Movement obstructed" ); } } } - TurtleBlockEvent.Move moveEvent = new TurtleBlockEvent.Move(turtle, turtlePlayer, oldWorld, newPosition); - if (TurtleEvent.post(moveEvent)) { - return TurtleCommandResult.failure(moveEvent.getFailureMessage()); + TurtleBlockEvent.Move moveEvent = new TurtleBlockEvent.Move( turtle, turtlePlayer, oldWorld, newPosition ); + if( TurtleEvent.post( moveEvent ) ) + { + return TurtleCommandResult.failure( moveEvent.getFailureMessage() ); } // Check fuel level - if (turtle.isFuelNeeded() && turtle.getFuelLevel() < 1) { - return TurtleCommandResult.failure("Out of fuel"); + if( turtle.isFuelNeeded() && turtle.getFuelLevel() < 1 ) + { + return TurtleCommandResult.failure( "Out of fuel" ); } // Move - if (!turtle.teleportTo(oldWorld, newPosition)) { - return TurtleCommandResult.failure("Movement failed"); + if( !turtle.teleportTo( oldWorld, newPosition ) ) + { + return TurtleCommandResult.failure( "Movement failed" ); } // Consume fuel - turtle.consumeFuel(1); + turtle.consumeFuel( 1 ); // Animate - switch (this.m_direction) { - case FORWARD: - default: - turtle.playAnimation(TurtleAnimation.MOVE_FORWARD); - break; - case BACK: - turtle.playAnimation(TurtleAnimation.MOVE_BACK); - break; - case UP: - turtle.playAnimation(TurtleAnimation.MOVE_UP); - break; - case DOWN: - turtle.playAnimation(TurtleAnimation.MOVE_DOWN); - break; + switch( this.m_direction ) + { + case FORWARD: + default: + turtle.playAnimation( TurtleAnimation.MOVE_FORWARD ); + break; + case BACK: + turtle.playAnimation( TurtleAnimation.MOVE_BACK ); + break; + case UP: + turtle.playAnimation( TurtleAnimation.MOVE_UP ); + break; + case DOWN: + turtle.playAnimation( TurtleAnimation.MOVE_DOWN ); + break; } return TurtleCommandResult.success(); } - private static TurtleCommandResult canEnter(TurtlePlayer turtlePlayer, World world, BlockPos position) { - if (World.isOutOfBuildLimitVertically(position)) { - return TurtleCommandResult.failure(position.getY() < 0 ? "Too low to move" : "Too high to move"); + private static TurtleCommandResult canEnter( TurtlePlayer turtlePlayer, World world, BlockPos position ) + { + if( World.isOutOfBuildLimitVertically( position ) ) + { + return TurtleCommandResult.failure( position.getY() < 0 ? "Too low to move" : "Too high to move" ); } - if (!World.isInBuildLimit(position)) { - return TurtleCommandResult.failure("Cannot leave the world"); + if( !World.isInBuildLimit( position ) ) + { + return TurtleCommandResult.failure( "Cannot leave the world" ); } // Check spawn protection - if (ComputerCraft.turtlesObeyBlockProtection && !TurtlePermissions.isBlockEnterable(world, position, turtlePlayer)) { - return TurtleCommandResult.failure("Cannot enter protected area"); + if( ComputerCraft.turtlesObeyBlockProtection && !TurtlePermissions.isBlockEnterable( world, position, turtlePlayer ) ) + { + return TurtleCommandResult.failure( "Cannot enter protected area" ); } - if (!world.isChunkLoaded(position)) { - return TurtleCommandResult.failure("Cannot leave loaded world"); + if( !world.isChunkLoaded( position ) ) + { + return TurtleCommandResult.failure( "Cannot leave loaded world" ); } - if (!world.getWorldBorder() - .contains(position)) { - return TurtleCommandResult.failure("Cannot pass the world border"); + if( !world.getWorldBorder() + .contains( position ) ) + { + return TurtleCommandResult.failure( "Cannot pass the world border" ); } return TurtleCommandResult.success(); } - private static Box getBox(VoxelShape shape) { + private static Box getBox( VoxelShape shape ) + { return shape.isEmpty() ? EMPTY_BOX : shape.getBoundingBox(); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java index d30264751..9817d650e 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import java.util.List; - -import javax.annotation.Nonnull; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; @@ -22,14 +18,12 @@ import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.DropConsumer; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.WorldUtil; -import net.minecraft.item.*; -import org.apache.commons.lang3.tuple.Pair; - import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.item.*; import net.minecraft.text.LiteralText; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; @@ -39,147 +33,177 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; -public class TurtlePlaceCommand implements ITurtleCommand { +import javax.annotation.Nonnull; +import java.util.List; + +public class TurtlePlaceCommand implements ITurtleCommand +{ private final InteractDirection m_direction; private final Object[] m_extraArguments; - public TurtlePlaceCommand(InteractDirection direction, Object[] arguments) { + public TurtlePlaceCommand( InteractDirection direction, Object[] arguments ) + { this.m_direction = direction; this.m_extraArguments = arguments; } - public static ItemStack deploy(@Nonnull ItemStack stack, ITurtleAccess turtle, Direction direction, Object[] extraArguments, String[] outErrorMessage) { + public static ItemStack deploy( @Nonnull ItemStack stack, ITurtleAccess turtle, Direction direction, Object[] extraArguments, String[] outErrorMessage ) + { // Create a fake player, and orient it appropriately BlockPos playerPosition = turtle.getPosition() - .offset(direction); - TurtlePlayer turtlePlayer = createPlayer(turtle, playerPosition, direction); + .offset( direction ); + TurtlePlayer turtlePlayer = createPlayer( turtle, playerPosition, direction ); - return deploy(stack, turtle, turtlePlayer, direction, extraArguments, outErrorMessage); + return deploy( stack, turtle, turtlePlayer, direction, extraArguments, outErrorMessage ); } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Get thing to place ItemStack stack = turtle.getInventory() - .getStack(turtle.getSelectedSlot()); - if (stack.isEmpty()) { - return TurtleCommandResult.failure("No items to place"); + .getStack( turtle.getSelectedSlot() ); + if( stack.isEmpty() ) + { + return TurtleCommandResult.failure( "No items to place" ); } // Remember old block - Direction direction = this.m_direction.toWorldDir(turtle); + Direction direction = this.m_direction.toWorldDir( turtle ); BlockPos coordinates = turtle.getPosition() - .offset(direction); + .offset( direction ); // Create a fake player, and orient it appropriately BlockPos playerPosition = turtle.getPosition() - .offset(direction); - TurtlePlayer turtlePlayer = createPlayer(turtle, playerPosition, direction); + .offset( direction ); + TurtlePlayer turtlePlayer = createPlayer( turtle, playerPosition, direction ); - TurtleBlockEvent.Place place = new TurtleBlockEvent.Place(turtle, turtlePlayer, turtle.getWorld(), coordinates, stack); - if (TurtleEvent.post(place)) { - return TurtleCommandResult.failure(place.getFailureMessage()); + TurtleBlockEvent.Place place = new TurtleBlockEvent.Place( turtle, turtlePlayer, turtle.getWorld(), coordinates, stack ); + if( TurtleEvent.post( place ) ) + { + return TurtleCommandResult.failure( place.getFailureMessage() ); } // Do the deploying String[] errorMessage = new String[1]; - ItemStack remainder = deploy(stack, turtle, turtlePlayer, direction, this.m_extraArguments, errorMessage); - if (remainder != stack) { + ItemStack remainder = deploy( stack, turtle, turtlePlayer, direction, this.m_extraArguments, errorMessage ); + if( remainder != stack ) + { // Put the remaining items back turtle.getInventory() - .setStack(turtle.getSelectedSlot(), remainder); + .setStack( turtle.getSelectedSlot(), remainder ); turtle.getInventory() - .markDirty(); + .markDirty(); // Animate and return success - turtle.playAnimation(TurtleAnimation.WAIT); + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); - } else { - if (errorMessage[0] != null) { - return TurtleCommandResult.failure(errorMessage[0]); - } else if (stack.getItem() instanceof BlockItem) { - return TurtleCommandResult.failure("Cannot place block here"); - } else { - return TurtleCommandResult.failure("Cannot place item here"); + } + else + { + if( errorMessage[0] != null ) + { + return TurtleCommandResult.failure( errorMessage[0] ); + } + else if( stack.getItem() instanceof BlockItem ) + { + return TurtleCommandResult.failure( "Cannot place block here" ); + } + else + { + return TurtleCommandResult.failure( "Cannot place item here" ); } } } - public static TurtlePlayer createPlayer(ITurtleAccess turtle, BlockPos position, Direction direction) { - TurtlePlayer turtlePlayer = TurtlePlayer.get(turtle); - orientPlayer(turtle, turtlePlayer, position, direction); + public static TurtlePlayer createPlayer( ITurtleAccess turtle, BlockPos position, Direction direction ) + { + TurtlePlayer turtlePlayer = TurtlePlayer.get( turtle ); + orientPlayer( turtle, turtlePlayer, position, direction ); return turtlePlayer; } - public static ItemStack deploy(@Nonnull ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, Direction direction, - Object[] extraArguments, String[] outErrorMessage) { + public static ItemStack deploy( @Nonnull ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, Direction direction, + Object[] extraArguments, String[] outErrorMessage ) + { // Deploy on an entity - ItemStack remainder = deployOnEntity(stack, turtle, turtlePlayer, direction, extraArguments, outErrorMessage); - if (remainder != stack) { + ItemStack remainder = deployOnEntity( stack, turtle, turtlePlayer, direction, extraArguments, outErrorMessage ); + if( remainder != stack ) + { return remainder; } // Deploy on the block immediately in front BlockPos position = turtle.getPosition(); - BlockPos newPosition = position.offset(direction); - remainder = deployOnBlock(stack, turtle, turtlePlayer, newPosition, direction.getOpposite(), extraArguments, true, outErrorMessage); - if (remainder != stack) { + BlockPos newPosition = position.offset( direction ); + remainder = deployOnBlock( stack, turtle, turtlePlayer, newPosition, direction.getOpposite(), extraArguments, true, outErrorMessage ); + if( remainder != stack ) + { return remainder; } // Deploy on the block one block away - remainder = deployOnBlock(stack, - turtle, - turtlePlayer, - newPosition.offset(direction), - direction.getOpposite(), - extraArguments, - false, - outErrorMessage); - if (remainder != stack) { + remainder = deployOnBlock( stack, + turtle, + turtlePlayer, + newPosition.offset( direction ), + direction.getOpposite(), + extraArguments, + false, + outErrorMessage ); + if( remainder != stack ) + { return remainder; } - if (direction.getAxis() != Direction.Axis.Y) { + if( direction.getAxis() != Direction.Axis.Y ) + { // Deploy down on the block in front - remainder = deployOnBlock(stack, turtle, turtlePlayer, newPosition.down(), Direction.UP, extraArguments, false, outErrorMessage); - if (remainder != stack) { + remainder = deployOnBlock( stack, turtle, turtlePlayer, newPosition.down(), Direction.UP, extraArguments, false, outErrorMessage ); + if( remainder != stack ) + { return remainder; } } // Deploy back onto the turtle - remainder = deployOnBlock(stack, turtle, turtlePlayer, position, direction, extraArguments, false, outErrorMessage); + remainder = deployOnBlock( stack, turtle, turtlePlayer, position, direction, extraArguments, false, outErrorMessage ); return remainder; // If nothing worked, return the original stack unchanged } - private static void orientPlayer(ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction direction) { + private static void orientPlayer( ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction direction ) + { double posX = position.getX() + 0.5; double posY = position.getY() + 0.5; double posZ = position.getZ() + 0.5; // Stop intersection with the turtle itself - if (turtle.getPosition() - .equals(position)) { + if( turtle.getPosition() + .equals( position ) ) + { posX += 0.48 * direction.getOffsetX(); posY += 0.48 * direction.getOffsetY(); posZ += 0.48 * direction.getOffsetZ(); } - if (direction.getAxis() != Direction.Axis.Y) { + if( direction.getAxis() != Direction.Axis.Y ) + { turtlePlayer.yaw = direction.asRotation(); turtlePlayer.pitch = 0.0f; - } else { + } + else + { turtlePlayer.yaw = turtle.getDirection() - .asRotation(); - turtlePlayer.pitch = DirectionUtil.toPitchAngle(direction); + .asRotation(); + turtlePlayer.pitch = DirectionUtil.toPitchAngle( direction ); } - turtlePlayer.setPos(posX, posY, posZ); + turtlePlayer.setPos( posX, posY, posZ ); turtlePlayer.prevX = posX; turtlePlayer.prevY = posY; turtlePlayer.prevZ = posZ; @@ -191,90 +215,105 @@ public class TurtlePlaceCommand implements ITurtleCommand { } @Nonnull - private static ItemStack deployOnEntity(@Nonnull ItemStack stack, final ITurtleAccess turtle, TurtlePlayer turtlePlayer, Direction direction, - Object[] extraArguments, String[] outErrorMessage) { + private static ItemStack deployOnEntity( @Nonnull ItemStack stack, final ITurtleAccess turtle, TurtlePlayer turtlePlayer, Direction direction, + Object[] extraArguments, String[] outErrorMessage ) + { // See if there is an entity present final World world = turtle.getWorld(); final BlockPos position = turtle.getPosition(); Vec3d turtlePos = turtlePlayer.getPos(); - Vec3d rayDir = turtlePlayer.getRotationVec(1.0f); - Pair hit = WorldUtil.rayTraceEntities(world, turtlePos, rayDir, 1.5); - if (hit == null) { + Vec3d rayDir = turtlePlayer.getRotationVec( 1.0f ); + Pair hit = WorldUtil.rayTraceEntities( world, turtlePos, rayDir, 1.5 ); + if( hit == null ) + { return stack; } // Load up the turtle's inventory ItemStack stackCopy = stack.copy(); - turtlePlayer.loadInventory(stackCopy); + turtlePlayer.loadInventory( stackCopy ); // Start claiming entity drops Entity hitEntity = hit.getKey(); Vec3d hitPos = hit.getValue(); - DropConsumer.set(hitEntity, drop -> InventoryUtil.storeItems(drop, turtle.getItemHandler(), turtle.getSelectedSlot())); + DropConsumer.set( hitEntity, drop -> InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() ) ); // Place on the entity boolean placed = false; - ActionResult cancelResult = hitEntity.interactAt(turtlePlayer, hitPos, Hand.MAIN_HAND); + ActionResult cancelResult = hitEntity.interactAt( turtlePlayer, hitPos, Hand.MAIN_HAND ); - if (cancelResult != null && cancelResult.isAccepted()) { + if( cancelResult != null && cancelResult.isAccepted() ) + { placed = true; } - else { - cancelResult = hitEntity.interact(turtlePlayer, Hand.MAIN_HAND); - if (cancelResult != null && cancelResult.isAccepted()) { + else + { + cancelResult = hitEntity.interact( turtlePlayer, Hand.MAIN_HAND ); + if( cancelResult != null && cancelResult.isAccepted() ) + { placed = true; } - else if (hitEntity instanceof LivingEntity) { - placed = stackCopy.useOnEntity(turtlePlayer, (LivingEntity) hitEntity, Hand.MAIN_HAND).isAccepted(); - if (placed) turtlePlayer.loadInventory(stackCopy); + else if( hitEntity instanceof LivingEntity ) + { + placed = stackCopy.useOnEntity( turtlePlayer, (LivingEntity) hitEntity, Hand.MAIN_HAND ).isAccepted(); + if( placed ) turtlePlayer.loadInventory( stackCopy ); } } // Stop claiming drops List remainingDrops = DropConsumer.clear(); - for (ItemStack remaining : remainingDrops) { - WorldUtil.dropItemStack(remaining, - world, - position, - turtle.getDirection() - .getOpposite()); + for( ItemStack remaining : remainingDrops ) + { + WorldUtil.dropItemStack( remaining, + world, + position, + turtle.getDirection() + .getOpposite() ); } // Put everything we collected into the turtles inventory, then return - ItemStack remainder = turtlePlayer.unloadInventory(turtle); - if (!placed && ItemStack.areEqual(stack, remainder)) { + ItemStack remainder = turtlePlayer.unloadInventory( turtle ); + if( !placed && ItemStack.areEqual( stack, remainder ) ) + { return stack; - } else if (!remainder.isEmpty()) { + } + else if( !remainder.isEmpty() ) + { return remainder; - } else { + } + else + { return ItemStack.EMPTY; } } @Nonnull - private static ItemStack deployOnBlock(@Nonnull ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction side, - Object[] extraArguments, boolean allowReplace, String[] outErrorMessage) { + private static ItemStack deployOnBlock( @Nonnull ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, Direction side, + Object[] extraArguments, boolean allowReplace, String[] outErrorMessage ) + { // Re-orient the fake player Direction playerDir = side.getOpposite(); - BlockPos playerPosition = position.offset(side); - orientPlayer(turtle, turtlePlayer, playerPosition, playerDir); + BlockPos playerPosition = position.offset( side ); + orientPlayer( turtle, turtlePlayer, playerPosition, playerDir ); ItemStack stackCopy = stack.copy(); - turtlePlayer.loadInventory(stackCopy); + turtlePlayer.loadInventory( stackCopy ); // Calculate where the turtle would hit the block float hitX = 0.5f + side.getOffsetX() * 0.5f; float hitY = 0.5f + side.getOffsetY() * 0.5f; float hitZ = 0.5f + side.getOffsetZ() * 0.5f; - if (Math.abs(hitY - 0.5f) < 0.01f) { + if( Math.abs( hitY - 0.5f ) < 0.01f ) + { hitY = 0.45f; } // Check if there's something suitable to place onto - BlockHitResult hit = new BlockHitResult(new Vec3d(hitX, hitY, hitZ), side, position, false); - ItemUsageContext context = new ItemUsageContext(turtlePlayer, Hand.MAIN_HAND, hit); - ItemPlacementContext placementContext = new ItemPlacementContext(context); - if (!canDeployOnBlock(new ItemPlacementContext(context), turtle, turtlePlayer, position, side, allowReplace, outErrorMessage)) { + BlockHitResult hit = new BlockHitResult( new Vec3d( hitX, hitY, hitZ ), side, position, false ); + ItemUsageContext context = new ItemUsageContext( turtlePlayer, Hand.MAIN_HAND, hit ); + ItemPlacementContext placementContext = new ItemPlacementContext( context ); + if( !canDeployOnBlock( new ItemPlacementContext( context ), turtle, turtlePlayer, position, side, allowReplace, outErrorMessage ) ) + { return stack; } @@ -284,87 +323,112 @@ public class TurtlePlaceCommand implements ITurtleCommand { // Do the deploying (put everything in the players inventory) boolean placed = false; BlockEntity existingTile = turtle.getWorld() - .getBlockEntity(position); + .getBlockEntity( position ); - if (stackCopy.useOnBlock(context).isAccepted()) { + if( stackCopy.useOnBlock( context ).isAccepted() ) + { placed = true; - turtlePlayer.loadInventory(stackCopy); + turtlePlayer.loadInventory( stackCopy ); } - if (!placed && (item instanceof BucketItem || item instanceof BoatItem || item instanceof LilyPadItem || item instanceof GlassBottleItem)) { - TypedActionResult result = stackCopy.use(turtle.getWorld(), turtlePlayer, Hand.MAIN_HAND); - if (result.getResult() - .isAccepted() && !ItemStack.areEqual(stack, result.getValue())) { + if( !placed && (item instanceof BucketItem || item instanceof BoatItem || item instanceof LilyPadItem || item instanceof GlassBottleItem) ) + { + TypedActionResult result = stackCopy.use( turtle.getWorld(), turtlePlayer, Hand.MAIN_HAND ); + if( result.getResult() + .isAccepted() && !ItemStack.areEqual( stack, result.getValue() ) ) + { placed = true; - turtlePlayer.loadInventory(result.getValue()); + turtlePlayer.loadInventory( result.getValue() ); } } // Set text on signs - if (placed && item instanceof SignItem) { - if (extraArguments != null && extraArguments.length >= 1 && extraArguments[0] instanceof String) { + if( placed && item instanceof SignItem ) + { + if( extraArguments != null && extraArguments.length >= 1 && extraArguments[0] instanceof String ) + { World world = turtle.getWorld(); - BlockEntity tile = world.getBlockEntity(position); - if (tile == null || tile == existingTile) { - tile = world.getBlockEntity(position.offset(side)); + BlockEntity tile = world.getBlockEntity( position ); + if( tile == null || tile == existingTile ) + { + tile = world.getBlockEntity( position.offset( side ) ); } - if (tile instanceof SignBlockEntity) { + if( tile instanceof SignBlockEntity ) + { SignBlockEntity signTile = (SignBlockEntity) tile; String s = (String) extraArguments[0]; - String[] split = s.split("\n"); + String[] split = s.split( "\n" ); int firstLine = split.length <= 2 ? 1 : 0; - for (int i = 0; i < 4; i++) { - if (i >= firstLine && i < firstLine + split.length) { - if (split[i - firstLine].length() > 15) { - signTile.setTextOnRow(i, new LiteralText(split[i - firstLine].substring(0, 15))); - } else { - signTile.setTextOnRow(i, new LiteralText(split[i - firstLine])); + for( int i = 0; i < 4; i++ ) + { + if( i >= firstLine && i < firstLine + split.length ) + { + if( split[i - firstLine].length() > 15 ) + { + signTile.setTextOnRow( i, new LiteralText( split[i - firstLine].substring( 0, 15 ) ) ); } - } else { - signTile.setTextOnRow(i, new LiteralText("")); + else + { + signTile.setTextOnRow( i, new LiteralText( split[i - firstLine] ) ); + } + } + else + { + signTile.setTextOnRow( i, new LiteralText( "" ) ); } } signTile.markDirty(); - world.updateListeners(tile.getPos(), tile.getCachedState(), tile.getCachedState(), 3); + world.updateListeners( tile.getPos(), tile.getCachedState(), tile.getCachedState(), 3 ); } } } // Put everything we collected into the turtles inventory, then return - ItemStack remainder = turtlePlayer.unloadInventory(turtle); - if (!placed && ItemStack.areEqual(stack, remainder)) { + ItemStack remainder = turtlePlayer.unloadInventory( turtle ); + if( !placed && ItemStack.areEqual( stack, remainder ) ) + { return stack; - } else if (!remainder.isEmpty()) { + } + else if( !remainder.isEmpty() ) + { return remainder; - } else { + } + else + { return ItemStack.EMPTY; } } - private static boolean canDeployOnBlock(@Nonnull ItemPlacementContext context, ITurtleAccess turtle, TurtlePlayer player, BlockPos position, - Direction side, boolean allowReplaceable, String[] outErrorMessage) { + private static boolean canDeployOnBlock( @Nonnull ItemPlacementContext context, ITurtleAccess turtle, TurtlePlayer player, BlockPos position, + Direction side, boolean allowReplaceable, String[] outErrorMessage ) + { World world = turtle.getWorld(); - if (!World.isInBuildLimit(position) || world.isAir(position) || (context.getStack() - .getItem() instanceof BlockItem && WorldUtil.isLiquidBlock(world, - position))) { + if( !World.isInBuildLimit( position ) || world.isAir( position ) || (context.getStack() + .getItem() instanceof BlockItem && WorldUtil.isLiquidBlock( world, + position )) ) + { return false; } - BlockState state = world.getBlockState(position); + BlockState state = world.getBlockState( position ); - boolean replaceable = state.canReplace(context); - if (!allowReplaceable && replaceable) { + boolean replaceable = state.canReplace( context ); + if( !allowReplaceable && replaceable ) + { return false; } - if (ComputerCraft.turtlesObeyBlockProtection) { + if( ComputerCraft.turtlesObeyBlockProtection ) + { // Check spawn protection - boolean editable = replaceable ? TurtlePermissions.isBlockEditable(world, position, player) : TurtlePermissions.isBlockEditable(world, - position.offset( - side), - player); - if (!editable) { - if (outErrorMessage != null) { + boolean editable = replaceable ? TurtlePermissions.isBlockEditable( world, position, player ) : TurtlePermissions.isBlockEditable( world, + position.offset( + side ), + player ); + if( !editable ) + { + if( outErrorMessage != null ) + { outErrorMessage[0] = "Cannot place in protected area"; } return false; diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java index 52d2259b8..5ec609d09 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java @@ -6,12 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import java.util.OptionalInt; -import java.util.UUID; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.mojang.authlib.GameProfile; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.FakePlayer; @@ -20,7 +14,6 @@ import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.util.FakeNetHandler; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.WorldUtil; - import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; @@ -31,17 +24,24 @@ import net.minecraft.entity.passive.HorseBaseEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.NamedScreenHandlerFactory; -import net.minecraft.server.world.ServerWorld; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; -@SuppressWarnings ("EntityConstructor") -public final class TurtlePlayer extends FakePlayer { - private static final GameProfile DEFAULT_PROFILE = new GameProfile(UUID.fromString("0d0c4ca0-4ff1-11e4-916c-0800200c9a66"), "[ComputerCraft]"); -// TODO [M3R1-01] Fix Turtle not giving player achievement for actions +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.OptionalInt; +import java.util.UUID; + +@SuppressWarnings( "EntityConstructor" ) +public final class TurtlePlayer extends FakePlayer +{ + private static final GameProfile DEFAULT_PROFILE = new GameProfile( UUID.fromString( "0d0c4ca0-4ff1-11e4-916c-0800200c9a66" ), "[ComputerCraft]" ); + + // TODO [M3R1-01] Fix Turtle not giving player achievement for actions private TurtlePlayer( ServerWorld world, GameProfile name ) { super( world, name ); @@ -61,70 +61,82 @@ public final class TurtlePlayer extends FakePlayer { // Constructing a player overrides the "active player" variable in advancements. As fake players cannot // get advancements, this prevents a normal player who has placed a turtle from getting advancements. // We try to locate the "actual" player and restore them. - ServerPlayerEntity actualPlayer = world.getServer().getPlayerManager().getPlayer(player.getUuid()); - if( actualPlayer != null ) player.getAdvancementTracker().setOwner(actualPlayer); + ServerPlayerEntity actualPlayer = world.getServer().getPlayerManager().getPlayer( player.getUuid() ); + if( actualPlayer != null ) player.getAdvancementTracker().setOwner( actualPlayer ); } return player; - } + } - private static GameProfile getProfile(@Nullable GameProfile profile) { + private static GameProfile getProfile( @Nullable GameProfile profile ) + { return profile != null && profile.isComplete() ? profile : DEFAULT_PROFILE; } - private void setState(ITurtleAccess turtle) { - if (this.currentScreenHandler != playerScreenHandler) { - ComputerCraft.log.warn("Turtle has open container ({})", this.currentScreenHandler); + private void setState( ITurtleAccess turtle ) + { + if( this.currentScreenHandler != playerScreenHandler ) + { + ComputerCraft.log.warn( "Turtle has open container ({})", this.currentScreenHandler ); closeHandledScreen(); } BlockPos position = turtle.getPosition(); - this.setPos(position.getX() + 0.5, position.getY() + 0.5, position.getZ() + 0.5); + this.setPos( position.getX() + 0.5, position.getY() + 0.5, position.getZ() + 0.5 ); this.yaw = turtle.getDirection() - .asRotation(); + .asRotation(); this.pitch = 0.0f; this.inventory.clear(); } - public static TurtlePlayer get(ITurtleAccess access) { + public static TurtlePlayer get( ITurtleAccess access ) + { if( !(access instanceof TurtleBrain) ) return create( access ); TurtleBrain brain = (TurtleBrain) access; TurtlePlayer player = brain.m_cachedPlayer; - if (player == null || player.getGameProfile() != getProfile(access.getOwningPlayer()) || player.getEntityWorld() != access.getWorld()) { - player = brain.m_cachedPlayer = create(brain); - } else { - player.setState(access); + if( player == null || player.getGameProfile() != getProfile( access.getOwningPlayer() ) || player.getEntityWorld() != access.getWorld() ) + { + player = brain.m_cachedPlayer = create( brain ); + } + else + { + player.setState( access ); } return player; } - public void loadInventory(@Nonnull ItemStack currentStack) { + public void loadInventory( @Nonnull ItemStack currentStack ) + { // Load up the fake inventory this.inventory.selectedSlot = 0; - this.inventory.setStack(0, currentStack); + this.inventory.setStack( 0, currentStack ); } - public ItemStack unloadInventory(ITurtleAccess turtle) { + public ItemStack unloadInventory( ITurtleAccess turtle ) + { // Get the item we placed with - ItemStack results = this.inventory.getStack(0); - this.inventory.setStack(0, ItemStack.EMPTY); + ItemStack results = this.inventory.getStack( 0 ); + this.inventory.setStack( 0, ItemStack.EMPTY ); // Store (or drop) anything else we found BlockPos dropPosition = turtle.getPosition(); Direction dropDirection = turtle.getDirection() - .getOpposite(); - for (int i = 0; i < this.inventory.size(); i++) { - ItemStack stack = this.inventory.getStack(i); - if (!stack.isEmpty()) { - ItemStack remainder = InventoryUtil.storeItems(stack, turtle.getItemHandler(), turtle.getSelectedSlot()); - if (!remainder.isEmpty()) { - WorldUtil.dropItemStack(remainder, turtle.getWorld(), dropPosition, dropDirection); + .getOpposite(); + for( int i = 0; i < this.inventory.size(); i++ ) + { + ItemStack stack = this.inventory.getStack( i ); + if( !stack.isEmpty() ) + { + ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() ); + if( !remainder.isEmpty() ) + { + WorldUtil.dropItemStack( remainder, turtle.getWorld(), dropPosition, dropDirection ); } - this.inventory.setStack(i, ItemStack.EMPTY); + this.inventory.setStack( i, ItemStack.EMPTY ); } } this.inventory.markDirty(); @@ -133,79 +145,96 @@ public final class TurtlePlayer extends FakePlayer { @Nonnull @Override - public EntityType getType() { + public EntityType getType() + { return ComputerCraftRegistry.ModEntities.TURTLE_PLAYER; } @Override - public float getEyeHeight(@Nonnull EntityPose pose) { + public float getEyeHeight( @Nonnull EntityPose pose ) + { return 0; } @Override - public Vec3d getPos() { - return new Vec3d(this.getX(), this.getY(), this.getZ()); + public Vec3d getPos() + { + return new Vec3d( this.getX(), this.getY(), this.getZ() ); } @Override - public float getActiveEyeHeight(@Nonnull EntityPose pose, @Nonnull EntityDimensions size) { + public float getActiveEyeHeight( @Nonnull EntityPose pose, @Nonnull EntityDimensions size ) + { return 0; } @Override - public void enterCombat() { + public void enterCombat() + { } @Override - public void endCombat() { + public void endCombat() + { } @Override - public boolean startRiding(@Nonnull Entity entityIn, boolean force) { + public boolean startRiding( @Nonnull Entity entityIn, boolean force ) + { return false; } @Override - public void stopRiding() { + public void stopRiding() + { } @Override - public void openEditSignScreen(@Nonnull SignBlockEntity signTile) { + public void openEditSignScreen( @Nonnull SignBlockEntity signTile ) + { } //region Code which depends on the connection @Nonnull @Override - public OptionalInt openHandledScreen(@Nullable NamedScreenHandlerFactory prover) { + public OptionalInt openHandledScreen( @Nullable NamedScreenHandlerFactory prover ) + { return OptionalInt.empty(); } @Override - public void openHorseInventory(@Nonnull HorseBaseEntity horse, @Nonnull Inventory inventory) { + public void openHorseInventory( @Nonnull HorseBaseEntity horse, @Nonnull Inventory inventory ) + { } @Override - public void openEditBookScreen(@Nonnull ItemStack stack, @Nonnull Hand hand) { + public void openEditBookScreen( @Nonnull ItemStack stack, @Nonnull Hand hand ) + { } @Override - public void closeHandledScreen() { + public void closeHandledScreen() + { } @Override - public void updateCursorStack() { + public void updateCursorStack() + { } @Override - protected void onStatusEffectApplied(@Nonnull StatusEffectInstance id) { + protected void onStatusEffectApplied( @Nonnull StatusEffectInstance id ) + { } @Override - protected void onStatusEffectUpgraded(@Nonnull StatusEffectInstance id, boolean apply) { + protected void onStatusEffectUpgraded( @Nonnull StatusEffectInstance id, boolean apply ) + { } @Override - protected void onStatusEffectRemoved(@Nonnull StatusEffectInstance effect) { + protected void onStatusEffectRemoved( @Nonnull StatusEffectInstance effect ) + { } //endregion } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleRefuelCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleRefuelCommand.java index 6f59cdb3d..37d998c3c 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleRefuelCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleRefuelCommand.java @@ -6,46 +6,52 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleAnimation; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.event.TurtleEvent; import dan200.computercraft.api.turtle.event.TurtleRefuelEvent; - import net.minecraft.item.ItemStack; -public class TurtleRefuelCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleRefuelCommand implements ITurtleCommand +{ private final int limit; - public TurtleRefuelCommand(int limit) { + public TurtleRefuelCommand( int limit ) + { this.limit = limit; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { int slot = turtle.getSelectedSlot(); ItemStack stack = turtle.getInventory() - .getStack(slot); - if (stack.isEmpty()) { - return TurtleCommandResult.failure("No items to combust"); + .getStack( slot ); + if( stack.isEmpty() ) + { + return TurtleCommandResult.failure( "No items to combust" ); } - TurtleRefuelEvent event = new TurtleRefuelEvent(turtle, stack); - if (TurtleEvent.post(event)) { - return TurtleCommandResult.failure(event.getFailureMessage()); + TurtleRefuelEvent event = new TurtleRefuelEvent( turtle, stack ); + if( TurtleEvent.post( event ) ) + { + return TurtleCommandResult.failure( event.getFailureMessage() ); } - if (event.getHandler() == null) { - return TurtleCommandResult.failure("Items not combustible"); + if( event.getHandler() == null ) + { + return TurtleCommandResult.failure( "Items not combustible" ); } - if (this.limit != 0) { - turtle.addFuel(event.getHandler() - .refuel(turtle, stack, slot, this.limit)); - turtle.playAnimation(TurtleAnimation.WAIT); + if( this.limit != 0 ) + { + turtle.addFuel( event.getHandler() + .refuel( turtle, stack, slot, this.limit ) ); + turtle.playAnimation( TurtleAnimation.WAIT ); } return TurtleCommandResult.success(); diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleSuckCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleSuckCommand.java index 8c01e5b4e..bae644c73 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleSuckCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleSuckCommand.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import java.util.List; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleAnimation; @@ -18,7 +14,6 @@ import dan200.computercraft.api.turtle.event.TurtleEvent; import dan200.computercraft.api.turtle.event.TurtleInventoryEvent; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.ItemStorage; - import net.minecraft.entity.ItemEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; @@ -28,114 +23,143 @@ import net.minecraft.util.math.Box; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class TurtleSuckCommand implements ITurtleCommand { +import javax.annotation.Nonnull; +import java.util.List; + +public class TurtleSuckCommand implements ITurtleCommand +{ private final InteractDirection m_direction; private final int m_quantity; - public TurtleSuckCommand(InteractDirection direction, int quantity) { + public TurtleSuckCommand( InteractDirection direction, int quantity ) + { this.m_direction = direction; this.m_quantity = quantity; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Sucking nothing is easy - if (this.m_quantity == 0) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( this.m_quantity == 0 ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); } // Get world direction from direction - Direction direction = this.m_direction.toWorldDir(turtle); + Direction direction = this.m_direction.toWorldDir( turtle ); // Get inventory for thing in front World world = turtle.getWorld(); BlockPos turtlePosition = turtle.getPosition(); - BlockPos blockPosition = turtlePosition.offset(direction); + BlockPos blockPosition = turtlePosition.offset( direction ); Direction side = direction.getOpposite(); - Inventory inventory = InventoryUtil.getInventory(world, blockPosition, side); + Inventory inventory = InventoryUtil.getInventory( world, blockPosition, side ); // Fire the event, exiting if it is cancelled. - TurtlePlayer player = TurtlePlaceCommand.createPlayer(turtle, turtlePosition, direction); - TurtleInventoryEvent.Suck event = new TurtleInventoryEvent.Suck(turtle, player, world, blockPosition, inventory); - if (TurtleEvent.post(event)) { - return TurtleCommandResult.failure(event.getFailureMessage()); + TurtlePlayer player = TurtlePlaceCommand.createPlayer( turtle, turtlePosition, direction ); + TurtleInventoryEvent.Suck event = new TurtleInventoryEvent.Suck( turtle, player, world, blockPosition, inventory ); + if( TurtleEvent.post( event ) ) + { + return TurtleCommandResult.failure( event.getFailureMessage() ); } - if (inventory != null) { + if( inventory != null ) + { // Take from inventory of thing in front - ItemStack stack = InventoryUtil.takeItems(this.m_quantity, ItemStorage.wrap(inventory)); - if (stack.isEmpty()) { - return TurtleCommandResult.failure("No items to take"); + ItemStack stack = InventoryUtil.takeItems( this.m_quantity, ItemStorage.wrap( inventory ) ); + if( stack.isEmpty() ) + { + return TurtleCommandResult.failure( "No items to take" ); } // Try to place into the turtle - ItemStack remainder = InventoryUtil.storeItems(stack, turtle.getItemHandler(), turtle.getSelectedSlot()); - if (!remainder.isEmpty()) { + ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() ); + if( !remainder.isEmpty() ) + { // Put the remainder back in the inventory - InventoryUtil.storeItems(remainder, ItemStorage.wrap(inventory)); + InventoryUtil.storeItems( remainder, ItemStorage.wrap( inventory ) ); } // Return true if we consumed anything - if (remainder != stack) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( remainder != stack ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); - } else { - return TurtleCommandResult.failure("No space for items"); } - } else { + else + { + return TurtleCommandResult.failure( "No space for items" ); + } + } + else + { // Suck up loose items off the ground - Box aabb = new Box(blockPosition.getX(), - blockPosition.getY(), - blockPosition.getZ(), - blockPosition.getX() + 1.0, - blockPosition.getY() + 1.0, - blockPosition.getZ() + 1.0); - List list = world.getEntitiesByClass(ItemEntity.class, aabb, EntityPredicates.VALID_ENTITY); - if (list.isEmpty()) { - return TurtleCommandResult.failure("No items to take"); + Box aabb = new Box( blockPosition.getX(), + blockPosition.getY(), + blockPosition.getZ(), + blockPosition.getX() + 1.0, + blockPosition.getY() + 1.0, + blockPosition.getZ() + 1.0 ); + List list = world.getEntitiesByClass( ItemEntity.class, aabb, EntityPredicates.VALID_ENTITY ); + if( list.isEmpty() ) + { + return TurtleCommandResult.failure( "No items to take" ); } - for (ItemEntity entity : list) { + for( ItemEntity entity : list ) + { // Suck up the item ItemStack stack = entity.getStack() - .copy(); + .copy(); ItemStack storeStack; ItemStack leaveStack; - if (stack.getCount() > this.m_quantity) { - storeStack = stack.split(this.m_quantity); + if( stack.getCount() > this.m_quantity ) + { + storeStack = stack.split( this.m_quantity ); leaveStack = stack; - } else { + } + else + { storeStack = stack; leaveStack = ItemStack.EMPTY; } - ItemStack remainder = InventoryUtil.storeItems(storeStack, turtle.getItemHandler(), turtle.getSelectedSlot()); + ItemStack remainder = InventoryUtil.storeItems( storeStack, turtle.getItemHandler(), turtle.getSelectedSlot() ); - if (remainder != storeStack) { - if (remainder.isEmpty() && leaveStack.isEmpty()) { + if( remainder != storeStack ) + { + if( remainder.isEmpty() && leaveStack.isEmpty() ) + { entity.remove(); - } else if (remainder.isEmpty()) { - entity.setStack(leaveStack); - } else if (leaveStack.isEmpty()) { - entity.setStack(remainder); - } else { - leaveStack.increment(remainder.getCount()); - entity.setStack(leaveStack); + } + else if( remainder.isEmpty() ) + { + entity.setStack( leaveStack ); + } + else if( leaveStack.isEmpty() ) + { + entity.setStack( remainder ); + } + else + { + leaveStack.increment( remainder.getCount() ); + entity.setStack( leaveStack ); } // Play fx - world.syncGlobalEvent(1000, turtlePosition, 0); // BLOCK_DISPENSER_DISPENSE - turtle.playAnimation(TurtleAnimation.WAIT); + world.syncGlobalEvent( 1000, turtlePosition, 0 ); // BLOCK_DISPENSER_DISPENSE + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); } } - return TurtleCommandResult.failure("No space for items"); + return TurtleCommandResult.failure( "No space for items" ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java index 1c33d1b86..e875f7e8b 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java @@ -6,72 +6,77 @@ package dan200.computercraft.shared.turtle.core; -import java.util.Locale; +import dan200.computercraft.api.turtle.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Locale; -import dan200.computercraft.api.turtle.ITurtleAccess; -import dan200.computercraft.api.turtle.ITurtleCommand; -import dan200.computercraft.api.turtle.ITurtleUpgrade; -import dan200.computercraft.api.turtle.TurtleAnimation; -import dan200.computercraft.api.turtle.TurtleCommandResult; -import dan200.computercraft.api.turtle.TurtleSide; -import dan200.computercraft.api.turtle.TurtleVerb; - -public class TurtleToolCommand implements ITurtleCommand { +public class TurtleToolCommand implements ITurtleCommand +{ private final TurtleVerb verb; private final InteractDirection direction; private final TurtleSide side; - public TurtleToolCommand(TurtleVerb verb, InteractDirection direction, TurtleSide side) { + public TurtleToolCommand( TurtleVerb verb, InteractDirection direction, TurtleSide side ) + { this.verb = verb; this.direction = direction; this.side = side; } - public static TurtleToolCommand attack(InteractDirection direction, @Nullable TurtleSide side) { - return new TurtleToolCommand(TurtleVerb.ATTACK, direction, side); + public static TurtleToolCommand attack( InteractDirection direction, @Nullable TurtleSide side ) + { + return new TurtleToolCommand( TurtleVerb.ATTACK, direction, side ); } - public static TurtleToolCommand dig(InteractDirection direction, @Nullable TurtleSide side) { - return new TurtleToolCommand(TurtleVerb.DIG, direction, side); + public static TurtleToolCommand dig( InteractDirection direction, @Nullable TurtleSide side ) + { + return new TurtleToolCommand( TurtleVerb.DIG, direction, side ); } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { TurtleCommandResult firstFailure = null; - for (TurtleSide side : TurtleSide.values()) { - if (this.side != null && this.side != side) { + for( TurtleSide side : TurtleSide.values() ) + { + if( this.side != null && this.side != side ) + { continue; } - ITurtleUpgrade upgrade = turtle.getUpgrade(side); - if (upgrade == null || !upgrade.getType() - .isTool()) { + ITurtleUpgrade upgrade = turtle.getUpgrade( side ); + if( upgrade == null || !upgrade.getType() + .isTool() ) + { continue; } - TurtleCommandResult result = upgrade.useTool(turtle, side, this.verb, this.direction.toWorldDir(turtle)); - if (result.isSuccess()) { - switch (side) { - case LEFT: - turtle.playAnimation(TurtleAnimation.SWING_LEFT_TOOL); - break; - case RIGHT: - turtle.playAnimation(TurtleAnimation.SWING_RIGHT_TOOL); - break; - default: - turtle.playAnimation(TurtleAnimation.WAIT); - break; + TurtleCommandResult result = upgrade.useTool( turtle, side, this.verb, this.direction.toWorldDir( turtle ) ); + if( result.isSuccess() ) + { + switch( side ) + { + case LEFT: + turtle.playAnimation( TurtleAnimation.SWING_LEFT_TOOL ); + break; + case RIGHT: + turtle.playAnimation( TurtleAnimation.SWING_RIGHT_TOOL ); + break; + default: + turtle.playAnimation( TurtleAnimation.WAIT ); + break; } return result; - } else if (firstFailure == null) { + } + else if( firstFailure == null ) + { firstFailure = result; } } - return firstFailure != null ? firstFailure : TurtleCommandResult.failure("No tool to " + this.verb.name() - .toLowerCase(Locale.ROOT) + " with"); + return firstFailure != null ? firstFailure : TurtleCommandResult.failure( "No tool to " + this.verb.name() + .toLowerCase( Locale.ROOT ) + " with" ); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTransferToCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTransferToCommand.java index 47e04417a..adc971f09 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTransferToCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTransferToCommand.java @@ -6,48 +6,55 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleAnimation; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.shared.util.InventoryUtil; - import net.minecraft.item.ItemStack; -public class TurtleTransferToCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleTransferToCommand implements ITurtleCommand +{ private final int m_slot; private final int m_quantity; - public TurtleTransferToCommand(int slot, int limit) { + public TurtleTransferToCommand( int slot, int limit ) + { this.m_slot = slot; this.m_quantity = limit; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { // Take stack - ItemStack stack = InventoryUtil.takeItems(this.m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot()); - if (stack.isEmpty()) { - turtle.playAnimation(TurtleAnimation.WAIT); + ItemStack stack = InventoryUtil.takeItems( this.m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() ); + if( stack.isEmpty() ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); } // Store stack - ItemStack remainder = InventoryUtil.storeItems(stack, turtle.getItemHandler(), this.m_slot, 1, this.m_slot); - if (!remainder.isEmpty()) { + ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), this.m_slot, 1, this.m_slot ); + if( !remainder.isEmpty() ) + { // Put the remainder back - InventoryUtil.storeItems(remainder, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot()); + InventoryUtil.storeItems( remainder, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() ); } // Return true if we moved anything - if (remainder != stack) { - turtle.playAnimation(TurtleAnimation.WAIT); + if( remainder != stack ) + { + turtle.playAnimation( TurtleAnimation.WAIT ); return TurtleCommandResult.success(); - } else { - return TurtleCommandResult.failure("No space for items"); + } + else + { + return TurtleCommandResult.failure( "No space for items" ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTurnCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTurnCommand.java index ab53aad7e..312f002cf 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTurnCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleTurnCommand.java @@ -6,8 +6,6 @@ package dan200.computercraft.shared.turtle.core; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleCommand; import dan200.computercraft.api.turtle.TurtleAnimation; @@ -16,37 +14,47 @@ import dan200.computercraft.api.turtle.event.TurtleAction; import dan200.computercraft.api.turtle.event.TurtleActionEvent; import dan200.computercraft.api.turtle.event.TurtleEvent; -public class TurtleTurnCommand implements ITurtleCommand { +import javax.annotation.Nonnull; + +public class TurtleTurnCommand implements ITurtleCommand +{ private final TurnDirection m_direction; - public TurtleTurnCommand(TurnDirection direction) { + public TurtleTurnCommand( TurnDirection direction ) + { this.m_direction = direction; } @Nonnull @Override - public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { - TurtleActionEvent event = new TurtleActionEvent(turtle, TurtleAction.TURN); - if (TurtleEvent.post(event)) { - return TurtleCommandResult.failure(event.getFailureMessage()); + public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) + { + TurtleActionEvent event = new TurtleActionEvent( turtle, TurtleAction.TURN ); + if( TurtleEvent.post( event ) ) + { + return TurtleCommandResult.failure( event.getFailureMessage() ); } - switch (this.m_direction) { - case LEFT: { - turtle.setDirection(turtle.getDirection() - .rotateYCounterclockwise()); - turtle.playAnimation(TurtleAnimation.TURN_LEFT); - return TurtleCommandResult.success(); - } - case RIGHT: { - turtle.setDirection(turtle.getDirection() - .rotateYClockwise()); - turtle.playAnimation(TurtleAnimation.TURN_RIGHT); - return TurtleCommandResult.success(); - } - default: { - return TurtleCommandResult.failure("Unknown direction"); - } + switch( this.m_direction ) + { + case LEFT: + { + turtle.setDirection( turtle.getDirection() + .rotateYCounterclockwise() ); + turtle.playAnimation( TurtleAnimation.TURN_LEFT ); + return TurtleCommandResult.success(); + } + case RIGHT: + { + turtle.setDirection( turtle.getDirection() + .rotateYClockwise() ); + turtle.playAnimation( TurtleAnimation.TURN_RIGHT ); + return TurtleCommandResult.success(); + } + default: + { + return TurtleCommandResult.failure( "Unknown direction" ); + } } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java index 905e72022..487d11434 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.turtle.inventory; -import java.util.function.Predicate; - -import javax.annotation.Nonnull; - import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.IComputer; @@ -18,7 +14,6 @@ import dan200.computercraft.shared.network.container.ComputerContainerData; import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.core.TurtleBrain; import dan200.computercraft.shared.util.SingleIntArray; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; @@ -29,100 +24,127 @@ import net.minecraft.screen.ArrayPropertyDelegate; import net.minecraft.screen.PropertyDelegate; import net.minecraft.screen.slot.Slot; -public class ContainerTurtle extends ContainerComputerBase { +import javax.annotation.Nonnull; +import java.util.function.Predicate; + +public class ContainerTurtle extends ContainerComputerBase +{ public static final int PLAYER_START_Y = 134; public static final int TURTLE_START_X = 175; private final PropertyDelegate properties; - public ContainerTurtle(int id, PlayerInventory player, TurtleBrain turtle) { - this(id, - p -> turtle.getOwner() - .canPlayerUse(p), - turtle.getOwner() - .createServerComputer(), - turtle.getFamily(), - player, - turtle.getInventory(), - (SingleIntArray) turtle::getSelectedSlot); + public ContainerTurtle( int id, PlayerInventory player, TurtleBrain turtle ) + { + this( id, + p -> turtle.getOwner() + .canPlayerUse( p ), + turtle.getOwner() + .createServerComputer(), + turtle.getFamily(), + player, + turtle.getInventory(), + (SingleIntArray) turtle::getSelectedSlot ); } - private ContainerTurtle(int id, Predicate canUse, IComputer computer, ComputerFamily family, PlayerInventory playerInventory, - Inventory inventory, PropertyDelegate properties) { - super(ComputerCraftRegistry.ModContainers.TURTLE, id, canUse, computer, family); + private ContainerTurtle( int id, Predicate canUse, IComputer computer, ComputerFamily family, PlayerInventory playerInventory, + Inventory inventory, PropertyDelegate properties ) + { + super( ComputerCraftRegistry.ModContainers.TURTLE, id, canUse, computer, family ); this.properties = properties; - this.addProperties(properties); + this.addProperties( properties ); // Turtle inventory - for (int y = 0; y < 4; y++) { - for (int x = 0; x < 4; x++) { - this.addSlot(new Slot(inventory, x + y * 4, TURTLE_START_X + 1 + x * 18, PLAYER_START_Y + 1 + y * 18)); + for( int y = 0; y < 4; y++ ) + { + for( int x = 0; x < 4; x++ ) + { + this.addSlot( new Slot( inventory, x + y * 4, TURTLE_START_X + 1 + x * 18, PLAYER_START_Y + 1 + y * 18 ) ); } } // Player inventory - for (int y = 0; y < 3; y++) { - for (int x = 0; x < 9; x++) { - this.addSlot(new Slot(playerInventory, x + y * 9 + 9, 8 + x * 18, PLAYER_START_Y + 1 + y * 18)); + for( int y = 0; y < 3; y++ ) + { + for( int x = 0; x < 9; x++ ) + { + this.addSlot( new Slot( playerInventory, x + y * 9 + 9, 8 + x * 18, PLAYER_START_Y + 1 + y * 18 ) ); } } // Player hotbar - for (int x = 0; x < 9; x++) { - this.addSlot(new Slot(playerInventory, x, 8 + x * 18, PLAYER_START_Y + 3 * 18 + 5)); + for( int x = 0; x < 9; x++ ) + { + this.addSlot( new Slot( playerInventory, x, 8 + x * 18, PLAYER_START_Y + 3 * 18 + 5 ) ); } } - public ContainerTurtle(int id, PlayerInventory player, PacketByteBuf packetByteBuf) { - this(id, player, new ComputerContainerData(packetByteBuf)); + public ContainerTurtle( int id, PlayerInventory player, PacketByteBuf packetByteBuf ) + { + this( id, player, new ComputerContainerData( packetByteBuf ) ); } - public ContainerTurtle(int id, PlayerInventory player, ComputerContainerData data) { - this(id, - x -> true, - getComputer(player, data), - data.getFamily(), - player, - new SimpleInventory(TileTurtle.INVENTORY_SIZE), - new ArrayPropertyDelegate(1)); + public ContainerTurtle( int id, PlayerInventory player, ComputerContainerData data ) + { + this( id, + x -> true, + getComputer( player, data ), + data.getFamily(), + player, + new SimpleInventory( TileTurtle.INVENTORY_SIZE ), + new ArrayPropertyDelegate( 1 ) ); } - public int getSelectedSlot() { - return this.properties.get(0); + public int getSelectedSlot() + { + return this.properties.get( 0 ); } @Nonnull @Override - public ItemStack transferSlot(@Nonnull PlayerEntity player, int slotNum) { - if (slotNum >= 0 && slotNum < 16) { - return this.tryItemMerge(player, slotNum, 16, 52, true); - } else if (slotNum >= 16) { - return this.tryItemMerge(player, slotNum, 0, 16, false); + public ItemStack transferSlot( @Nonnull PlayerEntity player, int slotNum ) + { + if( slotNum >= 0 && slotNum < 16 ) + { + return this.tryItemMerge( player, slotNum, 16, 52, true ); + } + else if( slotNum >= 16 ) + { + return this.tryItemMerge( player, slotNum, 0, 16, false ); } return ItemStack.EMPTY; } @Nonnull - private ItemStack tryItemMerge(PlayerEntity player, int slotNum, int firstSlot, int lastSlot, boolean reverse) { - Slot slot = this.slots.get(slotNum); + private ItemStack tryItemMerge( PlayerEntity player, int slotNum, int firstSlot, int lastSlot, boolean reverse ) + { + Slot slot = this.slots.get( slotNum ); ItemStack originalStack = ItemStack.EMPTY; - if (slot != null && slot.hasStack()) { + if( slot != null && slot.hasStack() ) + { ItemStack clickedStack = slot.getStack(); originalStack = clickedStack.copy(); - if (!this.insertItem(clickedStack, firstSlot, lastSlot, reverse)) { + if( !this.insertItem( clickedStack, firstSlot, lastSlot, reverse ) ) + { return ItemStack.EMPTY; } - if (clickedStack.isEmpty()) { - slot.setStack(ItemStack.EMPTY); - } else { + if( clickedStack.isEmpty() ) + { + slot.setStack( ItemStack.EMPTY ); + } + else + { slot.markDirty(); } - if (clickedStack.getCount() != originalStack.getCount()) { - slot.onTakeItem(player, clickedStack); - } else { + if( clickedStack.getCount() != originalStack.getCount() ) + { + slot.onTakeItem( player, clickedStack ); + } + else + { return ItemStack.EMPTY; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/items/ITurtleItem.java b/src/main/java/dan200/computercraft/shared/turtle/items/ITurtleItem.java index 6aeb23583..349fc3cab 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/items/ITurtleItem.java +++ b/src/main/java/dan200/computercraft/shared/turtle/items/ITurtleItem.java @@ -6,23 +6,23 @@ package dan200.computercraft.shared.turtle.items; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.common.IColouredItem; import dan200.computercraft.shared.computer.items.IComputerItem; - import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; -public interface ITurtleItem extends IComputerItem, IColouredItem { - @Nullable - ITurtleUpgrade getUpgrade(@Nonnull ItemStack stack, @Nonnull TurtleSide side); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; - int getFuelLevel(@Nonnull ItemStack stack); +public interface ITurtleItem extends IComputerItem, IColouredItem +{ + @Nullable + ITurtleUpgrade getUpgrade( @Nonnull ItemStack stack, @Nonnull TurtleSide side ); + + int getFuelLevel( @Nonnull ItemStack stack ); @Nullable - Identifier getOverlay(@Nonnull ItemStack stack); + Identifier getOverlay( @Nonnull ItemStack stack ); } diff --git a/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtle.java index 9583f9b76..2e9046127 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtle.java @@ -6,13 +6,6 @@ package dan200.computercraft.shared.turtle.items; -import static dan200.computercraft.shared.turtle.core.TurtleBrain.NBT_FUEL; -import static dan200.computercraft.shared.turtle.core.TurtleBrain.NBT_LEFT_UPGRADE; -import static dan200.computercraft.shared.turtle.core.TurtleBrain.NBT_OVERLAY; -import static dan200.computercraft.shared.turtle.core.TurtleBrain.NBT_RIGHT_UPGRADE; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.TurtleUpgrades; @@ -20,7 +13,6 @@ import dan200.computercraft.shared.common.IColouredItem; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.items.ItemComputerBase; import dan200.computercraft.shared.turtle.blocks.BlockTurtle; - import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; @@ -30,58 +22,73 @@ import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; -public class ItemTurtle extends ItemComputerBase implements ITurtleItem { - public ItemTurtle(BlockTurtle block, Settings settings) { - super(block, settings); +import javax.annotation.Nonnull; + +import static dan200.computercraft.shared.turtle.core.TurtleBrain.*; + +public class ItemTurtle extends ItemComputerBase implements ITurtleItem +{ + public ItemTurtle( BlockTurtle block, Settings settings ) + { + super( block, settings ); } @Override - public void appendStacks(@Nonnull ItemGroup group, @Nonnull DefaultedList list) { - if (!this.isIn(group)) { + public void appendStacks( @Nonnull ItemGroup group, @Nonnull DefaultedList list ) + { + if( !this.isIn( group ) ) + { return; } ComputerFamily family = this.getFamily(); - list.add(this.create(-1, null, -1, null, null, 0, null)); + list.add( this.create( -1, null, -1, null, null, 0, null ) ); TurtleUpgrades.getVanillaUpgrades() - .filter(x -> TurtleUpgrades.suitableForFamily(family, x)) - .map(x -> this.create(-1, null, -1, null, x, 0, null)) - .forEach(list::add); + .filter( x -> TurtleUpgrades.suitableForFamily( family, x ) ) + .map( x -> this.create( -1, null, -1, null, x, 0, null ) ) + .forEach( list::add ); } - public ItemStack create(int id, String label, int colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, int fuelLevel, Identifier overlay) { + public ItemStack create( int id, String label, int colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, int fuelLevel, Identifier overlay ) + { // Build the stack - ItemStack stack = new ItemStack(this); - if (label != null) { - stack.setCustomName(new LiteralText(label)); + ItemStack stack = new ItemStack( this ); + if( label != null ) + { + stack.setCustomName( new LiteralText( label ) ); } - if (id >= 0) { + if( id >= 0 ) + { stack.getOrCreateTag() - .putInt(NBT_ID, id); + .putInt( NBT_ID, id ); } - IColouredItem.setColourBasic(stack, colour); - if (fuelLevel > 0) { + IColouredItem.setColourBasic( stack, colour ); + if( fuelLevel > 0 ) + { stack.getOrCreateTag() - .putInt(NBT_FUEL, fuelLevel); + .putInt( NBT_FUEL, fuelLevel ); } - if (overlay != null) { + if( overlay != null ) + { stack.getOrCreateTag() - .putString(NBT_OVERLAY, overlay.toString()); + .putString( NBT_OVERLAY, overlay.toString() ); } - if (leftUpgrade != null) { + if( leftUpgrade != null ) + { stack.getOrCreateTag() - .putString(NBT_LEFT_UPGRADE, - leftUpgrade.getUpgradeID() - .toString()); + .putString( NBT_LEFT_UPGRADE, + leftUpgrade.getUpgradeID() + .toString() ); } - if (rightUpgrade != null) { + if( rightUpgrade != null ) + { stack.getOrCreateTag() - .putString(NBT_RIGHT_UPGRADE, - rightUpgrade.getUpgradeID() - .toString()); + .putString( NBT_RIGHT_UPGRADE, + rightUpgrade.getUpgradeID() + .toString() ); } return stack; @@ -89,20 +96,28 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem { @Nonnull @Override - public Text getName(@Nonnull ItemStack stack) { - String baseString = this.getTranslationKey(stack); - ITurtleUpgrade left = this.getUpgrade(stack, TurtleSide.LEFT); - ITurtleUpgrade right = this.getUpgrade(stack, TurtleSide.RIGHT); - if (left != null && right != null) { - return new TranslatableText(baseString + ".upgraded_twice", - new TranslatableText(right.getUnlocalisedAdjective()), - new TranslatableText(left.getUnlocalisedAdjective())); - } else if (left != null) { - return new TranslatableText(baseString + ".upgraded", new TranslatableText(left.getUnlocalisedAdjective())); - } else if (right != null) { - return new TranslatableText(baseString + ".upgraded", new TranslatableText(right.getUnlocalisedAdjective())); - } else { - return new TranslatableText(baseString); + public Text getName( @Nonnull ItemStack stack ) + { + String baseString = this.getTranslationKey( stack ); + ITurtleUpgrade left = this.getUpgrade( stack, TurtleSide.LEFT ); + ITurtleUpgrade right = this.getUpgrade( stack, TurtleSide.RIGHT ); + if( left != null && right != null ) + { + return new TranslatableText( baseString + ".upgraded_twice", + new TranslatableText( right.getUnlocalisedAdjective() ), + new TranslatableText( left.getUnlocalisedAdjective() ) ); + } + else if( left != null ) + { + return new TranslatableText( baseString + ".upgraded", new TranslatableText( left.getUnlocalisedAdjective() ) ); + } + else if( right != null ) + { + return new TranslatableText( baseString + ".upgraded", new TranslatableText( right.getUnlocalisedAdjective() ) ); + } + else + { + return new TranslatableText( baseString ); } } @@ -131,32 +146,37 @@ public class ItemTurtle extends ItemComputerBase implements ITurtleItem { // } @Override - public ITurtleUpgrade getUpgrade(@Nonnull ItemStack stack, @Nonnull TurtleSide side) { + public ITurtleUpgrade getUpgrade( @Nonnull ItemStack stack, @Nonnull TurtleSide side ) + { CompoundTag tag = stack.getTag(); - if (tag == null) { + if( tag == null ) + { return null; } String key = side == TurtleSide.LEFT ? NBT_LEFT_UPGRADE : NBT_RIGHT_UPGRADE; - return tag.contains(key) ? TurtleUpgrades.get(tag.getString(key)) : null; + return tag.contains( key ) ? TurtleUpgrades.get( tag.getString( key ) ) : null; } @Override - public int getFuelLevel(@Nonnull ItemStack stack) { + public int getFuelLevel( @Nonnull ItemStack stack ) + { CompoundTag tag = stack.getTag(); - return tag != null && tag.contains(NBT_FUEL) ? tag.getInt(NBT_FUEL) : 0; + return tag != null && tag.contains( NBT_FUEL ) ? tag.getInt( NBT_FUEL ) : 0; } @Override - public Identifier getOverlay(@Nonnull ItemStack stack) { + public Identifier getOverlay( @Nonnull ItemStack stack ) + { CompoundTag tag = stack.getTag(); - return tag != null && tag.contains(NBT_OVERLAY) ? new Identifier(tag.getString(NBT_OVERLAY)) : null; + return tag != null && tag.contains( NBT_OVERLAY ) ? new Identifier( tag.getString( NBT_OVERLAY ) ) : null; } @Override - public ItemStack withFamily(@Nonnull ItemStack stack, @Nonnull ComputerFamily family) { - return TurtleItemFactory.create(this.getComputerID(stack), this.getLabel(stack), this.getColour(stack), - family, this.getUpgrade(stack, TurtleSide.LEFT), - this.getUpgrade(stack, TurtleSide.RIGHT), this.getFuelLevel(stack), this.getOverlay(stack)); + public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ) + { + return TurtleItemFactory.create( this.getComputerID( stack ), this.getLabel( stack ), this.getColour( stack ), + family, this.getUpgrade( stack, TurtleSide.LEFT ), + this.getUpgrade( stack, TurtleSide.RIGHT ), this.getFuelLevel( stack ), this.getOverlay( stack ) ); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItemFactory.java b/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItemFactory.java index c75a6f30b..9d604502f 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItemFactory.java +++ b/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItemFactory.java @@ -6,45 +6,48 @@ package dan200.computercraft.shared.turtle.items; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.turtle.blocks.ITurtleTile; - import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; -public final class TurtleItemFactory { +import javax.annotation.Nonnull; + +public final class TurtleItemFactory +{ private TurtleItemFactory() {} @Nonnull - public static ItemStack create(ITurtleTile turtle) { + public static ItemStack create( ITurtleTile turtle ) + { ITurtleAccess access = turtle.getAccess(); - return create(turtle.getComputerID(), - turtle.getLabel(), - turtle.getColour(), - turtle.getFamily(), - access.getUpgrade(TurtleSide.LEFT), - access.getUpgrade(TurtleSide.RIGHT), - access.getFuelLevel(), - turtle.getOverlay()); + return create( turtle.getComputerID(), + turtle.getLabel(), + turtle.getColour(), + turtle.getFamily(), + access.getUpgrade( TurtleSide.LEFT ), + access.getUpgrade( TurtleSide.RIGHT ), + access.getFuelLevel(), + turtle.getOverlay() ); } @Nonnull - public static ItemStack create(int id, String label, int colour, ComputerFamily family, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, - int fuelLevel, Identifier overlay) { - switch (family) { - case NORMAL: - return ComputerCraftRegistry.ModItems.TURTLE_NORMAL.create(id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay); - case ADVANCED: - return ComputerCraftRegistry.ModItems.TURTLE_ADVANCED.create(id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay); - default: - return ItemStack.EMPTY; + public static ItemStack create( int id, String label, int colour, ComputerFamily family, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, + int fuelLevel, Identifier overlay ) + { + switch( family ) + { + case NORMAL: + return ComputerCraftRegistry.ModItems.TURTLE_NORMAL.create( id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay ); + case ADVANCED: + return ComputerCraftRegistry.ModItems.TURTLE_ADVANCED.create( id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay ); + default: + return ItemStack.EMPTY; } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java b/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java index 61032889f..4df8575fb 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java +++ b/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java @@ -6,46 +6,51 @@ package dan200.computercraft.shared.turtle.recipes; -import javax.annotation.Nonnull; - import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.items.IComputerItem; import dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe; import dan200.computercraft.shared.turtle.items.TurtleItemFactory; - import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.RecipeSerializer; import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; -public final class TurtleRecipe extends ComputerFamilyRecipe { - public static final RecipeSerializer SERIALIZER = - new dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe.Serializer() { - @Override - protected TurtleRecipe create(Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result - , ComputerFamily family) { - return new TurtleRecipe(identifier, group, width, height, ingredients, result, family); - } - }; +import javax.annotation.Nonnull; - private TurtleRecipe(Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, - ComputerFamily family) { - super(identifier, group, width, height, ingredients, result, family); +public final class TurtleRecipe extends ComputerFamilyRecipe +{ + public static final RecipeSerializer SERIALIZER = + new dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe.Serializer() + { + @Override + protected TurtleRecipe create( Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result + , ComputerFamily family ) + { + return new TurtleRecipe( identifier, group, width, height, ingredients, result, family ); + } + }; + + private TurtleRecipe( Identifier identifier, String group, int width, int height, DefaultedList ingredients, ItemStack result, + ComputerFamily family ) + { + super( identifier, group, width, height, ingredients, result, family ); } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } @Nonnull @Override - protected ItemStack convert(@Nonnull IComputerItem item, @Nonnull ItemStack stack) { - int computerID = item.getComputerID(stack); - String label = item.getLabel(stack); + protected ItemStack convert( @Nonnull IComputerItem item, @Nonnull ItemStack stack ) + { + int computerID = item.getComputerID( stack ); + String label = item.getLabel( stack ); - return TurtleItemFactory.create(computerID, label, -1, this.getFamily(), null, null, 0, null); + return TurtleItemFactory.create( computerID, label, -1, this.getFamily(), null, null, 0, null ); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java b/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java index a3ef94120..da301a48a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java +++ b/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java @@ -6,15 +6,12 @@ package dan200.computercraft.shared.turtle.recipes; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.TurtleUpgrades; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.turtle.items.ITurtleItem; import dan200.computercraft.shared.turtle.items.TurtleItemFactory; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.recipe.RecipeSerializer; @@ -23,77 +20,108 @@ import net.minecraft.recipe.SpecialRecipeSerializer; import net.minecraft.util.Identifier; import net.minecraft.world.World; -public final class TurtleUpgradeRecipe extends SpecialCraftingRecipe { - public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>(TurtleUpgradeRecipe::new); +import javax.annotation.Nonnull; - private TurtleUpgradeRecipe(Identifier id) { - super(id); +public final class TurtleUpgradeRecipe extends SpecialCraftingRecipe +{ + public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>( TurtleUpgradeRecipe::new ); + + private TurtleUpgradeRecipe( Identifier id ) + { + super( id ); } @Nonnull @Override - public ItemStack getOutput() { - return TurtleItemFactory.create(-1, null, -1, ComputerFamily.NORMAL, null, null, 0, null); + public ItemStack getOutput() + { + return TurtleItemFactory.create( -1, null, -1, ComputerFamily.NORMAL, null, null, 0, null ); } @Override - public boolean matches(@Nonnull CraftingInventory inventory, @Nonnull World world) { - return !this.craft(inventory).isEmpty(); + public boolean matches( @Nonnull CraftingInventory inventory, @Nonnull World world ) + { + return !this.craft( inventory ).isEmpty(); } @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inventory) { + public ItemStack craft( @Nonnull CraftingInventory inventory ) + { // Scan the grid for a row containing a turtle and 1 or 2 items ItemStack leftItem = ItemStack.EMPTY; ItemStack turtle = ItemStack.EMPTY; ItemStack rightItem = ItemStack.EMPTY; - for (int y = 0; y < inventory.getHeight(); y++) { - if (turtle.isEmpty()) { + for( int y = 0; y < inventory.getHeight(); y++ ) + { + if( turtle.isEmpty() ) + { // Search this row for potential turtles boolean finishedRow = false; - for (int x = 0; x < inventory.getWidth(); x++) { - ItemStack item = inventory.getStack(x + y * inventory.getWidth()); - if (!item.isEmpty()) { - if (finishedRow) { + for( int x = 0; x < inventory.getWidth(); x++ ) + { + ItemStack item = inventory.getStack( x + y * inventory.getWidth() ); + if( !item.isEmpty() ) + { + if( finishedRow ) + { return ItemStack.EMPTY; } - if (item.getItem() instanceof ITurtleItem) { + if( item.getItem() instanceof ITurtleItem ) + { // Item is a turtle - if (turtle.isEmpty()) { + if( turtle.isEmpty() ) + { turtle = item; - } else { - return ItemStack.EMPTY; } - } else { - // Item is not a turtle - if (turtle.isEmpty() && leftItem.isEmpty()) { - leftItem = item; - } else if (!turtle.isEmpty() && rightItem.isEmpty()) { - rightItem = item; - } else { + else + { return ItemStack.EMPTY; } } - } else { + else + { + // Item is not a turtle + if( turtle.isEmpty() && leftItem.isEmpty() ) + { + leftItem = item; + } + else if( !turtle.isEmpty() && rightItem.isEmpty() ) + { + rightItem = item; + } + else + { + return ItemStack.EMPTY; + } + } + } + else + { // Item is empty - if (!leftItem.isEmpty() || !turtle.isEmpty()) { + if( !leftItem.isEmpty() || !turtle.isEmpty() ) + { finishedRow = true; } } } // If we found anything, check we found a turtle too - if (turtle.isEmpty() && (!leftItem.isEmpty() || !rightItem.isEmpty())) { + if( turtle.isEmpty() && (!leftItem.isEmpty() || !rightItem.isEmpty()) ) + { return ItemStack.EMPTY; } - } else { + } + else + { // Turtle is already found, just check this row is empty - for (int x = 0; x < inventory.getWidth(); x++) { - ItemStack item = inventory.getStack(x + y * inventory.getWidth()); - if (!item.isEmpty()) { + for( int x = 0; x < inventory.getWidth(); x++ ) + { + ItemStack item = inventory.getStack( x + y * inventory.getWidth() ); + if( !item.isEmpty() ) + { return ItemStack.EMPTY; } } @@ -101,7 +129,8 @@ public final class TurtleUpgradeRecipe extends SpecialCraftingRecipe { } // See if we found a turtle + one or more items - if (turtle.isEmpty() || leftItem.isEmpty() && rightItem.isEmpty()) { + if( turtle.isEmpty() || leftItem.isEmpty() && rightItem.isEmpty() ) + { return ItemStack.EMPTY; } @@ -110,25 +139,30 @@ public final class TurtleUpgradeRecipe extends SpecialCraftingRecipe { ITurtleItem itemTurtle = (ITurtleItem) turtle.getItem(); ComputerFamily family = itemTurtle.getFamily(); ITurtleUpgrade[] upgrades = new ITurtleUpgrade[] { - itemTurtle.getUpgrade(turtle, TurtleSide.LEFT), - itemTurtle.getUpgrade(turtle, TurtleSide.RIGHT), - }; + itemTurtle.getUpgrade( turtle, TurtleSide.LEFT ), + itemTurtle.getUpgrade( turtle, TurtleSide.RIGHT ), + }; // Get the upgrades for the new items ItemStack[] items = new ItemStack[] { rightItem, leftItem }; - for (int i = 0; i < 2; i++) { - if (!items[i].isEmpty()) { - ITurtleUpgrade itemUpgrade = TurtleUpgrades.get(items[i]); - if (itemUpgrade == null) { + for( int i = 0; i < 2; i++ ) + { + if( !items[i].isEmpty() ) + { + ITurtleUpgrade itemUpgrade = TurtleUpgrades.get( items[i] ); + if( itemUpgrade == null ) + { return ItemStack.EMPTY; } - if (upgrades[i] != null) { + if( upgrades[i] != null ) + { return ItemStack.EMPTY; } - if (!TurtleUpgrades.suitableForFamily(family, itemUpgrade)) { + if( !TurtleUpgrades.suitableForFamily( family, itemUpgrade ) ) + { return ItemStack.EMPTY; } upgrades[i] = itemUpgrade; @@ -136,22 +170,24 @@ public final class TurtleUpgradeRecipe extends SpecialCraftingRecipe { } // Construct the new stack - int computerID = itemTurtle.getComputerID(turtle); - String label = itemTurtle.getLabel(turtle); - int fuelLevel = itemTurtle.getFuelLevel(turtle); - int colour = itemTurtle.getColour(turtle); - Identifier overlay = itemTurtle.getOverlay(turtle); - return TurtleItemFactory.create(computerID, label, colour, family, upgrades[0], upgrades[1], fuelLevel, overlay); + int computerID = itemTurtle.getComputerID( turtle ); + String label = itemTurtle.getLabel( turtle ); + int fuelLevel = itemTurtle.getFuelLevel( turtle ); + int colour = itemTurtle.getColour( turtle ); + Identifier overlay = itemTurtle.getOverlay( turtle ); + return TurtleItemFactory.create( computerID, label, colour, family, upgrades[0], upgrades[1], fuelLevel, overlay ); } @Override - public boolean fits(int x, int y) { + public boolean fits( int x, int y ) + { return x >= 3 && y >= 1; } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java index bffffadfe..959ed2b7b 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java @@ -6,10 +6,6 @@ package dan200.computercraft.shared.turtle.upgrades; -import java.util.Optional; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.MethodResult; @@ -17,6 +13,9 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.shared.turtle.core.TurtleCraftCommand; +import javax.annotation.Nonnull; +import java.util.Optional; + /** * The workbench peripheral allows you to craft items within the turtle's inventory. * @@ -24,36 +23,43 @@ import dan200.computercraft.shared.turtle.core.TurtleCraftCommand; * @hidden * @cc.see turtle.craft This uses the {@link CraftingTablePeripheral} peripheral to craft items. */ -public class CraftingTablePeripheral implements IPeripheral { +public class CraftingTablePeripheral implements IPeripheral +{ private final ITurtleAccess turtle; - public CraftingTablePeripheral(ITurtleAccess turtle) { + public CraftingTablePeripheral( ITurtleAccess turtle ) + { this.turtle = turtle; } @Nonnull @Override - public String getType() { + public String getType() + { return "workbench"; } @Nonnull @Override - public Object getTarget() { + public Object getTarget() + { return this.turtle; } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return other instanceof CraftingTablePeripheral; } @LuaFunction - public final MethodResult craft(Optional count) throws LuaException { - int limit = count.orElse(64); - if (limit < 0 || limit > 64) { - throw new LuaException("Crafting count " + limit + " out of range"); + public final MethodResult craft( Optional count ) throws LuaException + { + int limit = count.orElse( 64 ); + if( limit < 0 || limit > 64 ) + { + throw new LuaException( "Crafting count " + limit + " out of range" ); } - return this.turtle.executeCommand(new TurtleCraftCommand(limit)); + return this.turtle.executeCommand( new TurtleCraftCommand( limit ) ); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleAxe.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleAxe.java index 1b1563f1b..635536c0f 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleAxe.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleAxe.java @@ -10,21 +10,26 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; -public class TurtleAxe extends TurtleTool { - public TurtleAxe(Identifier id, String adjective, Item item) { - super(id, adjective, item); +public class TurtleAxe extends TurtleTool +{ + public TurtleAxe( Identifier id, String adjective, Item item ) + { + super( id, adjective, item ); } - public TurtleAxe(Identifier id, Item item) { - super(id, item); + public TurtleAxe( Identifier id, Item item ) + { + super( id, item ); } - public TurtleAxe(Identifier id, ItemStack craftItem, ItemStack toolItem) { - super(id, craftItem, toolItem); + public TurtleAxe( Identifier id, ItemStack craftItem, ItemStack toolItem ) + { + super( id, craftItem, toolItem ); } @Override - protected float getDamageMultiplier() { + protected float getDamageMultiplier() + { return 6.0f; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleCraftingTable.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleCraftingTable.java index 81c3540e7..0ebfc06a3 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleCraftingTable.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleCraftingTable.java @@ -6,49 +6,55 @@ package dan200.computercraft.shared.turtle.upgrades; -import javax.annotation.Nonnull; - import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.turtle.AbstractTurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleUpgradeType; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.Blocks; import net.minecraft.client.util.ModelIdentifier; import net.minecraft.util.Identifier; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; -public class TurtleCraftingTable extends AbstractTurtleUpgrade { - @Environment (EnvType.CLIENT) private ModelIdentifier m_leftModel; +public class TurtleCraftingTable extends AbstractTurtleUpgrade +{ + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_leftModel; - @Environment (EnvType.CLIENT) private ModelIdentifier m_rightModel; + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_rightModel; - public TurtleCraftingTable(Identifier id) { - super(id, TurtleUpgradeType.PERIPHERAL, Blocks.CRAFTING_TABLE); + public TurtleCraftingTable( Identifier id ) + { + super( id, TurtleUpgradeType.PERIPHERAL, Blocks.CRAFTING_TABLE ); } @Override - public IPeripheral createPeripheral(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { - return new CraftingTablePeripheral(turtle); + public IPeripheral createPeripheral( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side ) + { + return new CraftingTablePeripheral( turtle ); } @Nonnull @Override - @Environment (EnvType.CLIENT) - public TransformedModel getModel(ITurtleAccess turtle, @Nonnull TurtleSide side) { + @Environment( EnvType.CLIENT ) + public TransformedModel getModel( ITurtleAccess turtle, @Nonnull TurtleSide side ) + { this.loadModelLocations(); - return TransformedModel.of(side == TurtleSide.LEFT ? this.m_leftModel : this.m_rightModel); + return TransformedModel.of( side == TurtleSide.LEFT ? this.m_leftModel : this.m_rightModel ); } - @Environment (EnvType.CLIENT) - private void loadModelLocations() { - if (this.m_leftModel == null) { - this.m_leftModel = new ModelIdentifier("computercraft:turtle_crafting_table_left", "inventory"); - this.m_rightModel = new ModelIdentifier("computercraft:turtle_crafting_table_right", "inventory"); + @Environment( EnvType.CLIENT ) + private void loadModelLocations() + { + if( this.m_leftModel == null ) + { + this.m_leftModel = new ModelIdentifier( "computercraft:turtle_crafting_table_left", "inventory" ); + this.m_rightModel = new ModelIdentifier( "computercraft:turtle_crafting_table_right", "inventory" ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleHoe.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleHoe.java index 2893203d8..97d92eaa5 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleHoe.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleHoe.java @@ -6,15 +6,12 @@ package dan200.computercraft.shared.turtle.upgrades; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleVerb; import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand; import dan200.computercraft.shared.turtle.core.TurtlePlayer; - import net.minecraft.block.BlockState; import net.minecraft.block.Material; import net.minecraft.item.Item; @@ -24,35 +21,46 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class TurtleHoe extends TurtleTool { - public TurtleHoe(Identifier id, String adjective, Item item) { - super(id, adjective, item); +import javax.annotation.Nonnull; + +public class TurtleHoe extends TurtleTool +{ + public TurtleHoe( Identifier id, String adjective, Item item ) + { + super( id, adjective, item ); } - public TurtleHoe(Identifier id, Item item) { - super(id, item); + public TurtleHoe( Identifier id, Item item ) + { + super( id, item ); } - public TurtleHoe(Identifier id, ItemStack craftItem, ItemStack toolItem) { - super(id, craftItem, toolItem); + public TurtleHoe( Identifier id, ItemStack craftItem, ItemStack toolItem ) + { + super( id, craftItem, toolItem ); } @Nonnull @Override - public TurtleCommandResult useTool(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction) { - if (verb == TurtleVerb.DIG) { + public TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction ) + { + if( verb == TurtleVerb.DIG ) + { ItemStack hoe = this.item.copy(); - ItemStack remainder = TurtlePlaceCommand.deploy(hoe, turtle, direction, null, null); - if (remainder != hoe) { + ItemStack remainder = TurtlePlaceCommand.deploy( hoe, turtle, direction, null, null ); + if( remainder != hoe ) + { return TurtleCommandResult.success(); } } - return super.useTool(turtle, side, verb, direction); + return super.useTool( turtle, side, verb, direction ); } @Override - protected boolean canBreakBlock(BlockState state, World world, BlockPos pos, TurtlePlayer player) { - if (!super.canBreakBlock(state, world, pos, player)) { + protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) + { + if( !super.canBreakBlock( state, world, pos, player ) ) + { return false; } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java index c7fabe344..3aa249829 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java @@ -6,17 +6,9 @@ package dan200.computercraft.shared.turtle.upgrades; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.core.TurtlePlayer; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; @@ -26,33 +18,46 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; -public class TurtleInventoryCrafting extends CraftingInventory { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TurtleInventoryCrafting extends CraftingInventory +{ private ITurtleAccess m_turtle; private int m_xStart; private int m_yStart; - @SuppressWarnings ("ConstantConditions") - public TurtleInventoryCrafting(ITurtleAccess turtle) { + @SuppressWarnings( "ConstantConditions" ) + public TurtleInventoryCrafting( ITurtleAccess turtle ) + { // Passing null in here is evil, but we don't have a container present. We override most methods in order to // avoid throwing any NPEs. - super(null, 0, 0); + super( null, 0, 0 ); this.m_turtle = turtle; this.m_xStart = 0; this.m_yStart = 0; } @Nullable - private Recipe tryCrafting(int xStart, int yStart) { + private Recipe tryCrafting( int xStart, int yStart ) + { this.m_xStart = xStart; this.m_yStart = yStart; // Check the non-relevant parts of the inventory are empty - for (int x = 0; x < TileTurtle.INVENTORY_WIDTH; x++) { - for (int y = 0; y < TileTurtle.INVENTORY_HEIGHT; y++) { - if (x < this.m_xStart || x >= this.m_xStart + 3 || y < this.m_yStart || y >= this.m_yStart + 3) { - if (!this.m_turtle.getInventory() - .getStack(x + y * TileTurtle.INVENTORY_WIDTH) - .isEmpty()) { + for( int x = 0; x < TileTurtle.INVENTORY_WIDTH; x++ ) + { + for( int y = 0; y < TileTurtle.INVENTORY_HEIGHT; y++ ) + { + if( x < this.m_xStart || x >= this.m_xStart + 3 || y < this.m_yStart || y >= this.m_yStart + 3 ) + { + if( !this.m_turtle.getInventory() + .getStack( x + y * TileTurtle.INVENTORY_WIDTH ) + .isEmpty() ) + { return null; } } @@ -61,72 +66,89 @@ public class TurtleInventoryCrafting extends CraftingInventory { // Check the actual crafting return this.m_turtle.getWorld() - .getRecipeManager() - .getFirstMatch(RecipeType.CRAFTING, this, this.m_turtle.getWorld()) - .orElse(null); + .getRecipeManager() + .getFirstMatch( RecipeType.CRAFTING, this, this.m_turtle.getWorld() ) + .orElse( null ); } @Nullable - public List doCrafting(World world, int maxCount) { - if (world.isClient || !(world instanceof ServerWorld)) { + public List doCrafting( World world, int maxCount ) + { + if( world.isClient || !(world instanceof ServerWorld) ) + { return null; } // Find out what we can craft - Recipe recipe = this.tryCrafting(0, 0); - if (recipe == null) { - recipe = this.tryCrafting(0, 1); + Recipe recipe = this.tryCrafting( 0, 0 ); + if( recipe == null ) + { + recipe = this.tryCrafting( 0, 1 ); } - if (recipe == null) { - recipe = this.tryCrafting(1, 0); + if( recipe == null ) + { + recipe = this.tryCrafting( 1, 0 ); } - if (recipe == null) { - recipe = this.tryCrafting(1, 1); + if( recipe == null ) + { + recipe = this.tryCrafting( 1, 1 ); } - if (recipe == null) { + if( recipe == null ) + { return null; } // Special case: craft(0) just returns an empty list if crafting was possible - if (maxCount == 0) { + if( maxCount == 0 ) + { return Collections.emptyList(); } - TurtlePlayer player = TurtlePlayer.get(this.m_turtle); + TurtlePlayer player = TurtlePlayer.get( this.m_turtle ); ArrayList results = new ArrayList<>(); - for (int i = 0; i < maxCount && recipe.matches(this, world); i++) { - ItemStack result = recipe.craft(this); - if (result.isEmpty()) { + for( int i = 0; i < maxCount && recipe.matches( this, world ); i++ ) + { + ItemStack result = recipe.craft( this ); + if( result.isEmpty() ) + { break; } - results.add(result); + results.add( result ); - result.onCraft(world, player, result.getCount()); - DefaultedList remainders = recipe.getRemainingStacks(this); + result.onCraft( world, player, result.getCount() ); + DefaultedList remainders = recipe.getRemainingStacks( this ); - for (int slot = 0; slot < remainders.size(); slot++) { - ItemStack existing = this.getStack(slot); - ItemStack remainder = remainders.get(slot); + for( int slot = 0; slot < remainders.size(); slot++ ) + { + ItemStack existing = this.getStack( slot ); + ItemStack remainder = remainders.get( slot ); - if (!existing.isEmpty()) { - this.removeStack(slot, 1); - existing = this.getStack(slot); + if( !existing.isEmpty() ) + { + this.removeStack( slot, 1 ); + existing = this.getStack( slot ); } - if (remainder.isEmpty()) { + if( remainder.isEmpty() ) + { continue; } // Either update the current stack or add it to the remainder list (to be inserted into the inventory // afterwards). - if (existing.isEmpty()) { - this.setStack(slot, remainder); - } else if (ItemStack.areItemsEqualIgnoreDamage(existing, remainder) && ItemStack.areTagsEqual(existing, remainder)) { - remainder.increment(existing.getCount()); - this.setStack(slot, remainder); - } else { - results.add(remainder); + if( existing.isEmpty() ) + { + this.setStack( slot, remainder ); + } + else if( ItemStack.areItemsEqualIgnoreDamage( existing, remainder ) && ItemStack.areTagsEqual( existing, remainder ) ) + { + remainder.increment( existing.getCount() ); + this.setStack( slot, remainder ); + } + else + { + results.add( remainder ); } } } @@ -135,25 +157,34 @@ public class TurtleInventoryCrafting extends CraftingInventory { } @Override - public int getMaxCountPerStack() { + public int getMaxCountPerStack() + { return this.m_turtle.getInventory() - .getMaxCountPerStack(); - } @Override - public int getWidth() { + .getMaxCountPerStack(); + } + + @Override + public int getWidth() + { return 3; } @Override - public boolean isValid(int i, @Nonnull ItemStack stack) { - i = this.modifyIndex(i); + public boolean isValid( int i, @Nonnull ItemStack stack ) + { + i = this.modifyIndex( i ); return this.m_turtle.getInventory() - .isValid(i, stack); - } @Override - public int getHeight() { + .isValid( i, stack ); + } + + @Override + public int getHeight() + { return 3; } - private int modifyIndex(int index) { + private int modifyIndex( int index ) + { int x = this.m_xStart + index % this.getWidth(); int y = this.m_yStart + index / this.getHeight(); return x >= 0 && x < TileTurtle.INVENTORY_WIDTH && y >= 0 && y < TileTurtle.INVENTORY_HEIGHT ? x + y * TileTurtle.INVENTORY_WIDTH : -1; @@ -162,62 +193,69 @@ public class TurtleInventoryCrafting extends CraftingInventory { // IInventory implementation @Override - public int size() { + public int size() + { return this.getWidth() * this.getHeight(); } @Nonnull @Override - public ItemStack getStack(int i) { - i = this.modifyIndex(i); + public ItemStack getStack( int i ) + { + i = this.modifyIndex( i ); return this.m_turtle.getInventory() - .getStack(i); + .getStack( i ); } @Nonnull @Override - public ItemStack removeStack(int i) { - i = this.modifyIndex(i); + public ItemStack removeStack( int i ) + { + i = this.modifyIndex( i ); return this.m_turtle.getInventory() - .removeStack(i); + .removeStack( i ); } @Nonnull @Override - public ItemStack removeStack(int i, int size) { - i = this.modifyIndex(i); + public ItemStack removeStack( int i, int size ) + { + i = this.modifyIndex( i ); return this.m_turtle.getInventory() - .removeStack(i, size); + .removeStack( i, size ); } @Override - public void setStack(int i, @Nonnull ItemStack stack) { - i = this.modifyIndex(i); + public void setStack( int i, @Nonnull ItemStack stack ) + { + i = this.modifyIndex( i ); this.m_turtle.getInventory() - .setStack(i, stack); + .setStack( i, stack ); } - @Override - public void markDirty() { + public void markDirty() + { this.m_turtle.getInventory() - .markDirty(); + .markDirty(); } @Override - public boolean canPlayerUse(@Nonnull PlayerEntity player) { + public boolean canPlayerUse( @Nonnull PlayerEntity player ) + { return true; } - @Override - public void clear() { - for (int i = 0; i < this.size(); i++) { - int j = this.modifyIndex(i); + public void clear() + { + for( int i = 0; i < this.size(); i++ ) + { + int j = this.modifyIndex( i ); this.m_turtle.getInventory() - .setStack(j, ItemStack.EMPTY); + .setStack( j, ItemStack.EMPTY ); } } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java index 1a66308b9..e3951e563 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java @@ -6,20 +6,14 @@ package dan200.computercraft.shared.turtle.upgrades; -import javax.annotation.Nonnull; - import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.peripheral.IPeripheral; -import dan200.computercraft.api.turtle.AbstractTurtleUpgrade; -import dan200.computercraft.api.turtle.ITurtleAccess; -import dan200.computercraft.api.turtle.TurtleCommandResult; -import dan200.computercraft.api.turtle.TurtleSide; -import dan200.computercraft.api.turtle.TurtleUpgradeType; -import dan200.computercraft.api.turtle.TurtleVerb; +import dan200.computercraft.api.turtle.*; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.util.ModelIdentifier; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Identifier; @@ -28,105 +22,128 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; -public class TurtleModem extends AbstractTurtleUpgrade { +public class TurtleModem extends AbstractTurtleUpgrade +{ private final boolean advanced; - @Environment (EnvType.CLIENT) private ModelIdentifier m_leftOffModel; - @Environment (EnvType.CLIENT) private ModelIdentifier m_rightOffModel; - @Environment (EnvType.CLIENT) private ModelIdentifier m_leftOnModel; - @Environment (EnvType.CLIENT) private ModelIdentifier m_rightOnModel; + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_leftOffModel; + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_rightOffModel; + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_leftOnModel; + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_rightOnModel; - public TurtleModem(boolean advanced, Identifier id) { - super(id, - TurtleUpgradeType.PERIPHERAL, - advanced ? ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_ADVANCED : ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_NORMAL); + public TurtleModem( boolean advanced, Identifier id ) + { + super( id, + TurtleUpgradeType.PERIPHERAL, + advanced ? ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_ADVANCED : ComputerCraftRegistry.ModBlocks.WIRELESS_MODEM_NORMAL ); this.advanced = advanced; } @Override - public IPeripheral createPeripheral(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { - return new Peripheral(turtle, this.advanced); + public IPeripheral createPeripheral( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side ) + { + return new Peripheral( turtle, this.advanced ); } @Nonnull @Override - public TurtleCommandResult useTool(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction dir) { + public TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction dir ) + { return TurtleCommandResult.failure(); } @Nonnull @Override - @Environment (EnvType.CLIENT) - public TransformedModel getModel(ITurtleAccess turtle, @Nonnull TurtleSide side) { + @Environment( EnvType.CLIENT ) + public TransformedModel getModel( ITurtleAccess turtle, @Nonnull TurtleSide side ) + { this.loadModelLocations(); boolean active = false; - if (turtle != null) { - CompoundTag turtleNBT = turtle.getUpgradeNBTData(side); - active = turtleNBT.contains("active") && turtleNBT.getBoolean("active"); + if( turtle != null ) + { + CompoundTag turtleNBT = turtle.getUpgradeNBTData( side ); + active = turtleNBT.contains( "active" ) && turtleNBT.getBoolean( "active" ); } - return side == TurtleSide.LEFT ? TransformedModel.of(active ? this.m_leftOnModel : this.m_leftOffModel) : TransformedModel.of(active ? this.m_rightOnModel : this.m_rightOffModel); + return side == TurtleSide.LEFT ? TransformedModel.of( active ? this.m_leftOnModel : this.m_leftOffModel ) : TransformedModel.of( active ? this.m_rightOnModel : this.m_rightOffModel ); } - @Environment (EnvType.CLIENT) - private void loadModelLocations() { - if (this.m_leftOffModel == null) { - if (this.advanced) { - this.m_leftOffModel = new ModelIdentifier("computercraft:turtle_modem_advanced_off_left", "inventory"); - this.m_rightOffModel = new ModelIdentifier("computercraft:turtle_modem_advanced_off_right", "inventory"); - this.m_leftOnModel = new ModelIdentifier("computercraft:turtle_modem_advanced_on_left", "inventory"); - this.m_rightOnModel = new ModelIdentifier("computercraft:turtle_modem_advanced_on_right", "inventory"); - } else { - this.m_leftOffModel = new ModelIdentifier("computercraft:turtle_modem_normal_off_left", "inventory"); - this.m_rightOffModel = new ModelIdentifier("computercraft:turtle_modem_normal_off_right", "inventory"); - this.m_leftOnModel = new ModelIdentifier("computercraft:turtle_modem_normal_on_left", "inventory"); - this.m_rightOnModel = new ModelIdentifier("computercraft:turtle_modem_normal_on_right", "inventory"); + @Environment( EnvType.CLIENT ) + private void loadModelLocations() + { + if( this.m_leftOffModel == null ) + { + if( this.advanced ) + { + this.m_leftOffModel = new ModelIdentifier( "computercraft:turtle_modem_advanced_off_left", "inventory" ); + this.m_rightOffModel = new ModelIdentifier( "computercraft:turtle_modem_advanced_off_right", "inventory" ); + this.m_leftOnModel = new ModelIdentifier( "computercraft:turtle_modem_advanced_on_left", "inventory" ); + this.m_rightOnModel = new ModelIdentifier( "computercraft:turtle_modem_advanced_on_right", "inventory" ); + } + else + { + this.m_leftOffModel = new ModelIdentifier( "computercraft:turtle_modem_normal_off_left", "inventory" ); + this.m_rightOffModel = new ModelIdentifier( "computercraft:turtle_modem_normal_off_right", "inventory" ); + this.m_leftOnModel = new ModelIdentifier( "computercraft:turtle_modem_normal_on_left", "inventory" ); + this.m_rightOnModel = new ModelIdentifier( "computercraft:turtle_modem_normal_on_right", "inventory" ); } } } @Override - public void update(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { + public void update( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side ) + { // Advance the modem - if (!turtle.getWorld().isClient) { - IPeripheral peripheral = turtle.getPeripheral(side); - if (peripheral instanceof Peripheral) { + if( !turtle.getWorld().isClient ) + { + IPeripheral peripheral = turtle.getPeripheral( side ); + if( peripheral instanceof Peripheral ) + { ModemState state = ((Peripheral) peripheral).getModemState(); - if (state.pollChanged()) { - turtle.getUpgradeNBTData(side) - .putBoolean("active", state.isOpen()); - turtle.updateUpgradeNBTData(side); + if( state.pollChanged() ) + { + turtle.getUpgradeNBTData( side ) + .putBoolean( "active", state.isOpen() ); + turtle.updateUpgradeNBTData( side ); } } } } - private static class Peripheral extends WirelessModemPeripheral { + private static class Peripheral extends WirelessModemPeripheral + { private final ITurtleAccess turtle; - Peripheral(ITurtleAccess turtle, boolean advanced) { - super(new ModemState(), advanced); + Peripheral( ITurtleAccess turtle, boolean advanced ) + { + super( new ModemState(), advanced ); this.turtle = turtle; } @Nonnull @Override - public World getWorld() { + public World getWorld() + { return this.turtle.getWorld(); } @Nonnull @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { BlockPos turtlePos = this.turtle.getPosition(); - return new Vec3d(turtlePos.getX(), turtlePos.getY(), turtlePos.getZ()); + return new Vec3d( turtlePos.getX(), turtlePos.getY(), turtlePos.getZ() ); } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return this == other || (other instanceof Peripheral && ((Peripheral) other).turtle == this.turtle); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleShovel.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleShovel.java index d60522d7f..79ce86663 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleShovel.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleShovel.java @@ -6,15 +6,12 @@ package dan200.computercraft.shared.turtle.upgrades; -import javax.annotation.Nonnull; - import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleCommandResult; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleVerb; import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand; import dan200.computercraft.shared.turtle.core.TurtlePlayer; - import net.minecraft.block.BlockState; import net.minecraft.block.Material; import net.minecraft.item.Item; @@ -24,35 +21,46 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public class TurtleShovel extends TurtleTool { - public TurtleShovel(Identifier id, String adjective, Item item) { - super(id, adjective, item); +import javax.annotation.Nonnull; + +public class TurtleShovel extends TurtleTool +{ + public TurtleShovel( Identifier id, String adjective, Item item ) + { + super( id, adjective, item ); } - public TurtleShovel(Identifier id, Item item) { - super(id, item); + public TurtleShovel( Identifier id, Item item ) + { + super( id, item ); } - public TurtleShovel(Identifier id, ItemStack craftItem, ItemStack toolItem) { - super(id, craftItem, toolItem); + public TurtleShovel( Identifier id, ItemStack craftItem, ItemStack toolItem ) + { + super( id, craftItem, toolItem ); } @Nonnull @Override - public TurtleCommandResult useTool(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction) { - if (verb == TurtleVerb.DIG) { + public TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction ) + { + if( verb == TurtleVerb.DIG ) + { ItemStack shovel = this.item.copy(); - ItemStack remainder = TurtlePlaceCommand.deploy(shovel, turtle, direction, null, null); - if (remainder != shovel) { + ItemStack remainder = TurtlePlaceCommand.deploy( shovel, turtle, direction, null, null ); + if( remainder != shovel ) + { return TurtleCommandResult.success(); } } - return super.useTool(turtle, side, verb, direction); + return super.useTool( turtle, side, verb, direction ); } @Override - protected boolean canBreakBlock(BlockState state, World world, BlockPos pos, TurtlePlayer player) { - if (!super.canBreakBlock(state, world, pos, player)) { + protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) + { + if( !super.canBreakBlock( state, world, pos, player ) ) + { return false; } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java index cd90b2699..187080a90 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java @@ -5,8 +5,6 @@ */ package dan200.computercraft.shared.turtle.upgrades; -import javax.annotation.Nonnull; - import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.turtle.AbstractTurtleUpgrade; @@ -15,74 +13,89 @@ import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleUpgradeType; import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral; - +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.client.util.ModelIdentifier; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import javax.annotation.Nonnull; -public class TurtleSpeaker extends AbstractTurtleUpgrade { - @Environment (EnvType.CLIENT) private ModelIdentifier m_leftModel; - @Environment (EnvType.CLIENT) private ModelIdentifier m_rightModel; +public class TurtleSpeaker extends AbstractTurtleUpgrade +{ + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_leftModel; + @Environment( EnvType.CLIENT ) + private ModelIdentifier m_rightModel; - public TurtleSpeaker(Identifier id) { - super(id, TurtleUpgradeType.PERIPHERAL, ComputerCraftRegistry.ModBlocks.SPEAKER); + public TurtleSpeaker( Identifier id ) + { + super( id, TurtleUpgradeType.PERIPHERAL, ComputerCraftRegistry.ModBlocks.SPEAKER ); } @Override - public IPeripheral createPeripheral(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { - return new TurtleSpeaker.Peripheral(turtle); + public IPeripheral createPeripheral( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side ) + { + return new TurtleSpeaker.Peripheral( turtle ); } @Nonnull @Override - @Environment (EnvType.CLIENT) - public TransformedModel getModel(ITurtleAccess turtle, @Nonnull TurtleSide side) { + @Environment( EnvType.CLIENT ) + public TransformedModel getModel( ITurtleAccess turtle, @Nonnull TurtleSide side ) + { this.loadModelLocations(); - return TransformedModel.of(side == TurtleSide.LEFT ? this.m_leftModel : this.m_rightModel); + return TransformedModel.of( side == TurtleSide.LEFT ? this.m_leftModel : this.m_rightModel ); } - @Environment (EnvType.CLIENT) - private void loadModelLocations() { - if (this.m_leftModel == null) { - this.m_leftModel = new ModelIdentifier("computercraft:turtle_speaker_upgrade_left", "inventory"); - this.m_rightModel = new ModelIdentifier("computercraft:turtle_speaker_upgrade_right", "inventory"); + @Environment( EnvType.CLIENT ) + private void loadModelLocations() + { + if( this.m_leftModel == null ) + { + this.m_leftModel = new ModelIdentifier( "computercraft:turtle_speaker_upgrade_left", "inventory" ); + this.m_rightModel = new ModelIdentifier( "computercraft:turtle_speaker_upgrade_right", "inventory" ); } } @Override - public void update(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide turtleSide) { - IPeripheral turtlePeripheral = turtle.getPeripheral(turtleSide); - if (turtlePeripheral instanceof Peripheral) { + public void update( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide turtleSide ) + { + IPeripheral turtlePeripheral = turtle.getPeripheral( turtleSide ); + if( turtlePeripheral instanceof Peripheral ) + { Peripheral peripheral = (Peripheral) turtlePeripheral; peripheral.update(); } } - private static class Peripheral extends SpeakerPeripheral { + private static class Peripheral extends SpeakerPeripheral + { ITurtleAccess turtle; - Peripheral(ITurtleAccess turtle) { + Peripheral( ITurtleAccess turtle ) + { this.turtle = turtle; } @Override - public World getWorld() { + public World getWorld() + { return this.turtle.getWorld(); } @Override - public Vec3d getPosition() { + public Vec3d getPosition() + { BlockPos pos = this.turtle.getPosition(); - return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ); } @Override - public boolean equals(IPeripheral other) { + public boolean equals( IPeripheral other ) + { return this == other || (other instanceof Peripheral && this.turtle == ((Peripheral) other).turtle); } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSword.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSword.java index 61853c33f..7c41f9b46 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSword.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSword.java @@ -7,7 +7,6 @@ package dan200.computercraft.shared.turtle.upgrades; import dan200.computercraft.shared.turtle.core.TurtlePlayer; - import net.minecraft.block.BlockState; import net.minecraft.block.Material; import net.minecraft.item.Item; @@ -16,27 +15,34 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -public class TurtleSword extends TurtleTool { - public TurtleSword(Identifier id, String adjective, Item item) { - super(id, adjective, item); +public class TurtleSword extends TurtleTool +{ + public TurtleSword( Identifier id, String adjective, Item item ) + { + super( id, adjective, item ); } - public TurtleSword(Identifier id, Item item) { - super(id, item); + public TurtleSword( Identifier id, Item item ) + { + super( id, item ); } - public TurtleSword(Identifier id, ItemStack craftItem, ItemStack toolItem) { - super(id, craftItem, toolItem); + public TurtleSword( Identifier id, ItemStack craftItem, ItemStack toolItem ) + { + super( id, craftItem, toolItem ); } @Override - protected float getDamageMultiplier() { + protected float getDamageMultiplier() + { return 9.0f; } @Override - protected boolean canBreakBlock(BlockState state, World world, BlockPos pos, TurtlePlayer player) { - if (!super.canBreakBlock(state, world, pos, player)) { + protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) + { + if( !super.canBreakBlock( state, world, pos, player ) ) + { return false; } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java index 2ba822b6f..45d63752b 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java @@ -6,21 +6,9 @@ package dan200.computercraft.shared.turtle.upgrades; -import java.util.List; -import java.util.function.Function; - -import javax.annotation.Nonnull; - -import org.apache.commons.lang3.tuple.Pair; - import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.client.TransformedModel; -import dan200.computercraft.api.turtle.AbstractTurtleUpgrade; -import dan200.computercraft.api.turtle.ITurtleAccess; -import dan200.computercraft.api.turtle.TurtleCommandResult; -import dan200.computercraft.api.turtle.TurtleSide; -import dan200.computercraft.api.turtle.TurtleUpgradeType; -import dan200.computercraft.api.turtle.TurtleVerb; +import dan200.computercraft.api.turtle.*; import dan200.computercraft.api.turtle.event.TurtleAttackEvent; import dan200.computercraft.api.turtle.event.TurtleBlockEvent; import dan200.computercraft.api.turtle.event.TurtleEvent; @@ -31,6 +19,9 @@ import dan200.computercraft.shared.turtle.core.TurtlePlayer; import dan200.computercraft.shared.util.DropConsumer; import dan200.computercraft.shared.util.InventoryUtil; import dan200.computercraft.shared.util.WorldUtil; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.player.AttackEntityCallback; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -51,29 +42,34 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.event.player.AttackEntityCallback; +import javax.annotation.Nonnull; +import java.util.List; +import java.util.function.Function; -public class TurtleTool extends AbstractTurtleUpgrade { +public class TurtleTool extends AbstractTurtleUpgrade +{ protected final ItemStack item; private static final int TAG_LIST = 9; private static final int TAG_COMPOUND = 10; - public TurtleTool(Identifier id, String adjective, Item item) { - super(id, TurtleUpgradeType.TOOL, adjective, item); - this.item = new ItemStack(item); + public TurtleTool( Identifier id, String adjective, Item item ) + { + super( id, TurtleUpgradeType.TOOL, adjective, item ); + this.item = new ItemStack( item ); } - public TurtleTool(Identifier id, Item item) { - super(id, TurtleUpgradeType.TOOL, item); - this.item = new ItemStack(item); + public TurtleTool( Identifier id, Item item ) + { + super( id, TurtleUpgradeType.TOOL, item ); + this.item = new ItemStack( item ); } - public TurtleTool(Identifier id, ItemStack craftItem, ItemStack toolItem) { - super(id, TurtleUpgradeType.TOOL, craftItem); + public TurtleTool( Identifier id, ItemStack craftItem, ItemStack toolItem ) + { + super( id, TurtleUpgradeType.TOOL, craftItem ); this.item = toolItem; } @@ -97,58 +93,65 @@ public class TurtleTool extends AbstractTurtleUpgrade { @Nonnull @Override - public TurtleCommandResult useTool(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction) { - switch (verb) { - case ATTACK: - return this.attack(turtle, direction, side); - case DIG: - return this.dig(turtle, direction, side); - default: - return TurtleCommandResult.failure("Unsupported action"); + public TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction ) + { + switch( verb ) + { + case ATTACK: + return this.attack( turtle, direction, side ); + case DIG: + return this.dig( turtle, direction, side ); + default: + return TurtleCommandResult.failure( "Unsupported action" ); } } @Nonnull @Override - @Environment (EnvType.CLIENT) - public TransformedModel getModel(ITurtleAccess turtle, @Nonnull TurtleSide side) { + @Environment( EnvType.CLIENT ) + public TransformedModel getModel( ITurtleAccess turtle, @Nonnull TurtleSide side ) + { float xOffset = side == TurtleSide.LEFT ? -0.40625f : 0.40625f; - return TransformedModel.of(this.getCraftingItem(), new AffineTransformation(new Vector3f(xOffset + 1, 0, 1), Vector3f.POSITIVE_Y.getDegreesQuaternion(270), new Vector3f(1, 1, 1), Vector3f.POSITIVE_Z.getDegreesQuaternion(90))); + return TransformedModel.of( this.getCraftingItem(), new AffineTransformation( new Vector3f( xOffset + 1, 0, 1 ), Vector3f.POSITIVE_Y.getDegreesQuaternion( 270 ), new Vector3f( 1, 1, 1 ), Vector3f.POSITIVE_Z.getDegreesQuaternion( 90 ) ) ); } - private TurtleCommandResult attack( ITurtleAccess turtle, Direction direction, TurtleSide side ) { + private TurtleCommandResult attack( ITurtleAccess turtle, Direction direction, TurtleSide side ) + { // Create a fake player, and orient it appropriately World world = turtle.getWorld(); BlockPos position = turtle.getPosition(); BlockEntity turtleBlock = turtle instanceof TurtleBrain ? ((TurtleBrain) turtle).getOwner() : world.getBlockEntity( position ); if( turtleBlock == null ) return TurtleCommandResult.failure( "Turtle has vanished from existence." ); - final TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer(turtle, position, direction); + final TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, position, direction ); // See if there is an entity present Vec3d turtlePos = turtlePlayer.getPos(); - Vec3d rayDir = turtlePlayer.getRotationVec(1.0f); - Pair hit = WorldUtil.rayTraceEntities(world, turtlePos, rayDir, 1.5); - if (hit != null) { + Vec3d rayDir = turtlePlayer.getRotationVec( 1.0f ); + Pair hit = WorldUtil.rayTraceEntities( world, turtlePos, rayDir, 1.5 ); + if( hit != null ) + { // Load up the turtle's inventoryf ItemStack stackCopy = this.item.copy(); - turtlePlayer.loadInventory(stackCopy); + turtlePlayer.loadInventory( stackCopy ); Entity hitEntity = hit.getKey(); // Fire several events to ensure we have permissions. - if (AttackEntityCallback.EVENT.invoker() - .interact(turtlePlayer, - world, - Hand.MAIN_HAND, - hitEntity, - null) == ActionResult.FAIL || !hitEntity.isAttackable()) { - return TurtleCommandResult.failure("Nothing to attack here"); + if( AttackEntityCallback.EVENT.invoker() + .interact( turtlePlayer, + world, + Hand.MAIN_HAND, + hitEntity, + null ) == ActionResult.FAIL || !hitEntity.isAttackable() ) + { + return TurtleCommandResult.failure( "Nothing to attack here" ); } - TurtleAttackEvent attackEvent = new TurtleAttackEvent(turtle, turtlePlayer, hitEntity, this, side); - if (TurtleEvent.post(attackEvent)) { - return TurtleCommandResult.failure(attackEvent.getFailureMessage()); + TurtleAttackEvent attackEvent = new TurtleAttackEvent( turtle, turtlePlayer, hitEntity, this, side ); + if( TurtleEvent.post( attackEvent ) ) + { + return TurtleCommandResult.failure( attackEvent.getFailureMessage() ); } // Start claiming entity drops @@ -156,20 +159,27 @@ public class TurtleTool extends AbstractTurtleUpgrade { // Attack the entity boolean attacked = false; - if (!hitEntity.handleAttack(turtlePlayer)) { - float damage = (float) turtlePlayer.getAttributeValue(EntityAttributes.GENERIC_ATTACK_DAMAGE); + if( !hitEntity.handleAttack( turtlePlayer ) ) + { + float damage = (float) turtlePlayer.getAttributeValue( EntityAttributes.GENERIC_ATTACK_DAMAGE ); damage *= this.getDamageMultiplier(); - if (damage > 0.0f) { - DamageSource source = DamageSource.player(turtlePlayer); - if (hitEntity instanceof ArmorStandEntity) { + if( damage > 0.0f ) + { + DamageSource source = DamageSource.player( turtlePlayer ); + if( hitEntity instanceof ArmorStandEntity ) + { // Special case for armor stands: attack twice to guarantee destroy - hitEntity.damage(source, damage); - if (hitEntity.isAlive()) { - hitEntity.damage(source, damage); + hitEntity.damage( source, damage ); + if( hitEntity.isAlive() ) + { + hitEntity.damage( source, damage ); } attacked = true; - } else { - if (hitEntity.damage(source, damage)) { + } + else + { + if( hitEntity.damage( source, damage ) ) + { attacked = true; } } @@ -180,16 +190,18 @@ public class TurtleTool extends AbstractTurtleUpgrade { stopConsuming( turtleBlock, turtle ); // Put everything we collected into the turtles inventory, then return - if (attacked) { - turtlePlayer.unloadInventory(turtle); + if( attacked ) + { + turtlePlayer.unloadInventory( turtle ); return TurtleCommandResult.success(); } } - return TurtleCommandResult.failure("Nothing to attack here"); + return TurtleCommandResult.failure( "Nothing to attack here" ); } - private TurtleCommandResult dig(ITurtleAccess turtle, Direction direction, TurtleSide side) { + private TurtleCommandResult dig( ITurtleAccess turtle, Direction direction, TurtleSide side ) + { // Get ready to dig World world = turtle.getWorld(); BlockPos turtlePosition = turtle.getPosition(); @@ -197,84 +209,96 @@ public class TurtleTool extends AbstractTurtleUpgrade { if( turtleBlock == null ) return TurtleCommandResult.failure( "Turtle has vanished from existence." ); - BlockPos blockPosition = turtlePosition.offset(direction); + BlockPos blockPosition = turtlePosition.offset( direction ); - if (world.isAir(blockPosition) || WorldUtil.isLiquidBlock(world, blockPosition)) { - return TurtleCommandResult.failure("Nothing to dig here"); + if( world.isAir( blockPosition ) || WorldUtil.isLiquidBlock( world, blockPosition ) ) + { + return TurtleCommandResult.failure( "Nothing to dig here" ); } - BlockState state = world.getBlockState(blockPosition); + BlockState state = world.getBlockState( blockPosition ); - TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer(turtle, turtlePosition, direction); - turtlePlayer.loadInventory(this.item.copy()); + TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, turtlePosition, direction ); + turtlePlayer.loadInventory( this.item.copy() ); - if (ComputerCraft.turtlesObeyBlockProtection) { - if (!TurtlePermissions.isBlockEditable(world, blockPosition, turtlePlayer)) { - return TurtleCommandResult.failure("Cannot break protected block"); + if( ComputerCraft.turtlesObeyBlockProtection ) + { + if( !TurtlePermissions.isBlockEditable( world, blockPosition, turtlePlayer ) ) + { + return TurtleCommandResult.failure( "Cannot break protected block" ); } } // Check if we can break the block - if (!this.canBreakBlock(state, world, blockPosition, turtlePlayer)) { - return TurtleCommandResult.failure("Unbreakable block detected"); + if( !this.canBreakBlock( state, world, blockPosition, turtlePlayer ) ) + { + return TurtleCommandResult.failure( "Unbreakable block detected" ); } // Fire the dig event, checking whether it was cancelled. - TurtleBlockEvent.Dig digEvent = new TurtleBlockEvent.Dig(turtle, turtlePlayer, world, blockPosition, state, this, side); - if (TurtleEvent.post(digEvent)) { - return TurtleCommandResult.failure(digEvent.getFailureMessage()); + TurtleBlockEvent.Dig digEvent = new TurtleBlockEvent.Dig( turtle, turtlePlayer, world, blockPosition, state, this, side ); + if( TurtleEvent.post( digEvent ) ) + { + return TurtleCommandResult.failure( digEvent.getFailureMessage() ); } // Consume the items the block drops DropConsumer.set( world, blockPosition, turtleDropConsumer( turtleBlock, turtle ) ); - BlockEntity tile = world.getBlockEntity(blockPosition); + BlockEntity tile = world.getBlockEntity( blockPosition ); // Much of this logic comes from PlayerInteractionManager#tryHarvestBlock, so it's a good idea // to consult there before making any changes. // Play the destruction sound and particles - world.syncWorldEvent(2001, blockPosition, Block.getRawIdFromState(state)); + world.syncWorldEvent( 2001, blockPosition, Block.getRawIdFromState( state ) ); // Destroy the block state.getBlock() - .onBreak(world, blockPosition, state, turtlePlayer); - if (world.removeBlock(blockPosition, false)) { + .onBreak( world, blockPosition, state, turtlePlayer ); + if( world.removeBlock( blockPosition, false ) ) + { state.getBlock() - .onBroken(world, blockPosition, state); - if (turtlePlayer.isUsingEffectiveTool(state)) { + .onBroken( world, blockPosition, state ); + if( turtlePlayer.isUsingEffectiveTool( state ) ) + { state.getBlock() - .afterBreak(world, turtlePlayer, blockPosition, state, tile, turtlePlayer.getMainHandStack()); + .afterBreak( world, turtlePlayer, blockPosition, state, tile, turtlePlayer.getMainHandStack() ); } } - stopConsuming(turtleBlock, turtle); + stopConsuming( turtleBlock, turtle ); return TurtleCommandResult.success(); } - private static Function turtleDropConsumer(BlockEntity turtleBlock, ITurtleAccess turtle) { - return drop -> turtleBlock.isRemoved() ? drop : InventoryUtil.storeItems(drop, turtle.getItemHandler(), turtle.getSelectedSlot()); + private static Function turtleDropConsumer( BlockEntity turtleBlock, ITurtleAccess turtle ) + { + return drop -> turtleBlock.isRemoved() ? drop : InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() ); } - protected float getDamageMultiplier() { + protected float getDamageMultiplier() + { return 3.0f; } - private static void stopConsuming(BlockEntity turtleBlock, ITurtleAccess turtle) { + private static void stopConsuming( BlockEntity turtleBlock, ITurtleAccess turtle ) + { Direction direction = turtleBlock.isRemoved() ? null : turtle.getDirection().getOpposite(); List extra = DropConsumer.clear(); - for (ItemStack remainder : extra) { - WorldUtil.dropItemStack(remainder, - turtle.getWorld(), - turtle.getPosition(), - direction); + for( ItemStack remainder : extra ) + { + WorldUtil.dropItemStack( remainder, + turtle.getWorld(), + turtle.getPosition(), + direction ); } } - protected boolean canBreakBlock(BlockState state, World world, BlockPos pos, TurtlePlayer player) { + protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player ) + { Block block = state.getBlock(); - return !state.isAir() && block != Blocks.BEDROCK && state.calcBlockBreakingDelta(player, world, pos) > 0; + return !state.isAir() && block != Blocks.BEDROCK && state.calcBlockBreakingDelta( player, world, pos ) > 0; } } diff --git a/src/main/java/dan200/computercraft/shared/util/Colour.java b/src/main/java/dan200/computercraft/shared/util/Colour.java index 1bf145d8a..0f7c2840f 100644 --- a/src/main/java/dan200/computercraft/shared/util/Colour.java +++ b/src/main/java/dan200/computercraft/shared/util/Colour.java @@ -6,44 +6,50 @@ package dan200.computercraft.shared.util; -public enum Colour { - BLACK(0x111111), - RED(0xcc4c4c), - GREEN(0x57A64E), - BROWN(0x7f664c), - BLUE(0x3366cc), - PURPLE(0xb266e5), - CYAN(0x4c99b2), - LIGHT_GREY(0x999999), - GREY(0x4c4c4c), - PINK(0xf2b2cc), - LIME(0x7fcc19), - YELLOW(0xdede6c), - LIGHT_BLUE(0x99b2f2), - MAGENTA(0xe57fd8), - ORANGE(0xf2b233), - WHITE(0xf0f0f0); +public enum Colour +{ + BLACK( 0x111111 ), + RED( 0xcc4c4c ), + GREEN( 0x57A64E ), + BROWN( 0x7f664c ), + BLUE( 0x3366cc ), + PURPLE( 0xb266e5 ), + CYAN( 0x4c99b2 ), + LIGHT_GREY( 0x999999 ), + GREY( 0x4c4c4c ), + PINK( 0xf2b2cc ), + LIME( 0x7fcc19 ), + YELLOW( 0xdede6c ), + LIGHT_BLUE( 0x99b2f2 ), + MAGENTA( 0xe57fd8 ), + ORANGE( 0xf2b233 ), + WHITE( 0xf0f0f0 ); public static final Colour[] VALUES = values(); private final int hex; private final float[] rgb; - Colour(int hex) { + Colour( int hex ) + { this.hex = hex; this.rgb = new float[] { ((hex >> 16) & 0xFF) / 255.0f, ((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f, - }; + }; } - public static Colour fromInt(int colour) { + public static Colour fromInt( int colour ) + { return colour >= 0 && colour < 16 ? Colour.VALUES[colour] : null; } - public static Colour fromHex(int colour) { - for (Colour entry : VALUES) { - if (entry.getHex() == colour) { + public static Colour fromHex( int colour ) + { + for( Colour entry : VALUES ) + { + if( entry.getHex() == colour ) + { return entry; } } @@ -51,31 +57,38 @@ public enum Colour { return null; } - public int getHex() { + public int getHex() + { return this.hex; } - public Colour getNext() { + public Colour getNext() + { return VALUES[(this.ordinal() + 1) % 16]; } - public Colour getPrevious() { + public Colour getPrevious() + { return VALUES[(this.ordinal() + 15) % 16]; } - public float[] getRGB() { + public float[] getRGB() + { return this.rgb; } - public float getR() { + public float getR() + { return this.rgb[0]; } - public float getG() { + public float getG() + { return this.rgb[1]; } - public float getB() { + public float getB() + { return this.rgb[2]; } } diff --git a/src/main/java/dan200/computercraft/shared/util/ColourTracker.java b/src/main/java/dan200/computercraft/shared/util/ColourTracker.java index 25daa65e2..3bfe9d062 100644 --- a/src/main/java/dan200/computercraft/shared/util/ColourTracker.java +++ b/src/main/java/dan200/computercraft/shared/util/ColourTracker.java @@ -11,19 +11,22 @@ import net.minecraft.util.DyeColor; /** * A reimplementation of the colour system in {@link ArmorDyeRecipe}, but bundled together as an object. */ -public class ColourTracker { +public class ColourTracker +{ private int total; private int totalR; private int totalG; private int totalB; private int count; - public void addColour(float r, float g, float b) { - this.addColour((int) (r * 255), (int) (g * 255), (int) (b * 255)); + public void addColour( float r, float g, float b ) + { + this.addColour( (int) (r * 255), (int) (g * 255), (int) (b * 255) ); } - public void addColour(int r, int g, int b) { - this.total += Math.max(r, Math.max(g, b)); + public void addColour( int r, int g, int b ) + { + this.total += Math.max( r, Math.max( g, b ) ); this.totalR += r; this.totalG += g; this.totalB += b; @@ -41,13 +44,14 @@ public class ColourTracker { return count > 0; } - public int getColour() { + public int getColour() + { int avgR = this.totalR / this.count; int avgG = this.totalG / this.count; int avgB = this.totalB / this.count; float avgTotal = (float) this.total / this.count; - float avgMax = Math.max(avgR, Math.max(avgG, avgB)); + float avgMax = Math.max( avgR, Math.max( avgG, avgB ) ); avgR = (int) (avgR * avgTotal / avgMax); avgG = (int) (avgG * avgTotal / avgMax); avgB = (int) (avgB * avgTotal / avgMax); diff --git a/src/main/java/dan200/computercraft/shared/util/ColourUtils.java b/src/main/java/dan200/computercraft/shared/util/ColourUtils.java index a89affa27..92a1a13fc 100644 --- a/src/main/java/dan200/computercraft/shared/util/ColourUtils.java +++ b/src/main/java/dan200/computercraft/shared/util/ColourUtils.java @@ -6,18 +6,20 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nullable; - import net.minecraft.item.DyeItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.DyeColor; -public final class ColourUtils { +import javax.annotation.Nullable; + +public final class ColourUtils +{ @Nullable private ColourUtils() {} - public static DyeColor getStackColour(ItemStack stack) { + public static DyeColor getStackColour( ItemStack stack ) + { Item item = stack.getItem(); return item instanceof DyeItem ? ((DyeItem) item).getColor() : null; } diff --git a/src/main/java/dan200/computercraft/shared/util/CommentedConfigSpec.java b/src/main/java/dan200/computercraft/shared/util/CommentedConfigSpec.java index a1d972d19..fe13c12ba 100644 --- a/src/main/java/dan200/computercraft/shared/util/CommentedConfigSpec.java +++ b/src/main/java/dan200/computercraft/shared/util/CommentedConfigSpec.java @@ -5,40 +5,50 @@ */ package dan200.computercraft.shared.util; -import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.CommentedConfig; +import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.ConfigSpec; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static com.electronwill.nightconfig.core.utils.StringUtils.split; -public class CommentedConfigSpec extends ConfigSpec { +public class CommentedConfigSpec extends ConfigSpec +{ private final Map, String> comments = new HashMap<>(); - public void comment(List path, String comment) { - comments.put(path, comment); + public void comment( List path, String comment ) + { + comments.put( path, comment ); } - public void comment(String path, String comment) { - comment(split(path, '.'), comment); + public void comment( String path, String comment ) + { + comment( split( path, '.' ), comment ); } - public int correct(Config config) { - return correct(config, (action, path, incorrectValue, correctedValue) -> {}); + public int correct( Config config ) + { + return correct( config, ( action, path, incorrectValue, correctedValue ) -> {} ); } - public int correct(Config config, ConfigSpec.CorrectionListener listener) { - int corrections = super.correct(config, listener); - if(config instanceof CommentedConfig) { - insertComments((CommentedConfig) config); + public int correct( Config config, ConfigSpec.CorrectionListener listener ) + { + int corrections = super.correct( config, listener ); + if( config instanceof CommentedConfig ) + { + insertComments( (CommentedConfig) config ); } return corrections; } - private void insertComments(CommentedConfig config) { - for(Map.Entry, String> entry : comments.entrySet()) { - config.setComment(entry.getKey(), entry.getValue()); + private void insertComments( CommentedConfig config ) + { + for( Map.Entry, String> entry : comments.entrySet() ) + { + config.setComment( entry.getKey(), entry.getValue() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/util/Config.java b/src/main/java/dan200/computercraft/shared/util/Config.java index fdf35bd77..b9fc34156 100644 --- a/src/main/java/dan200/computercraft/shared/util/Config.java +++ b/src/main/java/dan200/computercraft/shared/util/Config.java @@ -5,7 +5,10 @@ */ package dan200.computercraft.shared.util; -import com.electronwill.nightconfig.core.*; +import com.electronwill.nightconfig.core.CommentedConfig; +import com.electronwill.nightconfig.core.ConfigSpec; +import com.electronwill.nightconfig.core.EnumGetMethod; +import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.FileNotFoundAction; import com.google.common.base.CaseFormat; @@ -27,7 +30,8 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class Config { +public class Config +{ private static final int MODEM_MAX_RANGE = 100000; public static final String TRANSLATION_PREFIX = "gui.computercraft.config."; @@ -38,327 +42,346 @@ public class Config { public static CommentedConfig serverConfig; public static CommentedConfig clientConfig; - private static final WorldSavePath serverDir = WorldSavePathAccess.createWorldSavePath("serverconfig"); + private static final WorldSavePath serverDir = WorldSavePathAccess.createWorldSavePath( "serverconfig" ); private static final String serverFileName = "computercraft-server.toml"; - private static final Path clientPath = FabricLoader.INSTANCE.getConfigDir().resolve("computercraft-client.toml"); + private static final Path clientPath = FabricLoader.INSTANCE.getConfigDir().resolve( "computercraft-client.toml" ); - private Config() { + private Config() + { } - static { - System.setProperty("nightconfig.preserveInsertionOrder", "true"); + static + { + System.setProperty( "nightconfig.preserveInsertionOrder", "true" ); serverSpec = new CommentedConfigSpec(); { // General computers - serverSpec.comment("computer_space_limit", - "The disk space limit for computers and turtles, in bytes"); - serverSpec.define("computer_space_limit", ComputerCraft.computerSpaceLimit); + serverSpec.comment( "computer_space_limit", + "The disk space limit for computers and turtles, in bytes" ); + serverSpec.define( "computer_space_limit", ComputerCraft.computerSpaceLimit ); - serverSpec.comment("floppy_space_limit", - "The disk space limit for floppy disks, in bytes"); - serverSpec.define("floppy_space_limit", ComputerCraft.floppySpaceLimit); + serverSpec.comment( "floppy_space_limit", + "The disk space limit for floppy disks, in bytes" ); + serverSpec.define( "floppy_space_limit", ComputerCraft.floppySpaceLimit ); - serverSpec.comment("maximum_open_files", - "Set how many files a computer can have open at the same time. Set to 0 for unlimited."); - serverSpec.defineInRange("maximum_open_files", ComputerCraft.maximumFilesOpen, 0, Integer.MAX_VALUE); + serverSpec.comment( "maximum_open_files", + "Set how many files a computer can have open at the same time. Set to 0 for unlimited." ); + serverSpec.defineInRange( "maximum_open_files", ComputerCraft.maximumFilesOpen, 0, Integer.MAX_VALUE ); - serverSpec.comment("disable_lua51_features", - "Set this to true to disable Lua 5.1 functions that will be removed in a future update. " + - "Useful for ensuring forward compatibility of your programs now."); - serverSpec.define("disable_lua51_features", ComputerCraft.disableLua51Features); + serverSpec.comment( "disable_lua51_features", + "Set this to true to disable Lua 5.1 functions that will be removed in a future update. " + + "Useful for ensuring forward compatibility of your programs now." ); + serverSpec.define( "disable_lua51_features", ComputerCraft.disableLua51Features ); - serverSpec.comment("default_computer_settings", - "A comma separated list of default system settings to set on new computers. Example: " + + serverSpec.comment( "default_computer_settings", + "A comma separated list of default system settings to set on new computers. Example: " + "\"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" will disable all " + - "autocompletion"); - serverSpec.define("default_computer_settings", ComputerCraft.defaultComputerSettings); + "autocompletion" ); + serverSpec.define( "default_computer_settings", ComputerCraft.defaultComputerSettings ); - serverSpec.comment("debug_enabled", - "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players."); - serverSpec.define("debug_enabled", ComputerCraft.debugEnable); + serverSpec.comment( "debug_enabled", + "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players." ); + serverSpec.define( "debug_enabled", ComputerCraft.debugEnable ); - serverSpec.comment("log_computer_errors", - "Log exceptions thrown by peripherals and other Lua objects.\n" + - "This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods."); - serverSpec.define("log_computer_errors", ComputerCraft.logComputerErrors); + serverSpec.comment( "log_computer_errors", + "Log exceptions thrown by peripherals and other Lua objects.\n" + + "This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." ); + serverSpec.define( "log_computer_errors", ComputerCraft.logComputerErrors ); - serverSpec.comment("command_require_creative", - "Require players to be in creative mode and be opped in order to interact with command computers." + - "This is the default behaviour for vanilla's Command blocks."); - serverSpec.define("command_require_creative", ComputerCraft.commandRequireCreative); + serverSpec.comment( "command_require_creative", + "Require players to be in creative mode and be opped in order to interact with command computers." + + "This is the default behaviour for vanilla's Command blocks." ); + serverSpec.define( "command_require_creative", ComputerCraft.commandRequireCreative ); } { // Execution - serverSpec.comment("execution", - "Controls execution behaviour of computers. This is largely intended for fine-tuning " + - "servers, and generally shouldn't need to be touched"); + serverSpec.comment( "execution", + "Controls execution behaviour of computers. This is largely intended for fine-tuning " + + "servers, and generally shouldn't need to be touched" ); - serverSpec.comment("execution.computer_threads", - "Set the number of threads computers can run on. A higher number means more computers can run " + + serverSpec.comment( "execution.computer_threads", + "Set the number of threads computers can run on. A higher number means more computers can run " + "at once, but may induce lag.\n" + - "Please note that some mods may not work with a thread count higher than 1. Use with caution."); - serverSpec.defineInRange("execution.computer_threads", ComputerCraft.computerThreads, 1, Integer.MAX_VALUE); + "Please note that some mods may not work with a thread count higher than 1. Use with caution." ); + serverSpec.defineInRange( "execution.computer_threads", ComputerCraft.computerThreads, 1, Integer.MAX_VALUE ); - serverSpec.comment("execution.max_main_global_time", - "The maximum time that can be spent executing tasks in a single tick, in milliseconds.\n" + + serverSpec.comment( "execution.max_main_global_time", + "The maximum time that can be spent executing tasks in a single tick, in milliseconds.\n" + "Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " + - "- this aims to be the upper bound of the average time."); - serverSpec.defineInRange("execution.max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ), 1, Integer.MAX_VALUE); + "- this aims to be the upper bound of the average time." ); + serverSpec.defineInRange( "execution.max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ), 1, Integer.MAX_VALUE ); - serverSpec.comment("execution.max_main_computer_time", - "The ideal maximum time a computer can execute for in a tick, in milliseconds.\n" + + serverSpec.comment( "execution.max_main_computer_time", + "The ideal maximum time a computer can execute for in a tick, in milliseconds.\n" + "Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " + - "- this aims to be the upper bound of the average time."); - serverSpec.defineInRange("execution.max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ), 1, Integer.MAX_VALUE); + "- this aims to be the upper bound of the average time." ); + serverSpec.defineInRange( "execution.max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ), 1, Integer.MAX_VALUE ); } { // HTTP - serverSpec.comment("http", "Controls the HTTP API"); + serverSpec.comment( "http", "Controls the HTTP API" ); - serverSpec.comment("http.enabled", - "Enable the \"http\" API on Computers (see \"rules\" for more fine grained control than this)."); - serverSpec.define("http.enabled", ComputerCraft.httpEnabled); + serverSpec.comment( "http.enabled", + "Enable the \"http\" API on Computers (see \"rules\" for more fine grained control than this)." ); + serverSpec.define( "http.enabled", ComputerCraft.httpEnabled ); - serverSpec.comment("http.websocket_enabled", - "Enable use of http websockets. This requires the \"http_enable\" option to also be true."); - serverSpec.define("http.websocket_enabled", ComputerCraft.httpWebsocketEnabled); + serverSpec.comment( "http.websocket_enabled", + "Enable use of http websockets. This requires the \"http_enable\" option to also be true." ); + serverSpec.define( "http.websocket_enabled", ComputerCraft.httpWebsocketEnabled ); - serverSpec.comment("http.rules", - "A list of rules which control behaviour of the \"http\" API for specific domains or IPs.\n" + + serverSpec.comment( "http.rules", + "A list of rules which control behaviour of the \"http\" API for specific domains or IPs.\n" + "Each rule is an item with a 'host' to match against, and a series of properties. " + "The host may be a domain name (\"pastebin.com\"),\n" + - "wildcard (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\"). If no rules, the domain is blocked."); - serverSpec.defineList("http.rules", Arrays.asList( - AddressRuleConfig.makeRule("$private", Action.DENY), - AddressRuleConfig.makeRule("*", Action.ALLOW) - ), x -> x instanceof UnmodifiableConfig && AddressRuleConfig.checkRule((UnmodifiableConfig) x)); + "wildcard (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\"). If no rules, the domain is blocked." ); + serverSpec.defineList( "http.rules", Arrays.asList( + AddressRuleConfig.makeRule( "$private", Action.DENY ), + AddressRuleConfig.makeRule( "*", Action.ALLOW ) + ), x -> x instanceof UnmodifiableConfig && AddressRuleConfig.checkRule( (UnmodifiableConfig) x ) ); - serverSpec.comment("http.max_requests", - "The number of http requests a computer can make at one time. Additional requests will be queued, and sent when the running requests have finished. Set to 0 for unlimited."); - serverSpec.defineInRange("http.max_requests", ComputerCraft.httpMaxRequests, 0, Integer.MAX_VALUE); + serverSpec.comment( "http.max_requests", + "The number of http requests a computer can make at one time. Additional requests will be queued, and sent when the running requests have finished. Set to 0 for unlimited." ); + serverSpec.defineInRange( "http.max_requests", ComputerCraft.httpMaxRequests, 0, Integer.MAX_VALUE ); - serverSpec.comment("http.max_websockets", - "The number of websockets a computer can have open at one time. Set to 0 for unlimited."); - serverSpec.defineInRange("http.max_websockets", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE); + serverSpec.comment( "http.max_websockets", + "The number of websockets a computer can have open at one time. Set to 0 for unlimited." ); + serverSpec.defineInRange( "http.max_websockets", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE ); } { // Peripherals - serverSpec.comment("peripheral", "Various options relating to peripherals."); + serverSpec.comment( "peripheral", "Various options relating to peripherals." ); - serverSpec.comment("peripheral.command_block_enabled", - "Enable Command Block peripheral support"); - serverSpec.define("peripheral.command_block_enabled", ComputerCraft.enableCommandBlock); + serverSpec.comment( "peripheral.command_block_enabled", + "Enable Command Block peripheral support" ); + serverSpec.define( "peripheral.command_block_enabled", ComputerCraft.enableCommandBlock ); - serverSpec.comment("peripheral.modem_range", - "The range of Wireless Modems at low altitude in clear weather, in meters"); - serverSpec.defineInRange("peripheral.modem_range", ComputerCraft.modemRange, 0, MODEM_MAX_RANGE); + serverSpec.comment( "peripheral.modem_range", + "The range of Wireless Modems at low altitude in clear weather, in meters" ); + serverSpec.defineInRange( "peripheral.modem_range", ComputerCraft.modemRange, 0, MODEM_MAX_RANGE ); - serverSpec.comment("peripheral.modem_high_altitude_range", - "The range of Wireless Modems at maximum altitude in clear weather, in meters"); - serverSpec.defineInRange("peripheral.modem_high_altitude_range", ComputerCraft.modemHighAltitudeRange, 0, MODEM_MAX_RANGE); + serverSpec.comment( "peripheral.modem_high_altitude_range", + "The range of Wireless Modems at maximum altitude in clear weather, in meters" ); + serverSpec.defineInRange( "peripheral.modem_high_altitude_range", ComputerCraft.modemHighAltitudeRange, 0, MODEM_MAX_RANGE ); - serverSpec.comment("peripheral.modem_range_during_storm", - "The range of Wireless Modems at low altitude in stormy weather, in meters"); - serverSpec.defineInRange("peripheral.modem_range_during_storm", ComputerCraft.modemRangeDuringStorm, 0, MODEM_MAX_RANGE); + serverSpec.comment( "peripheral.modem_range_during_storm", + "The range of Wireless Modems at low altitude in stormy weather, in meters" ); + serverSpec.defineInRange( "peripheral.modem_range_during_storm", ComputerCraft.modemRangeDuringStorm, 0, MODEM_MAX_RANGE ); - serverSpec.comment("peripheral.modem_high_altitude_range_during_storm", - "The range of Wireless Modems at maximum altitude in stormy weather, in meters"); - serverSpec.defineInRange("peripheral.modem_high_altitude_range_during_storm", ComputerCraft.modemHighAltitudeRangeDuringStorm, 0, MODEM_MAX_RANGE); + serverSpec.comment( "peripheral.modem_high_altitude_range_during_storm", + "The range of Wireless Modems at maximum altitude in stormy weather, in meters" ); + serverSpec.defineInRange( "peripheral.modem_high_altitude_range_during_storm", ComputerCraft.modemHighAltitudeRangeDuringStorm, 0, MODEM_MAX_RANGE ); - serverSpec.comment("peripheral.max_notes_per_tick", - "Maximum amount of notes a speaker can play at once"); - serverSpec.defineInRange("peripheral.max_notes_per_tick", ComputerCraft.maxNotesPerTick, 1, Integer.MAX_VALUE); + serverSpec.comment( "peripheral.max_notes_per_tick", + "Maximum amount of notes a speaker can play at once" ); + serverSpec.defineInRange( "peripheral.max_notes_per_tick", ComputerCraft.maxNotesPerTick, 1, Integer.MAX_VALUE ); - serverSpec.comment("peripheral.monitor_bandwidth", - "The limit to how much monitor data can be sent *per tick*. Note:\n" + + serverSpec.comment( "peripheral.monitor_bandwidth", + "The limit to how much monitor data can be sent *per tick*. Note:\n" + " - Bandwidth is measured before compression, so the data sent to the client is smaller.\n" + " - This ignores the number of players a packet is sent to. Updating a monitor for one player consumes " + "the same bandwidth limit as sending to 20.\n" + " - A full sized monitor sends ~25kb of data. So the default (1MB) allows for ~40 monitors to be updated " + "in a single tick. \n" + - "Set to 0 to disable."); - serverSpec.defineInRange("peripheral.monitor_bandwidth", (int) ComputerCraft.monitorBandwidth, 0, Integer.MAX_VALUE); + "Set to 0 to disable." ); + serverSpec.defineInRange( "peripheral.monitor_bandwidth", (int) ComputerCraft.monitorBandwidth, 0, Integer.MAX_VALUE ); } { // Turtles - serverSpec.comment("turtle", "Various options relating to turtles."); + serverSpec.comment( "turtle", "Various options relating to turtles." ); - serverSpec.comment("turtle.need_fuel", - "Set whether Turtles require fuel to move"); - serverSpec.define("turtle.need_fuel", ComputerCraft.turtlesNeedFuel); + serverSpec.comment( "turtle.need_fuel", + "Set whether Turtles require fuel to move" ); + serverSpec.define( "turtle.need_fuel", ComputerCraft.turtlesNeedFuel ); - serverSpec.comment("turtle.normal_fuel_limit", "The fuel limit for Turtles"); - serverSpec.defineInRange("turtle.normal_fuel_limit", ComputerCraft.turtleFuelLimit, 0, Integer.MAX_VALUE); + serverSpec.comment( "turtle.normal_fuel_limit", "The fuel limit for Turtles" ); + serverSpec.defineInRange( "turtle.normal_fuel_limit", ComputerCraft.turtleFuelLimit, 0, Integer.MAX_VALUE ); - serverSpec.comment("turtle.advanced_fuel_limit", - "The fuel limit for Advanced Turtles"); - serverSpec.defineInRange("turtle.advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit, 0, Integer.MAX_VALUE); + serverSpec.comment( "turtle.advanced_fuel_limit", + "The fuel limit for Advanced Turtles" ); + serverSpec.defineInRange( "turtle.advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit, 0, Integer.MAX_VALUE ); - serverSpec.comment("turtle.obey_block_protection", - "If set to true, Turtles will be unable to build, dig, or enter protected areas (such as near the server spawn point)"); - serverSpec.define("turtle.obey_block_protection", ComputerCraft.turtlesObeyBlockProtection); + serverSpec.comment( "turtle.obey_block_protection", + "If set to true, Turtles will be unable to build, dig, or enter protected areas (such as near the server spawn point)" ); + serverSpec.define( "turtle.obey_block_protection", ComputerCraft.turtlesObeyBlockProtection ); - serverSpec.comment("turtle.can_push", - "If set to true, Turtles will push entities out of the way instead of stopping if there is space to do so"); - serverSpec.define("turtle.can_push", ComputerCraft.turtlesCanPush); + serverSpec.comment( "turtle.can_push", + "If set to true, Turtles will push entities out of the way instead of stopping if there is space to do so" ); + serverSpec.define( "turtle.can_push", ComputerCraft.turtlesCanPush ); - serverSpec.comment("turtle.disabled_actions", - "A list of turtle actions which are disabled."); - serverSpec.defineList("turtle.disabled_actions", Collections.emptyList(), x -> x instanceof String && getAction((String) x) != null); + serverSpec.comment( "turtle.disabled_actions", + "A list of turtle actions which are disabled." ); + serverSpec.defineList( "turtle.disabled_actions", Collections.emptyList(), x -> x instanceof String && getAction( (String) x ) != null ); } { - serverSpec.comment("term_sizes", "Configure the size of various computer's terminals.\n" + - "Larger terminals require more bandwidth, so use with care."); + serverSpec.comment( "term_sizes", "Configure the size of various computer's terminals.\n" + + "Larger terminals require more bandwidth, so use with care." ); - serverSpec.comment("term_sizes.computer", "Terminal size of computers"); - serverSpec.defineInRange("term_sizes.computer.width", ComputerCraft.computerTermWidth, 1, 255); - serverSpec.defineInRange("term_sizes.computer.height", ComputerCraft.computerTermHeight, 1, 255); + serverSpec.comment( "term_sizes.computer", "Terminal size of computers" ); + serverSpec.defineInRange( "term_sizes.computer.width", ComputerCraft.computerTermWidth, 1, 255 ); + serverSpec.defineInRange( "term_sizes.computer.height", ComputerCraft.computerTermHeight, 1, 255 ); - serverSpec.comment("term_sizes.pocket_computer", "Terminal size of pocket computers"); - serverSpec.defineInRange("term_sizes.pocket_computer.width", ComputerCraft.pocketTermWidth, 1, 255); - serverSpec.defineInRange("term_sizes.pocket_computer.height", ComputerCraft.pocketTermHeight, 1, 255); + serverSpec.comment( "term_sizes.pocket_computer", "Terminal size of pocket computers" ); + serverSpec.defineInRange( "term_sizes.pocket_computer.width", ComputerCraft.pocketTermWidth, 1, 255 ); + serverSpec.defineInRange( "term_sizes.pocket_computer.height", ComputerCraft.pocketTermHeight, 1, 255 ); - serverSpec.comment("term_sizes.monitor", "Maximum size of monitors (in blocks)"); - serverSpec.defineInRange("term_sizes.monitor.width", ComputerCraft.monitorWidth, 1, 32); - serverSpec.defineInRange("term_sizes.monitor.height", ComputerCraft.monitorHeight, 1, 32); + serverSpec.comment( "term_sizes.monitor", "Maximum size of monitors (in blocks)" ); + serverSpec.defineInRange( "term_sizes.monitor.width", ComputerCraft.monitorWidth, 1, 32 ); + serverSpec.defineInRange( "term_sizes.monitor.height", ComputerCraft.monitorHeight, 1, 32 ); } clientSpec = new CommentedConfigSpec(); - clientSpec.comment("monitor_renderer", - "The renderer to use for monitors. Generally this should be kept at \"best\" - if " + - "monitors have performance issues, you may wish to experiment with alternative renderers."); - clientSpec.defineRestrictedEnum("monitor_renderer", MonitorRenderer.BEST, EnumSet.allOf(MonitorRenderer.class), EnumGetMethod.NAME_IGNORECASE); + clientSpec.comment( "monitor_renderer", + "The renderer to use for monitors. Generally this should be kept at \"best\" - if " + + "monitors have performance issues, you may wish to experiment with alternative renderers." ); + clientSpec.defineRestrictedEnum( "monitor_renderer", MonitorRenderer.BEST, EnumSet.allOf( MonitorRenderer.class ), EnumGetMethod.NAME_IGNORECASE ); - clientSpec.comment("monitor_distance", - "The maximum distance monitors will render at. This defaults to the standard tile entity limit, " + + clientSpec.comment( "monitor_distance", + "The maximum distance monitors will render at. This defaults to the standard tile entity limit, " + "but may be extended if you wish to build larger monitors." ); - clientSpec.defineInRange("monitor_distance", 64, 16, 1024); + clientSpec.defineInRange( "monitor_distance", 64, 16, 1024 ); } - private static final FileNotFoundAction MAKE_DIRECTORIES = (file, configFormat) -> { - Files.createDirectories(file.getParent()); - Files.createFile(file); - configFormat.initEmptyFile(file); + private static final FileNotFoundAction MAKE_DIRECTORIES = ( file, configFormat ) -> { + Files.createDirectories( file.getParent() ); + Files.createFile( file ); + configFormat.initEmptyFile( file ); return false; }; - private static CommentedFileConfig buildFileConfig(Path path) { - return CommentedFileConfig.builder(path) - .onFileNotFound(MAKE_DIRECTORIES) - .preserveInsertionOrder() - .build(); + private static CommentedFileConfig buildFileConfig( Path path ) + { + return CommentedFileConfig.builder( path ) + .onFileNotFound( MAKE_DIRECTORIES ) + .preserveInsertionOrder() + .build(); } - public static void serverStarting(MinecraftServer server) { - Path serverPath = server.getSavePath(serverDir).resolve(serverFileName); + public static void serverStarting( MinecraftServer server ) + { + Path serverPath = server.getSavePath( serverDir ).resolve( serverFileName ); - try(CommentedFileConfig config = buildFileConfig(serverPath)) { + try( CommentedFileConfig config = buildFileConfig( serverPath ) ) + { config.load(); - serverSpec.correct(config, Config::correctionListener); + serverSpec.correct( config, Config::correctionListener ); config.save(); serverConfig = config; sync(); } } - public static void serverStopping(MinecraftServer server) { + public static void serverStopping( MinecraftServer server ) + { serverConfig = null; } - public static void clientStarted(MinecraftClient client) { - try (CommentedFileConfig config = buildFileConfig(clientPath)) { + public static void clientStarted( MinecraftClient client ) + { + try( CommentedFileConfig config = buildFileConfig( clientPath ) ) + { config.load(); - clientSpec.correct(config, Config::correctionListener); + clientSpec.correct( config, Config::correctionListener ); config.save(); clientConfig = config; sync(); } } - private static void correctionListener(ConfigSpec.CorrectionAction action, List path, Object incorrectValue, Object correctedValue) { - String key = String.join(".", path); - switch(action) { + private static void correctionListener( ConfigSpec.CorrectionAction action, List path, Object incorrectValue, Object correctedValue ) + { + String key = String.join( ".", path ); + switch( action ) + { case ADD: - ComputerCraft.log.warn("Config key {} missing -> added default value.", key); break; + ComputerCraft.log.warn( "Config key {} missing -> added default value.", key ); + break; case REMOVE: - ComputerCraft.log.warn("Config key {} not defined -> removed from config.", key); break; + ComputerCraft.log.warn( "Config key {} not defined -> removed from config.", key ); + break; case REPLACE: - ComputerCraft.log.warn("Config key {} not valid -> replaced with default value.", key); + ComputerCraft.log.warn( "Config key {} not valid -> replaced with default value.", key ); } } - public static void sync() { - if(serverConfig != null) { + public static void sync() + { + if( serverConfig != null ) + { // General - ComputerCraft.computerSpaceLimit = serverConfig.get("computer_space_limit"); - ComputerCraft.floppySpaceLimit = serverConfig.get("floppy_space_limit"); - ComputerCraft.maximumFilesOpen = serverConfig.get("maximum_open_files"); - ComputerCraft.disableLua51Features = serverConfig.get("disable_lua51_features"); - ComputerCraft.defaultComputerSettings = serverConfig.get("default_computer_settings"); - ComputerCraft.debugEnable = serverConfig.get("debug_enabled"); - ComputerCraft.logComputerErrors = serverConfig.get("log_computer_errors"); - ComputerCraft.commandRequireCreative = serverConfig.get("command_require_creative"); + ComputerCraft.computerSpaceLimit = serverConfig.get( "computer_space_limit" ); + ComputerCraft.floppySpaceLimit = serverConfig.get( "floppy_space_limit" ); + ComputerCraft.maximumFilesOpen = serverConfig.get( "maximum_open_files" ); + ComputerCraft.disableLua51Features = serverConfig.get( "disable_lua51_features" ); + ComputerCraft.defaultComputerSettings = serverConfig.get( "default_computer_settings" ); + ComputerCraft.debugEnable = serverConfig.get( "debug_enabled" ); + ComputerCraft.logComputerErrors = serverConfig.get( "log_computer_errors" ); + ComputerCraft.commandRequireCreative = serverConfig.get( "command_require_creative" ); // Execution - ComputerCraft.computerThreads = serverConfig.get("execution.computer_threads"); - ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(serverConfig.get("execution.max_main_global_time")); - ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(serverConfig.get("execution.max_main_computer_time")); + ComputerCraft.computerThreads = serverConfig.get( "execution.computer_threads" ); + ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( serverConfig.get( "execution.max_main_global_time" ) ); + ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( serverConfig.get( "execution.max_main_computer_time" ) ); // HTTP - ComputerCraft.httpEnabled = serverConfig.get("http.enabled"); - ComputerCraft.httpWebsocketEnabled = serverConfig.get("http.websocket_enabled"); - ComputerCraft.httpRules = serverConfig.>get("http.rules").stream().map(AddressRuleConfig::parseRule) - .filter(Objects::nonNull).collect(Collectors.toList()); - ComputerCraft.httpMaxRequests = serverConfig.get("http.max_requests"); - ComputerCraft.httpMaxWebsockets = serverConfig.get("http.max_websockets"); + ComputerCraft.httpEnabled = serverConfig.get( "http.enabled" ); + ComputerCraft.httpWebsocketEnabled = serverConfig.get( "http.websocket_enabled" ); + ComputerCraft.httpRules = serverConfig.>get( "http.rules" ).stream().map( AddressRuleConfig::parseRule ) + .filter( Objects::nonNull ).collect( Collectors.toList() ); + ComputerCraft.httpMaxRequests = serverConfig.get( "http.max_requests" ); + ComputerCraft.httpMaxWebsockets = serverConfig.get( "http.max_websockets" ); // Peripherals - ComputerCraft.enableCommandBlock = serverConfig.get("peripheral.command_block_enabled"); - ComputerCraft.modemRange = serverConfig.get("peripheral.modem_range"); - ComputerCraft.modemHighAltitudeRange = serverConfig.get("peripheral.modem_high_altitude_range"); - ComputerCraft.modemRangeDuringStorm = serverConfig.get("peripheral.modem_range_during_storm"); - ComputerCraft.modemHighAltitudeRangeDuringStorm = serverConfig.get("peripheral.modem_high_altitude_range_during_storm"); - ComputerCraft.maxNotesPerTick = serverConfig.get("peripheral.max_notes_per_tick"); - ComputerCraft.monitorBandwidth = serverConfig.get("peripheral.monitor_bandwidth"); + ComputerCraft.enableCommandBlock = serverConfig.get( "peripheral.command_block_enabled" ); + ComputerCraft.modemRange = serverConfig.get( "peripheral.modem_range" ); + ComputerCraft.modemHighAltitudeRange = serverConfig.get( "peripheral.modem_high_altitude_range" ); + ComputerCraft.modemRangeDuringStorm = serverConfig.get( "peripheral.modem_range_during_storm" ); + ComputerCraft.modemHighAltitudeRangeDuringStorm = serverConfig.get( "peripheral.modem_high_altitude_range_during_storm" ); + ComputerCraft.maxNotesPerTick = serverConfig.get( "peripheral.max_notes_per_tick" ); + ComputerCraft.monitorBandwidth = serverConfig.get( "peripheral.monitor_bandwidth" ); // Turtles - ComputerCraft.turtlesNeedFuel = serverConfig.get("turtle.need_fuel"); - ComputerCraft.turtleFuelLimit = serverConfig.get("turtle.normal_fuel_limit"); - ComputerCraft.advancedTurtleFuelLimit = serverConfig.get("turtle.advanced_fuel_limit"); - ComputerCraft.turtlesObeyBlockProtection = serverConfig.get("turtle.obey_block_protection"); - ComputerCraft.turtlesCanPush = serverConfig.get("turtle.can_push"); + ComputerCraft.turtlesNeedFuel = serverConfig.get( "turtle.need_fuel" ); + ComputerCraft.turtleFuelLimit = serverConfig.get( "turtle.normal_fuel_limit" ); + ComputerCraft.advancedTurtleFuelLimit = serverConfig.get( "turtle.advanced_fuel_limit" ); + ComputerCraft.turtlesObeyBlockProtection = serverConfig.get( "turtle.obey_block_protection" ); + ComputerCraft.turtlesCanPush = serverConfig.get( "turtle.can_push" ); ComputerCraft.turtleDisabledActions.clear(); - for(String value : serverConfig.>get("turtle.disabled_actions")) { - ComputerCraft.turtleDisabledActions.add(getAction(value)); + for( String value : serverConfig.>get( "turtle.disabled_actions" ) ) + { + ComputerCraft.turtleDisabledActions.add( getAction( value ) ); } // Terminal Size - ComputerCraft.computerTermWidth = serverConfig.get("term_sizes.computer.width"); - ComputerCraft.computerTermHeight = serverConfig.get("term_sizes.computer.height"); - ComputerCraft.pocketTermWidth = serverConfig.get("term_sizes.pocket_computer.width"); - ComputerCraft.pocketTermHeight = serverConfig.get("term_sizes.pocket_computer.height"); - ComputerCraft.monitorWidth = serverConfig.get("term_sizes.monitor.width"); - ComputerCraft.monitorHeight = serverConfig.get("term_sizes.monitor.height"); + ComputerCraft.computerTermWidth = serverConfig.get( "term_sizes.computer.width" ); + ComputerCraft.computerTermHeight = serverConfig.get( "term_sizes.computer.height" ); + ComputerCraft.pocketTermWidth = serverConfig.get( "term_sizes.pocket_computer.width" ); + ComputerCraft.pocketTermHeight = serverConfig.get( "term_sizes.pocket_computer.height" ); + ComputerCraft.monitorWidth = serverConfig.get( "term_sizes.monitor.width" ); + ComputerCraft.monitorHeight = serverConfig.get( "term_sizes.monitor.height" ); } // Client - if(clientConfig != null) { - ComputerCraft.monitorRenderer = clientConfig.getEnum("monitor_renderer", MonitorRenderer.class); - int distance = clientConfig.get("monitor_distance"); + if( clientConfig != null ) + { + ComputerCraft.monitorRenderer = clientConfig.getEnum( "monitor_renderer", MonitorRenderer.class ); + int distance = clientConfig.get( "monitor_distance" ); ComputerCraft.monitorDistanceSq = distance * distance; } } - private static final Converter converter = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE); + private static final Converter converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE ); - private static TurtleAction getAction(String value) { - try { - return TurtleAction.valueOf(converter.convert(value)); + private static TurtleAction getAction( String value ) + { + try + { + return TurtleAction.valueOf( converter.convert( value ) ); } - catch(IllegalArgumentException e) { + catch( IllegalArgumentException e ) + { return null; } } diff --git a/src/main/java/dan200/computercraft/shared/util/DefaultInventory.java b/src/main/java/dan200/computercraft/shared/util/DefaultInventory.java index 680a173f9..857fafd34 100644 --- a/src/main/java/dan200/computercraft/shared/util/DefaultInventory.java +++ b/src/main/java/dan200/computercraft/shared/util/DefaultInventory.java @@ -6,28 +6,33 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; -public interface DefaultInventory extends Inventory { +import javax.annotation.Nonnull; + +public interface DefaultInventory extends Inventory +{ @Override - default int getMaxCountPerStack() { + default int getMaxCountPerStack() + { return 64; } @Override - default void onOpen(@Nonnull PlayerEntity player) { + default void onOpen( @Nonnull PlayerEntity player ) + { } @Override - default void onClose(@Nonnull PlayerEntity player) { + default void onClose( @Nonnull PlayerEntity player ) + { } @Override - default boolean isValid(int slot, @Nonnull ItemStack stack) { + default boolean isValid( int slot, @Nonnull ItemStack stack ) + { return true; } } diff --git a/src/main/java/dan200/computercraft/shared/util/DefaultSidedInventory.java b/src/main/java/dan200/computercraft/shared/util/DefaultSidedInventory.java index fca4ee022..f2b234516 100644 --- a/src/main/java/dan200/computercraft/shared/util/DefaultSidedInventory.java +++ b/src/main/java/dan200/computercraft/shared/util/DefaultSidedInventory.java @@ -6,21 +6,24 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import net.minecraft.inventory.SidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.util.math.Direction; -public interface DefaultSidedInventory extends DefaultInventory, SidedInventory { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public interface DefaultSidedInventory extends DefaultInventory, SidedInventory +{ @Override - default boolean canInsert(int slot, @Nonnull ItemStack stack, @Nullable Direction side) { - return this.isValid(slot, stack); + default boolean canInsert( int slot, @Nonnull ItemStack stack, @Nullable Direction side ) + { + return this.isValid( slot, stack ); } @Override - default boolean canExtract(int slot, @Nonnull ItemStack stack, @Nonnull Direction side) { + default boolean canExtract( int slot, @Nonnull ItemStack stack, @Nonnull Direction side ) + { return true; } } diff --git a/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java b/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java index 9e1c7cc1a..9f6cb01a9 100644 --- a/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/DirectionUtil.java @@ -7,45 +7,54 @@ package dan200.computercraft.shared.util; import dan200.computercraft.core.computer.ComputerSide; - import net.minecraft.util.math.Direction; -public final class DirectionUtil { +public final class DirectionUtil +{ public static final Direction[] FACINGS = Direction.values(); private DirectionUtil() {} - public static ComputerSide toLocal(Direction front, Direction dir) { - if (front.getAxis() == Direction.Axis.Y) { + public static ComputerSide toLocal( Direction front, Direction dir ) + { + if( front.getAxis() == Direction.Axis.Y ) + { front = Direction.NORTH; } - if (dir == front) { + if( dir == front ) + { return ComputerSide.FRONT; } - if (dir == front.getOpposite()) { + if( dir == front.getOpposite() ) + { return ComputerSide.BACK; } - if (dir == front.rotateYCounterclockwise()) { + if( dir == front.rotateYCounterclockwise() ) + { return ComputerSide.LEFT; } - if (dir == front.rotateYClockwise()) { + if( dir == front.rotateYClockwise() ) + { return ComputerSide.RIGHT; } - if (dir == Direction.UP) { + if( dir == Direction.UP ) + { return ComputerSide.TOP; } return ComputerSide.BOTTOM; } - public static float toPitchAngle(Direction dir) { - switch (dir) { - case DOWN: - return 90.0f; - case UP: - return 270.0f; - default: - return 0.0f; + public static float toPitchAngle( Direction dir ) + { + switch( dir ) + { + case DOWN: + return 90.0f; + case UP: + return 270.0f; + default: + return 0.0f; } } } diff --git a/src/main/java/dan200/computercraft/shared/util/DropConsumer.java b/src/main/java/dan200/computercraft/shared/util/DropConsumer.java index f75be1e3f..43bb89d84 100644 --- a/src/main/java/dan200/computercraft/shared/util/DropConsumer.java +++ b/src/main/java/dan200/computercraft/shared/util/DropConsumer.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.util; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; import net.minecraft.item.ItemStack; @@ -18,34 +13,45 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.world.World; -public final class DropConsumer { +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +public final class DropConsumer +{ private static Function dropConsumer; private static List remainingDrops; private static WeakReference dropWorld; private static BlockPos dropPos; private static Box dropBounds; private static WeakReference dropEntity; - private DropConsumer() { + + private DropConsumer() + { } - public static void set(Entity entity, Function consumer) { + public static void set( Entity entity, Function consumer ) + { dropConsumer = consumer; remainingDrops = new ArrayList<>(); - dropEntity = new WeakReference<>(entity); - dropWorld = new WeakReference<>(entity.world); + dropEntity = new WeakReference<>( entity ); + dropWorld = new WeakReference<>( entity.world ); dropPos = null; - dropBounds = new Box(entity.getBlockPos()).expand(2, 2, 2); + dropBounds = new Box( entity.getBlockPos() ).expand( 2, 2, 2 ); } - public static void set(World world, BlockPos pos, Function consumer) { + public static void set( World world, BlockPos pos, Function consumer ) + { dropConsumer = consumer; - remainingDrops = new ArrayList<>(2); + remainingDrops = new ArrayList<>( 2 ); dropEntity = null; - dropWorld = new WeakReference<>(world); - dropBounds = new Box(pos).expand(2, 2, 2); + dropWorld = new WeakReference<>( world ); + dropBounds = new Box( pos ).expand( 2, 2, 2 ); } - public static List clear() { + public static List clear() + { List remainingStacks = remainingDrops; dropConsumer = null; @@ -57,33 +63,41 @@ public final class DropConsumer { return remainingStacks; } - public static boolean onHarvestDrops(World world, BlockPos pos, ItemStack stack) { - if (dropWorld != null && dropWorld.get() == world && dropPos != null && dropPos.equals(pos)) { - handleDrops(stack); + public static boolean onHarvestDrops( World world, BlockPos pos, ItemStack stack ) + { + if( dropWorld != null && dropWorld.get() == world && dropPos != null && dropPos.equals( pos ) ) + { + handleDrops( stack ); return true; } return false; } - private static void handleDrops(ItemStack stack) { - ItemStack remaining = dropConsumer.apply(stack); - if (!remaining.isEmpty()) { - remainingDrops.add(remaining); + private static void handleDrops( ItemStack stack ) + { + ItemStack remaining = dropConsumer.apply( stack ); + if( !remaining.isEmpty() ) + { + remainingDrops.add( remaining ); } } - public static boolean onEntitySpawn(Entity entity) { + public static boolean onEntitySpawn( Entity entity ) + { // Capture any nearby item spawns - if (dropWorld != null && dropWorld.get() == entity.getEntityWorld() && entity instanceof ItemEntity && dropBounds.contains(entity.getPos())) { - handleDrops(((ItemEntity) entity).getStack()); + if( dropWorld != null && dropWorld.get() == entity.getEntityWorld() && entity instanceof ItemEntity && dropBounds.contains( entity.getPos() ) ) + { + handleDrops( ((ItemEntity) entity).getStack() ); return true; } return false; } - public static boolean onLivingDrops(Entity entity, ItemStack stack) { - if (dropEntity != null && entity == dropEntity.get()) { - handleDrops(stack); + public static boolean onLivingDrops( Entity entity, ItemStack stack ) + { + if( dropEntity != null && entity == dropEntity.get() ) + { + handleDrops( stack ); return true; } return false; diff --git a/src/main/java/dan200/computercraft/shared/util/FakeNetHandler.java b/src/main/java/dan200/computercraft/shared/util/FakeNetHandler.java index 1a8365ce6..3be2298bd 100644 --- a/src/main/java/dan200/computercraft/shared/util/FakeNetHandler.java +++ b/src/main/java/dan200/computercraft/shared/util/FakeNetHandler.java @@ -6,11 +6,6 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; - import dan200.computercraft.api.turtle.FakePlayer; import io.netty.channel.ChannelHandlerContext; import io.netty.util.concurrent.Future; @@ -24,285 +19,358 @@ import net.minecraft.network.packet.c2s.play.*; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.text.Text; -public class FakeNetHandler extends ServerPlayNetworkHandler { - public FakeNetHandler(@Nonnull FakePlayer player) { - super(player.getServerWorld() - .getServer(), new FakeNetworkManager(), player); +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.crypto.Cipher; + +public class FakeNetHandler extends ServerPlayNetworkHandler +{ + public FakeNetHandler( @Nonnull FakePlayer player ) + { + super( player.getServerWorld() + .getServer(), new FakeNetworkManager(), player ); } @Override - public void tick() { + public void tick() + { } @Override - public void disconnect(@Nonnull Text reason) { + public void disconnect( @Nonnull Text reason ) + { } @Override - public void onPlayerInput(@Nonnull PlayerInputC2SPacket packet) { + public void onPlayerInput( @Nonnull PlayerInputC2SPacket packet ) + { } @Override - public void onVehicleMove(@Nonnull VehicleMoveC2SPacket packet) { + public void onVehicleMove( @Nonnull VehicleMoveC2SPacket packet ) + { } @Override - public void onTeleportConfirm(@Nonnull TeleportConfirmC2SPacket packet) { + public void onTeleportConfirm( @Nonnull TeleportConfirmC2SPacket packet ) + { } @Override - public void onAdvancementTab(@Nonnull AdvancementTabC2SPacket packet) { + public void onAdvancementTab( @Nonnull AdvancementTabC2SPacket packet ) + { } @Override - public void onRequestCommandCompletions(@Nonnull RequestCommandCompletionsC2SPacket packet) { + public void onRequestCommandCompletions( @Nonnull RequestCommandCompletionsC2SPacket packet ) + { } @Override - public void onUpdateCommandBlock(@Nonnull UpdateCommandBlockC2SPacket packet) { + public void onUpdateCommandBlock( @Nonnull UpdateCommandBlockC2SPacket packet ) + { } @Override - public void onUpdateCommandBlockMinecart(@Nonnull UpdateCommandBlockMinecartC2SPacket packet) { + public void onUpdateCommandBlockMinecart( @Nonnull UpdateCommandBlockMinecartC2SPacket packet ) + { } @Override - public void onPickFromInventory(@Nonnull PickFromInventoryC2SPacket packet) { + public void onPickFromInventory( @Nonnull PickFromInventoryC2SPacket packet ) + { } @Override - public void onRenameItem(@Nonnull RenameItemC2SPacket packet) { + public void onRenameItem( @Nonnull RenameItemC2SPacket packet ) + { } @Override - public void onUpdateBeacon(@Nonnull UpdateBeaconC2SPacket packet) { + public void onUpdateBeacon( @Nonnull UpdateBeaconC2SPacket packet ) + { } @Override - public void onStructureBlockUpdate(@Nonnull UpdateStructureBlockC2SPacket packet) { + public void onStructureBlockUpdate( @Nonnull UpdateStructureBlockC2SPacket packet ) + { } @Override - public void onJigsawUpdate(@Nonnull UpdateJigsawC2SPacket packet) { + public void onJigsawUpdate( @Nonnull UpdateJigsawC2SPacket packet ) + { } @Override - public void onJigsawGenerating(JigsawGeneratingC2SPacket packet) { + public void onJigsawGenerating( JigsawGeneratingC2SPacket packet ) + { } @Override - public void onMerchantTradeSelect(SelectMerchantTradeC2SPacket packet) { + public void onMerchantTradeSelect( SelectMerchantTradeC2SPacket packet ) + { } @Override - public void onBookUpdate(@Nonnull BookUpdateC2SPacket packet) { + public void onBookUpdate( @Nonnull BookUpdateC2SPacket packet ) + { } @Override - public void onRecipeBookData(RecipeBookDataC2SPacket packet) { + public void onRecipeBookData( RecipeBookDataC2SPacket packet ) + { } @Override - public void onRecipeCategoryOptions(RecipeCategoryOptionsC2SPacket packet) { - super.onRecipeCategoryOptions(packet); + public void onRecipeCategoryOptions( RecipeCategoryOptionsC2SPacket packet ) + { + super.onRecipeCategoryOptions( packet ); } @Override - public void onQueryEntityNbt(@Nonnull QueryEntityNbtC2SPacket packet) { + public void onQueryEntityNbt( @Nonnull QueryEntityNbtC2SPacket packet ) + { } @Override - public void onQueryBlockNbt(@Nonnull QueryBlockNbtC2SPacket packet) { + public void onQueryBlockNbt( @Nonnull QueryBlockNbtC2SPacket packet ) + { } @Override - public void onPlayerMove(@Nonnull PlayerMoveC2SPacket packet) { + public void onPlayerMove( @Nonnull PlayerMoveC2SPacket packet ) + { } @Override - public void onPlayerAction(@Nonnull PlayerActionC2SPacket packet) { + public void onPlayerAction( @Nonnull PlayerActionC2SPacket packet ) + { } @Override - public void onPlayerInteractBlock(@Nonnull PlayerInteractBlockC2SPacket packet) { + public void onPlayerInteractBlock( @Nonnull PlayerInteractBlockC2SPacket packet ) + { } @Override - public void onPlayerInteractItem(@Nonnull PlayerInteractItemC2SPacket packet) { + public void onPlayerInteractItem( @Nonnull PlayerInteractItemC2SPacket packet ) + { } @Override - public void onSpectatorTeleport(@Nonnull SpectatorTeleportC2SPacket packet) { + public void onSpectatorTeleport( @Nonnull SpectatorTeleportC2SPacket packet ) + { } @Override - public void onResourcePackStatus(@Nonnull ResourcePackStatusC2SPacket packet) { + public void onResourcePackStatus( @Nonnull ResourcePackStatusC2SPacket packet ) + { } @Override - public void onBoatPaddleState(@Nonnull BoatPaddleStateC2SPacket packet) { + public void onBoatPaddleState( @Nonnull BoatPaddleStateC2SPacket packet ) + { } @Override - public void onDisconnected(@Nonnull Text reason) { + public void onDisconnected( @Nonnull Text reason ) + { } @Override - public void sendPacket(@Nonnull Packet packet) { + public void sendPacket( @Nonnull Packet packet ) + { } @Override - public void sendPacket(@Nonnull Packet packet, @Nullable GenericFutureListener> whenSent) { + public void sendPacket( @Nonnull Packet packet, @Nullable GenericFutureListener> whenSent ) + { } @Override - public void onUpdateSelectedSlot(@Nonnull UpdateSelectedSlotC2SPacket packet) { + public void onUpdateSelectedSlot( @Nonnull UpdateSelectedSlotC2SPacket packet ) + { } @Override - public void onGameMessage(@Nonnull ChatMessageC2SPacket packet) { + public void onGameMessage( @Nonnull ChatMessageC2SPacket packet ) + { } @Override - public void onHandSwing(@Nonnull HandSwingC2SPacket packet) { + public void onHandSwing( @Nonnull HandSwingC2SPacket packet ) + { } @Override - public void onClientCommand(@Nonnull ClientCommandC2SPacket packet) { + public void onClientCommand( @Nonnull ClientCommandC2SPacket packet ) + { } @Override - public void onPlayerInteractEntity(@Nonnull PlayerInteractEntityC2SPacket packet) { + public void onPlayerInteractEntity( @Nonnull PlayerInteractEntityC2SPacket packet ) + { } @Override - public void onClientStatus(@Nonnull ClientStatusC2SPacket packet) { + public void onClientStatus( @Nonnull ClientStatusC2SPacket packet ) + { } @Override - public void onCloseHandledScreen(CloseHandledScreenC2SPacket packet) { + public void onCloseHandledScreen( CloseHandledScreenC2SPacket packet ) + { } @Override - public void onClickSlot(ClickSlotC2SPacket packet) { + public void onClickSlot( ClickSlotC2SPacket packet ) + { } @Override - public void onCraftRequest(@Nonnull CraftRequestC2SPacket packet) { + public void onCraftRequest( @Nonnull CraftRequestC2SPacket packet ) + { } @Override - public void onButtonClick(@Nonnull ButtonClickC2SPacket packet) { + public void onButtonClick( @Nonnull ButtonClickC2SPacket packet ) + { } @Override - public void onCreativeInventoryAction(@Nonnull CreativeInventoryActionC2SPacket packet) { + public void onCreativeInventoryAction( @Nonnull CreativeInventoryActionC2SPacket packet ) + { } @Override - public void onConfirmScreenAction(ConfirmScreenActionC2SPacket packet) { + public void onConfirmScreenAction( ConfirmScreenActionC2SPacket packet ) + { } @Override - public void onSignUpdate(@Nonnull UpdateSignC2SPacket packet) { + public void onSignUpdate( @Nonnull UpdateSignC2SPacket packet ) + { } @Override - public void onKeepAlive(@Nonnull KeepAliveC2SPacket packet) { + public void onKeepAlive( @Nonnull KeepAliveC2SPacket packet ) + { } @Override - public void onPlayerAbilities(@Nonnull UpdatePlayerAbilitiesC2SPacket packet) { + public void onPlayerAbilities( @Nonnull UpdatePlayerAbilitiesC2SPacket packet ) + { } @Override - public void onClientSettings(@Nonnull ClientSettingsC2SPacket packet) { + public void onClientSettings( @Nonnull ClientSettingsC2SPacket packet ) + { } @Override - public void onCustomPayload(@Nonnull CustomPayloadC2SPacket packet) { + public void onCustomPayload( @Nonnull CustomPayloadC2SPacket packet ) + { } @Override - public void onUpdateDifficulty(@Nonnull UpdateDifficultyC2SPacket packet) { + public void onUpdateDifficulty( @Nonnull UpdateDifficultyC2SPacket packet ) + { } @Override - public void onUpdateDifficultyLock(@Nonnull UpdateDifficultyLockC2SPacket packet) { + public void onUpdateDifficultyLock( @Nonnull UpdateDifficultyLockC2SPacket packet ) + { } - private static class FakeNetworkManager extends ClientConnection { + private static class FakeNetworkManager extends ClientConnection + { private PacketListener handler; private Text closeReason; - FakeNetworkManager() { - super(NetworkSide.CLIENTBOUND); + FakeNetworkManager() + { + super( NetworkSide.CLIENTBOUND ); } @Override - public void channelActive(@Nonnull ChannelHandlerContext context) { + public void channelActive( @Nonnull ChannelHandlerContext context ) + { } @Override - public void setState(@Nonnull NetworkState state) { + public void setState( @Nonnull NetworkState state ) + { } @Override - public void channelInactive(@Nonnull ChannelHandlerContext context) { + public void channelInactive( @Nonnull ChannelHandlerContext context ) + { } @Override - public void exceptionCaught(@Nonnull ChannelHandlerContext context, @Nonnull Throwable err) { + public void exceptionCaught( @Nonnull ChannelHandlerContext context, @Nonnull Throwable err ) + { } @Override - protected void channelRead0(@Nonnull ChannelHandlerContext context, @Nonnull Packet packet) { + protected void channelRead0( @Nonnull ChannelHandlerContext context, @Nonnull Packet packet ) + { } @Override - public void setPacketListener(@Nonnull PacketListener handler) { + public void setPacketListener( @Nonnull PacketListener handler ) + { this.handler = handler; } @Override - public void send(@Nonnull Packet packet) { + public void send( @Nonnull Packet packet ) + { } @Override - public void send(@Nonnull Packet packet, @Nullable GenericFutureListener> whenSent) { + public void send( @Nonnull Packet packet, @Nullable GenericFutureListener> whenSent ) + { } @Override - public void tick() { + public void tick() + { } @Override - public void disconnect(@Nonnull Text message) { + public void disconnect( @Nonnull Text message ) + { this.closeReason = message; } @Override - public void setupEncryption(Cipher cipher, Cipher cipher2) { + public void setupEncryption( Cipher cipher, Cipher cipher2 ) + { } @Nonnull @Override - public PacketListener getPacketListener() { + public PacketListener getPacketListener() + { return this.handler; } @Nullable @Override - public Text getDisconnectReason() { + public Text getDisconnectReason() + { return this.closeReason; } @Override - public void disableAutoRead() { + public void disableAutoRead() + { } @Override - public void setCompressionThreshold(int threshold) { + public void setCompressionThreshold( int threshold ) + { } } } diff --git a/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java b/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java index 20d1dd597..62bb4ceb0 100644 --- a/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java +++ b/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java @@ -6,50 +6,56 @@ package dan200.computercraft.shared.util; -import java.util.Collections; -import java.util.function.Function; -import java.util.function.Supplier; - -import javax.annotation.Nonnull; - import net.minecraft.block.Block; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.function.Function; +import java.util.function.Supplier; + /** * A {@link BlockEntityType} whose supplier uses itself as an argument. * * @param The type of the produced tile entity. */ -public final class FixedPointTileEntityType extends BlockEntityType { +public final class FixedPointTileEntityType extends BlockEntityType +{ private final Supplier block; - private FixedPointTileEntityType(Supplier block, Supplier builder) { - super(builder, Collections.emptySet(), null); + private FixedPointTileEntityType( Supplier block, Supplier builder ) + { + super( builder, Collections.emptySet(), null ); this.block = block; } - public static FixedPointTileEntityType create(Supplier block, Function, T> builder) { - return new FixedPointSupplier<>(block, builder).factory; + public static FixedPointTileEntityType create( Supplier block, Function, T> builder ) + { + return new FixedPointSupplier<>( block, builder ).factory; } @Override - public boolean supports(@Nonnull Block block) { + public boolean supports( @Nonnull Block block ) + { return block == this.block.get(); } - private static final class FixedPointSupplier implements Supplier { + private static final class FixedPointSupplier implements Supplier + { final FixedPointTileEntityType factory; private final Function, T> builder; - private FixedPointSupplier(Supplier block, Function, T> builder) { - this.factory = new FixedPointTileEntityType<>(block, this); + private FixedPointSupplier( Supplier block, Function, T> builder ) + { + this.factory = new FixedPointTileEntityType<>( block, this ); this.builder = builder; } @Override - public T get() { - return this.builder.apply(this.factory); + public T get() + { + return this.builder.apply( this.factory ); } } } diff --git a/src/main/java/dan200/computercraft/shared/util/Holiday.java b/src/main/java/dan200/computercraft/shared/util/Holiday.java index 3cea58e7e..2b1dd385b 100644 --- a/src/main/java/dan200/computercraft/shared/util/Holiday.java +++ b/src/main/java/dan200/computercraft/shared/util/Holiday.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.util; -public enum Holiday { +public enum Holiday +{ NONE, VALENTINES, APRIL_FOOLS_DAY, HALLOWEEN, CHRISTMAS, } diff --git a/src/main/java/dan200/computercraft/shared/util/HolidayUtil.java b/src/main/java/dan200/computercraft/shared/util/HolidayUtil.java index 0e893bde1..e24ce3610 100644 --- a/src/main/java/dan200/computercraft/shared/util/HolidayUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/HolidayUtil.java @@ -8,26 +8,33 @@ package dan200.computercraft.shared.util; import java.util.Calendar; -public final class HolidayUtil { +public final class HolidayUtil +{ private HolidayUtil() {} - public static Holiday getCurrentHoliday() { - return getHoliday(Calendar.getInstance()); + public static Holiday getCurrentHoliday() + { + return getHoliday( Calendar.getInstance() ); } - private static Holiday getHoliday(Calendar calendar) { - int month = calendar.get(Calendar.MONTH); - int day = calendar.get(Calendar.DAY_OF_MONTH); - if (month == Calendar.FEBRUARY && day == 14) { + private static Holiday getHoliday( Calendar calendar ) + { + int month = calendar.get( Calendar.MONTH ); + int day = calendar.get( Calendar.DAY_OF_MONTH ); + if( month == Calendar.FEBRUARY && day == 14 ) + { return Holiday.VALENTINES; } - if (month == Calendar.APRIL && day == 1) { + if( month == Calendar.APRIL && day == 1 ) + { return Holiday.APRIL_FOOLS_DAY; } - if (month == Calendar.OCTOBER && day == 31) { + if( month == Calendar.OCTOBER && day == 31 ) + { return Holiday.HALLOWEEN; } - if (month == Calendar.DECEMBER && day >= 24 && day <= 30) { + if( month == Calendar.DECEMBER && day >= 24 && day <= 30 ) + { return Holiday.CHRISTMAS; } return Holiday.NONE; diff --git a/src/main/java/dan200/computercraft/shared/util/IDAssigner.java b/src/main/java/dan200/computercraft/shared/util/IDAssigner.java index 0ef5db760..b50822b6c 100644 --- a/src/main/java/dan200/computercraft/shared/util/IDAssigner.java +++ b/src/main/java/dan200/computercraft/shared/util/IDAssigner.java @@ -6,6 +6,15 @@ package dan200.computercraft.shared.util; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.fabric.mixin.WorldSavePathAccess; +import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.WorldSavePath; + import java.io.File; import java.io.Reader; import java.io.Writer; @@ -17,85 +26,95 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; -import dan200.computercraft.ComputerCraft; -import dan200.computercraft.fabric.mixin.WorldSavePathAccess; -import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; - -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.WorldSavePath; - -public final class IDAssigner { - private static final WorldSavePath FOLDER = WorldSavePathAccess.createWorldSavePath(ComputerCraft.MOD_ID); +public final class IDAssigner +{ + private static final WorldSavePath FOLDER = WorldSavePathAccess.createWorldSavePath( ComputerCraft.MOD_ID ); private static final Gson GSON = new GsonBuilder().setPrettyPrinting() - .create(); + .create(); private static final Type ID_TOKEN = new TypeToken>() {}.getType(); private static Map ids; private static WeakReference server; private static Path idFile; - private IDAssigner() { + + private IDAssigner() + { } - public static synchronized int getNextId(String kind) { + public static synchronized int getNextId( String kind ) + { MinecraftServer currentServer = getCachedServer(); - if (currentServer == null) { + if( currentServer == null ) + { // The server has changed, refetch our ID map - if (GameInstanceUtils.getServer() != null) { - server = new WeakReference<>(GameInstanceUtils.getServer()); + if( GameInstanceUtils.getServer() != null ) + { + server = new WeakReference<>( GameInstanceUtils.getServer() ); File dir = getDir(); dir.mkdirs(); // Load our ID file from disk - idFile = new File(dir, "ids.json").toPath(); - if (Files.isRegularFile(idFile)) { - try (Reader reader = Files.newBufferedReader(idFile, StandardCharsets.UTF_8)) { - ids = GSON.fromJson(reader, ID_TOKEN); - } catch (Exception e) { - ComputerCraft.log.error("Cannot load id file '" + idFile + "'", e); + idFile = new File( dir, "ids.json" ).toPath(); + if( Files.isRegularFile( idFile ) ) + { + try( Reader reader = Files.newBufferedReader( idFile, StandardCharsets.UTF_8 ) ) + { + ids = GSON.fromJson( reader, ID_TOKEN ); + } + catch( Exception e ) + { + ComputerCraft.log.error( "Cannot load id file '" + idFile + "'", e ); ids = new HashMap<>(); } - } else { + } + else + { ids = new HashMap<>(); } } } - Integer existing = ids.get(kind); + Integer existing = ids.get( kind ); int next = existing == null ? 0 : existing + 1; - ids.put(kind, next); + ids.put( kind, next ); // We've changed the ID file, so save it back again. - try (Writer writer = Files.newBufferedWriter(idFile, StandardCharsets.UTF_8)) { - GSON.toJson(ids, writer); - } catch (Exception e) { - ComputerCraft.log.error("Cannot update ID file '" + idFile + "'", e); + try( Writer writer = Files.newBufferedWriter( idFile, StandardCharsets.UTF_8 ) ) + { + GSON.toJson( ids, writer ); + } + catch( Exception e ) + { + ComputerCraft.log.error( "Cannot update ID file '" + idFile + "'", e ); } return next; } - private static MinecraftServer getCachedServer() { - if (server == null) { + private static MinecraftServer getCachedServer() + { + if( server == null ) + { return null; } MinecraftServer currentServer = server.get(); - if (currentServer == null) { + if( currentServer == null ) + { return null; } - if (currentServer != GameInstanceUtils.getServer()) { + if( currentServer != GameInstanceUtils.getServer() ) + { return null; } return currentServer; } - public static File getDir() { + public static File getDir() + { return GameInstanceUtils.getServer() - .getSavePath(FOLDER) - .toFile(); + .getSavePath( FOLDER ) + .toFile(); } } diff --git a/src/main/java/dan200/computercraft/shared/util/ImpostorRecipe.java b/src/main/java/dan200/computercraft/shared/util/ImpostorRecipe.java index 2ed3f5e8f..2958e421f 100644 --- a/src/main/java/dan200/computercraft/shared/util/ImpostorRecipe.java +++ b/src/main/java/dan200/computercraft/shared/util/ImpostorRecipe.java @@ -6,10 +6,7 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; - import com.google.gson.JsonObject; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; @@ -21,68 +18,82 @@ import net.minecraft.util.JsonHelper; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; -public final class ImpostorRecipe extends ShapedRecipe { - public static final RecipeSerializer SERIALIZER = new RecipeSerializer() { +import javax.annotation.Nonnull; + +public final class ImpostorRecipe extends ShapedRecipe +{ + public static final RecipeSerializer SERIALIZER = new RecipeSerializer() + { @Override - public ImpostorRecipe read(@Nonnull Identifier identifier, @Nonnull JsonObject json) { - String group = JsonHelper.getString(json, "group", ""); - ShapedRecipe recipe = RecipeSerializer.SHAPED.read(identifier, json); - ItemStack result = ShapedRecipe.getItemStack(JsonHelper.getObject(json, "result")); - return new ImpostorRecipe(identifier, group, recipe.getWidth(), recipe.getHeight(), recipe.getPreviewInputs(), result); + public ImpostorRecipe read( @Nonnull Identifier identifier, @Nonnull JsonObject json ) + { + String group = JsonHelper.getString( json, "group", "" ); + ShapedRecipe recipe = RecipeSerializer.SHAPED.read( identifier, json ); + ItemStack result = ShapedRecipe.getItemStack( JsonHelper.getObject( json, "result" ) ); + return new ImpostorRecipe( identifier, group, recipe.getWidth(), recipe.getHeight(), recipe.getPreviewInputs(), result ); } @Override - public ImpostorRecipe read(@Nonnull Identifier identifier, @Nonnull PacketByteBuf buf) { + public ImpostorRecipe read( @Nonnull Identifier identifier, @Nonnull PacketByteBuf buf ) + { int width = buf.readVarInt(); int height = buf.readVarInt(); - String group = buf.readString(Short.MAX_VALUE); - DefaultedList items = DefaultedList.ofSize(width * height, Ingredient.EMPTY); - for (int k = 0; k < items.size(); ++k) { - items.set(k, Ingredient.fromPacket(buf)); + String group = buf.readString( Short.MAX_VALUE ); + DefaultedList items = DefaultedList.ofSize( width * height, Ingredient.EMPTY ); + for( int k = 0; k < items.size(); ++k ) + { + items.set( k, Ingredient.fromPacket( buf ) ); } ItemStack result = buf.readItemStack(); - return new ImpostorRecipe(identifier, group, width, height, items, result); + return new ImpostorRecipe( identifier, group, width, height, items, result ); } @Override - public void write(@Nonnull PacketByteBuf buf, @Nonnull ImpostorRecipe recipe) { - buf.writeVarInt(recipe.getWidth()); - buf.writeVarInt(recipe.getHeight()); - buf.writeString(recipe.getGroup()); - for (Ingredient ingredient : recipe.getPreviewInputs()) { - ingredient.write(buf); + public void write( @Nonnull PacketByteBuf buf, @Nonnull ImpostorRecipe recipe ) + { + buf.writeVarInt( recipe.getWidth() ); + buf.writeVarInt( recipe.getHeight() ); + buf.writeString( recipe.getGroup() ); + for( Ingredient ingredient : recipe.getPreviewInputs() ) + { + ingredient.write( buf ); } - buf.writeItemStack(recipe.getOutput()); + buf.writeItemStack( recipe.getOutput() ); } }; private final String group; - private ImpostorRecipe(@Nonnull Identifier id, @Nonnull String group, int width, int height, DefaultedList ingredients, - @Nonnull ItemStack result) { - super(id, group, width, height, ingredients, result); + private ImpostorRecipe( @Nonnull Identifier id, @Nonnull String group, int width, int height, DefaultedList ingredients, + @Nonnull ItemStack result ) + { + super( id, group, width, height, ingredients, result ); this.group = group; } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } @Nonnull @Override - public String getGroup() { + public String getGroup() + { return this.group; } @Override - public boolean matches(@Nonnull CraftingInventory inv, @Nonnull World world) { + public boolean matches( @Nonnull CraftingInventory inv, @Nonnull World world ) + { return false; } @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inventory) { + public ItemStack craft( @Nonnull CraftingInventory inventory ) + { return ItemStack.EMPTY; } } diff --git a/src/main/java/dan200/computercraft/shared/util/ImpostorShapelessRecipe.java b/src/main/java/dan200/computercraft/shared/util/ImpostorShapelessRecipe.java index 4ebb39cbc..b84e4bfe4 100644 --- a/src/main/java/dan200/computercraft/shared/util/ImpostorShapelessRecipe.java +++ b/src/main/java/dan200/computercraft/shared/util/ImpostorShapelessRecipe.java @@ -6,12 +6,9 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; - import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; - import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; @@ -24,30 +21,40 @@ import net.minecraft.util.JsonHelper; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; -public final class ImpostorShapelessRecipe extends ShapelessRecipe { - public static final RecipeSerializer SERIALIZER = new RecipeSerializer() { +import javax.annotation.Nonnull; + +public final class ImpostorShapelessRecipe extends ShapelessRecipe +{ + public static final RecipeSerializer SERIALIZER = new RecipeSerializer() + { @Override - public ImpostorShapelessRecipe read(@Nonnull Identifier id, @Nonnull JsonObject json) { - String s = JsonHelper.getString(json, "group", ""); - DefaultedList ingredients = this.readIngredients(JsonHelper.getArray(json, "ingredients")); + public ImpostorShapelessRecipe read( @Nonnull Identifier id, @Nonnull JsonObject json ) + { + String s = JsonHelper.getString( json, "group", "" ); + DefaultedList ingredients = this.readIngredients( JsonHelper.getArray( json, "ingredients" ) ); - if (ingredients.isEmpty()) { - throw new JsonParseException("No ingredients for shapeless recipe"); + if( ingredients.isEmpty() ) + { + throw new JsonParseException( "No ingredients for shapeless recipe" ); } - if (ingredients.size() > 9) { - throw new JsonParseException("Too many ingredients for shapeless recipe the max is 9"); + if( ingredients.size() > 9 ) + { + throw new JsonParseException( "Too many ingredients for shapeless recipe the max is 9" ); } - ItemStack itemstack = ShapedRecipe.getItemStack(JsonHelper.getObject(json, "result")); - return new ImpostorShapelessRecipe(id, s, itemstack, ingredients); + ItemStack itemstack = ShapedRecipe.getItemStack( JsonHelper.getObject( json, "result" ) ); + return new ImpostorShapelessRecipe( id, s, itemstack, ingredients ); } - private DefaultedList readIngredients(JsonArray arrays) { + private DefaultedList readIngredients( JsonArray arrays ) + { DefaultedList items = DefaultedList.of(); - for (int i = 0; i < arrays.size(); ++i) { - Ingredient ingredient = Ingredient.fromJson(arrays.get(i)); - if (!ingredient.isEmpty()) { - items.add(ingredient); + for( int i = 0; i < arrays.size(); ++i ) + { + Ingredient ingredient = Ingredient.fromJson( arrays.get( i ) ); + if( !ingredient.isEmpty() ) + { + items.add( ingredient ); } } @@ -55,58 +62,67 @@ public final class ImpostorShapelessRecipe extends ShapelessRecipe { } @Override - public ImpostorShapelessRecipe read(@Nonnull Identifier id, PacketByteBuf buffer) { - String s = buffer.readString(32767); + public ImpostorShapelessRecipe read( @Nonnull Identifier id, PacketByteBuf buffer ) + { + String s = buffer.readString( 32767 ); int i = buffer.readVarInt(); - DefaultedList items = DefaultedList.ofSize(i, Ingredient.EMPTY); + DefaultedList items = DefaultedList.ofSize( i, Ingredient.EMPTY ); - for (int j = 0; j < items.size(); j++) { - items.set(j, Ingredient.fromPacket(buffer)); + for( int j = 0; j < items.size(); j++ ) + { + items.set( j, Ingredient.fromPacket( buffer ) ); } ItemStack result = buffer.readItemStack(); - return new ImpostorShapelessRecipe(id, s, result, items); + return new ImpostorShapelessRecipe( id, s, result, items ); } @Override - public void write(@Nonnull PacketByteBuf buffer, @Nonnull ImpostorShapelessRecipe recipe) { - buffer.writeString(recipe.getGroup()); - buffer.writeVarInt(recipe.getPreviewInputs() - .size()); + public void write( @Nonnull PacketByteBuf buffer, @Nonnull ImpostorShapelessRecipe recipe ) + { + buffer.writeString( recipe.getGroup() ); + buffer.writeVarInt( recipe.getPreviewInputs() + .size() ); - for (Ingredient ingredient : recipe.getPreviewInputs()) { - ingredient.write(buffer); + for( Ingredient ingredient : recipe.getPreviewInputs() ) + { + ingredient.write( buffer ); } - buffer.writeItemStack(recipe.getOutput()); + buffer.writeItemStack( recipe.getOutput() ); } }; private final String group; - private ImpostorShapelessRecipe(@Nonnull Identifier id, @Nonnull String group, @Nonnull ItemStack result, DefaultedList ingredients) { - super(id, group, result, ingredients); + private ImpostorShapelessRecipe( @Nonnull Identifier id, @Nonnull String group, @Nonnull ItemStack result, DefaultedList ingredients ) + { + super( id, group, result, ingredients ); this.group = group; } @Nonnull @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() + { return SERIALIZER; } @Nonnull @Override - public String getGroup() { + public String getGroup() + { return this.group; } @Override - public boolean matches(@Nonnull CraftingInventory inv, @Nonnull World world) { + public boolean matches( @Nonnull CraftingInventory inv, @Nonnull World world ) + { return false; } @Nonnull @Override - public ItemStack craft(@Nonnull CraftingInventory inventory) { + public ItemStack craft( @Nonnull CraftingInventory inventory ) + { return ItemStack.EMPTY; } } diff --git a/src/main/java/dan200/computercraft/shared/util/InventoryDelegate.java b/src/main/java/dan200/computercraft/shared/util/InventoryDelegate.java index 935755ca5..f66bb98d4 100644 --- a/src/main/java/dan200/computercraft/shared/util/InventoryDelegate.java +++ b/src/main/java/dan200/computercraft/shared/util/InventoryDelegate.java @@ -6,15 +6,14 @@ package dan200.computercraft.shared.util; -import java.util.Set; - -import javax.annotation.Nonnull; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import javax.annotation.Nonnull; +import java.util.Set; + /** * Provides a delegate over inventories. * @@ -22,84 +21,100 @@ import net.minecraft.item.ItemStack; * inventories which change their backing store. */ @FunctionalInterface -public interface InventoryDelegate extends Inventory { +public interface InventoryDelegate extends Inventory +{ @Override - default int size() { + default int size() + { return this.getInventory().size(); } Inventory getInventory(); @Override - default boolean isEmpty() { + default boolean isEmpty() + { return this.getInventory().isEmpty(); } @Nonnull @Override - default ItemStack getStack(int slot) { - return this.getInventory().getStack(slot); + default ItemStack getStack( int slot ) + { + return this.getInventory().getStack( slot ); } @Nonnull @Override - default ItemStack removeStack(int slot, int count) { - return this.getInventory().removeStack(slot, count); + default ItemStack removeStack( int slot, int count ) + { + return this.getInventory().removeStack( slot, count ); } @Nonnull @Override - default ItemStack removeStack(int slot) { - return this.getInventory().removeStack(slot); + default ItemStack removeStack( int slot ) + { + return this.getInventory().removeStack( slot ); } @Override - default void setStack(int slot, @Nonnull ItemStack stack) { - this.getInventory().setStack(slot, stack); + default void setStack( int slot, @Nonnull ItemStack stack ) + { + this.getInventory().setStack( slot, stack ); } @Override - default int getMaxCountPerStack() { + default int getMaxCountPerStack() + { return this.getInventory().getMaxCountPerStack(); } @Override - default void markDirty() { + default void markDirty() + { this.getInventory().markDirty(); } @Override - default boolean canPlayerUse(@Nonnull PlayerEntity player) { - return this.getInventory().canPlayerUse(player); + default boolean canPlayerUse( @Nonnull PlayerEntity player ) + { + return this.getInventory().canPlayerUse( player ); } @Override - default void onOpen(@Nonnull PlayerEntity player) { - this.getInventory().onOpen(player); + default void onOpen( @Nonnull PlayerEntity player ) + { + this.getInventory().onOpen( player ); } @Override - default void onClose(@Nonnull PlayerEntity player) { - this.getInventory().onClose(player); + default void onClose( @Nonnull PlayerEntity player ) + { + this.getInventory().onClose( player ); } @Override - default boolean isValid(int slot, @Nonnull ItemStack stack) { - return this.getInventory().isValid(slot, stack); + default boolean isValid( int slot, @Nonnull ItemStack stack ) + { + return this.getInventory().isValid( slot, stack ); } @Override - default int count(@Nonnull Item stack) { - return this.getInventory().count(stack); + default int count( @Nonnull Item stack ) + { + return this.getInventory().count( stack ); } @Override - default boolean containsAny(@Nonnull Set set) { - return this.getInventory().containsAny(set); + default boolean containsAny( @Nonnull Set set ) + { + return this.getInventory().containsAny( set ); } @Override - default void clear() { + default void clear() + { this.getInventory().clear(); } } diff --git a/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java b/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java index 9eac0209e..e7bf6f8d0 100644 --- a/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java @@ -6,16 +6,12 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ChestBlock; import net.minecraft.block.InventoryProvider; -import net.minecraft.block.entity.ChestBlockEntity; -import org.apache.commons.lang3.tuple.Pair; - import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.ChestBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; @@ -23,64 +19,79 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; -public final class InventoryUtil { +import javax.annotation.Nonnull; + +public final class InventoryUtil +{ private InventoryUtil() {} // Methods for comparing things: - public static boolean areItemsStackable(@Nonnull ItemStack a, @Nonnull ItemStack b) { - return a == b || (a.getItem() == b.getItem() && ItemStack.areTagsEqual(a, b)); + public static boolean areItemsStackable( @Nonnull ItemStack a, @Nonnull ItemStack b ) + { + return a == b || (a.getItem() == b.getItem() && ItemStack.areTagsEqual( a, b )); } // Methods for finding inventories: - public static Inventory getInventory(World world, BlockPos pos, Direction side) { + public static Inventory getInventory( World world, BlockPos pos, Direction side ) + { // Look for tile with inventory int y = pos.getY(); - if (y >= 0 && y < world.getHeight()) { + if( y >= 0 && y < world.getHeight() ) + { // Check if block is InventoryProvider - BlockState blockState = world.getBlockState(pos); + BlockState blockState = world.getBlockState( pos ); Block block = blockState.getBlock(); - if (block instanceof InventoryProvider) { - return ((InventoryProvider)block).getInventory(blockState, world, pos); + if( block instanceof InventoryProvider ) + { + return ((InventoryProvider) block).getInventory( blockState, world, pos ); } // Check if block is BlockEntity w/ Inventory - if (block.hasBlockEntity()) { - BlockEntity tileEntity = world.getBlockEntity(pos); + if( block.hasBlockEntity() ) + { + BlockEntity tileEntity = world.getBlockEntity( pos ); - Inventory inventory = getInventory(tileEntity); - if (inventory != null) { + Inventory inventory = getInventory( tileEntity ); + if( inventory != null ) + { return inventory; } } } // Look for entity with inventory - Vec3d vecStart = new Vec3d(pos.getX() + 0.5 + 0.6 * side.getOffsetX(), - pos.getY() + 0.5 + 0.6 * side.getOffsetY(), - pos.getZ() + 0.5 + 0.6 * side.getOffsetZ()); + Vec3d vecStart = new Vec3d( pos.getX() + 0.5 + 0.6 * side.getOffsetX(), + pos.getY() + 0.5 + 0.6 * side.getOffsetY(), + pos.getZ() + 0.5 + 0.6 * side.getOffsetZ() ); Direction dir = side.getOpposite(); - Vec3d vecDir = new Vec3d(dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ()); - Pair hit = WorldUtil.rayTraceEntities(world, vecStart, vecDir, 1.1); - if (hit != null) { + Vec3d vecDir = new Vec3d( dir.getOffsetX(), dir.getOffsetY(), dir.getOffsetZ() ); + Pair hit = WorldUtil.rayTraceEntities( world, vecStart, vecDir, 1.1 ); + if( hit != null ) + { Entity entity = hit.getKey(); - if (entity instanceof Inventory) { + if( entity instanceof Inventory ) + { return (Inventory) entity; } } return null; } - public static Inventory getInventory(BlockEntity tileEntity) { + public static Inventory getInventory( BlockEntity tileEntity ) + { World world = tileEntity.getWorld(); BlockPos pos = tileEntity.getPos(); - BlockState blockState = world.getBlockState(pos); + BlockState blockState = world.getBlockState( pos ); Block block = blockState.getBlock(); - if (tileEntity instanceof Inventory) { - Inventory inventory = (Inventory)tileEntity; - if (inventory instanceof ChestBlockEntity && block instanceof ChestBlock) { - return ChestBlock.getInventory((ChestBlock) block, blockState, world, pos, true); + if( tileEntity instanceof Inventory ) + { + Inventory inventory = (Inventory) tileEntity; + if( inventory instanceof ChestBlockEntity && block instanceof ChestBlock ) + { + return ChestBlock.getInventory( (ChestBlock) block, blockState, world, pos, true ); } return inventory; } @@ -89,69 +100,84 @@ public final class InventoryUtil { } @Nonnull - public static ItemStack storeItems(@Nonnull ItemStack itemstack, ItemStorage inventory, int begin) { - return storeItems(itemstack, inventory, 0, inventory.size(), begin); + public static ItemStack storeItems( @Nonnull ItemStack itemstack, ItemStorage inventory, int begin ) + { + return storeItems( itemstack, inventory, 0, inventory.size(), begin ); } // Methods for placing into inventories: @Nonnull - public static ItemStack storeItems(@Nonnull ItemStack stack, ItemStorage inventory, int start, int range, int begin) { - if (stack.isEmpty()) { + public static ItemStack storeItems( @Nonnull ItemStack stack, ItemStorage inventory, int start, int range, int begin ) + { + if( stack.isEmpty() ) + { return ItemStack.EMPTY; } // Inspect the slots in order and try to find empty or stackable slots ItemStack remainder = stack.copy(); - for (int i = 0; i < range; i++) { + for( int i = 0; i < range; i++ ) + { int slot = start + (i + begin - start) % range; - if (remainder.isEmpty()) { + if( remainder.isEmpty() ) + { break; } - remainder = inventory.store(slot, remainder, false); + remainder = inventory.store( slot, remainder, false ); } - return areItemsEqual(stack, remainder) ? stack : remainder; + return areItemsEqual( stack, remainder ) ? stack : remainder; } - public static boolean areItemsEqual(@Nonnull ItemStack a, @Nonnull ItemStack b) { - return a == b || ItemStack.areEqual(a, b); + public static boolean areItemsEqual( @Nonnull ItemStack a, @Nonnull ItemStack b ) + { + return a == b || ItemStack.areEqual( a, b ); } @Nonnull - public static ItemStack storeItems(@Nonnull ItemStack itemstack, ItemStorage inventory) { - return storeItems(itemstack, inventory, 0, inventory.size(), 0); + public static ItemStack storeItems( @Nonnull ItemStack itemstack, ItemStorage inventory ) + { + return storeItems( itemstack, inventory, 0, inventory.size(), 0 ); } // Methods for taking out of inventories @Nonnull - public static ItemStack takeItems(int count, ItemStorage inventory, int begin) { - return takeItems(count, inventory, 0, inventory.size(), begin); + public static ItemStack takeItems( int count, ItemStorage inventory, int begin ) + { + return takeItems( count, inventory, 0, inventory.size(), begin ); } @Nonnull - public static ItemStack takeItems(int count, ItemStorage inventory, int start, int range, int begin) { + public static ItemStack takeItems( int count, ItemStorage inventory, int start, int range, int begin ) + { ItemStack partialStack = ItemStack.EMPTY; - for (int i = 0; i < range; i++) { + for( int i = 0; i < range; i++ ) + { int slot = start + (i + begin - start) % range; - if (count <= 0) { + if( count <= 0 ) + { break; } // If this doesn't slot, abort. - ItemStack extracted = inventory.take(slot, count, partialStack, false); - if (extracted.isEmpty()) { + ItemStack extracted = inventory.take( slot, count, partialStack, false ); + if( extracted.isEmpty() ) + { continue; } count -= extracted.getCount(); - if (partialStack.isEmpty()) { + if( partialStack.isEmpty() ) + { // If we've extracted for this first time, then limit the count to the maximum stack size. partialStack = extracted; - count = Math.min(count, extracted.getMaxCount()); - } else { - partialStack.increment(extracted.getCount()); + count = Math.min( count, extracted.getMaxCount() ); + } + else + { + partialStack.increment( extracted.getCount() ); } } @@ -159,7 +185,8 @@ public final class InventoryUtil { } @Nonnull - public static ItemStack takeItems(int count, ItemStorage inventory) { - return takeItems(count, inventory, 0, inventory.size(), 0); + public static ItemStack takeItems( int count, ItemStorage inventory ) + { + return takeItems( count, inventory, 0, inventory.size(), 0 ); } } diff --git a/src/main/java/dan200/computercraft/shared/util/IoUtil.java b/src/main/java/dan200/computercraft/shared/util/IoUtil.java index 30a89a935..eb915596b 100644 --- a/src/main/java/dan200/computercraft/shared/util/IoUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/IoUtil.java @@ -6,20 +6,25 @@ package dan200.computercraft.shared.util; +import javax.annotation.Nullable; import java.io.Closeable; import java.io.IOException; -import javax.annotation.Nullable; - -public final class IoUtil { +public final class IoUtil +{ private IoUtil() {} - public static void closeQuietly(@Nullable Closeable closeable) { - try { - if (closeable != null) { + public static void closeQuietly( @Nullable Closeable closeable ) + { + try + { + if( closeable != null ) + { closeable.close(); } - } catch (IOException ignored) { + } + catch( IOException ignored ) + { } } } diff --git a/src/main/java/dan200/computercraft/shared/util/ItemStorage.java b/src/main/java/dan200/computercraft/shared/util/ItemStorage.java index b5cbd096a..f0787f61d 100644 --- a/src/main/java/dan200/computercraft/shared/util/ItemStorage.java +++ b/src/main/java/dan200/computercraft/shared/util/ItemStorage.java @@ -5,242 +5,299 @@ */ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; - import net.minecraft.inventory.Inventory; import net.minecraft.inventory.SidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.util.math.Direction; +import javax.annotation.Nonnull; + /** * The most cutesy alternative of {@code IItemHandler} the world has ever seen. */ -public interface ItemStorage { - static ItemStorage wrap(Inventory inventory) { - return new InventoryWrapper(inventory); +public interface ItemStorage +{ + static ItemStorage wrap( Inventory inventory ) + { + return new InventoryWrapper( inventory ); } - static ItemStorage wrap(@Nonnull SidedInventory inventory, @Nonnull Direction facing) { - return new SidedInventoryWrapper(inventory, facing); + static ItemStorage wrap( @Nonnull SidedInventory inventory, @Nonnull Direction facing ) + { + return new SidedInventoryWrapper( inventory, facing ); } - static ItemStorage wrap(@Nonnull Inventory inventory, @Nonnull Direction facing) { - return inventory instanceof SidedInventory ? new SidedInventoryWrapper((SidedInventory) inventory, facing) : new InventoryWrapper(inventory); + static ItemStorage wrap( @Nonnull Inventory inventory, @Nonnull Direction facing ) + { + return inventory instanceof SidedInventory ? new SidedInventoryWrapper( (SidedInventory) inventory, facing ) : new InventoryWrapper( inventory ); } - static boolean areStackable(@Nonnull ItemStack a, @Nonnull ItemStack b) { - return a == b || (a.getItem() == b.getItem() && ItemStack.areTagsEqual(a, b)); + static boolean areStackable( @Nonnull ItemStack a, @Nonnull ItemStack b ) + { + return a == b || (a.getItem() == b.getItem() && ItemStack.areTagsEqual( a, b )); } int size(); @Nonnull - ItemStack getStack(int slot); + ItemStack getStack( int slot ); @Nonnull - ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate); + ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate ); @Nonnull - ItemStack store(int slot, @Nonnull ItemStack stack, boolean simulate); + ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate ); - default ItemStorage view(int start, int size) { - return new View(this, start, size); + default ItemStorage view( int start, int size ) + { + return new View( this, start, size ); } - class InventoryWrapper implements ItemStorage { + class InventoryWrapper implements ItemStorage + { private final Inventory inventory; - InventoryWrapper(Inventory inventory) { + InventoryWrapper( Inventory inventory ) + { this.inventory = inventory; } @Override - public int size() { + public int size() + { return this.inventory.size(); } @Override @Nonnull - public ItemStack getStack(int slot) { - return this.inventory.getStack(slot); + public ItemStack getStack( int slot ) + { + return this.inventory.getStack( slot ); } @Override @Nonnull - public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) { - ItemStack existing = this.inventory.getStack(slot); - if (existing.isEmpty() || !this.canExtract(slot, existing) || (!filter.isEmpty() && !areStackable(existing, filter))) { + public ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate ) + { + ItemStack existing = this.inventory.getStack( slot ); + if( existing.isEmpty() || !this.canExtract( slot, existing ) || (!filter.isEmpty() && !areStackable( existing, filter )) ) + { return ItemStack.EMPTY; } - if (simulate) { + if( simulate ) + { existing = existing.copy(); - if (existing.getCount() > limit) { - existing.setCount(limit); + if( existing.getCount() > limit ) + { + existing.setCount( limit ); } return existing; - } else if (existing.getCount() < limit) { - this.setAndDirty(slot, ItemStack.EMPTY); + } + else if( existing.getCount() < limit ) + { + this.setAndDirty( slot, ItemStack.EMPTY ); return existing; - } else { - ItemStack result = existing.split(limit); - this.setAndDirty(slot, existing); + } + else + { + ItemStack result = existing.split( limit ); + this.setAndDirty( slot, existing ); return result; } } - protected boolean canExtract(int slot, ItemStack stack) { + protected boolean canExtract( int slot, ItemStack stack ) + { return true; } - private void setAndDirty(int slot, @Nonnull ItemStack stack) { - this.inventory.setStack(slot, stack); + private void setAndDirty( int slot, @Nonnull ItemStack stack ) + { + this.inventory.setStack( slot, stack ); this.inventory.markDirty(); } @Override @Nonnull - public ItemStack store(int slot, @Nonnull ItemStack stack, boolean simulate) { - if (stack.isEmpty() || !this.inventory.isValid(slot, stack)) { + public ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate ) + { + if( stack.isEmpty() || !this.inventory.isValid( slot, stack ) ) + { return stack; } - ItemStack existing = this.inventory.getStack(slot); - if (existing.isEmpty()) { - int limit = Math.min(stack.getMaxCount(), this.inventory.getMaxCountPerStack()); - if (limit <= 0) { + ItemStack existing = this.inventory.getStack( slot ); + if( existing.isEmpty() ) + { + int limit = Math.min( stack.getMaxCount(), this.inventory.getMaxCountPerStack() ); + if( limit <= 0 ) + { return stack; } - if (stack.getCount() < limit) { - if (!simulate) { - this.setAndDirty(slot, stack); + if( stack.getCount() < limit ) + { + if( !simulate ) + { + this.setAndDirty( slot, stack ); } return ItemStack.EMPTY; - } else { + } + else + { stack = stack.copy(); - ItemStack insert = stack.split(limit); - if (!simulate) { - this.setAndDirty(slot, insert); + ItemStack insert = stack.split( limit ); + if( !simulate ) + { + this.setAndDirty( slot, insert ); } return stack; } - } else if (areStackable(stack, existing)) { - int limit = Math.min(existing.getMaxCount(), this.inventory.getMaxCountPerStack()) - existing.getCount(); - if (limit <= 0) { + } + else if( areStackable( stack, existing ) ) + { + int limit = Math.min( existing.getMaxCount(), this.inventory.getMaxCountPerStack() ) - existing.getCount(); + if( limit <= 0 ) + { return stack; } - if (stack.getCount() < limit) { - if (!simulate) { - existing.increment(stack.getCount()); - this.setAndDirty(slot, existing); + if( stack.getCount() < limit ) + { + if( !simulate ) + { + existing.increment( stack.getCount() ); + this.setAndDirty( slot, existing ); } return ItemStack.EMPTY; - } else { + } + else + { stack = stack.copy(); - stack.decrement(limit); - if (!simulate) { - existing.increment(limit); - this.setAndDirty(slot, existing); + stack.decrement( limit ); + if( !simulate ) + { + existing.increment( limit ); + this.setAndDirty( slot, existing ); } return stack; } - } else { + } + else + { return stack; } } } - class SidedInventoryWrapper extends InventoryWrapper { + class SidedInventoryWrapper extends InventoryWrapper + { private final SidedInventory inventory; private final Direction facing; - SidedInventoryWrapper(SidedInventory inventory, Direction facing) { - super(inventory); + SidedInventoryWrapper( SidedInventory inventory, Direction facing ) + { + super( inventory ); this.inventory = inventory; this.facing = facing; } @Override - protected boolean canExtract(int slot, ItemStack stack) { - return super.canExtract(slot, stack) && this.inventory.canExtract(slot, stack, this.facing); + protected boolean canExtract( int slot, ItemStack stack ) + { + return super.canExtract( slot, stack ) && this.inventory.canExtract( slot, stack, this.facing ); } @Override - public int size() { - return this.inventory.getAvailableSlots(this.facing).length; + public int size() + { + return this.inventory.getAvailableSlots( this.facing ).length; } @Nonnull @Override - public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) { - int[] slots = this.inventory.getAvailableSlots(this.facing); - return slot >= 0 && slot < slots.length ? super.take(slots[slot], limit, filter, simulate) : ItemStack.EMPTY; + public ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate ) + { + int[] slots = this.inventory.getAvailableSlots( this.facing ); + return slot >= 0 && slot < slots.length ? super.take( slots[slot], limit, filter, simulate ) : ItemStack.EMPTY; } @Nonnull @Override - public ItemStack store(int slot, @Nonnull ItemStack stack, boolean simulate) { - int[] slots = this.inventory.getAvailableSlots(this.facing); - if (slot < 0 || slot >= slots.length) { + public ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate ) + { + int[] slots = this.inventory.getAvailableSlots( this.facing ); + if( slot < 0 || slot >= slots.length ) + { return stack; } int mappedSlot = slots[slot]; - if (!this.inventory.canInsert(slot, stack, this.facing)) { + if( !this.inventory.canInsert( slot, stack, this.facing ) ) + { return stack; } - return super.store(mappedSlot, stack, simulate); + return super.store( mappedSlot, stack, simulate ); } } - class View implements ItemStorage { + class View implements ItemStorage + { private final ItemStorage parent; private final int start; private final int size; - View(ItemStorage parent, int start, int size) { + View( ItemStorage parent, int start, int size ) + { this.parent = parent; this.start = start; this.size = size; } @Override - public int size() { + public int size() + { return this.size; } @Override @Nonnull - public ItemStack getStack(int slot) { - if (slot < this.start || slot >= this.start + this.size) { + public ItemStack getStack( int slot ) + { + if( slot < this.start || slot >= this.start + this.size ) + { return ItemStack.EMPTY; } - return this.parent.getStack(slot - this.start ); + return this.parent.getStack( slot - this.start ); } @Nonnull @Override - public ItemStack take(int slot, int limit, @Nonnull ItemStack filter, boolean simulate) { - if (slot < this.start || slot >= this.start + this.size) { + public ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate ) + { + if( slot < this.start || slot >= this.start + this.size ) + { return ItemStack.EMPTY; } - return this.parent.take(slot - this.start, limit, filter, simulate); + return this.parent.take( slot - this.start, limit, filter, simulate ); } @Nonnull @Override - public ItemStack store(int slot, @Nonnull ItemStack stack, boolean simulate) { - if (slot < this.start || slot >= this.start + this.size) { + public ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate ) + { + if( slot < this.start || slot >= this.start + this.size ) + { return stack; } - return this.parent.store(slot - this.start, stack, simulate); + return this.parent.store( slot - this.start, stack, simulate ); } @Override - public ItemStorage view(int start, int size) { - return new View(this.parent, this.start + start, size); + public ItemStorage view( int start, int size ) + { + return new View( this.parent, this.start + start, size ); } } } diff --git a/src/main/java/dan200/computercraft/shared/util/NBTUtil.java b/src/main/java/dan200/computercraft/shared/util/NBTUtil.java index f2cef4ae2..99f39d71c 100644 --- a/src/main/java/dan200/computercraft/shared/util/NBTUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/NBTUtil.java @@ -6,6 +6,12 @@ package dan200.computercraft.shared.util; +import dan200.computercraft.ComputerCraft; +import net.minecraft.nbt.*; +import org.apache.commons.codec.binary.Hex; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.DataOutput; import java.io.DataOutputStream; import java.io.IOException; @@ -15,24 +21,8 @@ import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import dan200.computercraft.ComputerCraft; -import org.apache.commons.codec.binary.Hex; - -import net.minecraft.nbt.AbstractNumberTag; -import net.minecraft.nbt.ByteArrayTag; -import net.minecraft.nbt.ByteTag; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.DoubleTag; -import net.minecraft.nbt.IntArrayTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtIo; -import net.minecraft.nbt.StringTag; -import net.minecraft.nbt.Tag; - -public final class NBTUtil { +public final class NBTUtil +{ public static final int TAG_END = 0; public static final int TAG_BYTE = 1; public static final int TAG_SHORT = 2; @@ -50,191 +40,233 @@ public final class NBTUtil { private NBTUtil() {} - private static Tag toNBTTag(Object object) { - if (object == null) { + private static Tag toNBTTag( Object object ) + { + if( object == null ) + { return null; } - if (object instanceof Boolean) { - return ByteTag.of((byte) ((boolean) (Boolean) object ? 1 : 0)); + if( object instanceof Boolean ) + { + return ByteTag.of( (byte) ((boolean) (Boolean) object ? 1 : 0) ); } - if (object instanceof Number) { - return DoubleTag.of(((Number) object).doubleValue()); + if( object instanceof Number ) + { + return DoubleTag.of( ((Number) object).doubleValue() ); } - if (object instanceof String) { - return StringTag.of(object.toString()); + if( object instanceof String ) + { + return StringTag.of( object.toString() ); } - if (object instanceof Map) { + if( object instanceof Map ) + { Map m = (Map) object; CompoundTag nbt = new CompoundTag(); int i = 0; - for (Map.Entry entry : m.entrySet()) { - Tag key = toNBTTag(entry.getKey()); - Tag value = toNBTTag(entry.getKey()); - if (key != null && value != null) { - nbt.put("k" + i, key); - nbt.put("v" + i, value); + for( Map.Entry entry : m.entrySet() ) + { + Tag key = toNBTTag( entry.getKey() ); + Tag value = toNBTTag( entry.getKey() ); + if( key != null && value != null ) + { + nbt.put( "k" + i, key ); + nbt.put( "v" + i, value ); i++; } } - nbt.putInt("len", m.size()); + nbt.putInt( "len", m.size() ); return nbt; } return null; } - public static CompoundTag encodeObjects(Object[] objects) { - if (objects == null || objects.length <= 0) { + public static CompoundTag encodeObjects( Object[] objects ) + { + if( objects == null || objects.length <= 0 ) + { return null; } CompoundTag nbt = new CompoundTag(); - nbt.putInt("len", objects.length); - for (int i = 0; i < objects.length; i++) { - Tag child = toNBTTag(objects[i]); - if (child != null) { - nbt.put(Integer.toString(i), child); + nbt.putInt( "len", objects.length ); + for( int i = 0; i < objects.length; i++ ) + { + Tag child = toNBTTag( objects[i] ); + if( child != null ) + { + nbt.put( Integer.toString( i ), child ); } } return nbt; } - private static Object fromNBTTag(Tag tag) { - if (tag == null) { + private static Object fromNBTTag( Tag tag ) + { + if( tag == null ) + { return null; } - switch (tag.getType()) { - case TAG_BYTE: - return ((ByteTag) tag).getByte() > 0; - case TAG_DOUBLE: - return ((DoubleTag) tag).getDouble(); - default: - case TAG_STRING: - return tag.asString(); - case TAG_COMPOUND: { - CompoundTag c = (CompoundTag) tag; - int len = c.getInt("len"); - Map map = new HashMap<>(len); - for (int i = 0; i < len; i++) { - Object key = fromNBTTag(c.get("k" + i)); - Object value = fromNBTTag(c.get("v" + i)); - if (key != null && value != null) { - map.put(key, value); + switch( tag.getType() ) + { + case TAG_BYTE: + return ((ByteTag) tag).getByte() > 0; + case TAG_DOUBLE: + return ((DoubleTag) tag).getDouble(); + default: + case TAG_STRING: + return tag.asString(); + case TAG_COMPOUND: + { + CompoundTag c = (CompoundTag) tag; + int len = c.getInt( "len" ); + Map map = new HashMap<>( len ); + for( int i = 0; i < len; i++ ) + { + Object key = fromNBTTag( c.get( "k" + i ) ); + Object value = fromNBTTag( c.get( "v" + i ) ); + if( key != null && value != null ) + { + map.put( key, value ); + } } + return map; } - return map; - } } } - public static Object toLua(Tag tag) { - if (tag == null) { + public static Object toLua( Tag tag ) + { + if( tag == null ) + { return null; } byte typeID = tag.getType(); - switch (typeID) { - case TAG_BYTE: - case TAG_SHORT: - case TAG_INT: - case TAG_LONG: - return ((AbstractNumberTag) tag).getLong(); - case TAG_FLOAT: - case TAG_DOUBLE: - return ((AbstractNumberTag) tag).getDouble(); - case TAG_STRING: // String - return tag.asString(); - case TAG_COMPOUND: // Compound + switch( typeID ) { - CompoundTag compound = (CompoundTag) tag; - Map map = new HashMap<>(compound.getSize()); - for (String key : compound.getKeys()) { - Object value = toLua(compound.get(key)); - if (value != null) { - map.put(key, value); + case TAG_BYTE: + case TAG_SHORT: + case TAG_INT: + case TAG_LONG: + return ((AbstractNumberTag) tag).getLong(); + case TAG_FLOAT: + case TAG_DOUBLE: + return ((AbstractNumberTag) tag).getDouble(); + case TAG_STRING: // String + return tag.asString(); + case TAG_COMPOUND: // Compound + { + CompoundTag compound = (CompoundTag) tag; + Map map = new HashMap<>( compound.getSize() ); + for( String key : compound.getKeys() ) + { + Object value = toLua( compound.get( key ) ); + if( value != null ) + { + map.put( key, value ); + } } + return map; } - return map; - } - case TAG_LIST: { - ListTag list = (ListTag) tag; - Map map = new HashMap<>(list.size()); - for (int i = 0; i < list.size(); i++) { - map.put(i, toLua(list.get(i))); + case TAG_LIST: + { + ListTag list = (ListTag) tag; + Map map = new HashMap<>( list.size() ); + for( int i = 0; i < list.size(); i++ ) + { + map.put( i, toLua( list.get( i ) ) ); + } + return map; } - return map; - } - case TAG_BYTE_ARRAY: { - byte[] array = ((ByteArrayTag) tag).getByteArray(); - Map map = new HashMap<>(array.length); - for (int i = 0; i < array.length; i++) { - map.put(i + 1, array[i]); + case TAG_BYTE_ARRAY: + { + byte[] array = ((ByteArrayTag) tag).getByteArray(); + Map map = new HashMap<>( array.length ); + for( int i = 0; i < array.length; i++ ) + { + map.put( i + 1, array[i] ); + } + return map; } - return map; - } - case TAG_INT_ARRAY: { - int[] array = ((IntArrayTag) tag).getIntArray(); - Map map = new HashMap<>(array.length); - for (int i = 0; i < array.length; i++) { - map.put(i + 1, array[i]); + case TAG_INT_ARRAY: + { + int[] array = ((IntArrayTag) tag).getIntArray(); + Map map = new HashMap<>( array.length ); + for( int i = 0; i < array.length; i++ ) + { + map.put( i + 1, array[i] ); + } + return map; } - return map; - } - default: - return null; + default: + return null; } } - public static Object[] decodeObjects(CompoundTag tag) { - int len = tag.getInt("len"); - if (len <= 0) { + public static Object[] decodeObjects( CompoundTag tag ) + { + int len = tag.getInt( "len" ); + if( len <= 0 ) + { return null; } Object[] objects = new Object[len]; - for (int i = 0; i < len; i++) { - String key = Integer.toString(i); - if (tag.contains(key)) { - objects[i] = fromNBTTag(tag.get(key)); + for( int i = 0; i < len; i++ ) + { + String key = Integer.toString( i ); + if( tag.contains( key ) ) + { + objects[i] = fromNBTTag( tag.get( key ) ); } } return objects; } @Nullable - public static String getNBTHash(@Nullable CompoundTag tag) { - if (tag == null) { + public static String getNBTHash( @Nullable CompoundTag tag ) + { + if( tag == null ) + { return null; } - try { - MessageDigest digest = MessageDigest.getInstance("MD5"); - DataOutput output = new DataOutputStream(new DigestOutputStream(digest)); - NbtIo.write(tag, output); + try + { + MessageDigest digest = MessageDigest.getInstance( "MD5" ); + DataOutput output = new DataOutputStream( new DigestOutputStream( digest ) ); + NbtIo.write( tag, output ); byte[] hash = digest.digest(); - return new String(Hex.encodeHex(hash)); - } catch (NoSuchAlgorithmException | IOException e) { - ComputerCraft.log.error("Cannot hash NBT", e); + return new String( Hex.encodeHex( hash ) ); + } + catch( NoSuchAlgorithmException | IOException e ) + { + ComputerCraft.log.error( "Cannot hash NBT", e ); return null; } } - private static final class DigestOutputStream extends OutputStream { + private static final class DigestOutputStream extends OutputStream + { private final MessageDigest digest; - DigestOutputStream(MessageDigest digest) { + DigestOutputStream( MessageDigest digest ) + { this.digest = digest; } @Override - public void write(int b) { - this.digest.update((byte) b); + public void write( int b ) + { + this.digest.update( (byte) b ); } @Override - public void write(@Nonnull byte[] b, int off, int len) { - this.digest.update(b, off, len); + public void write( @Nonnull byte[] b, int off, int len ) + { + this.digest.update( b, off, len ); } } } diff --git a/src/main/java/dan200/computercraft/shared/util/Palette.java b/src/main/java/dan200/computercraft/shared/util/Palette.java index f208931c9..23f5654a0 100644 --- a/src/main/java/dan200/computercraft/shared/util/Palette.java +++ b/src/main/java/dan200/computercraft/shared/util/Palette.java @@ -9,75 +9,95 @@ package dan200.computercraft.shared.util; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.PacketByteBuf; -public class Palette { +public class Palette +{ public static final Palette DEFAULT = new Palette(); private static final int PALETTE_SIZE = 16; private final double[][] colours = new double[PALETTE_SIZE][3]; - public Palette() { + public Palette() + { // Get the default palette this.resetColours(); } - public void resetColours() { - for (int i = 0; i < Colour.VALUES.length; i++) { - this.resetColour(i); + public void resetColours() + { + for( int i = 0; i < Colour.VALUES.length; i++ ) + { + this.resetColour( i ); } } - public void resetColour(int i) { - if (i >= 0 && i < this.colours.length) { - this.setColour(i, Colour.VALUES[i]); + public void resetColour( int i ) + { + if( i >= 0 && i < this.colours.length ) + { + this.setColour( i, Colour.VALUES[i] ); } } - public void setColour(int i, Colour colour) { - this.setColour(i, colour.getR(), colour.getG(), colour.getB()); + public void setColour( int i, Colour colour ) + { + this.setColour( i, colour.getR(), colour.getG(), colour.getB() ); } - public void setColour(int i, double r, double g, double b) { - if (i >= 0 && i < this.colours.length) { + public void setColour( int i, double r, double g, double b ) + { + if( i >= 0 && i < this.colours.length ) + { this.colours[i][0] = r; this.colours[i][1] = g; this.colours[i][2] = b; } } - public double[] getColour(int i) { - if (i >= 0 && i < this.colours.length) { + public double[] getColour( int i ) + { + if( i >= 0 && i < this.colours.length ) + { return this.colours[i]; } return null; } - public void write(PacketByteBuf buffer) { - for (double[] colour : this.colours) { - for (double channel : colour) { - buffer.writeByte((int) (channel * 0xFF) & 0xFF); + public void write( PacketByteBuf buffer ) + { + for( double[] colour : this.colours ) + { + for( double channel : colour ) + { + buffer.writeByte( (int) (channel * 0xFF) & 0xFF ); } } } - public void read(PacketByteBuf buffer) { - for (double[] colour : this.colours) { - for (int i = 0; i < colour.length; i++) { + public void read( PacketByteBuf buffer ) + { + for( double[] colour : this.colours ) + { + for( int i = 0; i < colour.length; i++ ) + { colour[i] = (buffer.readByte() & 0xFF) / 255.0; } } } - public CompoundTag writeToNBT(CompoundTag nbt) { + public CompoundTag writeToNBT( CompoundTag nbt ) + { int[] rgb8 = new int[this.colours.length]; - for (int i = 0; i < this.colours.length; i++) { - rgb8[i] = encodeRGB8(this.colours[i]); + for( int i = 0; i < this.colours.length; i++ ) + { + rgb8[i] = encodeRGB8( this.colours[i] ); } - nbt.putIntArray("term_palette", rgb8); + nbt.putIntArray( "term_palette", rgb8 ); return nbt; } - public static int encodeRGB8(double[] rgb) { + public static int encodeRGB8( double[] rgb ) + { int r = (int) (rgb[0] * 255) & 0xFF; int g = (int) (rgb[1] * 255) & 0xFF; int b = (int) (rgb[2] * 255) & 0xFF; @@ -85,26 +105,31 @@ public class Palette { return (r << 16) | (g << 8) | b; } - public void readFromNBT(CompoundTag nbt) { - if (!nbt.contains("term_palette")) { + public void readFromNBT( CompoundTag nbt ) + { + if( !nbt.contains( "term_palette" ) ) + { return; } - int[] rgb8 = nbt.getIntArray("term_palette"); + int[] rgb8 = nbt.getIntArray( "term_palette" ); - if (rgb8.length != this.colours.length) { + if( rgb8.length != this.colours.length ) + { return; } - for (int i = 0; i < this.colours.length; i++) { - this.colours[i] = decodeRGB8(rgb8[i]); + for( int i = 0; i < this.colours.length; i++ ) + { + this.colours[i] = decodeRGB8( rgb8[i] ); } } - public static double[] decodeRGB8(int rgb) { + public static double[] decodeRGB8( int rgb ) + { return new double[] { ((rgb >> 16) & 0xFF) / 255.0f, ((rgb >> 8) & 0xFF) / 255.0f, (rgb & 0xFF) / 255.0f, - }; + }; } } diff --git a/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java b/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java index 8851d1ea8..8093458c2 100644 --- a/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java @@ -6,9 +6,6 @@ package dan200.computercraft.shared.util; -import java.util.Map; -import java.util.Set; - import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gson.JsonArray; @@ -16,93 +13,112 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import dan200.computercraft.shared.computer.core.ComputerFamily; - import net.minecraft.recipe.Ingredient; import net.minecraft.util.JsonHelper; import net.minecraft.util.collection.DefaultedList; +import java.util.Map; +import java.util.Set; + // TODO: Replace some things with Forge?? -public final class RecipeUtil { +public final class RecipeUtil +{ private RecipeUtil() {} - public static ShapedTemplate getTemplate(JsonObject json) { + public static ShapedTemplate getTemplate( JsonObject json ) + { Map ingMap = Maps.newHashMap(); - for (Map.Entry entry : JsonHelper.getObject(json, "key") - .entrySet()) { - if (entry.getKey() - .length() != 1) { - throw new JsonSyntaxException("Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)."); + for( Map.Entry entry : JsonHelper.getObject( json, "key" ) + .entrySet() ) + { + if( entry.getKey() + .length() != 1 ) + { + throw new JsonSyntaxException( "Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)." ); } - if (" ".equals(entry.getKey())) { - throw new JsonSyntaxException("Invalid key entry: ' ' is a reserved symbol."); + if( " ".equals( entry.getKey() ) ) + { + throw new JsonSyntaxException( "Invalid key entry: ' ' is a reserved symbol." ); } - ingMap.put(entry.getKey() - .charAt(0), Ingredient.fromJson(entry.getValue())); + ingMap.put( entry.getKey() + .charAt( 0 ), Ingredient.fromJson( entry.getValue() ) ); } - ingMap.put(' ', Ingredient.EMPTY); + ingMap.put( ' ', Ingredient.EMPTY ); - JsonArray patternJ = JsonHelper.getArray(json, "pattern"); + JsonArray patternJ = JsonHelper.getArray( json, "pattern" ); - if (patternJ.size() == 0) { - throw new JsonSyntaxException("Invalid pattern: empty pattern not allowed"); + if( patternJ.size() == 0 ) + { + throw new JsonSyntaxException( "Invalid pattern: empty pattern not allowed" ); } String[] pattern = new String[patternJ.size()]; - for (int x = 0; x < pattern.length; x++) { - String line = JsonHelper.asString(patternJ.get(x), "pattern[" + x + "]"); - if (x > 0 && pattern[0].length() != line.length()) { - throw new JsonSyntaxException("Invalid pattern: each row must be the same width"); + for( int x = 0; x < pattern.length; x++ ) + { + String line = JsonHelper.asString( patternJ.get( x ), "pattern[" + x + "]" ); + if( x > 0 && pattern[0].length() != line.length() ) + { + throw new JsonSyntaxException( "Invalid pattern: each row must be the same width" ); } pattern[x] = line; } int width = pattern[0].length(); int height = pattern.length; - DefaultedList ingredients = DefaultedList.ofSize(width * height, Ingredient.EMPTY); + DefaultedList ingredients = DefaultedList.ofSize( width * height, Ingredient.EMPTY ); - Set missingKeys = Sets.newHashSet(ingMap.keySet()); - missingKeys.remove(' '); + Set missingKeys = Sets.newHashSet( ingMap.keySet() ); + missingKeys.remove( ' ' ); int i = 0; - for (String line : pattern) { - for (char chr : line.toCharArray()) { - Ingredient ing = ingMap.get(chr); - if (ing == null) { - throw new JsonSyntaxException("Pattern references symbol '" + chr + "' but it's not defined in the key"); + for( String line : pattern ) + { + for( char chr : line.toCharArray() ) + { + Ingredient ing = ingMap.get( chr ); + if( ing == null ) + { + throw new JsonSyntaxException( "Pattern references symbol '" + chr + "' but it's not defined in the key" ); } - ingredients.set(i++, ing); - missingKeys.remove(chr); + ingredients.set( i++, ing ); + missingKeys.remove( chr ); } } - if (!missingKeys.isEmpty()) { - throw new JsonSyntaxException("Key defines symbols that aren't used in pattern: " + missingKeys); + if( !missingKeys.isEmpty() ) + { + throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + missingKeys ); } - return new ShapedTemplate(width, height, ingredients); + return new ShapedTemplate( width, height, ingredients ); } - public static ComputerFamily getFamily(JsonObject json, String name) { - String familyName = JsonHelper.getString(json, name); - for (ComputerFamily family : ComputerFamily.values()) { - if (family.name() - .equalsIgnoreCase(familyName)) { + public static ComputerFamily getFamily( JsonObject json, String name ) + { + String familyName = JsonHelper.getString( json, name ); + for( ComputerFamily family : ComputerFamily.values() ) + { + if( family.name() + .equalsIgnoreCase( familyName ) ) + { return family; } } - throw new JsonSyntaxException("Unknown computer family '" + familyName + "' for field " + name); + throw new JsonSyntaxException( "Unknown computer family '" + familyName + "' for field " + name ); } - public static class ShapedTemplate { + public static class ShapedTemplate + { public final int width; public final int height; public final DefaultedList ingredients; - public ShapedTemplate(int width, int height, DefaultedList ingredients) { + public ShapedTemplate( int width, int height, DefaultedList ingredients ) + { this.width = width; this.height = height; this.ingredients = ingredients; diff --git a/src/main/java/dan200/computercraft/shared/util/RecordUtil.java b/src/main/java/dan200/computercraft/shared/util/RecordUtil.java index 9fcb82bae..30de0b841 100644 --- a/src/main/java/dan200/computercraft/shared/util/RecordUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/RecordUtil.java @@ -9,17 +9,18 @@ package dan200.computercraft.shared.util; import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.network.NetworkMessage; import dan200.computercraft.shared.network.client.PlayRecordClientMessage; - import net.minecraft.sound.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public final class RecordUtil { +public final class RecordUtil +{ private RecordUtil() {} - public static void playRecord(SoundEvent record, String recordInfo, World world, BlockPos pos) { - NetworkMessage packet = record != null ? new PlayRecordClientMessage(pos, record, recordInfo) : new PlayRecordClientMessage(pos); - NetworkHandler.sendToAllAround(packet, world, Vec3d.ofCenter(pos), 64); + public static void playRecord( SoundEvent record, String recordInfo, World world, BlockPos pos ) + { + NetworkMessage packet = record != null ? new PlayRecordClientMessage( pos, record, recordInfo ) : new PlayRecordClientMessage( pos ); + NetworkHandler.sendToAllAround( packet, world, Vec3d.ofCenter( pos ), 64 ); } } diff --git a/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java b/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java index 1e6bf0f77..ca27dcde5 100644 --- a/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java @@ -11,12 +11,14 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; -public final class RedstoneUtil { - public static void propagateRedstoneOutput(World world, BlockPos pos, Direction side) { +public final class RedstoneUtil +{ + public static void propagateRedstoneOutput( World world, BlockPos pos, Direction side ) + { // Propagate ordinary output. See BlockRedstoneDiode.notifyNeighbors - BlockState block = world.getBlockState(pos); - BlockPos neighbourPos = pos.offset(side); - world.updateNeighbor(neighbourPos, block.getBlock(), pos); - world.updateNeighborsExcept(neighbourPos, block.getBlock(), side.getOpposite()); + BlockState block = world.getBlockState( pos ); + BlockPos neighbourPos = pos.offset( side ); + world.updateNeighbor( neighbourPos, block.getBlock(), pos ); + world.updateNeighborsExcept( neighbourPos, block.getBlock(), side.getOpposite() ); } } diff --git a/src/main/java/dan200/computercraft/shared/util/SingleIntArray.java b/src/main/java/dan200/computercraft/shared/util/SingleIntArray.java index 89355c1eb..7479b2e37 100644 --- a/src/main/java/dan200/computercraft/shared/util/SingleIntArray.java +++ b/src/main/java/dan200/computercraft/shared/util/SingleIntArray.java @@ -9,20 +9,24 @@ package dan200.computercraft.shared.util; import net.minecraft.screen.PropertyDelegate; @FunctionalInterface -public interface SingleIntArray extends PropertyDelegate { +public interface SingleIntArray extends PropertyDelegate +{ @Override - default int get(int property) { + default int get( int property ) + { return property == 0 ? this.get() : 0; } int get(); @Override - default void set(int property, int value) { + default void set( int property, int value ) + { } @Override - default int size() { + default int size() + { return 1; } } diff --git a/src/main/java/dan200/computercraft/shared/util/StringUtil.java b/src/main/java/dan200/computercraft/shared/util/StringUtil.java index c5ccb6a4d..2c8dd68b8 100644 --- a/src/main/java/dan200/computercraft/shared/util/StringUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/StringUtil.java @@ -8,29 +8,37 @@ package dan200.computercraft.shared.util; import javax.annotation.Nullable; -public final class StringUtil { +public final class StringUtil +{ private StringUtil() {} - public static String normaliseLabel(String label) { - if (label == null) { + public static String normaliseLabel( String label ) + { + if( label == null ) + { return null; } - int length = Math.min(32, label.length()); - StringBuilder builder = new StringBuilder(length); - for (int i = 0; i < length; i++) { - char c = label.charAt(i); - if ((c >= ' ' && c <= '~') || (c >= 161 && c <= 172) || (c >= 174 && c <= 255)) { - builder.append(c); - } else { - builder.append('?'); + int length = Math.min( 32, label.length() ); + StringBuilder builder = new StringBuilder( length ); + for( int i = 0; i < length; i++ ) + { + char c = label.charAt( i ); + if( (c >= ' ' && c <= '~') || (c >= 161 && c <= 172) || (c >= 174 && c <= 255) ) + { + builder.append( c ); + } + else + { + builder.append( '?' ); } } return builder.toString(); } - public static String toString(@Nullable Object value) { + public static String toString( @Nullable Object value ) + { return value == null ? "" : value.toString(); } } diff --git a/src/main/java/dan200/computercraft/shared/util/ThreadUtils.java b/src/main/java/dan200/computercraft/shared/util/ThreadUtils.java index d63950abd..24f487d4f 100644 --- a/src/main/java/dan200/computercraft/shared/util/ThreadUtils.java +++ b/src/main/java/dan200/computercraft/shared/util/ThreadUtils.java @@ -6,18 +6,20 @@ package dan200.computercraft.shared.util; -import java.util.concurrent.ThreadFactory; - import com.google.common.util.concurrent.ThreadFactoryBuilder; import dan200.computercraft.ComputerCraft; +import java.util.concurrent.ThreadFactory; + /** * Provides some utilities to create thread groups. */ -public final class ThreadUtils { - private static final ThreadGroup baseGroup = new ThreadGroup("ComputerCraft"); +public final class ThreadUtils +{ + private static final ThreadGroup baseGroup = new ThreadGroup( "ComputerCraft" ); - private ThreadUtils() { + private ThreadUtils() + { } /** @@ -25,7 +27,8 @@ public final class ThreadUtils { * * @return The ComputerCraft group. */ - public static ThreadGroup group() { + public static ThreadGroup group() + { return baseGroup; } @@ -39,8 +42,9 @@ public final class ThreadUtils { * @return The constructed thread factory. * @see #builder(String) */ - public static ThreadFactory factory(String name) { - return builder(name).build(); + public static ThreadFactory factory( String name ) + { + return builder( name ).build(); } /** @@ -53,13 +57,14 @@ public final class ThreadUtils { * @return The constructed thread factory builder, which may be extended with other properties. * @see #factory(String) */ - public static ThreadFactoryBuilder builder(String name) { - ThreadGroup group = group(name); - return new ThreadFactoryBuilder().setDaemon(true) - .setNameFormat(group.getName() - .replace("%", "%%") + "-%d") - .setUncaughtExceptionHandler((t, e) -> ComputerCraft.log.error("Exception in thread " + t.getName(), e)) - .setThreadFactory(x -> new Thread(group, x)); + public static ThreadFactoryBuilder builder( String name ) + { + ThreadGroup group = group( name ); + return new ThreadFactoryBuilder().setDaemon( true ) + .setNameFormat( group.getName() + .replace( "%", "%%" ) + "-%d" ) + .setUncaughtExceptionHandler( ( t, e ) -> ComputerCraft.log.error( "Exception in thread " + t.getName(), e ) ) + .setThreadFactory( x -> new Thread( group, x ) ); } /** @@ -68,7 +73,8 @@ public final class ThreadUtils { * @param name The group's name. This will be prefixed with "ComputerCraft-". * @return The constructed thread group. */ - public static ThreadGroup group(String name) { - return new ThreadGroup(baseGroup, baseGroup.getName() + "-" + name); + public static ThreadGroup group( String name ) + { + return new ThreadGroup( baseGroup, baseGroup.getName() + "-" + name ); } } diff --git a/src/main/java/dan200/computercraft/shared/util/TickScheduler.java b/src/main/java/dan200/computercraft/shared/util/TickScheduler.java index 4b4846bc3..98e3a8036 100644 --- a/src/main/java/dan200/computercraft/shared/util/TickScheduler.java +++ b/src/main/java/dan200/computercraft/shared/util/TickScheduler.java @@ -6,49 +6,55 @@ package dan200.computercraft.shared.util; -import java.util.Collections; -import java.util.Iterator; -import java.util.Set; - import com.google.common.collect.MapMaker; import dan200.computercraft.shared.common.TileGeneric; - import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; + /** * We use this when modems and other peripherals change a block in a different thread. */ -public final class TickScheduler { - private static final Set toTick = Collections.newSetFromMap(new MapMaker().weakKeys() - .makeMap()); +public final class TickScheduler +{ + private static final Set toTick = Collections.newSetFromMap( new MapMaker().weakKeys() + .makeMap() ); - private TickScheduler() { + private TickScheduler() + { } - public static void schedule(TileGeneric tile) { + public static void schedule( TileGeneric tile ) + { World world = tile.getWorld(); - if (world != null && !world.isClient) { - toTick.add(tile); + if( world != null && !world.isClient ) + { + toTick.add( tile ); } } - public static void tick() { + public static void tick() + { Iterator iterator = toTick.iterator(); - while (iterator.hasNext()) { + while( iterator.hasNext() ) + { BlockEntity tile = iterator.next(); iterator.remove(); World world = tile.getWorld(); BlockPos pos = tile.getPos(); - if (world != null && pos != null && world.isChunkLoaded(pos) && world.getBlockEntity(pos) == tile) { + if( world != null && pos != null && world.isChunkLoaded( pos ) && world.getBlockEntity( pos ) == tile ) + { world.getBlockTickScheduler() - .schedule(pos, - tile.getCachedState() - .getBlock(), - 0); + .schedule( pos, + tile.getCachedState() + .getBlock(), + 0 ); } } } diff --git a/src/main/java/dan200/computercraft/shared/util/ValidatingSlot.java b/src/main/java/dan200/computercraft/shared/util/ValidatingSlot.java index 517cf63a1..aa1e50940 100644 --- a/src/main/java/dan200/computercraft/shared/util/ValidatingSlot.java +++ b/src/main/java/dan200/computercraft/shared/util/ValidatingSlot.java @@ -6,19 +6,22 @@ package dan200.computercraft.shared.util; -import javax.annotation.Nonnull; - import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; -public class ValidatingSlot extends Slot { - public ValidatingSlot(Inventory inventoryIn, int index, int xPosition, int yPosition) { - super(inventoryIn, index, xPosition, yPosition); +import javax.annotation.Nonnull; + +public class ValidatingSlot extends Slot +{ + public ValidatingSlot( Inventory inventoryIn, int index, int xPosition, int yPosition ) + { + super( inventoryIn, index, xPosition, yPosition ); } @Override - public boolean canInsert(@Nonnull ItemStack stack) { + public boolean canInsert( @Nonnull ItemStack stack ) + { return true; // inventory.isItemValidForSlot( slotNumber, stack ); } } diff --git a/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java b/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java index 6606b5f88..7703ab8ef 100644 --- a/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java +++ b/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java @@ -20,10 +20,12 @@ import net.minecraft.world.WorldAccess; * * I'm fairly sure this exists on 1.14, but it's a useful convenience wrapper to have on 1.13. */ -public final class WaterloggableHelpers { +public final class WaterloggableHelpers +{ public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; - private WaterloggableHelpers() { + private WaterloggableHelpers() + { } /** @@ -32,8 +34,9 @@ public final class WaterloggableHelpers { * @param state The current state * @return This waterlogged block's current fluid */ - public static FluidState getWaterloggedFluidState(BlockState state) { - return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : Fluids.EMPTY.getDefaultState(); + public static FluidState getWaterloggedFluidState( BlockState state ) + { + return state.get( WATERLOGGED ) ? Fluids.WATER.getStill( false ) : Fluids.EMPTY.getDefaultState(); } /** @@ -41,18 +44,21 @@ public final class WaterloggableHelpers { * * @param state The current state * @param world The position of this block - * @param pos The world this block exists in + * @param pos The world this block exists in */ - public static void updateWaterloggedPostPlacement(BlockState state, WorldAccess world, BlockPos pos) { - if (state.get(WATERLOGGED)) { + public static void updateWaterloggedPostPlacement( BlockState state, WorldAccess world, BlockPos pos ) + { + if( state.get( WATERLOGGED ) ) + { world.getFluidTickScheduler() - .schedule(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + .schedule( pos, Fluids.WATER, Fluids.WATER.getTickRate( world ) ); } } - public static boolean getWaterloggedStateForPlacement(ItemPlacementContext context) { + public static boolean getWaterloggedStateForPlacement( ItemPlacementContext context ) + { return context.getWorld() - .getFluidState(context.getBlockPos()) - .getFluid() == Fluids.WATER; + .getFluidState( context.getBlockPos() ) + .getFluid() == Fluids.WATER; } } diff --git a/src/main/java/dan200/computercraft/shared/util/WorldUtil.java b/src/main/java/dan200/computercraft/shared/util/WorldUtil.java index 52f37c3ad..6e0ff4490 100644 --- a/src/main/java/dan200/computercraft/shared/util/WorldUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/WorldUtil.java @@ -6,21 +6,9 @@ package dan200.computercraft.shared.util; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; - import com.google.common.base.Predicate; import com.google.common.collect.MapMaker; -import org.apache.commons.lang3.tuple.Pair; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityDimensions; -import net.minecraft.entity.EntityPose; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.*; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.hit.HitResult; @@ -31,25 +19,36 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.RaycastContext; import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; -public final class WorldUtil { - @SuppressWarnings ("Guava") private static final Predicate CAN_COLLIDE = x -> x != null && x.isAlive() && x.collides(); +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Map; + +public final class WorldUtil +{ + @SuppressWarnings( "Guava" ) + private static final Predicate CAN_COLLIDE = x -> x != null && x.isAlive() && x.collides(); private static final Map entityCache = new MapMaker().weakKeys() - .weakValues() - .makeMap(); + .weakValues() + .makeMap(); - public static boolean isLiquidBlock(World world, BlockPos pos) { - if (!World.isInBuildLimit(pos)) { + public static boolean isLiquidBlock( World world, BlockPos pos ) + { + if( !World.isInBuildLimit( pos ) ) + { return false; } - return world.getBlockState(pos) - .getMaterial() - .isLiquid(); + return world.getBlockState( pos ) + .getMaterial() + .isLiquid(); } - public static boolean isVecInside(VoxelShape shape, Vec3d vec) { - if (shape.isEmpty()) { + public static boolean isVecInside( VoxelShape shape, Vec3d vec ) + { + if( shape.isEmpty() ) + { return false; } // AxisAlignedBB.contains, but without strict inequalities. @@ -57,111 +56,132 @@ public final class WorldUtil { return vec.x >= bb.minX && vec.x <= bb.maxX && vec.y >= bb.minY && vec.y <= bb.maxY && vec.z >= bb.minZ && vec.z <= bb.maxZ; } - public static Pair rayTraceEntities(World world, Vec3d vecStart, Vec3d vecDir, double distance) { - Vec3d vecEnd = vecStart.add(vecDir.x * distance, vecDir.y * distance, vecDir.z * distance); + public static Pair rayTraceEntities( World world, Vec3d vecStart, Vec3d vecDir, double distance ) + { + Vec3d vecEnd = vecStart.add( vecDir.x * distance, vecDir.y * distance, vecDir.z * distance ); // Raycast for blocks - Entity collisionEntity = getEntity(world); - collisionEntity.updatePosition(vecStart.x, vecStart.y, vecStart.z); - RaycastContext context = new RaycastContext(vecStart, - vecEnd, - RaycastContext.ShapeType.COLLIDER, - RaycastContext.FluidHandling.NONE, - collisionEntity); - HitResult result = world.raycast(context); - if (result != null && result.getType() == HitResult.Type.BLOCK) { - distance = vecStart.distanceTo(result.getPos()); - vecEnd = vecStart.add(vecDir.x * distance, vecDir.y * distance, vecDir.z * distance); + Entity collisionEntity = getEntity( world ); + collisionEntity.updatePosition( vecStart.x, vecStart.y, vecStart.z ); + RaycastContext context = new RaycastContext( vecStart, + vecEnd, + RaycastContext.ShapeType.COLLIDER, + RaycastContext.FluidHandling.NONE, + collisionEntity ); + HitResult result = world.raycast( context ); + if( result != null && result.getType() == HitResult.Type.BLOCK ) + { + distance = vecStart.distanceTo( result.getPos() ); + vecEnd = vecStart.add( vecDir.x * distance, vecDir.y * distance, vecDir.z * distance ); } // Check for entities - float xStretch = Math.abs(vecDir.x) > 0.25f ? 0.0f : 1.0f; - float yStretch = Math.abs(vecDir.y) > 0.25f ? 0.0f : 1.0f; - float zStretch = Math.abs(vecDir.z) > 0.25f ? 0.0f : 1.0f; - Box bigBox = new Box(Math.min(vecStart.x, vecEnd.x) - 0.375f * xStretch, - Math.min(vecStart.y, vecEnd.y) - 0.375f * yStretch, - Math.min(vecStart.z, vecEnd.z) - 0.375f * zStretch, - Math.max(vecStart.x, vecEnd.x) + 0.375f * xStretch, - Math.max(vecStart.y, vecEnd.y) + 0.375f * yStretch, - Math.max(vecStart.z, vecEnd.z) + 0.375f * zStretch); + float xStretch = Math.abs( vecDir.x ) > 0.25f ? 0.0f : 1.0f; + float yStretch = Math.abs( vecDir.y ) > 0.25f ? 0.0f : 1.0f; + float zStretch = Math.abs( vecDir.z ) > 0.25f ? 0.0f : 1.0f; + Box bigBox = new Box( Math.min( vecStart.x, vecEnd.x ) - 0.375f * xStretch, + Math.min( vecStart.y, vecEnd.y ) - 0.375f * yStretch, + Math.min( vecStart.z, vecEnd.z ) - 0.375f * zStretch, + Math.max( vecStart.x, vecEnd.x ) + 0.375f * xStretch, + Math.max( vecStart.y, vecEnd.y ) + 0.375f * yStretch, + Math.max( vecStart.z, vecEnd.z ) + 0.375f * zStretch ); Entity closest = null; double closestDist = 99.0; - List list = world.getEntitiesByClass(Entity.class, bigBox, CAN_COLLIDE); - for (Entity entity : list) { + List list = world.getEntitiesByClass( Entity.class, bigBox, CAN_COLLIDE ); + for( Entity entity : list ) + { Box littleBox = entity.getBoundingBox(); - if (littleBox.contains(vecStart)) { + if( littleBox.contains( vecStart ) ) + { closest = entity; closestDist = 0.0f; continue; } - Vec3d littleBoxResult = littleBox.raycast(vecStart, vecEnd) - .orElse(null); - if (littleBoxResult != null) { - double dist = vecStart.distanceTo(littleBoxResult); - if (closest == null || dist <= closestDist) { + Vec3d littleBoxResult = littleBox.raycast( vecStart, vecEnd ) + .orElse( null ); + if( littleBoxResult != null ) + { + double dist = vecStart.distanceTo( littleBoxResult ); + if( closest == null || dist <= closestDist ) + { closest = entity; closestDist = dist; } - } else if (littleBox.intersects(bigBox)) { - if (closest == null) { + } + else if( littleBox.intersects( bigBox ) ) + { + if( closest == null ) + { closest = entity; closestDist = distance; } } } - if (closest != null && closestDist <= distance) { - Vec3d closestPos = vecStart.add(vecDir.x * closestDist, vecDir.y * closestDist, vecDir.z * closestDist); - return Pair.of(closest, closestPos); + if( closest != null && closestDist <= distance ) + { + Vec3d closestPos = vecStart.add( vecDir.x * closestDist, vecDir.y * closestDist, vecDir.z * closestDist ); + return Pair.of( closest, closestPos ); } return null; } - private static synchronized Entity getEntity(World world) { + private static synchronized Entity getEntity( World world ) + { // TODO: It'd be nice if we could avoid this. Maybe always use the turtle player (if it's available). - Entity entity = entityCache.get(world); - if (entity != null) { + Entity entity = entityCache.get( world ); + if( entity != null ) + { return entity; } - entity = new ItemEntity(EntityType.ITEM, world) { + entity = new ItemEntity( EntityType.ITEM, world ) + { @Nonnull @Override - public EntityDimensions getDimensions(@Nonnull EntityPose pose) { - return EntityDimensions.fixed(0, 0); + public EntityDimensions getDimensions( @Nonnull EntityPose pose ) + { + return EntityDimensions.fixed( 0, 0 ); } }; entity.noClip = true; entity.calculateDimensions(); - entityCache.put(world, entity); + entityCache.put( world, entity ); return entity; } - public static Vec3d getRayEnd(PlayerEntity player) { + public static Vec3d getRayEnd( PlayerEntity player ) + { double reach = 5; Vec3d look = player.getRotationVector(); - return getRayStart(player).add(look.x * reach, look.y * reach, look.z * reach); + return getRayStart( player ).add( look.x * reach, look.y * reach, look.z * reach ); } - public static Vec3d getRayStart(LivingEntity entity) { - return entity.getCameraPosVec(1); + public static Vec3d getRayStart( LivingEntity entity ) + { + return entity.getCameraPosVec( 1 ); } - public static void dropItemStack(@Nonnull ItemStack stack, World world, BlockPos pos) { - dropItemStack(stack, world, pos, null); + public static void dropItemStack( @Nonnull ItemStack stack, World world, BlockPos pos ) + { + dropItemStack( stack, world, pos, null ); } - public static void dropItemStack(@Nonnull ItemStack stack, World world, BlockPos pos, Direction direction) { + public static void dropItemStack( @Nonnull ItemStack stack, World world, BlockPos pos, Direction direction ) + { double xDir; double yDir; double zDir; - if (direction != null) { + if( direction != null ) + { xDir = direction.getOffsetX(); yDir = direction.getOffsetY(); zDir = direction.getOffsetZ(); - } else { + } + else + { xDir = 0.0; yDir = 0.0; zDir = 0.0; @@ -170,22 +190,24 @@ public final class WorldUtil { double xPos = pos.getX() + 0.5 + xDir * 0.4; double yPos = pos.getY() + 0.5 + yDir * 0.4; double zPos = pos.getZ() + 0.5 + zDir * 0.4; - dropItemStack(stack, world, new Vec3d(xPos, yPos, zPos), xDir, yDir, zDir); + dropItemStack( stack, world, new Vec3d( xPos, yPos, zPos ), xDir, yDir, zDir ); } - public static void dropItemStack(@Nonnull ItemStack stack, World world, Vec3d pos, double xDir, double yDir, double zDir) { - ItemEntity item = new ItemEntity(world, pos.x, pos.y, pos.z, stack.copy()); - item.setVelocity(xDir * 0.7 + world.getRandom() - .nextFloat() * 0.2 - 0.1, - yDir * 0.7 + world.getRandom() - .nextFloat() * 0.2 - 0.1, - zDir * 0.7 + world.getRandom() - .nextFloat() * 0.2 - 0.1); + public static void dropItemStack( @Nonnull ItemStack stack, World world, Vec3d pos, double xDir, double yDir, double zDir ) + { + ItemEntity item = new ItemEntity( world, pos.x, pos.y, pos.z, stack.copy() ); + item.setVelocity( xDir * 0.7 + world.getRandom() + .nextFloat() * 0.2 - 0.1, + yDir * 0.7 + world.getRandom() + .nextFloat() * 0.2 - 0.1, + zDir * 0.7 + world.getRandom() + .nextFloat() * 0.2 - 0.1 ); item.setToDefaultPickupDelay(); - world.spawnEntity(item); + world.spawnEntity( item ); } - public static void dropItemStack(@Nonnull ItemStack stack, World world, Vec3d pos) { - dropItemStack(stack, world, pos, 0.0, 0.0, 0.0); + public static void dropItemStack( @Nonnull ItemStack stack, World world, Vec3d pos ) + { + dropItemStack( stack, world, pos, 0.0, 0.0, 0.0 ); } } diff --git a/src/main/java/dan200/computercraft/shared/wired/InvariantChecker.java b/src/main/java/dan200/computercraft/shared/wired/InvariantChecker.java index 2dc36f67e..ab790e922 100644 --- a/src/main/java/dan200/computercraft/shared/wired/InvariantChecker.java +++ b/src/main/java/dan200/computercraft/shared/wired/InvariantChecker.java @@ -13,39 +13,49 @@ import dan200.computercraft.ComputerCraft; * * This adds substantial overhead to network modification, and so should only be enabled in a development environment. */ -public final class InvariantChecker { +public final class InvariantChecker +{ private static final boolean ENABLED = false; private InvariantChecker() {} - public static void checkNetwork(WiredNetwork network) { - if (!ENABLED) { + public static void checkNetwork( WiredNetwork network ) + { + if( !ENABLED ) + { return; } - for (WiredNode node : network.nodes) { - checkNode(node); + for( WiredNode node : network.nodes ) + { + checkNode( node ); } } - public static void checkNode(WiredNode node) { - if (!ENABLED) { + public static void checkNode( WiredNode node ) + { + if( !ENABLED ) + { return; } WiredNetwork network = node.network; - if (network == null) { - ComputerCraft.log.error("Node's network is null", new Exception()); + if( network == null ) + { + ComputerCraft.log.error( "Node's network is null", new Exception() ); return; } - if (network.nodes == null || !network.nodes.contains(node)) { - ComputerCraft.log.error("Node's network does not contain node", new Exception()); + if( network.nodes == null || !network.nodes.contains( node ) ) + { + ComputerCraft.log.error( "Node's network does not contain node", new Exception() ); } - for (WiredNode neighbour : node.neighbours) { - if (!neighbour.neighbours.contains(node)) { - ComputerCraft.log.error("Neighbour is missing node", new Exception()); + for( WiredNode neighbour : node.neighbours ) + { + if( !neighbour.neighbours.contains( node ) ) + { + ComputerCraft.log.error( "Neighbour is missing node", new Exception() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/wired/WiredNetwork.java b/src/main/java/dan200/computercraft/shared/wired/WiredNetwork.java index 32375a800..9dd28fa52 100644 --- a/src/main/java/dan200/computercraft/shared/wired/WiredNetwork.java +++ b/src/main/java/dan200/computercraft/shared/wired/WiredNetwork.java @@ -6,197 +6,219 @@ package dan200.computercraft.shared.wired; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.TreeSet; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import javax.annotation.Nonnull; - import com.google.common.collect.ImmutableMap; import dan200.computercraft.api.network.Packet; import dan200.computercraft.api.network.wired.IWiredNetwork; import dan200.computercraft.api.network.wired.IWiredNode; import dan200.computercraft.api.peripheral.IPeripheral; - import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public final class WiredNetwork implements IWiredNetwork { +import javax.annotation.Nonnull; +import java.util.*; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public final class WiredNetwork implements IWiredNetwork +{ final ReadWriteLock lock = new ReentrantReadWriteLock(); HashSet nodes; private HashMap peripherals = new HashMap<>(); - WiredNetwork(WiredNode node) { - this.nodes = new HashSet<>(1); - this.nodes.add(node); + WiredNetwork( WiredNode node ) + { + this.nodes = new HashSet<>( 1 ); + this.nodes.add( node ); } - private WiredNetwork(HashSet nodes) { + private WiredNetwork( HashSet nodes ) + { this.nodes = nodes; } - static void transmitPacket(WiredNode start, Packet packet, double range, boolean interdimensional) { + static void transmitPacket( WiredNode start, Packet packet, double range, boolean interdimensional ) + { Map points = new HashMap<>(); TreeSet transmitTo = new TreeSet<>(); { TransmitPoint startEntry = start.element.getWorld() != packet.getSender() - .getWorld() ? new TransmitPoint(start, - Double.POSITIVE_INFINITY, - true) : new TransmitPoint(start, - start.element.getPosition() - .distanceTo( - packet.getSender() - .getPosition()), - false); - points.put(start, startEntry); - transmitTo.add(startEntry); + .getWorld() ? new TransmitPoint( start, + Double.POSITIVE_INFINITY, + true ) : new TransmitPoint( start, + start.element.getPosition() + .distanceTo( + packet.getSender() + .getPosition() ), + false ); + points.put( start, startEntry ); + transmitTo.add( startEntry ); } { TransmitPoint point; - while ((point = transmitTo.pollFirst()) != null) { + while( (point = transmitTo.pollFirst()) != null ) + { World world = point.node.element.getWorld(); Vec3d position = point.node.element.getPosition(); - for (WiredNode neighbour : point.node.neighbours) { - TransmitPoint neighbourPoint = points.get(neighbour); + for( WiredNode neighbour : point.node.neighbours ) + { + TransmitPoint neighbourPoint = points.get( neighbour ); boolean newInterdimensional; double newDistance; - if (world != neighbour.element.getWorld()) { + if( world != neighbour.element.getWorld() ) + { newInterdimensional = true; newDistance = Double.POSITIVE_INFINITY; - } else { + } + else + { newInterdimensional = false; - newDistance = point.distance + position.distanceTo(neighbour.element.getPosition()); + newDistance = point.distance + position.distanceTo( neighbour.element.getPosition() ); } - if (neighbourPoint == null) { - TransmitPoint nextPoint = new TransmitPoint(neighbour, newDistance, newInterdimensional); - points.put(neighbour, nextPoint); - transmitTo.add(nextPoint); - } else if (newDistance < neighbourPoint.distance) { - transmitTo.remove(neighbourPoint); + if( neighbourPoint == null ) + { + TransmitPoint nextPoint = new TransmitPoint( neighbour, newDistance, newInterdimensional ); + points.put( neighbour, nextPoint ); + transmitTo.add( nextPoint ); + } + else if( newDistance < neighbourPoint.distance ) + { + transmitTo.remove( neighbourPoint ); neighbourPoint.distance = newDistance; neighbourPoint.interdimensional = newInterdimensional; - transmitTo.add(neighbourPoint); + transmitTo.add( neighbourPoint ); } } } } - for (TransmitPoint point : points.values()) { - point.node.tryTransmit(packet, point.distance, point.interdimensional, range, interdimensional); + for( TransmitPoint point : points.values() ) + { + point.node.tryTransmit( packet, point.distance, point.interdimensional, range, interdimensional ); } } @Override - public boolean connect(@Nonnull IWiredNode nodeU, @Nonnull IWiredNode nodeV) { - WiredNode wiredU = checkNode(nodeU); - WiredNode wiredV = checkNode(nodeV); - if (nodeU == nodeV) { - throw new IllegalArgumentException("Cannot add a connection to oneself."); + public boolean connect( @Nonnull IWiredNode nodeU, @Nonnull IWiredNode nodeV ) + { + WiredNode wiredU = checkNode( nodeU ); + WiredNode wiredV = checkNode( nodeV ); + if( nodeU == nodeV ) + { + throw new IllegalArgumentException( "Cannot add a connection to oneself." ); } this.lock.writeLock() - .lock(); - try { - if (this.nodes == null) { - throw new IllegalStateException("Cannot add a connection to an empty network."); + .lock(); + try + { + if( this.nodes == null ) + { + throw new IllegalStateException( "Cannot add a connection to an empty network." ); } boolean hasU = wiredU.network == this; boolean hasV = wiredV.network == this; - if (!hasU && !hasV) { - throw new IllegalArgumentException("Neither node is in the network."); + if( !hasU && !hasV ) + { + throw new IllegalArgumentException( "Neither node is in the network." ); } // We're going to assimilate a node. Copy across all edges and vertices. - if (!hasU || !hasV) { + if( !hasU || !hasV ) + { WiredNetwork other = hasU ? wiredV.network : wiredU.network; other.lock.writeLock() - .lock(); - try { + .lock(); + try + { // Cache several properties for iterating over later Map otherPeripherals = other.peripherals; - Map thisPeripherals = otherPeripherals.isEmpty() ? this.peripherals : new HashMap<>(this.peripherals); + Map thisPeripherals = otherPeripherals.isEmpty() ? this.peripherals : new HashMap<>( this.peripherals ); - Collection thisNodes = otherPeripherals.isEmpty() ? this.nodes : new ArrayList<>(this.nodes); + Collection thisNodes = otherPeripherals.isEmpty() ? this.nodes : new ArrayList<>( this.nodes ); Collection otherNodes = other.nodes; // Move all nodes across into this network, destroying the original nodes. - this.nodes.addAll(otherNodes); - for (WiredNode node : otherNodes) { + this.nodes.addAll( otherNodes ); + for( WiredNode node : otherNodes ) + { node.network = this; } other.nodes = null; // Move all peripherals across, other.peripherals = null; - this.peripherals.putAll(otherPeripherals); + this.peripherals.putAll( otherPeripherals ); - if (!thisPeripherals.isEmpty()) { - WiredNetworkChange.added(thisPeripherals) - .broadcast(otherNodes); + if( !thisPeripherals.isEmpty() ) + { + WiredNetworkChange.added( thisPeripherals ) + .broadcast( otherNodes ); } - if (!otherPeripherals.isEmpty()) { - WiredNetworkChange.added(otherPeripherals) - .broadcast(thisNodes); + if( !otherPeripherals.isEmpty() ) + { + WiredNetworkChange.added( otherPeripherals ) + .broadcast( thisNodes ); } - } finally { + } + finally + { other.lock.writeLock() - .unlock(); + .unlock(); } } - boolean added = wiredU.neighbours.add(wiredV); - if (added) { - wiredV.neighbours.add(wiredU); + boolean added = wiredU.neighbours.add( wiredV ); + if( added ) + { + wiredV.neighbours.add( wiredU ); } - InvariantChecker.checkNetwork(this); - InvariantChecker.checkNode(wiredU); - InvariantChecker.checkNode(wiredV); + InvariantChecker.checkNetwork( this ); + InvariantChecker.checkNode( wiredU ); + InvariantChecker.checkNode( wiredV ); return added; - } finally { + } + finally + { this.lock.writeLock() - .unlock(); + .unlock(); } } @Override - public boolean disconnect(@Nonnull IWiredNode nodeU, @Nonnull IWiredNode nodeV) { - WiredNode wiredU = checkNode(nodeU); - WiredNode wiredV = checkNode(nodeV); - if (nodeU == nodeV) { - throw new IllegalArgumentException("Cannot remove a connection to oneself."); + public boolean disconnect( @Nonnull IWiredNode nodeU, @Nonnull IWiredNode nodeV ) + { + WiredNode wiredU = checkNode( nodeU ); + WiredNode wiredV = checkNode( nodeV ); + if( nodeU == nodeV ) + { + throw new IllegalArgumentException( "Cannot remove a connection to oneself." ); } this.lock.writeLock() - .lock(); - try { + .lock(); + try + { boolean hasU = wiredU.network == this; boolean hasV = wiredV.network == this; - if (!hasU || !hasV) { - throw new IllegalArgumentException("One node is not in the network."); + if( !hasU || !hasV ) + { + throw new IllegalArgumentException( "One node is not in the network." ); } // If there was no connection to remove then split. - if (!wiredU.neighbours.remove(wiredV)) { + if( !wiredU.neighbours.remove( wiredV ) ) + { return false; } - wiredV.neighbours.remove(wiredU); + wiredV.neighbours.remove( wiredU ); // Determine if there is still some connection from u to v. // Note this is an inlining of reachableNodes which short-circuits @@ -204,163 +226,193 @@ public final class WiredNetwork implements IWiredNetwork { Queue enqueued = new ArrayDeque<>(); HashSet reachableU = new HashSet<>(); - reachableU.add(wiredU); - enqueued.add(wiredU); + reachableU.add( wiredU ); + enqueued.add( wiredU ); - while (!enqueued.isEmpty()) { + while( !enqueued.isEmpty() ) + { WiredNode node = enqueued.remove(); - for (WiredNode neighbour : node.neighbours) { + for( WiredNode neighbour : node.neighbours ) + { // If we can reach wiredV from wiredU then abort. - if (neighbour == wiredV) { + if( neighbour == wiredV ) + { return true; } // Otherwise attempt to enqueue this neighbour as well. - if (reachableU.add(neighbour)) { - enqueued.add(neighbour); + if( reachableU.add( neighbour ) ) + { + enqueued.add( neighbour ); } } } // Create a new network with all U-reachable nodes/edges and remove them // from the existing graph. - WiredNetwork networkU = new WiredNetwork(reachableU); + WiredNetwork networkU = new WiredNetwork( reachableU ); networkU.lock.writeLock() - .lock(); - try { + .lock(); + try + { // Remove nodes from this network - this.nodes.removeAll(reachableU); + this.nodes.removeAll( reachableU ); // Set network and transfer peripherals - for (WiredNode node : reachableU) { + for( WiredNode node : reachableU ) + { node.network = networkU; - networkU.peripherals.putAll(node.peripherals); + networkU.peripherals.putAll( node.peripherals ); this.peripherals.keySet() - .removeAll(node.peripherals.keySet()); + .removeAll( node.peripherals.keySet() ); } // Broadcast changes - if (!this.peripherals.isEmpty()) { - WiredNetworkChange.removed(this.peripherals) - .broadcast(networkU.nodes); + if( !this.peripherals.isEmpty() ) + { + WiredNetworkChange.removed( this.peripherals ) + .broadcast( networkU.nodes ); } - if (!networkU.peripherals.isEmpty()) { - WiredNetworkChange.removed(networkU.peripherals) - .broadcast(this.nodes); + if( !networkU.peripherals.isEmpty() ) + { + WiredNetworkChange.removed( networkU.peripherals ) + .broadcast( this.nodes ); } - InvariantChecker.checkNetwork(this); - InvariantChecker.checkNetwork(networkU); - InvariantChecker.checkNode(wiredU); - InvariantChecker.checkNode(wiredV); + InvariantChecker.checkNetwork( this ); + InvariantChecker.checkNetwork( networkU ); + InvariantChecker.checkNode( wiredU ); + InvariantChecker.checkNode( wiredV ); return true; - } finally { - networkU.lock.writeLock() - .unlock(); } - } finally { + finally + { + networkU.lock.writeLock() + .unlock(); + } + } + finally + { this.lock.writeLock() - .unlock(); + .unlock(); } } @Override - public boolean remove(@Nonnull IWiredNode node) { - WiredNode wired = checkNode(node); + public boolean remove( @Nonnull IWiredNode node ) + { + WiredNode wired = checkNode( node ); this.lock.writeLock() - .lock(); - try { + .lock(); + try + { // If we're the empty graph then just abort: nodes must have _some_ network. - if (this.nodes == null) { + if( this.nodes == null ) + { return false; } - if (this.nodes.size() <= 1) { + if( this.nodes.size() <= 1 ) + { return false; } - if (wired.network != this) { + if( wired.network != this ) + { return false; } HashSet neighbours = wired.neighbours; // Remove this node and move into a separate network. - this.nodes.remove(wired); - for (WiredNode neighbour : neighbours) { - neighbour.neighbours.remove(wired); + this.nodes.remove( wired ); + for( WiredNode neighbour : neighbours ) + { + neighbour.neighbours.remove( wired ); } - WiredNetwork wiredNetwork = new WiredNetwork(wired); + WiredNetwork wiredNetwork = new WiredNetwork( wired ); // If we're a leaf node in the graph (only one neighbour) then we don't need to // check for network splitting - if (neighbours.size() == 1) { + if( neighbours.size() == 1 ) + { // Broadcast our simple peripheral changes - this.removeSingleNode(wired, wiredNetwork); - InvariantChecker.checkNode(wired); - InvariantChecker.checkNetwork(wiredNetwork); + this.removeSingleNode( wired, wiredNetwork ); + InvariantChecker.checkNode( wired ); + InvariantChecker.checkNetwork( wiredNetwork ); return true; } - HashSet reachable = reachableNodes(neighbours.iterator() - .next()); + HashSet reachable = reachableNodes( neighbours.iterator() + .next() ); // If all nodes are reachable then exit. - if (reachable.size() == this.nodes.size()) { + if( reachable.size() == this.nodes.size() ) + { // Broadcast our simple peripheral changes - this.removeSingleNode(wired, wiredNetwork); - InvariantChecker.checkNode(wired); - InvariantChecker.checkNetwork(wiredNetwork); + this.removeSingleNode( wired, wiredNetwork ); + InvariantChecker.checkNode( wired ); + InvariantChecker.checkNetwork( wiredNetwork ); return true; } // A split may cause 2..neighbours.size() separate networks, so we // iterate through our neighbour list, generating child networks. - neighbours.removeAll(reachable); - ArrayList maximals = new ArrayList<>(neighbours.size() + 1); - maximals.add(wiredNetwork); - maximals.add(new WiredNetwork(reachable)); + neighbours.removeAll( reachable ); + ArrayList maximals = new ArrayList<>( neighbours.size() + 1 ); + maximals.add( wiredNetwork ); + maximals.add( new WiredNetwork( reachable ) ); - while (!neighbours.isEmpty()) { - reachable = reachableNodes(neighbours.iterator() - .next()); - neighbours.removeAll(reachable); - maximals.add(new WiredNetwork(reachable)); + while( !neighbours.isEmpty() ) + { + reachable = reachableNodes( neighbours.iterator() + .next() ); + neighbours.removeAll( reachable ); + maximals.add( new WiredNetwork( reachable ) ); } - for (WiredNetwork network : maximals) { + for( WiredNetwork network : maximals ) + { network.lock.writeLock() - .lock(); + .lock(); } - try { + try + { // We special case the original node: detaching all peripherals when needed. wired.network = wiredNetwork; wired.peripherals = Collections.emptyMap(); // Ensure every network is finalised - for (WiredNetwork network : maximals) { - for (WiredNode child : network.nodes) { + for( WiredNetwork network : maximals ) + { + for( WiredNode child : network.nodes ) + { child.network = network; - network.peripherals.putAll(child.peripherals); + network.peripherals.putAll( child.peripherals ); } } - for (WiredNetwork network : maximals) { - InvariantChecker.checkNetwork(network); + for( WiredNetwork network : maximals ) + { + InvariantChecker.checkNetwork( network ); } - InvariantChecker.checkNode(wired); + InvariantChecker.checkNode( wired ); // Then broadcast network changes once all nodes are finalised - for (WiredNetwork network : maximals) { - WiredNetworkChange.changeOf(this.peripherals, network.peripherals) - .broadcast(network.nodes); + for( WiredNetwork network : maximals ) + { + WiredNetworkChange.changeOf( this.peripherals, network.peripherals ) + .broadcast( network.nodes ); } - } finally { - for (WiredNetwork network : maximals) { + } + finally + { + for( WiredNetwork network : maximals ) + { network.lock.writeLock() - .unlock(); + .unlock(); } } @@ -368,53 +420,63 @@ public final class WiredNetwork implements IWiredNetwork { this.peripherals.clear(); return true; - } finally { + } + finally + { this.lock.writeLock() - .unlock(); + .unlock(); } } @Override - public void updatePeripherals(@Nonnull IWiredNode node, @Nonnull Map newPeripherals) { - WiredNode wired = checkNode(node); - Objects.requireNonNull(this.peripherals, "peripherals cannot be null"); + public void updatePeripherals( @Nonnull IWiredNode node, @Nonnull Map newPeripherals ) + { + WiredNode wired = checkNode( node ); + Objects.requireNonNull( this.peripherals, "peripherals cannot be null" ); this.lock.writeLock() - .lock(); - try { - if (wired.network != this) { - throw new IllegalStateException("Node is not on this network"); + .lock(); + try + { + if( wired.network != this ) + { + throw new IllegalStateException( "Node is not on this network" ); } Map oldPeripherals = wired.peripherals; - WiredNetworkChange change = WiredNetworkChange.changeOf(oldPeripherals, newPeripherals); - if (change.isEmpty()) { + WiredNetworkChange change = WiredNetworkChange.changeOf( oldPeripherals, newPeripherals ); + if( change.isEmpty() ) + { return; } - wired.peripherals = ImmutableMap.copyOf(newPeripherals); + wired.peripherals = ImmutableMap.copyOf( newPeripherals ); // Detach the old peripherals then remove them. this.peripherals.keySet() - .removeAll(change.peripheralsRemoved() - .keySet()); + .removeAll( change.peripheralsRemoved() + .keySet() ); // Add the new peripherals and attach them - this.peripherals.putAll(change.peripheralsAdded()); + this.peripherals.putAll( change.peripheralsAdded() ); - change.broadcast(this.nodes); - } finally { + change.broadcast( this.nodes ); + } + finally + { this.lock.writeLock() - .unlock(); + .unlock(); } } - private void removeSingleNode(WiredNode wired, WiredNetwork wiredNetwork) { + private void removeSingleNode( WiredNode wired, WiredNetwork wiredNetwork ) + { wiredNetwork.lock.writeLock() - .lock(); - try { + .lock(); + try + { // Cache all the old nodes. - Map wiredPeripherals = new HashMap<>(wired.peripherals); + Map wiredPeripherals = new HashMap<>( wired.peripherals ); // Setup the new node's network // Detach the old peripherals then remove them from the old network @@ -423,38 +485,46 @@ public final class WiredNetwork implements IWiredNetwork { wired.peripherals = Collections.emptyMap(); // Broadcast the change - if (!this.peripherals.isEmpty()) { - WiredNetworkChange.removed(this.peripherals) - .broadcast(wired); + if( !this.peripherals.isEmpty() ) + { + WiredNetworkChange.removed( this.peripherals ) + .broadcast( wired ); } // Now remove all peripherals from this network and broadcast the change. this.peripherals.keySet() - .removeAll(wiredPeripherals.keySet()); - if (!wiredPeripherals.isEmpty()) { - WiredNetworkChange.removed(wiredPeripherals) - .broadcast(this.nodes); + .removeAll( wiredPeripherals.keySet() ); + if( !wiredPeripherals.isEmpty() ) + { + WiredNetworkChange.removed( wiredPeripherals ) + .broadcast( this.nodes ); } - } finally { + } + finally + { wiredNetwork.lock.writeLock() - .unlock(); + .unlock(); } } - private static HashSet reachableNodes(WiredNode start) { + private static HashSet reachableNodes( WiredNode start ) + { Queue enqueued = new ArrayDeque<>(); HashSet reachable = new HashSet<>(); - reachable.add(start); - enqueued.add(start); + reachable.add( start ); + enqueued.add( start ); WiredNode node; - while ((node = enqueued.poll()) != null) { - for (WiredNode neighbour : node.neighbours) { + while( (node = enqueued.poll()) != null ) + { + for( WiredNode neighbour : node.neighbours ) + { // Otherwise attempt to enqueue this neighbour as well. - if (reachable.add(neighbour)) { - enqueued.add(neighbour); + if( reachable.add( neighbour ) ) + { + enqueued.add( neighbour ); } } } @@ -462,29 +532,36 @@ public final class WiredNetwork implements IWiredNetwork { return reachable; } - private static WiredNode checkNode(IWiredNode node) { - if (node instanceof WiredNode) { + private static WiredNode checkNode( IWiredNode node ) + { + if( node instanceof WiredNode ) + { return (WiredNode) node; - } else { - throw new IllegalArgumentException("Unknown implementation of IWiredNode: " + node); + } + else + { + throw new IllegalArgumentException( "Unknown implementation of IWiredNode: " + node ); } } - private static class TransmitPoint implements Comparable { + private static class TransmitPoint implements Comparable + { final WiredNode node; double distance; boolean interdimensional; - TransmitPoint(WiredNode node, double distance, boolean interdimensional) { + TransmitPoint( WiredNode node, double distance, boolean interdimensional ) + { this.node = node; this.distance = distance; this.interdimensional = interdimensional; } @Override - public int compareTo(@Nonnull TransmitPoint o) { + public int compareTo( @Nonnull TransmitPoint o ) + { // Objects with the same distance are not the same object, so we must add an additional layer of ordering. - return this.distance == o.distance ? Integer.compare(this.node.hashCode(), o.node.hashCode()) : Double.compare(this.distance, o.distance); + return this.distance == o.distance ? Integer.compare( this.node.hashCode(), o.node.hashCode() ) : Double.compare( this.distance, o.distance ); } } } diff --git a/src/main/java/dan200/computercraft/shared/wired/WiredNetworkChange.java b/src/main/java/dan200/computercraft/shared/wired/WiredNetworkChange.java index fac45ccf7..cdaabfc32 100644 --- a/src/main/java/dan200/computercraft/shared/wired/WiredNetworkChange.java +++ b/src/main/java/dan200/computercraft/shared/wired/WiredNetworkChange.java @@ -6,96 +6,121 @@ package dan200.computercraft.shared.wired; +import dan200.computercraft.api.network.wired.IWiredNetworkChange; +import dan200.computercraft.api.peripheral.IPeripheral; + +import javax.annotation.Nonnull; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; - -import dan200.computercraft.api.network.wired.IWiredNetworkChange; -import dan200.computercraft.api.peripheral.IPeripheral; - -public final class WiredNetworkChange implements IWiredNetworkChange { - private static final WiredNetworkChange EMPTY = new WiredNetworkChange(Collections.emptyMap(), Collections.emptyMap()); +public final class WiredNetworkChange implements IWiredNetworkChange +{ + private static final WiredNetworkChange EMPTY = new WiredNetworkChange( Collections.emptyMap(), Collections.emptyMap() ); private final Map removed; private final Map added; - private WiredNetworkChange(Map removed, Map added) { + private WiredNetworkChange( Map removed, Map added ) + { this.removed = removed; this.added = added; } - public static WiredNetworkChange added(Map added) { - return added.isEmpty() ? EMPTY : new WiredNetworkChange(Collections.emptyMap(), Collections.unmodifiableMap(added)); + public static WiredNetworkChange added( Map added ) + { + return added.isEmpty() ? EMPTY : new WiredNetworkChange( Collections.emptyMap(), Collections.unmodifiableMap( added ) ); } - public static WiredNetworkChange removed(Map removed) { - return removed.isEmpty() ? EMPTY : new WiredNetworkChange(Collections.unmodifiableMap(removed), Collections.emptyMap()); + public static WiredNetworkChange removed( Map removed ) + { + return removed.isEmpty() ? EMPTY : new WiredNetworkChange( Collections.unmodifiableMap( removed ), Collections.emptyMap() ); } - public static WiredNetworkChange changeOf(Map oldPeripherals, Map newPeripherals) { + public static WiredNetworkChange changeOf( Map oldPeripherals, Map newPeripherals ) + { // Handle the trivial cases, where all peripherals have been added or removed. - if (oldPeripherals.isEmpty() && newPeripherals.isEmpty()) { + if( oldPeripherals.isEmpty() && newPeripherals.isEmpty() ) + { return EMPTY; - } else if (oldPeripherals.isEmpty()) { - return new WiredNetworkChange(Collections.emptyMap(), newPeripherals); - } else if (newPeripherals.isEmpty()) { - return new WiredNetworkChange(oldPeripherals, Collections.emptyMap()); + } + else if( oldPeripherals.isEmpty() ) + { + return new WiredNetworkChange( Collections.emptyMap(), newPeripherals ); + } + else if( newPeripherals.isEmpty() ) + { + return new WiredNetworkChange( oldPeripherals, Collections.emptyMap() ); } - Map added = new HashMap<>(newPeripherals); + Map added = new HashMap<>( newPeripherals ); Map removed = new HashMap<>(); - for (Map.Entry entry : oldPeripherals.entrySet()) { + for( Map.Entry entry : oldPeripherals.entrySet() ) + { String oldKey = entry.getKey(); IPeripheral oldValue = entry.getValue(); - if (newPeripherals.containsKey(oldKey)) { - IPeripheral rightValue = added.get(oldKey); - if (oldValue.equals(rightValue)) { - added.remove(oldKey); - } else { - removed.put(oldKey, oldValue); + if( newPeripherals.containsKey( oldKey ) ) + { + IPeripheral rightValue = added.get( oldKey ); + if( oldValue.equals( rightValue ) ) + { + added.remove( oldKey ); } - } else { - removed.put(oldKey, oldValue); + else + { + removed.put( oldKey, oldValue ); + } + } + else + { + removed.put( oldKey, oldValue ); } } - return changed(removed, added); + return changed( removed, added ); } - public static WiredNetworkChange changed(Map removed, Map added) { - return new WiredNetworkChange(Collections.unmodifiableMap(removed), Collections.unmodifiableMap(added)); + public static WiredNetworkChange changed( Map removed, Map added ) + { + return new WiredNetworkChange( Collections.unmodifiableMap( removed ), Collections.unmodifiableMap( added ) ); } @Nonnull @Override - public Map peripheralsRemoved() { + public Map peripheralsRemoved() + { return this.removed; } @Nonnull @Override - public Map peripheralsAdded() { + public Map peripheralsAdded() + { return this.added; } - void broadcast(Iterable nodes) { - if (!this.isEmpty()) { - for (WiredNode node : nodes) { - node.element.networkChanged(this); + void broadcast( Iterable nodes ) + { + if( !this.isEmpty() ) + { + for( WiredNode node : nodes ) + { + node.element.networkChanged( this ); } } } - public boolean isEmpty() { + public boolean isEmpty() + { return this.added.isEmpty() && this.removed.isEmpty(); } - void broadcast(WiredNode node) { - if (!this.isEmpty()) { - node.element.networkChanged(this); + void broadcast( WiredNode node ) + { + if( !this.isEmpty() ) + { + node.element.networkChanged( this ); } } } diff --git a/src/main/java/dan200/computercraft/shared/wired/WiredNode.java b/src/main/java/dan200/computercraft/shared/wired/WiredNode.java index 8d1c55241..fdb5048f0 100644 --- a/src/main/java/dan200/computercraft/shared/wired/WiredNode.java +++ b/src/main/java/dan200/computercraft/shared/wired/WiredNode.java @@ -6,15 +6,6 @@ package dan200.computercraft.shared.wired; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.locks.Lock; - -import javax.annotation.Nonnull; - import dan200.computercraft.api.network.IPacketReceiver; import dan200.computercraft.api.network.Packet; import dan200.computercraft.api.network.wired.IWiredElement; @@ -23,76 +14,100 @@ import dan200.computercraft.api.network.wired.IWiredNode; import dan200.computercraft.api.network.wired.IWiredSender; import dan200.computercraft.api.peripheral.IPeripheral; -public final class WiredNode implements IWiredNode { +import javax.annotation.Nonnull; +import java.util.*; +import java.util.concurrent.locks.Lock; + +public final class WiredNode implements IWiredNode +{ final IWiredElement element; final HashSet neighbours = new HashSet<>(); Map peripherals = Collections.emptyMap(); volatile WiredNetwork network; private Set receivers; - public WiredNode(IWiredElement element) { + public WiredNode( IWiredElement element ) + { this.element = element; - this.network = new WiredNetwork(this); + this.network = new WiredNetwork( this ); } @Override - public synchronized void addReceiver(@Nonnull IPacketReceiver receiver) { - if (this.receivers == null) { + public synchronized void addReceiver( @Nonnull IPacketReceiver receiver ) + { + if( this.receivers == null ) + { this.receivers = new HashSet<>(); } - this.receivers.add(receiver); + this.receivers.add( receiver ); } @Override - public synchronized void removeReceiver(@Nonnull IPacketReceiver receiver) { - if (this.receivers != null) { - this.receivers.remove(receiver); + public synchronized void removeReceiver( @Nonnull IPacketReceiver receiver ) + { + if( this.receivers != null ) + { + this.receivers.remove( receiver ); } } @Override - public boolean isWireless() { + public boolean isWireless() + { return false; } @Override - public void transmitSameDimension(@Nonnull Packet packet, double range) { - Objects.requireNonNull(packet, "packet cannot be null"); - if (!(packet.getSender() instanceof IWiredSender) || ((IWiredSender) packet.getSender()).getNode() != this) { - throw new IllegalArgumentException("Sender is not in the network"); + public void transmitSameDimension( @Nonnull Packet packet, double range ) + { + Objects.requireNonNull( packet, "packet cannot be null" ); + if( !(packet.getSender() instanceof IWiredSender) || ((IWiredSender) packet.getSender()).getNode() != this ) + { + throw new IllegalArgumentException( "Sender is not in the network" ); } this.acquireReadLock(); - try { - WiredNetwork.transmitPacket(this, packet, range, false); - } finally { + try + { + WiredNetwork.transmitPacket( this, packet, range, false ); + } + finally + { this.network.lock.readLock() - .unlock(); + .unlock(); } } @Override - public void transmitInterdimensional(@Nonnull Packet packet) { - Objects.requireNonNull(packet, "packet cannot be null"); - if (!(packet.getSender() instanceof IWiredSender) || ((IWiredSender) packet.getSender()).getNode() != this) { - throw new IllegalArgumentException("Sender is not in the network"); + public void transmitInterdimensional( @Nonnull Packet packet ) + { + Objects.requireNonNull( packet, "packet cannot be null" ); + if( !(packet.getSender() instanceof IWiredSender) || ((IWiredSender) packet.getSender()).getNode() != this ) + { + throw new IllegalArgumentException( "Sender is not in the network" ); } this.acquireReadLock(); - try { - WiredNetwork.transmitPacket(this, packet, 0, true); - } finally { + try + { + WiredNetwork.transmitPacket( this, packet, 0, true ); + } + finally + { this.network.lock.readLock() - .unlock(); + .unlock(); } } - private void acquireReadLock() { + private void acquireReadLock() + { WiredNetwork currentNetwork = this.network; - while (true) { + while( true ) + { Lock lock = currentNetwork.lock.readLock(); lock.lock(); - if (currentNetwork == this.network) { + if( currentNetwork == this.network ) + { return; } @@ -101,22 +116,30 @@ public final class WiredNode implements IWiredNode { } } - synchronized void tryTransmit(Packet packet, double packetDistance, boolean packetInterdimensional, double range, boolean interdimensional) { - if (this.receivers == null) { + synchronized void tryTransmit( Packet packet, double packetDistance, boolean packetInterdimensional, double range, boolean interdimensional ) + { + if( this.receivers == null ) + { return; } - for (IPacketReceiver receiver : this.receivers) { - if (!packetInterdimensional) { - double receiveRange = Math.max(range, receiver.getRange()); // Ensure range is symmetrical - if (interdimensional || receiver.isInterdimensional() || packetDistance < receiveRange) { - receiver.receiveSameDimension(packet, - packetDistance + this.element.getPosition() - .distanceTo(receiver.getPosition())); + for( IPacketReceiver receiver : this.receivers ) + { + if( !packetInterdimensional ) + { + double receiveRange = Math.max( range, receiver.getRange() ); // Ensure range is symmetrical + if( interdimensional || receiver.isInterdimensional() || packetDistance < receiveRange ) + { + receiver.receiveSameDimension( packet, + packetDistance + this.element.getPosition() + .distanceTo( receiver.getPosition() ) ); } - } else { - if (interdimensional || receiver.isInterdimensional()) { - receiver.receiveDifferentDimension(packet); + } + else + { + if( interdimensional || receiver.isInterdimensional() ) + { + receiver.receiveDifferentDimension( packet ); } } } @@ -124,19 +147,22 @@ public final class WiredNode implements IWiredNode { @Nonnull @Override - public IWiredElement getElement() { + public IWiredElement getElement() + { return this.element; } @Nonnull @Override - public IWiredNetwork getNetwork() { + public IWiredNetwork getNetwork() + { return this.network; } @Override - public String toString() { + public String toString() + { return "WiredNode{@" + this.element.getPosition() + " (" + this.element.getClass() - .getSimpleName() + ")}"; + .getSimpleName() + ")}"; } }