129 lines
5.9 KiB
Java
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();
|
|
}
|
|
|
|
} |