package wtf.hak.survivalfabric.sharedenderchest; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.minecraft.block.EnderChestBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventories; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtSizeTracker; import net.minecraft.screen.GenericContainerScreenHandler; import net.minecraft.screen.SimpleNamedScreenHandlerFactory; import net.minecraft.server.MinecraftServer; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; import net.minecraft.util.*; import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import static wtf.hak.survivalfabric.SurvivalFabric.LOGGER; import static wtf.hak.survivalfabric.config.ConfigManager.getConfig; public class SharedEnderChest implements ServerLifecycleEvents.ServerStopping, ServerLifecycleEvents.ServerStarted, ServerTickEvents.EndTick { private static SharedInventory sharedInventory; private long ticksUntilSave = -20; public void onServerStarted(MinecraftServer server) { File inventoryFile = getFile(server); if (inventoryFile.exists()) { try (FileInputStream inventoryFileInputStream = new FileInputStream(inventoryFile); DataInputStream inventoryFileDataInput = new DataInputStream(inventoryFileInputStream)) { NbtCompound nbt = NbtIo.readCompressed(inventoryFileDataInput, NbtSizeTracker.ofUnlimitedBytes()); DefaultedList inventoryItemStacks = DefaultedList.ofSize(getConfig().sharedEnderChestRows * 9, ItemStack.EMPTY); Inventories.readNbt(nbt, inventoryItemStacks, server.getRegistryManager()); sharedInventory = new SharedInventory(inventoryItemStacks); } catch (Exception e) { LOGGER.error("Error while loading Shared Ender Chest: " + e); sharedInventory = new SharedInventory(getConfig().sharedEnderChestRows); } } else { sharedInventory = new SharedInventory(getConfig().sharedEnderChestRows); } } public static void saveInventory(MinecraftServer server) { File inventoryFile = getFile(server); NbtCompound nbt = new NbtCompound(); DefaultedList inventoryItemStacks = DefaultedList.ofSize(getConfig().sharedEnderChestRows * 9, ItemStack.EMPTY); Inventories.writeNbt(nbt, sharedInventory.getList(inventoryItemStacks), server.getRegistryManager()); try (FileOutputStream inventoryFileOutputStream = new FileOutputStream(inventoryFile); DataOutputStream inventoryFileDataOutput = new DataOutputStream(inventoryFileOutputStream)) { inventoryFile.createNewFile(); NbtIo.writeCompressed(nbt, inventoryFileDataOutput); } catch (Exception e) { LOGGER.error("Error while saving Shared Ender Chest: " + e); } } public void onServerStopping(MinecraftServer server) { saveInventory(server); } public void onEndTick(MinecraftServer server) { if (ticksUntilSave != -20 && --ticksUntilSave <= 0L) { saveInventory(server); ticksUntilSave = 20L; } } public void onInitialize() { ticksUntilSave = 20L; UseBlockCallback listenerUseBlock = (player, world, hand, hitResult) -> { if (world.getBlockState(hitResult.getBlockPos()).getBlock() instanceof EnderChestBlock) { if (!player.isSpectator()) { if(!getConfig().sharedEnderChestLimitedAccess) { if (world.isClient()) return ActionResult.SUCCESS; playEnderChestOpenSound(world, hitResult.getBlockPos()); openSharedEnderChest(player); return ActionResult.SUCCESS; } else { for(String name : getConfig().sharedEnderChestNames) { if(name.toLowerCase().strip().equalsIgnoreCase(player.getNameForScoreboard().toLowerCase())) { if (world.isClient()) return ActionResult.SUCCESS; playEnderChestOpenSound(world, hitResult.getBlockPos()); openSharedEnderChest(player); return ActionResult.SUCCESS; } } } } } return ActionResult.PASS; }; UseBlockCallback.EVENT.register(listenerUseBlock); ServerLifecycleEvents.SERVER_STARTED.register(this); ServerLifecycleEvents.SERVER_STOPPING.register(this); ServerTickEvents.END_SERVER_TICK.register(this); } public static void openSharedEnderChest(PlayerEntity player) { player.openHandledScreen(new SimpleNamedScreenHandlerFactory((int_1, playerInventory, playerEntity) -> new GenericContainerScreenHandler(getConfig().screenHandlerType(), int_1, playerInventory, sharedInventory, getConfig().sharedEnderChestRows), Text.of(getConfig().sharedEnderChestName))); } public static void playEnderChestOpenSound(World world, BlockPos pos) { world.playSound(null, pos, SoundEvents.BLOCK_ENDER_CHEST_OPEN, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); } private static File getFile(MinecraftServer server) { return server.getSavePath(WorldSavePath.ROOT).resolve("sharedenderchest.sav").toFile(); } }