Files
SurvivalFabric/src/main/java/wtf/hak/survivalfabric/sharedenderchest/SharedEnderChest.java
2025-03-26 10:04:28 +01:00

129 lines
5.9 KiB
Java

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<ItemStack> 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<ItemStack> 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();
}
}