Do something with the wireless terminal
This commit is contained in:
		| @@ -11,7 +11,7 @@ loader_version=0.16.0 | ||||
| fabric_version=0.102.1+1.21.1 | ||||
|  | ||||
| # Mod Properties | ||||
| mod_version=3.1.2 | ||||
| mod_version=3.2 | ||||
| maven_group=systems.brn | ||||
| archives_base_name=Serverstorage | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package systems.brn.serverstorage; | ||||
|  | ||||
| import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; | ||||
| import net.fabricmc.api.ModInitializer; | ||||
| import net.fabricmc.fabric.api.event.player.UseItemCallback; | ||||
| import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; | ||||
| import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; | ||||
| import net.minecraft.block.entity.BlockEntityType; | ||||
| @@ -11,16 +12,19 @@ import net.minecraft.util.Identifier; | ||||
| import net.minecraft.world.GameRules; | ||||
| import systems.brn.serverstorage.blockentities.HardDriveContainerBlockEntity; | ||||
| import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.blocks.BusConnectorBlock; | ||||
| import systems.brn.serverstorage.blocks.HardDriveContainerBlock; | ||||
| import systems.brn.serverstorage.blocks.InventoryInterfaceBlock; | ||||
| import systems.brn.serverstorage.blocks.StorageInterfaceBlock; | ||||
| import systems.brn.serverstorage.blocks.*; | ||||
| import systems.brn.serverstorage.items.HardDriveItem; | ||||
| import systems.brn.serverstorage.items.SimpleBlockItem; | ||||
| import systems.brn.serverstorage.items.SimpleItem; | ||||
| import systems.brn.serverstorage.items.WirelessTerminalItem; | ||||
| import systems.brn.serverstorage.lib.Antenna; | ||||
| import systems.brn.serverstorage.lib.EventHandler; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
|  | ||||
| public class ServerStorage implements ModInitializer { | ||||
| @@ -30,6 +34,8 @@ public class ServerStorage implements ModInitializer { | ||||
|  | ||||
|     public static final String MOD_ID = "serverstorage"; | ||||
|  | ||||
|     public static final String WIRELESS_TERMINAL_ID = "wireless_terminal"; | ||||
|  | ||||
|     public static final String BUS_CONNECTOR_MODEL_ID = "bus_connector"; | ||||
|     public static BusConnectorBlock BUS_CONNECTOR_BLOCK; | ||||
|  | ||||
| @@ -37,6 +43,10 @@ public class ServerStorage implements ModInitializer { | ||||
|     public static BlockEntityType<HardDriveContainerBlockEntity> HARD_DRIVE_CONTAINER_BLOCK_ENTITY; | ||||
|     public static HardDriveContainerBlock HARD_DRIVE_CONTAINER_BLOCK; | ||||
|  | ||||
|     public static final String RADIO_INTERFACE_BLOCK_MODEL_ID = "radio_interface"; | ||||
|     public static BlockEntityType<RadioInterfaceBlockEntity> RADIO_INTERFACE_BLOCK_ENTITY; | ||||
|     public static RadioInterfaceBlock RADIO_INTERFACE_BLOCK; | ||||
|  | ||||
|     public static final String STORAGE_MODEL_ID = "storage"; | ||||
|     public static StorageInterfaceBlock STORAGE_INTERFACE_BLOCK; | ||||
|     public static BlockEntityType<StorageInterfaceBlockEntity> STORAGE_INTERFACE_BLOCK_ENTITY; | ||||
| @@ -60,6 +70,10 @@ public class ServerStorage implements ModInitializer { | ||||
|     public static List<Item> PLATTERS; | ||||
|     public static List<Item> DRIVES; | ||||
|     public static List<Item> HEADS; | ||||
|     public static List<Item> ANTENNA_LIST = new ArrayList<>(); | ||||
|     public static final HashMap<Item, Integer> ANTENNA_RANGES = new HashMap<>(); | ||||
|  | ||||
|     public static Item WIRELESS_TERMINAL; | ||||
|  | ||||
|  | ||||
|     public static Identifier id(String path) { | ||||
| @@ -80,6 +94,9 @@ public class ServerStorage implements ModInitializer { | ||||
|         InventoryInterfaceBlock.register(); | ||||
|         SimpleBlockItem.register(INVENTORY_INTERFACE_BLOCK); | ||||
|  | ||||
|         RadioInterfaceBlock.register(); | ||||
|         SimpleBlockItem.register(RADIO_INTERFACE_BLOCK); | ||||
|  | ||||
|         MATERIALS = SimpleItem.register("material", materialList, false, ItemGroups.INGREDIENTS); | ||||
|         MODULES = SimpleItem.register("module", moduleList, false, ItemGroups.INGREDIENTS); | ||||
|  | ||||
| @@ -88,6 +105,12 @@ public class ServerStorage implements ModInitializer { | ||||
|  | ||||
|         DRIVES = HardDriveItem.register(tiers); | ||||
|  | ||||
|         ANTENNA_LIST = Antenna.register(tiers); | ||||
|  | ||||
|         WIRELESS_TERMINAL = WirelessTerminalItem.register(); | ||||
|  | ||||
|         UseItemCallback.EVENT.register(EventHandler::onItemUse); | ||||
|  | ||||
|         systems.brn.serverstorage.lib.ItemGroups.register(); | ||||
|         PolymerResourcePackUtils.addModAssets(MOD_ID); | ||||
|         PolymerResourcePackUtils.markAsRequired(); | ||||
|   | ||||
| @@ -0,0 +1,129 @@ | ||||
| package systems.brn.serverstorage.blockentities; | ||||
|  | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.entity.LootableContainerBlockEntity; | ||||
| import net.minecraft.entity.player.PlayerInventory; | ||||
| import net.minecraft.inventory.Inventories; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.nbt.NbtCompound; | ||||
| import net.minecraft.nbt.NbtList; | ||||
| import net.minecraft.registry.RegistryWrapper; | ||||
| import net.minecraft.screen.ScreenHandler; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.collection.DefaultedList; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import systems.brn.serverstorage.lib.Session; | ||||
| import systems.brn.serverstorage.screenhandlers.RadioInterfaceScreenHandler; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.UUID; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.ANTENNA_RANGES; | ||||
| import static systems.brn.serverstorage.ServerStorage.RADIO_INTERFACE_BLOCK_ENTITY; | ||||
|  | ||||
| public class RadioInterfaceBlockEntity extends LootableContainerBlockEntity { | ||||
|     public DefaultedList<ItemStack> inventory; | ||||
|     public int antennaRange = 0; | ||||
|     public final ArrayList<Session> sessions = new ArrayList<>(); | ||||
|     public static final int INVENTORY_SIZE = 1; | ||||
|  | ||||
|     public RadioInterfaceBlockEntity(BlockPos pos, BlockState state) { | ||||
|         super(RADIO_INTERFACE_BLOCK_ENTITY, pos, state); | ||||
|         this.inventory = DefaultedList.ofSize(INVENTORY_SIZE, ItemStack.EMPTY); | ||||
|         updateAntenna(); | ||||
|     } | ||||
|  | ||||
|     public boolean isSessionAuthorized(UUID sessionKey, UUID playerUUID) { | ||||
|         for (Session session : sessions) { | ||||
|             if (session.sessionKey().equals(sessionKey) && session.playerUUID().equals(playerUUID)) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public void authorizeSession(UUID sessionKey, ServerPlayerEntity player) { | ||||
|         if (!isSessionAuthorized(sessionKey, player.getUuid())) { | ||||
|             sessions.add(new Session(sessionKey, player.getUuid())); | ||||
|             markDirty(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void deAuthorizeSession(UUID sessionKey, UUID playerUUID) { | ||||
|         for (Session session : sessions) { | ||||
|             if (session.sessionKey().equals(sessionKey) && session.playerUUID().equals(playerUUID)) { | ||||
|                 sessions.remove(session); | ||||
|                 markDirty(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void updateAntenna() { | ||||
|         ItemStack stack = inventory.getFirst(); | ||||
|         if (!stack.isEmpty()) { | ||||
|             Item antennaItem = stack.getItem(); | ||||
|             antennaRange = ANTENNA_RANGES.getOrDefault(antennaItem, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected Text getContainerName() { | ||||
|         return Text.translatable("block.serverstorage.radio_interface"); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DefaultedList<ItemStack> getHeldStacks() { | ||||
|         return inventory; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void setHeldStacks(DefaultedList<ItemStack> inventory) { | ||||
|         this.inventory = inventory; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected ScreenHandler createScreenHandler(int syncId, PlayerInventory playerInventory) { | ||||
|         return new RadioInterfaceScreenHandler(syncId, playerInventory, this); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int size() { | ||||
|         return INVENTORY_SIZE; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { | ||||
|         super.readNbt(nbt, registryLookup); | ||||
|         this.inventory = DefaultedList.ofSize(this.size(), ItemStack.EMPTY); | ||||
|         this.antennaRange = nbt.getInt("AntennaRange"); | ||||
|         if (!this.readLootTable(nbt)) { | ||||
|             Inventories.readNbt(nbt, this.inventory, registryLookup); | ||||
|         } | ||||
|         updateAntenna(); | ||||
|         // Deserialize sessions list | ||||
|         this.sessions.clear(); | ||||
|         NbtList sessionsNbtList = nbt.getList("Sessions", 10); // 10 = NbtCompound type | ||||
|         for (int i = 0; i < sessionsNbtList.size(); i++) { | ||||
|             NbtCompound sessionNbt = sessionsNbtList.getCompound(i); | ||||
|             this.sessions.add(Session.fromNbt(sessionNbt)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { | ||||
|         super.writeNbt(nbt, registryLookup); | ||||
|         nbt.putInt("AntennaRange", antennaRange); | ||||
|         if (!this.writeLootTable(nbt)) { | ||||
|             Inventories.writeNbt(nbt, this.inventory, registryLookup); | ||||
|         } | ||||
|         // Serialize sessions list | ||||
|         NbtList sessionsNbtList = new NbtList(); | ||||
|         for (Session session : sessions) { | ||||
|             sessionsNbtList.add(session.toNbt()); | ||||
|         } | ||||
|         nbt.put("Sessions", sessionsNbtList); | ||||
|     } | ||||
| } | ||||
| @@ -37,6 +37,12 @@ public class StorageInterfaceBlockEntity extends BlockEntity { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void enforceNetwork() { | ||||
|         if (this.network == null) { | ||||
|             this.network = new StorageNetwork(world, this.pos, sortAlphabetically, searchString); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void refreshTerminals() { | ||||
|         reindexDrives(); | ||||
|         this.network.updateDisplays(); | ||||
|   | ||||
| @@ -0,0 +1,151 @@ | ||||
| package systems.brn.serverstorage.blocks; | ||||
|  | ||||
| import eu.pb4.polymer.blocks.api.BlockModelType; | ||||
| import eu.pb4.polymer.blocks.api.PolymerBlockModel; | ||||
| import eu.pb4.polymer.blocks.api.PolymerBlockResourceUtils; | ||||
| import eu.pb4.polymer.blocks.api.PolymerTexturedBlock; | ||||
| import eu.pb4.polymer.core.api.block.PolymerBlockUtils; | ||||
| import net.fabricmc.fabric.api.event.player.UseBlockCallback; | ||||
| import net.minecraft.block.*; | ||||
| import net.minecraft.block.entity.BlockEntity; | ||||
| import net.minecraft.block.entity.BlockEntityType; | ||||
| import net.minecraft.entity.player.PlayerEntity; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemPlacementContext; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.registry.Registries; | ||||
| import net.minecraft.registry.Registry; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.state.StateManager; | ||||
| import net.minecraft.state.property.DirectionProperty; | ||||
| import net.minecraft.util.ActionResult; | ||||
| import net.minecraft.util.Hand; | ||||
| import net.minecraft.util.Identifier; | ||||
| import net.minecraft.util.ItemScatterer; | ||||
| import net.minecraft.util.hit.BlockHitResult; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import net.minecraft.util.math.Direction; | ||||
| import net.minecraft.world.World; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.items.WirelessTerminalItem; | ||||
| import systems.brn.serverstorage.lib.SessionStorageClass; | ||||
| import systems.brn.serverstorage.lib.WirelessTerminalComponents; | ||||
| import systems.brn.serverstorage.screens.RadioBlockPlayerMangementScreen; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.UUID; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.*; | ||||
| import static systems.brn.serverstorage.lib.Util.removePosition; | ||||
|  | ||||
| public class RadioInterfaceBlock extends ConnectedBlock implements PolymerTexturedBlock, BlockEntityProvider { | ||||
|     final Identifier identifier; | ||||
|     public static final DirectionProperty FACING = FacingBlock.FACING; | ||||
|     private final BlockState polymerBlockState; | ||||
|  | ||||
|     public RadioInterfaceBlock(Settings settings, Identifier identifier) { | ||||
|         super(settings, Blocks.NOTE_BLOCK); | ||||
|         this.identifier = identifier; | ||||
|         this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH)); | ||||
|         this.polymerBlockState = PolymerBlockResourceUtils.requestBlock(BlockModelType.FULL_BLOCK, PolymerBlockModel.of(identifier.withPath("block/" + identifier.getPath()))); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public BlockState getPlacementState(ItemPlacementContext ctx) { | ||||
|         return this.getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { | ||||
|         super.appendProperties(builder); | ||||
|         builder.add(FACING); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public BlockState getPolymerBlockState(BlockState state) { | ||||
|         return this.polymerBlockState; | ||||
|     } | ||||
|  | ||||
|     public static void register() { | ||||
|         var modId = id(RADIO_INTERFACE_BLOCK_MODEL_ID); | ||||
|         RADIO_INTERFACE_BLOCK = Registry.register(Registries.BLOCK, modId, | ||||
|                 new RadioInterfaceBlock(Settings.copy(Blocks.WHITE_WOOL), modId)); | ||||
|         UseBlockCallback.EVENT.register(RadioInterfaceBlock::onUse); | ||||
|  | ||||
|         RADIO_INTERFACE_BLOCK.setDefaultState(); | ||||
|  | ||||
|         RADIO_INTERFACE_BLOCK_ENTITY = Registry.register( | ||||
|                 Registries.BLOCK_ENTITY_TYPE, | ||||
|                 modId, | ||||
|                 BlockEntityType.Builder.create(RadioInterfaceBlockEntity::new, RADIO_INTERFACE_BLOCK).build(null) | ||||
|         ); | ||||
|         PolymerBlockUtils.registerBlockEntity(RADIO_INTERFACE_BLOCK_ENTITY); | ||||
|     } | ||||
|  | ||||
|     private static ActionResult onUse(PlayerEntity plr, World world, Hand hand, BlockHitResult hitResult) { | ||||
|         BlockPos pos = hitResult.getBlockPos(); | ||||
|         BlockState state = world.getBlockState(pos); | ||||
|         Block block = state.getBlock(); | ||||
|  | ||||
|         if (block instanceof RadioInterfaceBlock) { | ||||
|             if (!world.isClient && !plr.isSpectator() && plr instanceof ServerPlayerEntity player && hand == Hand.MAIN_HAND) { | ||||
|                 BlockEntity storageBlockEntity = world.getBlockEntity(pos); | ||||
|                 if (storageBlockEntity instanceof RadioInterfaceBlockEntity radioInterfaceBlockEntity) { | ||||
|                     if (!player.isSneaking()) { | ||||
|                         RadioBlockPlayerMangementScreen radioBlockPlayerMangementScreen = new RadioBlockPlayerMangementScreen(player, radioInterfaceBlockEntity); | ||||
|                         radioBlockPlayerMangementScreen.updateDisplay(); | ||||
|                         radioBlockPlayerMangementScreen.open(); | ||||
|                     } else { | ||||
|                         ItemStack stack = player.getStackInHand(hand); | ||||
|                         Item item = stack.getItem(); | ||||
|                         if (item == WIRELESS_TERMINAL) { | ||||
|                             WirelessTerminalItem.ensureUUID(stack, player.getServer()); | ||||
|                             UUID wirelessTerminalSession = stack.getOrDefault(WirelessTerminalComponents.SESSION_KEY, null); | ||||
|                             List<SessionStorageClass> wirelessTerminalSessions = new ArrayList<>(stack.getOrDefault(WirelessTerminalComponents.SESSIONS, new ArrayList<>())); | ||||
|                             if (wirelessTerminalSession != null) { | ||||
|                                 if (radioInterfaceBlockEntity.isSessionAuthorized(wirelessTerminalSession, player.getUuid())) { | ||||
|                                     radioInterfaceBlockEntity.deAuthorizeSession(wirelessTerminalSession, player.getUuid()); | ||||
|                                     removePosition(pos, stack); | ||||
|                                 } else { | ||||
|                                     radioInterfaceBlockEntity.authorizeSession(wirelessTerminalSession, player); | ||||
|                                     SessionStorageClass sessionStorageClass = null; | ||||
|                                     for (SessionStorageClass sessionStorageClassLoop : wirelessTerminalSessions) { | ||||
|                                         if (sessionStorageClassLoop.getTerminalPos().equals(pos)) { | ||||
|                                             sessionStorageClass = sessionStorageClassLoop; | ||||
|                                             break; | ||||
|                                         } | ||||
|                                     } | ||||
|                                     if (sessionStorageClass == null || !sessionStorageClass.getPlayerUUID().equals(player.getUuid())) { | ||||
|                                         sessionStorageClass = new SessionStorageClass(player.getUuid(), player.getServerWorld(), pos); | ||||
|                                         wirelessTerminalSessions.add(sessionStorageClass); | ||||
|                                     } | ||||
|                                     stack.set(WirelessTerminalComponents.SESSIONS, wirelessTerminalSessions); | ||||
|                                 } | ||||
|                             } | ||||
|                             WirelessTerminalItem.updateLore(stack, player.getServer()); | ||||
|                             player.setStackInHand(hand, stack); | ||||
|                         } else { | ||||
|                             player.openHandledScreen(radioInterfaceBlockEntity); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return ActionResult.SUCCESS; | ||||
|         } | ||||
|         return ActionResult.PASS; | ||||
|     } | ||||
|  | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||
|         return new RadioInterfaceBlockEntity(pos, state); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { | ||||
|         ItemScatterer.onStateReplaced(state, newState, world, pos); | ||||
|         super.onStateReplaced(state, world, pos, newState, moved); | ||||
|     } | ||||
| } | ||||
| @@ -22,8 +22,8 @@ public class SimpleItem extends SimplePolymerItem implements PolymerItem { | ||||
|     private final PolymerModelData polymerModel; | ||||
|  | ||||
|     public SimpleItem(Settings settings, Identifier identifier) { | ||||
|         super(settings, Items.BARRIER); | ||||
|         this.polymerModel = PolymerResourcePackUtils.requestModel(Items.BARRIER, identifier.withPath("item/" + identifier.getPath())); | ||||
|         super(settings, Items.STICK); | ||||
|         this.polymerModel = PolymerResourcePackUtils.requestModel(Items.STICK, identifier.withPath("item/" + identifier.getPath())); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -0,0 +1,252 @@ | ||||
| package systems.brn.serverstorage.items; | ||||
|  | ||||
| import com.mojang.authlib.GameProfile; | ||||
| import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; | ||||
| import net.minecraft.component.DataComponentTypes; | ||||
| import net.minecraft.component.type.LoreComponent; | ||||
| import net.minecraft.entity.player.PlayerInventory; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemGroups; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.registry.Registries; | ||||
| import net.minecraft.registry.Registry; | ||||
| import net.minecraft.server.MinecraftServer; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.server.world.ServerWorld; | ||||
| import net.minecraft.sound.SoundCategory; | ||||
| import net.minecraft.sound.SoundEvents; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Hand; | ||||
| import net.minecraft.util.Identifier; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import net.minecraft.util.math.Vec3d; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.lib.*; | ||||
| import systems.brn.serverstorage.screens.StorageScreen; | ||||
| import systems.brn.serverstorage.screens.WirelessTerminalSelectorScreen; | ||||
|  | ||||
| import java.util.*; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.*; | ||||
|  | ||||
| public class WirelessTerminalItem extends SimpleItem { | ||||
|     public WirelessTerminalItem(Settings settings, Identifier identifier) { | ||||
|         super(settings, identifier); | ||||
|     } | ||||
|  | ||||
|     public static Item register() { | ||||
|         Identifier identifier = id(WIRELESS_TERMINAL_ID); | ||||
|         Item item = Registry.register(Registries.ITEM, identifier, new SimpleItem( | ||||
|                 new Settings() | ||||
|                         .maxCount(1) | ||||
|                         .component(WirelessTerminalComponents.SESSION_KEY, null) | ||||
|                         .component(WirelessTerminalComponents.SESSIONS, new ArrayList<>()) | ||||
|                         .component(WirelessTerminalComponents.SELECTED_POSITION, -1) | ||||
|                         .component(WirelessTerminalComponents.SORT_ALPHABETICALLY, false) | ||||
|                         .component(WirelessTerminalComponents.QUERY_STRING, "") | ||||
|                         .component(WirelessTerminalComponents.PAGE, 0) | ||||
|                 , identifier)); | ||||
|         ItemGroupEvents.modifyEntriesEvent(ItemGroups.FUNCTIONAL).register(content -> content.add(item)); | ||||
|         return item; | ||||
|     } | ||||
|  | ||||
|     public static RadioInterfaceBlockEntity getRadioInterface(BlockPos pos, ServerWorld world) { | ||||
|         if (world.getBlockState(pos).getBlock() == RADIO_INTERFACE_BLOCK && world.getBlockEntity(pos) instanceof RadioInterfaceBlockEntity radioInterfaceBlockEntity) { | ||||
|             return radioInterfaceBlockEntity; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public static RadioDistance getDistance(ServerPlayerEntity player, RadioInterfaceBlockEntity radioInterfaceBlockEntity) { | ||||
|         Vec3d playerTempPos = player.getPos(); | ||||
|         BlockPos playerPos = player.getBlockPos(); | ||||
|         BlockPos pos = radioInterfaceBlockEntity.getPos(); | ||||
|         ServerWorld playerWorld = player.getServerWorld(); | ||||
|         ServerWorld terminalWorld = playerWorld; | ||||
|         int finalDistance = 0; | ||||
|         int actualDistance = 0; | ||||
|         if (radioInterfaceBlockEntity.getWorld() instanceof ServerWorld terminalWorldTemp) { | ||||
|             double distanceCoefficient = 1; | ||||
|             terminalWorld = terminalWorldTemp; | ||||
|             if (playerWorld.getRegistryKey() != terminalWorld.getRegistryKey()) { | ||||
|                 int playerWorldScale = (int) playerWorld.getDimension().coordinateScale(); | ||||
|                 int terminalWorldScale = (int) terminalWorld.getDimension().coordinateScale(); | ||||
|                 playerTempPos = new Vec3d(playerTempPos.getX() * playerWorldScale, playerTempPos.getY(), playerTempPos.getZ() * terminalWorldScale); | ||||
|                 playerTempPos = new Vec3d(playerTempPos.getX() / terminalWorldScale, playerTempPos.getY(), playerTempPos.getZ() / terminalWorldScale); | ||||
|                 distanceCoefficient = 0.4; | ||||
|             } | ||||
|             playerPos = BlockPos.ofFloored(playerTempPos); | ||||
|             finalDistance = (int) (radioInterfaceBlockEntity.antennaRange * distanceCoefficient); | ||||
|             finalDistance = Math.max(finalDistance, 1); | ||||
|             actualDistance = (int) Math.sqrt(playerPos.getSquaredDistance(pos)); | ||||
|         } | ||||
|         return new RadioDistance(radioInterfaceBlockEntity, finalDistance, actualDistance, playerPos, pos, playerWorld, terminalWorld); | ||||
|     } | ||||
|  | ||||
|     public static boolean openTerminal(BlockPos pos, ServerPlayerEntity player, ItemStack stack, ServerWorld world) { | ||||
|  | ||||
|         ServerWorld playerWorld = player.getServerWorld(); | ||||
|         String playerWorldName = playerWorld.getRegistryKey().getValue().toString(); | ||||
|         String terminalWorldName = world.getRegistryKey().getValue().toString(); | ||||
|         if (stack.getItem() == WIRELESS_TERMINAL) { | ||||
|             RadioInterfaceBlockEntity radioInterfaceBlockEntity = WirelessTerminalItem.getRadioInterface(pos, world); | ||||
|             if (radioInterfaceBlockEntity != null) { | ||||
|                 RadioDistance radioDistance = getDistance(player, radioInterfaceBlockEntity); | ||||
|                 if (radioInterfaceBlockEntity.antennaRange > 0 && radioDistance.actualDistance() <= radioDistance.finalDistance()) { | ||||
|                     player.sendMessage(Text.translatable("gui.serverstorage.radio_connected", pos.toShortString(), terminalWorldName, radioDistance.playerPos().toShortString(), playerWorldName, radioDistance.actualDistance(), radioDistance.finalDistance()), true); | ||||
|                     UUID wirelessTerminalSession = stack.getOrDefault(WirelessTerminalComponents.SESSION_KEY, null); | ||||
|                     if (radioInterfaceBlockEntity.isSessionAuthorized(wirelessTerminalSession, player.getUuid())) { | ||||
|                         boolean sortAlphabetically = stack.getOrDefault(WirelessTerminalComponents.SORT_ALPHABETICALLY, false); | ||||
|                         String searchQuery = stack.getOrDefault(WirelessTerminalComponents.QUERY_STRING, ""); | ||||
|                         StorageNetwork storageNetwork = new StorageNetwork(world, pos, sortAlphabetically, searchQuery); | ||||
|                         StorageScreen storageScreen = new StorageScreen(player, stack, storageNetwork, radioInterfaceBlockEntity); | ||||
|                         storageScreen.updateDisplay(); | ||||
|                         storageScreen.open(); | ||||
|                     } else { | ||||
|                         player.sendMessage(Text.translatable("gui.serverstorage.radio_unauthorized", pos.toShortString(), terminalWorldName), true); | ||||
|                         player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_BASS.value(), SoundCategory.PLAYERS, 1f, 1f); | ||||
|                         return false; | ||||
|                     } | ||||
|                 } else { | ||||
|                     player.sendMessage(Text.translatable("gui.serverstorage.radio_out_of_range", pos.toShortString(), terminalWorldName, radioDistance.playerPos().toShortString(), playerWorldName, radioDistance.actualDistance(), radioDistance.finalDistance()), true); | ||||
|                     player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_COW_BELL.value(), SoundCategory.PLAYERS, 1f, 1f); | ||||
|                 } | ||||
|                 return true; | ||||
|             } else { | ||||
|                 player.sendMessage(Text.translatable("gui.serverstorage.radio_not_found", pos.toShortString(), terminalWorldName, player.getBlockPos().toShortString(), playerWorldName), true); | ||||
|                 player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_SNARE.value(), SoundCategory.PLAYERS, 1f, 1f); | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private static void setSelectedPosition(ItemStack stack, List<SessionStorageClass> sessions) { | ||||
|         int selectedIndex = stack.getOrDefault(WirelessTerminalComponents.SELECTED_POSITION, -1); | ||||
|         if (selectedIndex >= sessions.size()) { | ||||
|             selectedIndex = sessions.size() - 1; | ||||
|         } | ||||
|         stack.set(WirelessTerminalComponents.SELECTED_POSITION, selectedIndex); | ||||
|     } | ||||
|  | ||||
|     public static void removePosition(BlockPos pos, ItemStack stack) { | ||||
|         List<SessionStorageClass> sessions = Util.removePosition(pos, stack); | ||||
|         setSelectedPosition(stack, sessions); | ||||
|     } | ||||
|  | ||||
|     public static void ensureUUID(ItemStack stack, MinecraftServer server) { | ||||
|         UUID wirelessTerminalSession = stack.getOrDefault(WirelessTerminalComponents.SESSION_KEY, null); | ||||
|         if (wirelessTerminalSession == null) { | ||||
|             stack.set(WirelessTerminalComponents.SESSION_KEY, UUID.randomUUID()); | ||||
|             updateLore(stack, server); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static void updateLore(ItemStack stack, MinecraftServer server) { | ||||
|         UUID wirelessTerminalSessionKey = stack.getOrDefault(WirelessTerminalComponents.SESSION_KEY, null); | ||||
|         List<SessionStorageClass> sessions = new ArrayList<>(stack.getOrDefault(WirelessTerminalComponents.SESSIONS, new ArrayList<>())); | ||||
|         int selectedPositionIndex = stack.getOrDefault(WirelessTerminalComponents.SELECTED_POSITION, -1); | ||||
|         Text radioPlacedAt = Text.translatable("gui.serverstorage.radio_position_error"); | ||||
|         Text ownedBy = Text.translatable("gui.serverstorage.player_management_session_owner_error"); | ||||
|         if (selectedPositionIndex >= 0 && !sessions.isEmpty()) { | ||||
|             SessionStorageClass session = sessions.get(selectedPositionIndex); | ||||
|             BlockPos pos = session.getTerminalPos(); | ||||
|             radioPlacedAt = Text.translatable("gui.serverstorage.radio_position", pos.toShortString(), session.getWorldKey().getValue().getPath()); | ||||
|             GameProfile owner = session.getPlayerProfile(server); | ||||
|             String ownerName = owner != null ? owner.getName() : "No one"; | ||||
|             ownedBy = Text.translatable("gui.serverstorage.player_management_session_owner", ownerName); | ||||
|         } | ||||
|         int page = stack.getOrDefault(WirelessTerminalComponents.PAGE, 0); | ||||
|         boolean sortingAlphabetically = stack.getOrDefault(WirelessTerminalComponents.SORT_ALPHABETICALLY, false); | ||||
|         String searchQuery = stack.getOrDefault(WirelessTerminalComponents.QUERY_STRING, "*"); | ||||
|         if (selectedPositionIndex < 0 && !sessions.isEmpty()) { | ||||
|             selectedPositionIndex = sessions.size() - 1; | ||||
|             stack.set(WirelessTerminalComponents.SELECTED_POSITION, selectedPositionIndex); | ||||
|         } | ||||
|         stack.set(DataComponentTypes.LORE, new LoreComponent(List.of( | ||||
|                 Text.translatable("gui.serverstorage.player_management_session_key", wirelessTerminalSessionKey == null ? "Missing UUID" : wirelessTerminalSessionKey.toString()), | ||||
|                 Text.translatable("gui.serverstorage.wireless_terminal_link_count", sessions.size()), | ||||
|                 ownedBy, | ||||
|                 Text.translatable("gui.serverstorage.wireless_terminal_link_index", selectedPositionIndex), | ||||
|                 Text.translatable("gui.serverstorage.wireless_terminal_page", page), | ||||
|                 Text.translatable("gui.serverstorage.wireless_terminal_search_query", searchQuery), | ||||
|                 Text.translatable(sortingAlphabetically ? "gui.serverstorage.wireless_terminal_sorting_alphabetically" : "gui.serverstorage.wireless_terminal_sorting_numerically"), | ||||
|                 radioPlacedAt | ||||
|         ))); | ||||
|     } | ||||
|  | ||||
|     public static boolean stackMatches(ItemStack stack, ItemStack stack2) { | ||||
|         UUID stack1UUID = stack.getOrDefault(WirelessTerminalComponents.SESSION_KEY, null); | ||||
|         UUID stack2UUID = stack2.getOrDefault(WirelessTerminalComponents.SESSION_KEY, null); | ||||
|         return stack.getItem() == WIRELESS_TERMINAL && stack2.getItem() == WIRELESS_TERMINAL && stack1UUID != null && stack1UUID.equals(stack2UUID); | ||||
|     } | ||||
|  | ||||
|     public static void saveStack(ItemStack changedStack, ItemStack originalStack, ServerPlayerEntity player) { | ||||
|         ItemStack stackInMainHand = player.getMainHandStack(); | ||||
|         ItemStack stackInOffHand = player.getOffHandStack(); | ||||
|         if (stackMatches(originalStack, stackInMainHand)) { | ||||
|             player.setStackInHand(Hand.MAIN_HAND, changedStack); | ||||
|         } else if (stackMatches(originalStack, stackInOffHand)) { | ||||
|             player.setStackInHand(Hand.OFF_HAND, changedStack); | ||||
|         } else { | ||||
|             PlayerInventory playerInventory = player.getInventory(); | ||||
|             for (int i = 0; i < playerInventory.size(); i++) { | ||||
|                 ItemStack stackInSlot = playerInventory.getStack(i); | ||||
|                 if (stackMatches(stackInSlot, stackInMainHand)) { | ||||
|                     playerInventory.setStack(i, changedStack); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static boolean useItem(ServerWorld world, ServerPlayerEntity playerEntity, ItemStack stackTemp) { | ||||
|         MinecraftServer server = world.getServer(); | ||||
|         ensureUUID(stackTemp, server); | ||||
|         updateLore(stackTemp, server); | ||||
|         if (!playerEntity.isSneaking()) { | ||||
|             ItemStack stack = stackTemp.copy(); | ||||
|             List<SessionStorageClass> wirelessTerminalPositions = new ArrayList<>(stack.getOrDefault(WirelessTerminalComponents.SESSIONS, new ArrayList<>())); | ||||
|             int selectedPosition = stack.getOrDefault(WirelessTerminalComponents.SELECTED_POSITION, -1); | ||||
|  | ||||
|             if (selectedPosition < 0 && !wirelessTerminalPositions.isEmpty()) { | ||||
|                 selectedPosition = wirelessTerminalPositions.size() - 1; | ||||
|                 stack.set(WirelessTerminalComponents.SELECTED_POSITION, selectedPosition); | ||||
|                 saveStack(stack, stackTemp, playerEntity); | ||||
|             } | ||||
|  | ||||
|             if (wirelessTerminalPositions.isEmpty()) { | ||||
|                 stack.remove(WirelessTerminalComponents.SELECTED_POSITION); | ||||
|                 saveStack(stack, stackTemp, playerEntity); | ||||
|                 selectedPosition = -1; | ||||
|             } | ||||
|  | ||||
|             if (selectedPosition < 0) { | ||||
|                 WirelessTerminalSelectorScreen wirelessTerminalSelectorScreen = new WirelessTerminalSelectorScreen(playerEntity, null); | ||||
|                 wirelessTerminalSelectorScreen.open(); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             SessionStorageClass sessionStorageClass = wirelessTerminalPositions.get(selectedPosition); | ||||
|             BlockPos selectedPos = sessionStorageClass.getTerminalPos(); | ||||
|  | ||||
|             if (sessionStorageClass.getPlayerUUID().equals(playerEntity.getUuid()) && sessionStorageClass.getWorld(server).getBlockEntity(selectedPos) instanceof RadioInterfaceBlockEntity) { | ||||
|                 boolean success = openTerminal(selectedPos, playerEntity, stack, sessionStorageClass.getWorld(server)); | ||||
|                 if (!success) { | ||||
|                     removePosition(selectedPos, stack); | ||||
|                     saveStack(stack, stackTemp, playerEntity); | ||||
|                 } | ||||
|                 return true; | ||||
|             } else { | ||||
|                 removePosition(selectedPos, stack); | ||||
|                 saveStack(stack, stackTemp, playerEntity); | ||||
|                 playerEntity.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_BASS.value(), SoundCategory.PLAYERS, 1f, 1f); | ||||
|                 WirelessTerminalSelectorScreen wirelessTerminalSelectorScreen = new WirelessTerminalSelectorScreen(playerEntity, null); | ||||
|                 wirelessTerminalSelectorScreen.open(); | ||||
|             } | ||||
|         } else { | ||||
|             WirelessTerminalSelectorScreen wirelessTerminalSelectorScreen = new WirelessTerminalSelectorScreen(playerEntity, null); | ||||
|             wirelessTerminalSelectorScreen.open(); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								src/main/java/systems/brn/serverstorage/lib/Antenna.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/main/java/systems/brn/serverstorage/lib/Antenna.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; | ||||
| import net.minecraft.component.DataComponentTypes; | ||||
| import net.minecraft.component.type.LoreComponent; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemGroups; | ||||
| import net.minecraft.registry.Registries; | ||||
| import net.minecraft.registry.Registry; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Identifier; | ||||
| import systems.brn.serverstorage.items.SimpleItem; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.ANTENNA_RANGES; | ||||
| import static systems.brn.serverstorage.ServerStorage.id; | ||||
|  | ||||
| public class Antenna extends SimpleItem { | ||||
|     public final int range; | ||||
|  | ||||
|     public Antenna(Settings settings, Identifier identifier, int range) { | ||||
|         super(settings.component(DataComponentTypes.LORE, | ||||
|                 new LoreComponent(List.of( | ||||
|                         Text.translatable("gui.serverstorage.antenna_range", range) | ||||
|                 ))), identifier); | ||||
|         this.range = range; | ||||
|     } | ||||
|  | ||||
|     public static List<Item> register(List<String> tiers) { | ||||
|         ArrayList<Item> items = new ArrayList<>(); | ||||
|         int range = 16; | ||||
|         for (String tier : tiers) { | ||||
|             Identifier identifier = id(tier + "_antenna"); | ||||
|             Item item = Registry.register(Registries.ITEM, identifier, new Antenna(new Settings() | ||||
|                     .maxCount(1) | ||||
|                     , identifier, range)); | ||||
|             ItemGroupEvents.modifyEntriesEvent(ItemGroups.FUNCTIONAL).register(content -> content.add(item)); | ||||
|             items.add(item); | ||||
|             ANTENNA_RANGES.put(item, range); | ||||
|             range *= 3; | ||||
|         } | ||||
|         return items; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/main/java/systems/brn/serverstorage/lib/AntennaSlot.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/main/java/systems/brn/serverstorage/lib/AntennaSlot.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import net.minecraft.inventory.Inventory; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.screen.slot.Slot; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.ANTENNA_LIST; | ||||
|  | ||||
| public class AntennaSlot extends Slot { | ||||
|     public AntennaSlot(Inventory inventory, int index, int x, int y) { | ||||
|         super(inventory, index, x, y); | ||||
|     } | ||||
|  | ||||
|     public static boolean isAntenna(Item item) { | ||||
|         return ANTENNA_LIST.contains(item); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean canInsert(ItemStack stack) { | ||||
|         return isAntenna(stack.getItem()); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,31 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import net.minecraft.entity.player.PlayerEntity; | ||||
| import net.minecraft.item.Item; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.server.world.ServerWorld; | ||||
| import net.minecraft.util.Hand; | ||||
| import net.minecraft.util.TypedActionResult; | ||||
| import net.minecraft.world.World; | ||||
| import systems.brn.serverstorage.items.WirelessTerminalItem; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.WIRELESS_TERMINAL; | ||||
|  | ||||
| public class EventHandler { | ||||
|     public static TypedActionResult<ItemStack> onItemUse(PlayerEntity playerEntity, World worldTemp, Hand hand) { | ||||
|         ItemStack itemStack = playerEntity.getStackInHand(hand); | ||||
|         Item item = itemStack.getItem(); | ||||
|         if (!worldTemp.isClient) { | ||||
|             if (playerEntity instanceof ServerPlayerEntity player) { | ||||
|                 if (worldTemp instanceof ServerWorld world) { | ||||
|                     if (item == WIRELESS_TERMINAL) { | ||||
|                         return WirelessTerminalItem.useItem(world, player, itemStack) ? TypedActionResult.success(itemStack) : TypedActionResult.pass(itemStack); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return TypedActionResult.pass(itemStack); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,73 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import com.mojang.authlib.GameProfile; | ||||
| import eu.pb4.sgui.api.elements.GuiElementBuilder; | ||||
| import net.minecraft.item.Items; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Formatting; | ||||
| import net.minecraft.util.UserCache; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
| import java.util.UUID; | ||||
|  | ||||
| //inspired by: https://github.com/Patbox/get-off-my-lawn-reserved/blob/1.21/src/main/java/draylar/goml/ui/GenericPlayerListGui.java | ||||
| public class GenericPlayerListGui extends PagedGui { | ||||
|     public final List<UUID> uuids = new ArrayList<>(); | ||||
|  | ||||
|     public GenericPlayerListGui(ServerPlayerEntity player, @Nullable Runnable onClose) { | ||||
|         super(player, onClose); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected int getPageAmount() { | ||||
|         return (this.getEntryCount()) / PAGE_SIZE; | ||||
|     } | ||||
|  | ||||
|     protected int getEntryCount() { | ||||
|         return this.uuids.size(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement getElement(int id) { | ||||
|         return getPlayerElement(id); | ||||
|     } | ||||
|  | ||||
|     protected DisplayElement getPlayerElement(int id) { | ||||
|         if (this.uuids.size() > id) { | ||||
|             return getPlayerElement(this.uuids.get(id)); | ||||
|         } | ||||
|  | ||||
|         return DisplayElement.empty(); | ||||
|     } | ||||
|  | ||||
|     protected DisplayElement getPlayerElement(UUID uuid) { | ||||
|         UserCache userCache = this.player.server.getUserCache(); | ||||
|         GameProfile gameProfile = null; | ||||
|         Optional<GameProfile> gameProfileTemp; | ||||
|         boolean exists = false; | ||||
|  | ||||
|         if (userCache != null) { | ||||
|             gameProfileTemp = userCache.getByUuid(uuid); | ||||
|             exists = gameProfileTemp.isPresent(); | ||||
|             gameProfile = exists ? gameProfileTemp.get() : null; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         var builder = new GuiElementBuilder(exists ? Items.PLAYER_HEAD : Items.SKELETON_SKULL) | ||||
|                 .setName(Text.literal(exists ? gameProfile.getName() : "<" + uuid.toString() + ">") | ||||
|                         .formatted(Formatting.WHITE) | ||||
|                 ); | ||||
|  | ||||
|         if (exists) { | ||||
|             builder.setSkullOwner(gameProfile, null); | ||||
|         } else { | ||||
|             builder.setSkullOwner(PagedGui.GUI_QUESTION_MARK); | ||||
|         } | ||||
|  | ||||
|         return DisplayElement.of(builder); | ||||
|     } | ||||
| } | ||||
| @@ -16,6 +16,7 @@ public class ItemGroups { | ||||
|                 entries.add(HARD_DRIVE_CONTAINER_BLOCK); | ||||
|                 entries.add(BUS_CONNECTOR_BLOCK); | ||||
|                 entries.add(INVENTORY_INTERFACE_BLOCK); | ||||
|                 entries.add(RADIO_INTERFACE_BLOCK); | ||||
|             })) | ||||
|             .build(); | ||||
|  | ||||
| @@ -36,6 +37,10 @@ public class ItemGroups { | ||||
|                         entries.add(HEADS.get(i)); | ||||
|                     } | ||||
|                 } | ||||
|                 for (Item antenna : ANTENNA_LIST) { | ||||
|                     entries.add(antenna); | ||||
|                 } | ||||
|                 entries.add(WIRELESS_TERMINAL); | ||||
|             })) | ||||
|             .build(); | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,16 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import net.minecraft.server.world.ServerWorld; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
|  | ||||
| public record RadioDistance( | ||||
|         RadioInterfaceBlockEntity radioInterfaceBlockEntity, | ||||
|         int finalDistance, | ||||
|         int actualDistance, | ||||
|         BlockPos playerPos, | ||||
|         BlockPos terminalPos, | ||||
|         ServerWorld playerWorld, | ||||
|         ServerWorld terminalWorld | ||||
| ) { | ||||
| } | ||||
							
								
								
									
										23
									
								
								src/main/java/systems/brn/serverstorage/lib/Session.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/main/java/systems/brn/serverstorage/lib/Session.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import net.minecraft.nbt.NbtCompound; | ||||
|  | ||||
| import java.util.UUID; | ||||
|  | ||||
| public record Session(UUID sessionKey, UUID playerUUID) { | ||||
|  | ||||
|     // Serialize to NBT | ||||
|     public NbtCompound toNbt() { | ||||
|         NbtCompound nbt = new NbtCompound(); | ||||
|         nbt.putUuid("SessionKey", this.sessionKey); | ||||
|         nbt.putUuid("PlayerUUID", this.playerUUID); | ||||
|         return nbt; | ||||
|     } | ||||
|  | ||||
|     // Deserialize from NBT | ||||
|     public static Session fromNbt(NbtCompound nbt) { | ||||
|         UUID sessionKey = nbt.getUuid("SessionKey"); | ||||
|         UUID playerUUID = nbt.getUuid("PlayerUUID"); | ||||
|         return new Session(sessionKey, playerUUID); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,50 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import com.mojang.authlib.GameProfile; | ||||
| import net.minecraft.registry.RegistryKey; | ||||
| import net.minecraft.server.MinecraftServer; | ||||
| import net.minecraft.server.world.ServerWorld; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import net.minecraft.world.World; | ||||
|  | ||||
| import java.util.UUID; | ||||
|  | ||||
| import static systems.brn.serverstorage.lib.Util.getGameProfile; | ||||
|  | ||||
| public class SessionStorageClass { | ||||
|     private final BlockPos terminalPos; | ||||
|     private final UUID playerUUID; | ||||
|     private final RegistryKey<World> worldKey; | ||||
|  | ||||
|     public SessionStorageClass(UUID playerUUID, ServerWorld world, BlockPos terminalPos) { | ||||
|         this.playerUUID = playerUUID; | ||||
|         this.worldKey = world.getRegistryKey(); | ||||
|         this.terminalPos = terminalPos; | ||||
|     } | ||||
|  | ||||
|     public SessionStorageClass(UUID playerUUID, RegistryKey<World> worldKey, BlockPos terminalPos) { | ||||
|         this.playerUUID = playerUUID; | ||||
|         this.worldKey = worldKey; | ||||
|         this.terminalPos = terminalPos; | ||||
|     } | ||||
|  | ||||
|     public BlockPos getTerminalPos() { | ||||
|         return terminalPos; | ||||
|     } | ||||
|  | ||||
|     public UUID getPlayerUUID() { | ||||
|         return playerUUID; | ||||
|     } | ||||
|  | ||||
|     public GameProfile getPlayerProfile(MinecraftServer server) { | ||||
|         return getGameProfile(playerUUID, server); | ||||
|     } | ||||
|  | ||||
|     public RegistryKey<World> getWorldKey() { | ||||
|         return worldKey; | ||||
|     } | ||||
|  | ||||
|     public ServerWorld getWorld(MinecraftServer server) { | ||||
|         return server.getWorld(this.worldKey); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,6 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import com.mojang.authlib.GameProfile; | ||||
| import net.minecraft.component.DataComponentTypes; | ||||
| import net.minecraft.component.type.LoreComponent; | ||||
| import net.minecraft.item.Item; | ||||
| @@ -10,11 +11,10 @@ import net.minecraft.text.RawFilteredPair; | ||||
| import net.minecraft.text.Style; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Formatting; | ||||
| import net.minecraft.util.UserCache; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| public class Util { | ||||
| @@ -86,6 +86,31 @@ public class Util { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static GameProfile getGameProfile(UUID playerUUID, MinecraftServer server) { | ||||
|         UserCache userCache = server.getUserCache(); | ||||
|         GameProfile gameProfile = null; | ||||
|         Optional<GameProfile> gameProfileTemp; | ||||
|  | ||||
|         if (userCache != null) { | ||||
|             gameProfileTemp = userCache.getByUuid(playerUUID); | ||||
|             boolean exists = gameProfileTemp.isPresent(); | ||||
|             gameProfile = exists ? gameProfileTemp.get() : null; | ||||
|         } | ||||
|         return gameProfile; | ||||
|     } | ||||
|  | ||||
|     public static List<SessionStorageClass> removePosition(BlockPos pos, ItemStack stack) { | ||||
|         List<SessionStorageClass> sessions = new ArrayList<>(stack.getOrDefault(WirelessTerminalComponents.SESSIONS, new ArrayList<>())); | ||||
|         for (SessionStorageClass session : sessions) { | ||||
|             if (session.getTerminalPos().equals(pos)) { | ||||
|                 sessions.remove(session); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         stack.set(WirelessTerminalComponents.SESSIONS, sessions); | ||||
|         return sessions; | ||||
|     } | ||||
|  | ||||
|     public static ItemStack removeCountFromLore(ItemStack stack) { | ||||
|         LoreComponent oldLore = stack.get(DataComponentTypes.LORE); | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,71 @@ | ||||
| package systems.brn.serverstorage.lib; | ||||
|  | ||||
| import com.mojang.serialization.Codec; | ||||
| import com.mojang.serialization.codecs.RecordCodecBuilder; | ||||
| import eu.pb4.polymer.core.api.other.PolymerComponent; | ||||
| import net.minecraft.component.ComponentType; | ||||
| import net.minecraft.registry.Registries; | ||||
| import net.minecraft.registry.Registry; | ||||
| import net.minecraft.server.world.ServerWorld; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.UUID; | ||||
| import java.util.function.UnaryOperator; | ||||
|  | ||||
| import static systems.brn.serverstorage.lib.DriveComponents.UUID_CODEC; | ||||
|  | ||||
|  | ||||
| public class WirelessTerminalComponents { | ||||
|  | ||||
|     public static final Codec<SessionStorageClass> SESSION_CODEC = RecordCodecBuilder.create(instance -> instance.group( | ||||
|             UUID_CODEC.fieldOf("playerUUID").forGetter(SessionStorageClass::getPlayerUUID), | ||||
|             ServerWorld.CODEC.fieldOf("worldKey").forGetter(SessionStorageClass::getWorldKey), | ||||
|             BlockPos.CODEC.fieldOf("terminalPos").forGetter(SessionStorageClass::getTerminalPos) | ||||
|     ).apply(instance, SessionStorageClass::new)); | ||||
|  | ||||
|     public static final Codec<List<SessionStorageClass>> SESSIONS_CODEC = Codec.list(SESSION_CODEC); | ||||
|  | ||||
|  | ||||
|     public static final ComponentType<UUID> SESSION_KEY = register( | ||||
|             "session_key", | ||||
|             builder -> builder.codec(UUID_CODEC) // No packetCodec needed for this example | ||||
|     ); | ||||
|  | ||||
|     public static final ComponentType<List<SessionStorageClass>> SESSIONS = register( | ||||
|             "sessions", | ||||
|             builder -> builder.codec(SESSIONS_CODEC) // No packetCodec needed for this example | ||||
|     ); | ||||
|  | ||||
|     public static final ComponentType<Integer> SELECTED_POSITION = register( | ||||
|             "selected_position", | ||||
|             builder -> builder.codec(Codec.INT) // No packetCodec needed for this example | ||||
|     ); | ||||
|  | ||||
|     public static final ComponentType<Integer> PAGE = register( | ||||
|             "page", | ||||
|             builder -> builder.codec(Codec.INT) // No packetCodec needed for this example | ||||
|     ); | ||||
|  | ||||
|  | ||||
|     public static final ComponentType<Boolean> SORT_ALPHABETICALLY = register( | ||||
|             "sort_alphabetically", | ||||
|             builder -> builder.codec(Codec.BOOL) // No packetCodec needed for this example | ||||
|     ); | ||||
|  | ||||
|     public static final ComponentType<String> QUERY_STRING = register( | ||||
|             "query_string", | ||||
|             builder -> builder.codec(Codec.STRING) // No packetCodec needed for this example | ||||
|     ); | ||||
|  | ||||
|  | ||||
|     private static <T> ComponentType<T> register(String id, UnaryOperator<ComponentType.Builder<T>> builderOperator) { | ||||
|         ComponentType<T> componentType = Registry.register( | ||||
|                 Registries.DATA_COMPONENT_TYPE, | ||||
|                 id, | ||||
|                 builderOperator.apply(ComponentType.builder()).build() | ||||
|         ); | ||||
|         PolymerComponent.registerDataComponent(componentType); | ||||
|         return componentType; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,85 @@ | ||||
| package systems.brn.serverstorage.screenhandlers; | ||||
|  | ||||
| import net.minecraft.entity.player.PlayerEntity; | ||||
| import net.minecraft.entity.player.PlayerInventory; | ||||
| import net.minecraft.inventory.Inventory; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.screen.ScreenHandler; | ||||
| import net.minecraft.screen.ScreenHandlerType; | ||||
| import net.minecraft.screen.slot.Slot; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.lib.AntennaSlot; | ||||
|  | ||||
| public class RadioInterfaceScreenHandler extends ScreenHandler { | ||||
|     private final Inventory inventory; | ||||
|     private final RadioInterfaceBlockEntity blockEntity; | ||||
|  | ||||
|     public RadioInterfaceScreenHandler(int syncId, PlayerInventory playerInventory, RadioInterfaceBlockEntity blockEntity) { | ||||
|         super(ScreenHandlerType.BEACON, syncId); | ||||
|         this.blockEntity = blockEntity; | ||||
|         checkSize(blockEntity, RadioInterfaceBlockEntity.INVENTORY_SIZE); | ||||
|         this.inventory = blockEntity; | ||||
|         inventory.onOpen(playerInventory.player); | ||||
|  | ||||
|         int j; | ||||
|         this.addSlot(new AntennaSlot(inventory, 0, 44, 20)); | ||||
|  | ||||
|         for (j = 0; j < 3; ++j) { | ||||
|             for (int k = 0; k < 9; ++k) { | ||||
|                 this.addSlot(new Slot(playerInventory, k + j * 9 + 9, 8 + k * 18, j * 18 + 51)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (j = 0; j < 9; ++j) { | ||||
|             this.addSlot(new Slot(playerInventory, j, 8 + j * 18, 109)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean canUse(PlayerEntity player) { | ||||
|         return this.inventory.canPlayerUse(player); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public ItemStack quickMove(PlayerEntity player, int slot) { | ||||
|         return quickMoveHelper(player, slot); | ||||
|     } | ||||
|  | ||||
|     public ItemStack quickMoveHelper(PlayerEntity player, int slot) { | ||||
|         ItemStack itemStack = ItemStack.EMPTY; | ||||
|         Slot slot2 = this.slots.get(slot); | ||||
|         if (slot2.hasStack()) { | ||||
|             ItemStack itemStack2 = slot2.getStack(); | ||||
|             itemStack = itemStack2.copy(); | ||||
|             if (slot < this.inventory.size()) { | ||||
|                 if (!this.insertItem(itemStack2, this.inventory.size(), this.slots.size(), true)) { | ||||
|                     return ItemStack.EMPTY; | ||||
|                 } | ||||
|             } else if (!this.insertItem(itemStack2, 0, this.inventory.size(), false)) { | ||||
|                 return ItemStack.EMPTY; | ||||
|             } | ||||
|  | ||||
|             if (itemStack2.isEmpty()) { | ||||
|                 slot2.setStack(ItemStack.EMPTY); | ||||
|             } else { | ||||
|                 slot2.markDirty(); | ||||
|             } | ||||
|  | ||||
|             if (itemStack2.getCount() == itemStack.getCount()) { | ||||
|                 return ItemStack.EMPTY; | ||||
|             } | ||||
|  | ||||
|             slot2.onTakeItem(player, itemStack2); | ||||
|         } | ||||
|  | ||||
|         return itemStack; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onClosed(PlayerEntity player) { | ||||
|         super.onClosed(player); | ||||
|         this.inventory.onClose(player); | ||||
|         this.blockEntity.updateAntenna(); | ||||
|     } | ||||
| } | ||||
| @@ -35,15 +35,26 @@ public class CraftingScreen extends PagedGui { | ||||
|         this.updateDisplay(); | ||||
|     } | ||||
|  | ||||
|     public void reindexDrives() { | ||||
|         if (blockEntity == null) { | ||||
|             storageScreen.getNetwork().reindexNetwork(); | ||||
|         } else { | ||||
|             blockEntity.reindexDrives(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void updateDisplay() { | ||||
|         blockEntity.reindexDrives(); // Use justReindexDrives to avoid looping | ||||
|  | ||||
|         Map<ItemStack, Integer> itemStackMap = new HashMap<>(); | ||||
|         addInventoryToMap(storageScreen.getPlayer().getInventory(), itemStackMap); | ||||
|         itemStackMap.putAll(blockEntity.network.itemStackMap); | ||||
|         itemStackMap.putAll(storageScreen.getNetwork().itemStackMap); | ||||
|         Map<ItemStack, Integer> items = sortAndFilterMap(itemStackMap, false, null); | ||||
|         this.craftingEntries = getCraftableRecipes(items, Objects.requireNonNull(player.getServer())); | ||||
|         this.recipesList = getAvailableRecipes(); | ||||
|         if (blockEntity != null){ | ||||
|             blockEntity.refreshTerminals(); | ||||
|         } | ||||
|         super.updateDisplay(); | ||||
|     } | ||||
|  | ||||
| @@ -92,7 +103,7 @@ public class CraftingScreen extends PagedGui { | ||||
|     } | ||||
|  | ||||
|     private boolean canCraft(RecipeEntry<CraftingRecipe> recipeEntry) { | ||||
|         blockEntity.reindexDrives(); | ||||
|         reindexDrives(); | ||||
|         for (Ingredient ingredient : recipeEntry.value().getIngredients()) { | ||||
|             if (findMatchingStack(ingredient) == null) { | ||||
|                 return false; | ||||
| @@ -131,8 +142,8 @@ public class CraftingScreen extends PagedGui { | ||||
|             } | ||||
|         } else { | ||||
|             ItemStack insertStack = outputStack.copy(); | ||||
|             if (this.blockEntity.network.canAddItemStack(insertStack)) { | ||||
|                 this.blockEntity.network.putItemStackRemainder(insertStack); | ||||
|             if (this.storageScreen.getNetwork().canAddItemStack(insertStack)) { | ||||
|                 this.storageScreen.getNetwork().putItemStackRemainder(insertStack); | ||||
|             } else { | ||||
|                 return true; // Storage full or unable to insert all items | ||||
|             } | ||||
| @@ -148,7 +159,7 @@ public class CraftingScreen extends PagedGui { | ||||
|             ItemStack playerStack = playerInventory.getStack(i); | ||||
|             if (ingredient.test(playerStack)) { | ||||
|                 ItemStack stackToRemove = playerStack.copy(); | ||||
|                 for (ItemStack matchingStack : ingredient.getMatchingStacks()){ | ||||
|                 for (ItemStack matchingStack : ingredient.getMatchingStacks()) { | ||||
|                     if (matchingStack.getItem() == stackToRemove.getItem()) { | ||||
|                         stackToRemove.setCount(matchingStack.getCount()); // Set count to ingredient requirement | ||||
|                         break; | ||||
| @@ -160,7 +171,7 @@ public class CraftingScreen extends PagedGui { | ||||
|  | ||||
|         // Check storage network | ||||
|         for (ItemStack stack : ingredient.getMatchingStacks()) { | ||||
|             if (this.blockEntity.network.canRemove(stack)) { | ||||
|             if (this.storageScreen.getNetwork().canRemove(stack)) { | ||||
|                 ItemStack stackToRemove = stack.copy(); | ||||
|                 stackToRemove.setCount(ingredient.getMatchingStacks()[0].getCount()); // Set count to ingredient requirement | ||||
|                 return stackToRemove; | ||||
| @@ -170,7 +181,7 @@ public class CraftingScreen extends PagedGui { | ||||
|     } | ||||
|  | ||||
|     private void removeItems(ItemStack stack) { | ||||
|         ItemStack removedFromStorage = this.blockEntity.network.removeItemStack(stack); | ||||
|         ItemStack removedFromStorage = this.storageScreen.getNetwork().removeItemStack(stack); | ||||
|         if (removedFromStorage.getCount() > 0) { | ||||
|             Inventory playerInventory = player.getInventory(); | ||||
|             for (int i = 0; i < playerInventory.size(); i++) { | ||||
| @@ -184,22 +195,29 @@ public class CraftingScreen extends PagedGui { | ||||
|  | ||||
|     @Override | ||||
|     public boolean open() { | ||||
|         page = blockEntity.page; | ||||
|         this.blockEntity.openCraftingScreens.add(this); | ||||
|         blockEntity.updateDisplays(); | ||||
|         if (this.blockEntity != null) { | ||||
|             this.blockEntity.openCraftingScreens.add(this); | ||||
|             blockEntity.updateDisplays(); | ||||
|         } else { | ||||
|             updateDisplay(); | ||||
|         } | ||||
|         return super.open(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onClose() { | ||||
|         super.onClose(); | ||||
|         this.blockEntity.openCraftingScreens.remove(this); | ||||
|         if (this.blockEntity != null) { | ||||
|             this.blockEntity.openCraftingScreens.remove(this); | ||||
|             this.blockEntity.refreshTerminals(); | ||||
|         } | ||||
|         storageScreen.open(); | ||||
|         storageScreen.updateDisplay(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected int getPageAmount() { | ||||
|         return Math.ceilDivExact(recipesList.size(), 9 * 6); | ||||
|         return Math.ceilDivExact(recipesList.size(), PAGE_SIZE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -0,0 +1,67 @@ | ||||
| package systems.brn.serverstorage.screens; | ||||
|  | ||||
| import com.mojang.authlib.GameProfile; | ||||
| import eu.pb4.sgui.api.elements.GuiElementBuilder; | ||||
| import net.minecraft.item.Items; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Formatting; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.lib.PagedGui; | ||||
| import systems.brn.serverstorage.lib.Session; | ||||
|  | ||||
| import static systems.brn.serverstorage.lib.Util.getGameProfile; | ||||
|  | ||||
| public class RadioBlockPlayerMangementScreen extends PagedGui { | ||||
|     public final RadioInterfaceBlockEntity radioInterfaceBlockEntity; | ||||
|  | ||||
|     public RadioBlockPlayerMangementScreen(ServerPlayerEntity player, RadioInterfaceBlockEntity radioInterfaceBlockEntity) { | ||||
|         super(player, null); | ||||
|         this.radioInterfaceBlockEntity = radioInterfaceBlockEntity; | ||||
|         this.setTitle(Text.translatable("gui.serverstorage.player_management")); | ||||
|     } | ||||
|  | ||||
|     protected DisplayElement getSessionElement(Session session, int index) { | ||||
|  | ||||
|         GameProfile gameProfile = null; | ||||
|         if (player != null && player.getServer() != null) { | ||||
|             gameProfile = getGameProfile(session.playerUUID(), player.getServer()); | ||||
|         } | ||||
|  | ||||
|         var builder = new GuiElementBuilder(gameProfile != null ? Items.PLAYER_HEAD : Items.SKELETON_SKULL) | ||||
|                 .setName(Text.translatable("gui.serverstorage.player_management_session", index)) | ||||
|                 .addLoreLine(Text.translatable("gui.serverstorage.player_management_session_owner", | ||||
|                                 gameProfile != null ? gameProfile.getName() : "<" + session.playerUUID().toString() + ">") | ||||
|                         .formatted(Formatting.WHITE) | ||||
|                 ) | ||||
|                 .addLoreLine(Text.translatable("gui.serverstorage.player_management_session_key", session.sessionKey().toString())) | ||||
|                 .addLoreLine(Text.translatable("gui.serverstorage.player_management_session_click_deauthorize")) | ||||
|                 .setCallback((clickIndex, clickType, slotActionType) -> { | ||||
|                     playClickSound(getPlayer()); | ||||
|                     radioInterfaceBlockEntity.deAuthorizeSession(session.sessionKey(), session.playerUUID()); | ||||
|                     updateDisplay(); | ||||
|                 }); | ||||
|  | ||||
|         if (gameProfile != null) { | ||||
|             builder.setSkullOwner(gameProfile, null); | ||||
|         } else { | ||||
|             builder.setSkullOwner(PagedGui.GUI_QUESTION_MARK); | ||||
|         } | ||||
|  | ||||
|         return DisplayElement.of(builder); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected int getPageAmount() { | ||||
|         return radioInterfaceBlockEntity.sessions.size() / PAGE_SIZE; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement getElement(int id) { | ||||
|         if (id < radioInterfaceBlockEntity.sessions.size()) { | ||||
|             Session session = radioInterfaceBlockEntity.sessions.get(id); | ||||
|             return getSessionElement(session, id); | ||||
|         } | ||||
|         return DisplayElement.empty(); | ||||
|     } | ||||
| } | ||||
| @@ -58,7 +58,7 @@ public class SettingsScreen extends PagedGui { | ||||
|  | ||||
|     @Override | ||||
|     protected int getPageAmount() { | ||||
|         return Math.ceilDivExact(settingsList.size(), 9 * 5); | ||||
|         return Math.ceilDivExact(settingsList.size(), PAGE_SIZE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -8,15 +8,24 @@ import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.item.Items; | ||||
| import net.minecraft.screen.slot.SlotActionType; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.server.world.ServerWorld; | ||||
| import net.minecraft.sound.SoundCategory; | ||||
| import net.minecraft.sound.SoundEvents; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Formatting; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import net.minecraft.world.World; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
| import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; | ||||
| import systems.brn.serverstorage.lib.PagedGui; | ||||
| import systems.brn.serverstorage.lib.RadioDistance; | ||||
| import systems.brn.serverstorage.lib.StorageNetwork; | ||||
| import systems.brn.serverstorage.lib.WirelessTerminalComponents; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.ServerStorage_Crafting_Enable; | ||||
| import static systems.brn.serverstorage.items.WirelessTerminalItem.getDistance; | ||||
| import static systems.brn.serverstorage.lib.StorageOperations.*; | ||||
| import static systems.brn.serverstorage.lib.Util.addCountToLore; | ||||
| import static systems.brn.serverstorage.lib.Util.removeCountFromLore; | ||||
| @@ -24,6 +33,27 @@ import static systems.brn.serverstorage.lib.Util.removeCountFromLore; | ||||
| public class StorageScreen extends PagedGui { | ||||
|     private final ServerPlayerEntity player; | ||||
|     public final StorageInterfaceBlockEntity blockEntity; | ||||
|     public final StorageNetwork network; | ||||
|     public final ItemStack itemStack; | ||||
|     public final ServerWorld world; | ||||
|     public final RadioInterfaceBlockEntity radioInterfaceBlockEntity; | ||||
|  | ||||
|     public boolean checkDistance() { | ||||
|         if (radioInterfaceBlockEntity != null) { | ||||
|             RadioDistance radioDistance = getDistance(player, radioInterfaceBlockEntity); | ||||
|             if (radioDistance.actualDistance() > radioDistance.finalDistance()) { | ||||
|                 close(); | ||||
|                 ServerWorld playerWorld = radioDistance.playerWorld(); | ||||
|                 ServerWorld terminalWorld = radioDistance.terminalWorld(); | ||||
|                 String playerWorldName = playerWorld.getRegistryKey().getValue().toString(); | ||||
|                 String terminalWorldName = terminalWorld.getRegistryKey().getValue().toString(); | ||||
|                 player.sendMessage(Text.translatable("gui.serverstorage.radio_out_of_range", radioDistance.terminalPos().toShortString(), terminalWorldName, player.getBlockPos().toShortString(), playerWorldName, radioDistance.actualDistance(), radioDistance.finalDistance()), true); | ||||
|                 player.playSoundToPlayer(SoundEvents.BLOCK_NOTE_BLOCK_COW_BELL.value(), SoundCategory.PLAYERS, 1f, 1f); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public StorageScreen(ServerPlayerEntity player, BlockPos pos, @Nullable Runnable closeCallback) { | ||||
|         super(player, closeCallback); | ||||
| @@ -31,30 +61,122 @@ public class StorageScreen extends PagedGui { | ||||
|         this.setLockPlayerInventory(false); | ||||
|         this.blockEntity = (StorageInterfaceBlockEntity) player.getWorld().getBlockEntity(pos); | ||||
|         assert blockEntity != null; | ||||
|         this.network = null; | ||||
|         this.itemStack = ItemStack.EMPTY; | ||||
|         this.world = player.getServerWorld(); | ||||
|         this.radioInterfaceBlockEntity = null; | ||||
|     } | ||||
|  | ||||
|     public StorageScreen(ServerPlayerEntity player, ItemStack itemStack, StorageNetwork storageNetwork, RadioInterfaceBlockEntity radioInterfaceBlockEntity) { | ||||
|         super(player, null); | ||||
|         this.player = player; | ||||
|         this.blockEntity = null; | ||||
|         this.setLockPlayerInventory(false); | ||||
|         this.network = storageNetwork; | ||||
|         this.itemStack = itemStack; | ||||
|         this.world = player.getServerWorld(); | ||||
|         this.radioInterfaceBlockEntity = radioInterfaceBlockEntity; | ||||
|     } | ||||
|  | ||||
|     public StorageNetwork getNetwork() { | ||||
|         if (blockEntity != null) { | ||||
|             blockEntity.enforceNetwork(); | ||||
|             return blockEntity.network; | ||||
|         } | ||||
|         return network; | ||||
|     } | ||||
|  | ||||
|     public boolean getAlphabeticalSorting() { | ||||
|         if (blockEntity == null) { | ||||
|             return itemStack.getOrDefault(WirelessTerminalComponents.SORT_ALPHABETICALLY, false); | ||||
|         } else { | ||||
|             return blockEntity.sortAlphabetically; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void setAlphabeticalSorting(boolean sorting) { | ||||
|         if (blockEntity == null) { | ||||
|             itemStack.set(WirelessTerminalComponents.SORT_ALPHABETICALLY, sorting); | ||||
|         } else { | ||||
|             blockEntity.sortAlphabetically = sorting; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public String getQueryString() { | ||||
|         if (blockEntity == null) { | ||||
|             return itemStack.getOrDefault(WirelessTerminalComponents.QUERY_STRING, ""); | ||||
|         } else { | ||||
|             return blockEntity.searchString; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void setQueryString(String queryString) { | ||||
|         if (blockEntity == null) { | ||||
|             itemStack.set(WirelessTerminalComponents.QUERY_STRING, queryString); | ||||
|         } else { | ||||
|             blockEntity.searchString = queryString; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public int getPage() { | ||||
|         if (blockEntity == null) { | ||||
|             return itemStack.getOrDefault(WirelessTerminalComponents.PAGE, 0); | ||||
|         } else { | ||||
|             return blockEntity.page; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void setPage(int page) { | ||||
|         if (page > getPageAmount()) { | ||||
|             page = getPageAmount() - 1; | ||||
|         } | ||||
|         if (blockEntity == null) { | ||||
|             itemStack.set(WirelessTerminalComponents.PAGE, page); | ||||
|         } else { | ||||
|             blockEntity.page = page; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void refreshTerminals() { | ||||
|         if (blockEntity == null) { | ||||
|             this.network.sortAlphabetically = getAlphabeticalSorting(); | ||||
|             this.network.searchString = getQueryString(); | ||||
|             getNetwork().reindexNetwork(); | ||||
|             getNetwork().updateDisplays(); | ||||
|             updateDisplay(); | ||||
|         } else { | ||||
|             blockEntity.refreshTerminals(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean open() { | ||||
|         page = blockEntity.page; | ||||
|         this.blockEntity.openStorageScreens.add(this); | ||||
|         blockEntity.updateDisplays(); | ||||
|         page = getPage(); | ||||
|         if (blockEntity == null) { | ||||
|             updateDisplay(); | ||||
|             if (!checkDistance()) { | ||||
|                 return false; | ||||
|             } | ||||
|         } else { | ||||
|             blockEntity.openStorageScreens.add(this); | ||||
|             blockEntity.updateDisplays(); | ||||
|         } | ||||
|         return super.open(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void updateDisplay() { | ||||
|         blockEntity.reindexDrives(); | ||||
|         String title = blockEntity.network.driveUsedSlots + | ||||
|         String title = getNetwork().driveUsedSlots + | ||||
|                 "u/" + | ||||
|                 blockEntity.network.driveTotalSlots + | ||||
|                 getNetwork().driveTotalSlots + | ||||
|                 "t(" + | ||||
|                 blockEntity.network.driveFreeSlots + | ||||
|                 getNetwork().driveFreeSlots + | ||||
|                 "f)" + | ||||
|                 "[" + | ||||
|                 blockEntity.network.driveContainerCount + | ||||
|                 getNetwork().driveContainerCount + | ||||
|                 "c]" + | ||||
|                 "[" + | ||||
|                 blockEntity.network.drivesCount + | ||||
|                 getNetwork().drivesCount + | ||||
|                 "d]"; | ||||
|  | ||||
|         setTitle(Text.of(title)); | ||||
| @@ -63,15 +185,15 @@ public class StorageScreen extends PagedGui { | ||||
|  | ||||
|     @Override | ||||
|     protected int getPageAmount() { | ||||
|         return Math.ceilDivExact(blockEntity.network.filteredItemStackMap.size(), 9 * 5); | ||||
|         return Math.ceilDivExact(getNetwork().filteredItemStackMap.size(), PAGE_SIZE); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement getElement(int id) { | ||||
|         if (blockEntity.network.filteredItemStackMap.size() > id) { | ||||
|             ItemStack itemStackKey = (ItemStack) blockEntity.network.filteredItemStackMap.keySet().toArray()[id]; | ||||
|         if (getNetwork().filteredItemStackMap.size() > id) { | ||||
|             ItemStack itemStackKey = (ItemStack) getNetwork().filteredItemStackMap.keySet().toArray()[id]; | ||||
|             ItemStack aestheticStack = itemStackKey.copy(); | ||||
|             int count = blockEntity.network.filteredItemStackMap.get(itemStackKey); | ||||
|             int count = getNetwork().filteredItemStackMap.get(itemStackKey); | ||||
|             aestheticStack.setCount(Math.min(aestheticStack.getMaxCount(), count)); | ||||
|             ItemStack newStack = addCountToLore(count, aestheticStack, null); | ||||
|             GuiElementBuilder guiElement = new GuiElementBuilder(newStack); | ||||
| @@ -82,12 +204,15 @@ public class StorageScreen extends PagedGui { | ||||
|  | ||||
|     @Override | ||||
|     public boolean onClick(int index, ClickType type, SlotActionType action, GuiElementInterface element) { | ||||
|         if (!checkDistance()) { | ||||
|             return false; | ||||
|         } | ||||
|         GuiElementInterface clickedElement = getSlot(index); | ||||
|         ItemStack cursorStack = getPlayer().currentScreenHandler.getCursorStack(); | ||||
|         if (clickedElement != null && cursorStack.isEmpty()) { | ||||
|             ItemStack clickedItem = clickedElement.getItemStack(); | ||||
|             ItemStack noLoreStack = removeCountFromLore(clickedItem); | ||||
|             noLoreStack = blockEntity.network.findSimilarStack(noLoreStack); | ||||
|             noLoreStack = getNetwork().findSimilarStack(noLoreStack); | ||||
|             if (type.isRight) { | ||||
|                 if (!type.shift) { | ||||
|                     noLoreStack.setCount(Math.min(noLoreStack.getMaxCount(), noLoreStack.getCount() / 2)); //half stack | ||||
| @@ -110,11 +235,11 @@ public class StorageScreen extends PagedGui { | ||||
|                 int insertCount = canInsertItemIntoInventory(playerInventory, noLoreStack); | ||||
|                 ItemStack insertingStack = noLoreStack.copy(); | ||||
|                 insertingStack.setCount(insertCount); | ||||
|                 blockEntity.refreshTerminals(); | ||||
|                 if (blockEntity.network.canRemove(noLoreStack) && insertCount > 0) { | ||||
|                 refreshTerminals(); | ||||
|                 if (getNetwork().canRemove(noLoreStack) && insertCount > 0) { | ||||
|                     playerInventory.insertStack(insertingStack.copy()); | ||||
|                     blockEntity.network.removeItemStack(insertingStack); | ||||
|                     blockEntity.refreshTerminals(); | ||||
|                     getNetwork().removeItemStack(insertingStack); | ||||
|                     refreshTerminals(); | ||||
|                 } | ||||
|             } | ||||
|         } else if (!cursorStack.isEmpty()) { | ||||
| @@ -124,23 +249,29 @@ public class StorageScreen extends PagedGui { | ||||
|     } | ||||
|  | ||||
|     public void insertItem(ItemStack stack) { | ||||
|         int canPutIn = stack.getCount() - blockEntity.network.putItemStackRemainder(stack); | ||||
|         if (!checkDistance()) { | ||||
|             return; | ||||
|         } | ||||
|         int canPutIn = stack.getCount() - getNetwork().putItemStackRemainder(stack); | ||||
|         if (canPutIn > 0) { | ||||
|             removeFromInventory(player.getInventory(), stack, canPutIn); | ||||
|             blockEntity.refreshTerminals(); | ||||
|             refreshTerminals(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) { | ||||
|         blockEntity.refreshTerminals(); | ||||
|         if (!checkDistance()) { | ||||
|             return false; | ||||
|         } | ||||
|         refreshTerminals(); | ||||
|         insertItem(stack); | ||||
|         return super.insertItem(stack, startIndex, endIndex, fromLast); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement search() { | ||||
|         String searchString = blockEntity.searchString; | ||||
|         String searchString = getQueryString(); | ||||
|         if (searchString == null || searchString.isEmpty() || searchString.equals("*")) { | ||||
|             searchString = "Filter not set"; | ||||
|         } | ||||
| @@ -151,11 +282,13 @@ public class StorageScreen extends PagedGui { | ||||
|                         .setSkullOwner(GUI_QUESTION_MARK) | ||||
|                         .setCallback((x, y, z) -> { | ||||
|                             playClickSound(getPlayer()); | ||||
|                             if (y.isRight) { | ||||
|                                 doSearch(""); | ||||
|                             } else if (y.isLeft) { | ||||
|                                 SearchScreen searchScreen = new SearchScreen(this, ""); | ||||
|                                 searchScreen.open(); | ||||
|                             if (checkDistance()) { | ||||
|                                 if (y.isRight) { | ||||
|                                     doSearch(""); | ||||
|                                 } else if (y.isLeft) { | ||||
|                                     SearchScreen searchScreen = new SearchScreen(this, ""); | ||||
|                                     searchScreen.open(); | ||||
|                                 } | ||||
|                             } | ||||
|                         }) | ||||
|         ); | ||||
| @@ -163,6 +296,10 @@ public class StorageScreen extends PagedGui { | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement settings() { | ||||
|         if (blockEntity == null) { | ||||
|             WirelessTerminalSelectorScreen wirelessTerminalSelectorScreen = new WirelessTerminalSelectorScreen(this); | ||||
|             return wirelessTerminalSelectorScreen.getItem(); | ||||
|         } | ||||
|         SettingsScreen settingsScreen = new SettingsScreen(this); | ||||
|         return settingsScreen.getItem(); | ||||
|     } | ||||
| @@ -171,17 +308,43 @@ public class StorageScreen extends PagedGui { | ||||
|     protected DisplayElement sorting() { | ||||
|         return DisplayElement.of( | ||||
|                 new GuiElementBuilder(Items.PLAYER_HEAD) | ||||
|                         .setName(Text.translatable(this.blockEntity.sortAlphabetically ? "A->Z" : "9->1").formatted(Formatting.WHITE)) | ||||
|                         .setName(Text.translatable(getAlphabeticalSorting() ? "A->Z" : "9->1").formatted(Formatting.WHITE)) | ||||
|                         .hideDefaultTooltip().noDefaults() | ||||
|                         .setSkullOwner(this.blockEntity.sortAlphabetically ? GUI_A : GUI_1) | ||||
|                         .setSkullOwner(getAlphabeticalSorting() ? GUI_A : GUI_1) | ||||
|                         .setCallback((x, y, z) -> { | ||||
|                             this.blockEntity.sortAlphabetically ^= true; | ||||
|                             playClickSound(getPlayer()); | ||||
|                             this.blockEntity.refreshTerminals(); | ||||
|                             if (checkDistance()) { | ||||
|                                 setAlphabeticalSorting(!getAlphabeticalSorting()); | ||||
|                                 this.refreshTerminals(); | ||||
|                             } | ||||
|                         }) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private int insertIntoPlayer(ItemStack stack, int count, PlayerInventory playerInventory) { | ||||
|         int maxFit = howMuchFits(stack, playerInventory); | ||||
|         int finalCount = Math.min(count, maxFit); | ||||
|         ItemStack insertedStack = stack.copy(); | ||||
|         insertedStack.setCount(finalCount); | ||||
|         getNetwork().removeItemStack(insertedStack); | ||||
|         getNetwork().updateDisplays(); | ||||
|         updateDisplay(); | ||||
|         int remainingToInsert = finalCount; | ||||
|         for (int i = 0; i < Math.ceilDivExact(finalCount, stack.getMaxCount()); i++) { | ||||
|             ItemStack cappedStack = insertedStack.copy(); | ||||
|             cappedStack.setCount(Math.min(insertedStack.getMaxCount(), remainingToInsert)); | ||||
|  | ||||
|             ItemStack remaining = insertStackIntoInventory(playerInventory, cappedStack.copy()); | ||||
|             if (!remaining.isEmpty()) { | ||||
|                 ItemStack reverseStack = stack.copy(); | ||||
|                 reverseStack.setCount(remaining.getCount() + remainingToInsert); | ||||
|                 getNetwork().putItemStackRemainder(reverseStack); | ||||
|                 break; | ||||
|             } | ||||
|             remainingToInsert -= cappedStack.getCount(); | ||||
|         } | ||||
|         return count - (finalCount - remainingToInsert); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement storeAll() { | ||||
| @@ -192,9 +355,22 @@ public class StorageScreen extends PagedGui { | ||||
|                         .setSkullOwner(GUI_STORE_ALL) | ||||
|                         .setCallback((x, y, z) -> { | ||||
|                             playClickSound(player); | ||||
|                             for (int i = 0; i < player.getInventory().main.size(); i++) { | ||||
|                                 ItemStack stack = player.getInventory().main.get(i); | ||||
|                                 insertItem(stack, 0, getVirtualSize(), false); | ||||
|                             if (checkDistance()) { | ||||
|                                 if (y.isLeft) { | ||||
|                                     for (int i = 0; i < player.getInventory().main.size(); i++) { | ||||
|                                         ItemStack stack = player.getInventory().main.get(i); | ||||
|                                         insertItem(stack, 0, getVirtualSize(), false); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 if (y.isRight) { | ||||
|                                     //give to player | ||||
|                                     for (Map.Entry<ItemStack, Integer> entry : getNetwork().filteredItemStackMap.entrySet()) { | ||||
|                                         int leftOver = insertIntoPlayer(entry.getKey(), entry.getValue(), player.getInventory()); | ||||
|                                         if (leftOver > 0) { | ||||
|                                             break; | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         }) | ||||
|         ); | ||||
| @@ -202,7 +378,6 @@ public class StorageScreen extends PagedGui { | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement crafting() { | ||||
|         World world = blockEntity.getWorld(); | ||||
|         if (world != null && world.getGameRules().getBoolean(ServerStorage_Crafting_Enable)) { | ||||
|             return DisplayElement.of( | ||||
|                     new GuiElementBuilder(Items.PLAYER_HEAD) | ||||
| @@ -211,9 +386,11 @@ public class StorageScreen extends PagedGui { | ||||
|                             .setSkullOwner(GUI_CRAFTING) | ||||
|                             .setCallback((x, y, z) -> { | ||||
|                                 playClickSound(player); | ||||
|                                 CraftingScreen craftingScreen = new CraftingScreen(this); | ||||
|                                 playClickSound(getPlayer()); | ||||
|                                 craftingScreen.open(); | ||||
|                                 if (checkDistance()) { | ||||
|                                     CraftingScreen craftingScreen = new CraftingScreen(this); | ||||
|                                     playClickSound(getPlayer()); | ||||
|                                     craftingScreen.open(); | ||||
|                                 } | ||||
|                             }) | ||||
|             ); | ||||
|         } else { | ||||
| @@ -222,9 +399,9 @@ public class StorageScreen extends PagedGui { | ||||
|     } | ||||
|  | ||||
|     public void doSearch(String query) { | ||||
|         this.blockEntity.searchString = query; | ||||
|         this.blockEntity.refreshTerminals(); | ||||
|         this.page = 0; | ||||
|         setQueryString(query); | ||||
|         refreshTerminals(); | ||||
|         setPage(0); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -236,18 +413,22 @@ public class StorageScreen extends PagedGui { | ||||
|                         .hideDefaultTooltip().noDefaults() | ||||
|                         .setCallback((x, y, z) -> { | ||||
|                             playClickSound(player); | ||||
|                             this.page = 0; | ||||
|                             this.blockEntity.searchString = ""; | ||||
|                             this.blockEntity.refreshTerminals(); | ||||
|                             if (checkDistance()) { | ||||
|                                 setPage(0); | ||||
|                                 setQueryString(""); | ||||
|                                 refreshTerminals(); | ||||
|                             } | ||||
|                         }) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onClose() { | ||||
|         this.blockEntity.page = page; | ||||
|         this.blockEntity.markDirty(); | ||||
|         this.blockEntity.openStorageScreens.remove(this); | ||||
|         setPage(page); | ||||
|         if (blockEntity != null) { | ||||
|             this.blockEntity.markDirty(); | ||||
|             this.blockEntity.openStorageScreens.remove(this); | ||||
|         } | ||||
|         super.onClose(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,156 @@ | ||||
| package systems.brn.serverstorage.screens; | ||||
|  | ||||
| import com.mojang.authlib.GameProfile; | ||||
| import eu.pb4.sgui.api.elements.GuiElementBuilder; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.item.Items; | ||||
| import net.minecraft.server.MinecraftServer; | ||||
| import net.minecraft.server.network.ServerPlayerEntity; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.Formatting; | ||||
| import net.minecraft.util.math.BlockPos; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
| import systems.brn.serverstorage.items.WirelessTerminalItem; | ||||
| import systems.brn.serverstorage.lib.PagedGui; | ||||
| import systems.brn.serverstorage.lib.SessionStorageClass; | ||||
| import systems.brn.serverstorage.lib.Util; | ||||
| import systems.brn.serverstorage.lib.WirelessTerminalComponents; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import static systems.brn.serverstorage.ServerStorage.WIRELESS_TERMINAL; | ||||
| import static systems.brn.serverstorage.items.WirelessTerminalItem.saveStack; | ||||
|  | ||||
| public class WirelessTerminalSelectorScreen extends PagedGui { | ||||
|  | ||||
|     final public ItemStack stack; | ||||
|     final public ItemStack stackOriginal; | ||||
|     public List<SessionStorageClass> sessions; | ||||
|     public int selectedIndex; | ||||
|     public final StorageScreen storageScreen; | ||||
|  | ||||
|     public WirelessTerminalSelectorScreen(ServerPlayerEntity player, @Nullable StorageScreen storageScreen) { | ||||
|         super(player, null); | ||||
|         final ItemStack stackOriginal = player.getStackInHand(player.getActiveHand()); | ||||
|         final ItemStack stack = stackOriginal.copy(); | ||||
|         if (stack.getItem() == WIRELESS_TERMINAL) { | ||||
|             this.stack = stack; | ||||
|             this.stackOriginal = stackOriginal; | ||||
|             this.sessions = new ArrayList<>(stack.getOrDefault(WirelessTerminalComponents.SESSIONS, new ArrayList<>())); | ||||
|             this.selectedIndex = stack.getOrDefault(WirelessTerminalComponents.SELECTED_POSITION, -1); | ||||
|             this.setTitle(Text.translatable("gui.serverstorage.radio_selector")); | ||||
|             this.storageScreen = storageScreen; | ||||
|             this.updateDisplay(); | ||||
|         } else { | ||||
|             this.stack = ItemStack.EMPTY; | ||||
|             this.stackOriginal = stack; | ||||
|             this.sessions = new ArrayList<>(); | ||||
|             this.selectedIndex = -1; | ||||
|             this.storageScreen = storageScreen; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public WirelessTerminalSelectorScreen(StorageScreen storageScreen) { | ||||
|         this(storageScreen.getPlayer(), storageScreen); | ||||
|     } | ||||
|  | ||||
|     private void commitStack() { | ||||
|         saveStack(stack, stackOriginal, player); | ||||
|     } | ||||
|  | ||||
|     private void setSelectedPosition() { | ||||
|         if (selectedIndex >= sessions.size()) { | ||||
|             selectedIndex = sessions.size() - 1; | ||||
|         } | ||||
|         stack.set(WirelessTerminalComponents.SELECTED_POSITION, selectedIndex); | ||||
|         commitStack(); | ||||
|     } | ||||
|  | ||||
|     private void removePosition(BlockPos pos) { | ||||
|         this.sessions = Util.removePosition(pos, stack); | ||||
|         setSelectedPosition(); | ||||
|     } | ||||
|  | ||||
|     protected DisplayElement getRadioTerminal(BlockPos position, SessionStorageClass sessionStorageClass, int index) { | ||||
|         if (player != null && player.getServer() != null) { | ||||
|             MinecraftServer server = player.getServer(); | ||||
|             GameProfile gameProfile = sessionStorageClass.getPlayerProfile(server); | ||||
|  | ||||
|             String playerName = gameProfile != null ? gameProfile.getName() : "Profile nonexistent"; | ||||
|  | ||||
|             var builder = new GuiElementBuilder(gameProfile != null ? Items.PLAYER_HEAD : Items.SKELETON_SKULL) | ||||
|                     .setName(Text.translatable("gui.serverstorage.radio_entry", index)) | ||||
|                     .setSkullOwner(gameProfile, player.getServer()) | ||||
|                     .addLoreLine(Text.translatable("gui.serverstorage.radio_position", | ||||
|                             position.toShortString(), sessionStorageClass.getWorldKey().getValue().getPath() | ||||
|                                     .formatted(Formatting.WHITE) | ||||
|                     )) | ||||
|                     .addLoreLine(Text.translatable("gui.serverstorage.player_management_session_owner", playerName)) | ||||
|                     .addLoreLine(Text.translatable("gui.serverstorage.radio_session_click_select")) | ||||
|                     .addLoreLine(Text.translatable("gui.serverstorage.radio_session_click_open")) | ||||
|                     .addLoreLine(Text.translatable("gui.serverstorage.radio_session_click_delete")) | ||||
|                     .setCallback((clickIndex, clickType, slotActionType) -> { | ||||
|                         playClickSound(getPlayer()); | ||||
|                         if (clickType.isLeft) { | ||||
|                             if (clickType.shift) { | ||||
|                                 removePosition(position); | ||||
|                             } else { | ||||
|                                 boolean success = WirelessTerminalItem.openTerminal(position, player, player.getStackInHand(player.getActiveHand()), sessionStorageClass.getWorld(server)); | ||||
|                                 if (!success) { | ||||
|                                     removePosition(position); | ||||
|                                 } | ||||
|                             } | ||||
|                         } else if (clickType.isRight) { | ||||
|                             this.selectedIndex = index; | ||||
|                             setSelectedPosition(); | ||||
|                             boolean success = WirelessTerminalItem.openTerminal(position, player, player.getStackInHand(player.getActiveHand()), sessionStorageClass.getWorld(server)); | ||||
|                             if (!success) { | ||||
|                                 removePosition(position); | ||||
|                             } | ||||
|                         } | ||||
|                         updateDisplay(); | ||||
|                     }); | ||||
|  | ||||
|             return DisplayElement.of(builder); | ||||
|         } else { | ||||
|             return DisplayElement.empty(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected int getPageAmount() { | ||||
|         return sessions.size() / PAGE_SIZE; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected DisplayElement getElement(int id) { | ||||
|         if (id < sessions.size()) { | ||||
|             SessionStorageClass sessionStorageClass = sessions.get(id); | ||||
|             return getRadioTerminal(sessionStorageClass.getTerminalPos(), sessionStorageClass, id); | ||||
|         } | ||||
|         return DisplayElement.empty(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onClose() { | ||||
|         super.onClose(); | ||||
|         WirelessTerminalItem.updateLore(stack, player.getServer()); | ||||
|         if (storageScreen != null) { | ||||
|             storageScreen.open(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public DisplayElement getItem() { | ||||
|         return DisplayElement.of( | ||||
|                 new GuiElementBuilder(Items.PLAYER_HEAD) | ||||
|                         .setName(Text.translatable("mco.configure.world.settings.title").formatted(Formatting.WHITE)) | ||||
|                         .hideDefaultTooltip().noDefaults() | ||||
|                         .setSkullOwner(GUI_SETTINGS) | ||||
|                         .setCallback((x, y, z) -> { | ||||
|                             playClickSound(getPlayer()); | ||||
|                             this.open(); | ||||
|                         }) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @@ -1,51 +1,84 @@ | ||||
| { | ||||
|   "block.serverstorage.storage": "Networked storage interface", | ||||
|   "block.serverstorage.storage": "Networked Storage Interface", | ||||
|  | ||||
|   "block.serverstorage.inventory_interface": "Networked inventory interface", | ||||
|   "block.serverstorage.inventory_interface": "Networked Inventory Interface", | ||||
|  | ||||
|   "block.serverstorage.drive_container": "Hard drive container", | ||||
|   "block.serverstorage.drive_container": "Hard Drive Container", | ||||
|  | ||||
|   "block.serverstorage.bus_connector": "Storage network connector", | ||||
|   "block.serverstorage.bus_connector": "Storage Network Connector", | ||||
|  | ||||
|   "item.serverstorage.iron_drive": "Iron hard drive", | ||||
|   "item.serverstorage.iron_head": "Iron hard drive head", | ||||
|   "item.serverstorage.iron_platter": "Iron hard drive platter", | ||||
|   "block.serverstorage.radio_interface": "Networked Radio Interface", | ||||
|  | ||||
|   "item.serverstorage.golden_drive": "Golden hard drive", | ||||
|   "item.serverstorage.golden_head": "Golden hard drive head", | ||||
|   "item.serverstorage.golden_platter": "Golden hard drive platter", | ||||
|   "item.serverstorage.iron_drive": "Iron Hard Drive", | ||||
|   "item.serverstorage.iron_head": "Iron Hard Drive Head", | ||||
|   "item.serverstorage.iron_platter": "Iron Hard Drive Platter", | ||||
|  | ||||
|   "item.serverstorage.diamond_drive": "Diamond hard drive", | ||||
|   "item.serverstorage.diamond_head": "Diamond hard drive head", | ||||
|   "item.serverstorage.diamond_platter": "Diamond hard drive platter", | ||||
|   "item.serverstorage.golden_drive": "Golden Hard Drive", | ||||
|   "item.serverstorage.golden_head": "Golden Hard Drive Head", | ||||
|   "item.serverstorage.golden_platter": "Golden Hard Drive Platter", | ||||
|  | ||||
|   "item.serverstorage.netherite_drive": "Netherite hard drive", | ||||
|   "item.serverstorage.netherite_head": "Netherite hard drive head", | ||||
|   "item.serverstorage.netherite_platter": "Netherite hard drive platter", | ||||
|   "item.serverstorage.diamond_drive": "Diamond Hard Drive", | ||||
|   "item.serverstorage.diamond_head": "Diamond Hard Drive Head", | ||||
|   "item.serverstorage.diamond_platter": "Diamond Hard Drive Platter", | ||||
|  | ||||
|   "item.serverstorage.module_bus": "Bus module", | ||||
|   "item.serverstorage.module_configuration": "Configuration module", | ||||
|   "item.serverstorage.module_container": "Container module", | ||||
|   "item.serverstorage.module_display": "Display module", | ||||
|   "item.serverstorage.module_drive": "Drive module", | ||||
|   "item.serverstorage.module_filtering": "Filtering module", | ||||
|   "item.serverstorage.module_inventory": "Inventory module", | ||||
|   "item.serverstorage.module_pagination": "Pagination module", | ||||
|   "item.serverstorage.module_transport": "Transport module", | ||||
|   "item.serverstorage.module_netherite_upgrade": "Netherite upgrade module", | ||||
|   "item.serverstorage.netherite_drive": "Netherite Hard Drive", | ||||
|   "item.serverstorage.netherite_head": "Netherite Hard Drive Head", | ||||
|   "item.serverstorage.netherite_platter": "Netherite Hard Drive Platter", | ||||
|  | ||||
|   "item.serverstorage.module_bus": "Bus Module", | ||||
|   "item.serverstorage.module_configuration": "Configuration Module", | ||||
|   "item.serverstorage.module_container": "Container Module", | ||||
|   "item.serverstorage.module_display": "Display Module", | ||||
|   "item.serverstorage.module_drive": "Drive Module", | ||||
|   "item.serverstorage.module_filtering": "Filtering Module", | ||||
|   "item.serverstorage.module_inventory": "Inventory Module", | ||||
|   "item.serverstorage.module_pagination": "Pagination Module", | ||||
|   "item.serverstorage.module_transport": "Transport Module", | ||||
|   "item.serverstorage.module_netherite_upgrade": "Netherite Upgrade Module", | ||||
|  | ||||
|  | ||||
|   "item.serverstorage.module_pcb": "Module PCB", | ||||
|  | ||||
|   "item.serverstorage.material_drive_casing": "Hard drive casing", | ||||
|   "item.serverstorage.material_drive_controller": "Drive controller", | ||||
|   "item.serverstorage.material_drive_casing": "Hard Drive Casing", | ||||
|   "item.serverstorage.material_drive_controller": "Drive Controller", | ||||
|   "item.serverstorage.material_cpu": "Central Processing Unit", | ||||
|   "item.serverstorage.material_cpu_substrate": "CPU substrate", | ||||
|   "item.serverstorage.material_cpu_substrate": "CPU Substrate", | ||||
|   "item.serverstorage.material_pcb": "Printed Circuit Board", | ||||
|   "item.serverstorage.material_pcb_substrate": "PCB substrate", | ||||
|   "item.serverstorage.material_pcb_substrate": "PCB Substrate", | ||||
|  | ||||
|   "item.serverstorage.iron_antenna": "Iron Antenna", | ||||
|   "item.serverstorage.golden_antenna": "Golden Antenna", | ||||
|   "item.serverstorage.diamond_antenna": "Diamond Antenna", | ||||
|   "item.serverstorage.netherite_antenna": "Netherite Antenna", | ||||
|  | ||||
|   "item.serverstorage.wireless_terminal": "Wireless terminal", | ||||
|  | ||||
|   "gui.serverstorage.store_all": "Store all items from inventory", | ||||
|   "gui.serverstorage.player_management": "Player management", | ||||
|   "gui.serverstorage.player_management_session": "Session %d", | ||||
|   "gui.serverstorage.player_management_session_owner": "Owned by: %s", | ||||
|   "gui.serverstorage.player_management_session_owner_error": "Not owned", | ||||
|   "gui.serverstorage.player_management_session_key": "Session key: %s", | ||||
|  | ||||
|   "gui.serverstorage.wireless_terminal_link_count": "Linked to %d devices", | ||||
|   "gui.serverstorage.wireless_terminal_link_index": "Current link index is %d", | ||||
|   "gui.serverstorage.wireless_terminal_page": "Page: %d", | ||||
|   "gui.serverstorage.wireless_terminal_search_query": "Search query: %s", | ||||
|   "gui.serverstorage.wireless_terminal_sorting_alphabetically": "Sorting alphabetically", | ||||
|   "gui.serverstorage.wireless_terminal_sorting_numerically": "Sorting numerically", | ||||
|   "gui.serverstorage.antenna_range": "Range: %d blocks", | ||||
|   "gui.serverstorage.player_management_session_click_deauthorize": "Click to deauthorize", | ||||
|   "gui.serverstorage.radio_selector": "Radio selector", | ||||
|   "gui.serverstorage.radio_entry": "Radio %d", | ||||
|   "gui.serverstorage.radio_connected": "Connected to radio at %s in %s from %s in %s, distance %d/%d", | ||||
|   "gui.serverstorage.radio_unauthorized": "Session unauthorized in radio at %s in %s", | ||||
|   "gui.serverstorage.radio_out_of_range": "Radio out of range at %s in %s from %s in %s, distance %d/%d", | ||||
|   "gui.serverstorage.radio_not_found": "Radio not found at %s in %s from %s in %s", | ||||
|   "gui.serverstorage.radio_position": "Placed at %s in %s", | ||||
|   "gui.serverstorage.radio_position_error": "Not Placed", | ||||
|   "gui.serverstorage.radio_session_click_select": "Left click to connect", | ||||
|   "gui.serverstorage.radio_session_click_open": "Right click to select", | ||||
|   "gui.serverstorage.radio_session_click_delete": "Shift Left click to remove", | ||||
|   "gui.serverstorage.filter": "Filter", | ||||
|   "gui.serverstorage.sort_alphabetically": "Sort alphabetically", | ||||
|   "gui.serverstorage.sort_descending": "Sort by count descending", | ||||
| @@ -58,9 +91,9 @@ | ||||
|   "gui.serverstorage.direction_up": "Up", | ||||
|   "gui.serverstorage.direction_down": "Down", | ||||
|  | ||||
|   "serverstorage.groups.blocks" : "Serverstorage blocks", | ||||
|   "serverstorage.groups.materials" : "Serverstorage materials", | ||||
|   "serverstorage.groups.drives" : "Serverstorage drives", | ||||
|   "serverstorage.groups.blocks" : "Serverstorage Blocks", | ||||
|   "serverstorage.groups.materials" : "Serverstorage Materials", | ||||
|   "serverstorage.groups.drives" : "Serverstorage Drives", | ||||
|  | ||||
|   "message.serverstorage.block_disabled": "This block was disabled in a gamerule, contact admins" | ||||
| } | ||||
		Reference in New Issue
	
	Block a user