forked from BRNSystems/Server_storage
		
	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