Add blacklisting

This commit is contained in:
Bruno Rybársky 2024-05-28 19:10:50 +02:00
parent 1d4b658400
commit 5473358a75
9 changed files with 203 additions and 159 deletions

@ -77,22 +77,4 @@ jar {
from("LICENSE") { from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"} rename { "${it}_${project.archivesBaseName}"}
} }
} }
// configure the maven publication
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}

@ -8,7 +8,7 @@ yarn_mappings=1.20.6+build.3
loader_version=0.15.11 loader_version=0.15.11
# Mod Properties # Mod Properties
mod_version=2.2 mod_version=2.3
maven_group=systems.brn maven_group=systems.brn
archives_base_name=Server_storage archives_base_name=Server_storage

@ -17,19 +17,17 @@ import java.util.ArrayList;
import static systems.brn.server_storage.ServerStorage.STORAGE_BLOCK_ENTITY; import static systems.brn.server_storage.ServerStorage.STORAGE_BLOCK_ENTITY;
public class StorageBlockEntity extends BlockEntity implements Inventory, SidedInventory, Runnable { public class StorageBlockEntity extends BlockEntity implements Inventory, SidedInventory {
@Override public void removeScreen(StorageScreen storageScreenToDelete) {
public void run() {
assert storageScreenToDelete != null;
openStorageScreens.remove(storageScreenToDelete); openStorageScreens.remove(storageScreenToDelete);
} }
public StorageScreen storageScreenToDelete;
public Boolean sortAlphabetically = false; public Boolean sortAlphabetically = false;
public Boolean allInventories = false;
public String searchString = ""; public String searchString = "";
public int page = 0; public int page = 0;
public ConnectedChests chests;
public ArrayList<StorageScreen> openStorageScreens = new ArrayList<>(); public ArrayList<StorageScreen> openStorageScreens = new ArrayList<>();
@ -37,35 +35,73 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
super(STORAGE_BLOCK_ENTITY, pos, state); super(STORAGE_BLOCK_ENTITY, pos, state);
} }
public void rescanChests() {
this.chests = new ConnectedChests(world, this.pos, sortAlphabetically, searchString, allInventories);
this.updateDisplays();
}
@Override @Override
public int size() { public int size() {
return 1; if (chests != null) {
this.rescanChests();
return chests.inventory.size();
}
else {
return 1;
}
} }
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return true; if (chests != null) {
this.rescanChests();
return chests.inventory.isEmpty();
}
else {
return true;
}
} }
@Override @Override
public ItemStack getStack(int slot) { public ItemStack getStack(int slot) {
return ItemStack.EMPTY; if (chests != null) {
this.rescanChests();
return chests.inventory.getStack(slot);
}
else {
return ItemStack.EMPTY;
}
} }
@Override @Override
public ItemStack removeStack(int slot, int amount) { public ItemStack removeStack(int slot, int amount) {
return ItemStack.EMPTY; if (chests != null) {
ItemStack stackToRemove = chests.inventory.getStack(slot);
stackToRemove.setCount(
Math.min(
Math.min(stackToRemove.getCount(), amount), stackToRemove.getMaxCount())
);
return chests.removeItemStack(stackToRemove);
}
else {
return ItemStack.EMPTY;
}
} }
@Override @Override
public ItemStack removeStack(int slot) { public ItemStack removeStack(int slot) {
return ItemStack.EMPTY; if (chests != null) {
ItemStack stackToRemove = chests.inventory.getStack(slot);
stackToRemove.setCount(Math.min(stackToRemove.getCount(), stackToRemove.getMaxCount()));
return chests.removeItemStack(stackToRemove);
}
else {
return ItemStack.EMPTY;
}
} }
@Override @Override
public void setStack(int slot, ItemStack stack) { public void setStack(int slot, ItemStack stack) {
markDirty();
ConnectedChests chests = new ConnectedChests(world, this.pos, false);
chests.tryPutItemStack(stack); chests.tryPutItemStack(stack);
updateDisplays(); updateDisplays();
} }
@ -89,18 +125,29 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
// SidedInventory methods // SidedInventory methods
@Override @Override
public int[] getAvailableSlots(Direction side) { public int[] getAvailableSlots(Direction side) {
return new int[]{0}; // Allow access to the single slot if(this.chests != null) {
this.rescanChests();
int[] output = new int[chests.inventory.size()];
for (int i = 0; i < chests.inventory.size() - 1; i++) {
output[i] = i;
}
return output;
}
else {
return new int[0];
}
} }
@Override @Override
public boolean canInsert(int slot, ItemStack stack, Direction dir) { public boolean canInsert(int slot, ItemStack stack, Direction dir) {
ConnectedChests chests = new ConnectedChests(world, this.pos, false); rescanChests();
return chests.canAddItemStack(stack); return chests.canAddItemStack(stack);
} }
@Override @Override
public boolean canExtract(int slot, ItemStack stack, Direction dir) { public boolean canExtract(int slot, ItemStack stack, Direction dir) {
return false; // Prevent extraction rescanChests();
return chests.canRemove(stack);
} }
// Serialize the BlockEntity // Serialize the BlockEntity
@ -110,6 +157,7 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
nbt.putInt("page", page); nbt.putInt("page", page);
nbt.putBoolean("sortAlphabetically", sortAlphabetically); nbt.putBoolean("sortAlphabetically", sortAlphabetically);
nbt.putString("searchString", searchString); nbt.putString("searchString", searchString);
nbt.putBoolean("allInventories", allInventories);
super.writeNbt(nbt, wrapperLookup); super.writeNbt(nbt, wrapperLookup);
} }
@ -122,5 +170,6 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
page = nbt.getInt("page"); page = nbt.getInt("page");
sortAlphabetically = nbt.getBoolean("sortAlphabetically"); sortAlphabetically = nbt.getBoolean("sortAlphabetically");
searchString = nbt.getString("searchString"); searchString = nbt.getString("searchString");
allInventories = nbt.getBoolean("allInventories");
} }
} }

@ -28,7 +28,6 @@ import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import systems.brn.server_storage.ServerStorage; import systems.brn.server_storage.ServerStorage;
import systems.brn.server_storage.blockentities.StorageBlockEntity; import systems.brn.server_storage.blockentities.StorageBlockEntity;
import systems.brn.server_storage.lib.ConnectedChests;
import systems.brn.server_storage.screens.StorageScreen; import systems.brn.server_storage.screens.StorageScreen;
import java.util.List; import java.util.List;
@ -72,17 +71,15 @@ public class StorageBlock extends Block implements PolymerTexturedBlock, BlockEn
if (block instanceof StorageBlock) { if (block instanceof StorageBlock) {
if (!world.isClient && !player.isSpectator()) { if (!world.isClient && !player.isSpectator()) {
if(!player.isSneaking()){ if(!player.isSneaking()){
StorageBlockEntity blockEntity = (StorageBlockEntity) world.getBlockEntity(pos); StorageScreen storageScreen = new StorageScreen((ServerPlayerEntity) player, pos, null);
assert blockEntity != null;
StorageScreen storageScreen = new StorageScreen((ServerPlayerEntity) player, pos, blockEntity);
storageScreen.open(); storageScreen.open();
blockEntity.openStorageScreens.add(storageScreen);
} }
else if(player.getStackInHand(hand).getItem() == Items.WRITTEN_BOOK) { else if(player.getStackInHand(hand).getItem() == Items.WRITTEN_BOOK) {
ItemStack book = player.getStackInHand(hand); ItemStack book = player.getStackInHand(hand);
ConnectedChests chests = new ConnectedChests(world, pos, true); StorageBlockEntity storageBlockEntity = (StorageBlockEntity) world.getBlockEntity(pos);
List<RawFilteredPair<Text>> generatedContent = generateBookContent(chests.inventory); assert storageBlockEntity != null;
List<RawFilteredPair<Text>> generatedContent = generateBookContent(storageBlockEntity.chests.inventory);
book.set(DataComponentTypes.WRITTEN_BOOK_CONTENT, new WrittenBookContentComponent( book.set(DataComponentTypes.WRITTEN_BOOK_CONTENT, new WrittenBookContentComponent(
RawFilteredPair.of("Item Listing"), RawFilteredPair.of("Item Listing"),
player.getGameProfile().getName(), player.getGameProfile().getName(),

@ -1,14 +1,13 @@
package systems.brn.server_storage.lib; package systems.brn.server_storage.lib;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.*;
import net.minecraft.block.entity.HopperBlockEntity;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory; import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import systems.brn.server_storage.blocks.StorageBlock; import systems.brn.server_storage.blockentities.StorageBlockEntity;
import java.util.*; import java.util.*;
@ -23,15 +22,15 @@ public class ConnectedChests {
public final int containerUsedSlots; public final int containerUsedSlots;
public final int containerFreeSlots; public final int containerFreeSlots;
public ConnectedChests(World world, BlockPos startPos, boolean sortAlphabetically) { public ConnectedChests(World world, BlockPos startPos, boolean sortAlphabetically, String searchString, boolean allInventories) {
List<Inventory> inventories = new ArrayList<>(); List<Inventory> inventories = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
getConnectedChestsHelper(world, startPos, inventories, visited); getConnectedChestsHelper(world, startPos, inventories, visited, allInventories);
this.inventories = inventories; this.inventories = inventories;
this.containerCount = inventories.size(); this.containerCount = inventories.size();
this.inventory = getCombinedInventory(sortAlphabetically); this.inventory = getCombinedInventory(sortAlphabetically, searchString);
int tempContainerSlots = 0; int tempContainerSlots = 0;
int tempContainerUsedSlots = 0; int tempContainerUsedSlots = 0;
@ -52,27 +51,34 @@ public class ConnectedChests {
containerFreeSlots = tempContainerFreeSlots; containerFreeSlots = tempContainerFreeSlots;
} }
private static void getConnectedChestsHelper(World world, BlockPos pos, List<Inventory> inventories, Set<BlockPos> visited) { private static boolean isEnabledContainer(BlockEntity blockEntity, boolean allContainers) {
return (allContainers && blockEntity instanceof Inventory) ||
blockEntity instanceof BarrelBlockEntity ||
blockEntity instanceof ChestBlockEntity ||
blockEntity instanceof ShulkerBoxBlockEntity;
}
private static void getConnectedChestsHelper(World world, BlockPos pos, List<Inventory> inventories, Set<BlockPos> visited, Boolean allContainers) {
if (visited.contains(pos)) { if (visited.contains(pos)) {
return; return;
} }
visited.add(pos); visited.add(pos);
BlockEntity blockEntity = world.getBlockEntity(pos); BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof Inventory || world.getBlockState(pos).getBlock() instanceof StorageBlock) { if (isEnabledContainer(blockEntity, allContainers) || blockEntity instanceof StorageBlockEntity) {
if (blockEntity instanceof Inventory && !(world.getBlockState(pos).getBlock() instanceof StorageBlock)) { if (isEnabledContainer(blockEntity, allContainers) && !(blockEntity instanceof StorageBlockEntity)) {
inventories.add((Inventory) blockEntity); inventories.add((Inventory) blockEntity);
} }
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
BlockPos nextPos = pos.offset(direction); BlockPos nextPos = pos.offset(direction);
getConnectedChestsHelper(world, nextPos, inventories, visited); getConnectedChestsHelper(world, nextPos, inventories, visited, allContainers);
} }
} }
} }
// Modify getCombinedInventoryFromChests to include item metadata and combine stacks // Modify getCombinedInventoryFromChests to include item metadata and combine stacks
private SimpleInventory getCombinedInventory(boolean sortAlphabetically) { private SimpleInventory getCombinedInventory(boolean sortAlphabetically, String query) {
Map<ItemStack, Integer> itemStackMap = new HashMap<>(); Map<ItemStack, Integer> itemStackMap = new HashMap<>();
for (Inventory inventory : inventories) { for (Inventory inventory : inventories) {
for (int i = 0; i < inventory.size(); i++) { for (int i = 0; i < inventory.size(); i++) {
@ -84,7 +90,7 @@ public class ConnectedChests {
ItemStack existingStack = entry.getKey(); ItemStack existingStack = entry.getKey();
if (ItemStack.areItemsAndComponentsEqual(stack, existingStack)) { if (ItemStack.areItemsAndComponentsEqual(stack, existingStack)) {
int count = entry.getValue() + stack.getCount(); int count = entry.getValue() + stack.getCount();
itemStackMap.put(existingStack, count); itemStackMap.put(existingStack.copy(), count);
found = true; found = true;
break; break;
} }
@ -97,7 +103,26 @@ public class ConnectedChests {
} }
} }
} }
return getSimpleInventory(itemStackMap.size(), itemStackMap, sortAlphabetically); return filterInventory(getSimpleInventory(itemStackMap.size(), itemStackMap, sortAlphabetically), query, sortAlphabetically);
}
// Modify filterInventory to include item metadata
private SimpleInventory filterInventory(SimpleInventory inventory, String query, boolean sortAlphabetically) {
if (query == null || query.isEmpty()) {
return inventory;
}
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
int itemCount = 0;
for (int slot = 0; slot < inventory.size(); slot++) {
ItemStack stack = inventory.getStack(slot);
ItemStack filteredStack = filterStack(stack, query);
if (!filteredStack.isEmpty()) {
itemCount++;
int count = itemStackMap.getOrDefault(filteredStack, 0) + filteredStack.getCount();
itemStackMap.put(filteredStack.copy(), count);
}
}
return getSimpleInventory(itemCount, itemStackMap, sortAlphabetically);
} }
public boolean tryPutItemStack(ItemStack stack) { public boolean tryPutItemStack(ItemStack stack) {
@ -135,16 +160,38 @@ public class ConnectedChests {
return false; return false;
} }
public void removeItemStack(ItemStack stackToRemove) { public boolean canRemove(ItemStack stackToRemove) {
int remainingToRemove = stackToRemove.getCount();
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
if (canCombine(slotStack, stackToRemove)) {
// If the slot contains the same item type
if (slotStack.getCount() >= remainingToRemove) {
// If the count in the slot is sufficient to remove the requested amount
return true;
} else {
// If the count in the slot is not sufficient, update remainingToRemove
remainingToRemove -= slotStack.getCount();
}
}
}
// If no matching stack with sufficient count is found, return false
return false;
}
public ItemStack removeItemStack(ItemStack stackToRemove) {
int remainingToRemove = stackToRemove.getCount(); int remainingToRemove = stackToRemove.getCount();
ItemStack outStack = stackToRemove.copy();
for (Inventory chest : inventories) { for (Inventory chest : inventories) {
remainingToRemove = removeFromInventory(chest, stackToRemove, remainingToRemove); remainingToRemove = removeFromInventory(chest, stackToRemove, remainingToRemove);
if (remainingToRemove <= 0) { if (remainingToRemove <= 0) {
return; return outStack;
} }
} }
outStack.setCount(outStack.getCount() - remainingToRemove);
return outStack;
} }
} }

@ -31,6 +31,7 @@ public abstract class PagedGui extends SimpleGui {
public static final String GUI_A = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGU0MTc0ODEyMTYyNmYyMmFlMTZhNGM2NjRjNzMwMWE5ZjhlYTU5MWJmNGQyOTg4ODk1NzY4MmE5ZmRhZiJ9fX0="; public static final String GUI_A = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGU0MTc0ODEyMTYyNmYyMmFlMTZhNGM2NjRjNzMwMWE5ZjhlYTU5MWJmNGQyOTg4ODk1NzY4MmE5ZmRhZiJ9fX0=";
public static final String GUI_1 = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2E1MTZmYmFlMTYwNThmMjUxYWVmOWE2OGQzMDc4NTQ5ZjQ4ZjZkNWI2ODNmMTljZjVhMTc0NTIxN2Q3MmNjIn19fQ=="; public static final String GUI_1 = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2E1MTZmYmFlMTYwNThmMjUxYWVmOWE2OGQzMDc4NTQ5ZjQ4ZjZkNWI2ODNmMTljZjVhMTc0NTIxN2Q3MmNjIn19fQ==";
public static final String GUI_STORE_ALL = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWFkNmM4MWY4OTlhNzg1ZWNmMjZiZTFkYzQ4ZWFlMmJjZmU3NzdhODYyMzkwZjU3ODVlOTViZDgzYmQxNGQifX19"; public static final String GUI_STORE_ALL = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWFkNmM4MWY4OTlhNzg1ZWNmMjZiZTFkYzQ4ZWFlMmJjZmU3NzdhODYyMzkwZjU3ODVlOTViZDgzYmQxNGQifX19";
public static final String GUI_SETTINGS = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2EzYzhjNmQzYWFhOTYzNjNkNGJlZjI1NzhmMTAyNDc4MWVhMTRlOWQ4NWE5ZGNmYzA5MzU4NDdhNmZiNWM4ZCJ9fX0=";
public static final int PAGE_SIZE = 9 * 5; public static final int PAGE_SIZE = 9 * 5;
protected final Runnable closeCallback; protected final Runnable closeCallback;
@ -115,7 +116,8 @@ public abstract class PagedGui extends SimpleGui {
case 3 -> this.sorting(); case 3 -> this.sorting();
case 4 -> this.refresh(); case 4 -> this.refresh();
case 5 -> this.storeAll(); case 5 -> this.storeAll();
case 6 -> DisplayElement.nextPage(this); case 6 -> this.settings();
case 7 -> DisplayElement.nextPage(this);
case 8 -> DisplayElement.of( case 8 -> DisplayElement.of(
new GuiElementBuilder(Items.STRUCTURE_VOID) new GuiElementBuilder(Items.STRUCTURE_VOID)
.setName(Text.translatable(this.closeCallback != null ? "gui.back" : "mco.selectServer.close").formatted(Formatting.RED)) .setName(Text.translatable(this.closeCallback != null ? "gui.back" : "mco.selectServer.close").formatted(Formatting.RED))
@ -129,13 +131,24 @@ public abstract class PagedGui extends SimpleGui {
}; };
} }
protected abstract DisplayElement refresh(); protected DisplayElement refresh() {
return DisplayElement.filler();
}
protected abstract DisplayElement search(); protected DisplayElement search(){
return DisplayElement.filler();
}
protected DisplayElement sorting(){
return DisplayElement.filler();
}
protected abstract DisplayElement sorting(); protected DisplayElement storeAll(){
return DisplayElement.filler();
}
protected abstract DisplayElement storeAll(); protected DisplayElement settings(){
return DisplayElement.filler();
}
public record DisplayElement(@Nullable GuiElementInterface element, @Nullable Slot slot) { public record DisplayElement(@Nullable GuiElementInterface element, @Nullable Slot slot) {

@ -8,8 +8,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
@ -20,23 +18,17 @@ public class StorageOperations {
if (sortAlphabetically) { if (sortAlphabetically) {
// Sort alphabetically by item name // Sort alphabetically by item name
sortedMap = new TreeMap<>(new Comparator<ItemStack>() { sortedMap = new TreeMap<>((o1, o2) -> {
@Override String name1 = String.valueOf(o1.getItem());
public int compare(ItemStack o1, ItemStack o2) { String name2 = String.valueOf(o2.getItem());
String name1 = String.valueOf(o1.getItem()); return name1.compareToIgnoreCase(name2);
String name2 = String.valueOf(o2.getItem());
return name1.compareToIgnoreCase(name2);
}
}); });
} else { } else {
// Sort by count in descending order // Sort by count in descending order
sortedMap = new TreeMap<>(new Comparator<ItemStack>() { sortedMap = new TreeMap<>((o1, o2) -> {
@Override int countCompare = Integer.compare(o2.getCount(), o1.getCount());
public int compare(ItemStack o1, ItemStack o2) { // If counts are equal, compare items alphabetically by name
int countCompare = Integer.compare(o2.getCount(), o1.getCount()); return countCompare == 0 ? String.valueOf(o1.getItem()).compareToIgnoreCase(String.valueOf(o2.getItem())) : countCompare;
// If counts are equal, compare items alphabetically by name
return countCompare == 0 ? String.valueOf(o1.getItem()).compareToIgnoreCase(String.valueOf(o2.getItem())) : countCompare;
}
}); });
} }
@ -54,25 +46,6 @@ public class StorageOperations {
return inv; return inv;
} }
// Modify filterInventory to include item metadata
public static Inventory filterInventory(Inventory inventory, String query, boolean sortAlphabetically) {
if(query == null || query.isEmpty()) {
return inventory;
}
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
int itemCount = 0;
for (int slot = 0; slot < inventory.size(); slot++) {
ItemStack stack = inventory.getStack(slot);
ItemStack filteredStack = filterStack(stack, query);
if (!filteredStack.isEmpty()) {
itemCount++;
int count = itemStackMap.getOrDefault(filteredStack, 0) + filteredStack.getCount();
itemStackMap.put(filteredStack, count);
}
}
return getSimpleInventory(itemCount, itemStackMap, sortAlphabetically);
}
// Modify filterStack to include item metadata // Modify filterStack to include item metadata
public static ItemStack filterStack(ItemStack stack, String query) { public static ItemStack filterStack(ItemStack stack, String query) {
Item item = stack.getItem(); Item item = stack.getItem();
@ -109,26 +82,6 @@ public class StorageOperations {
return maxInsert; // Return the maximum insertion count return maxInsert; // Return the maximum insertion count
} }
public static boolean canRemoveFromInventory(Inventory inventory, ItemStack stackToRemove) {
int remainingToRemove = stackToRemove.getCount();
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
if (canCombine(slotStack, stackToRemove)) {
// If the slot contains the same item type
if (slotStack.getCount() >= remainingToRemove) {
// If the count in the slot is sufficient to remove the requested amount
return true;
} else {
// If the count in the slot is not sufficient, update remainingToRemove
remainingToRemove -= slotStack.getCount();
}
}
}
// If no matching stack with sufficient count is found, return false
return false;
}
public static ItemStack insertStackIntoInventory(Inventory inventory, ItemStack stack) { public static ItemStack insertStackIntoInventory(Inventory inventory, ItemStack stack) {
// First, try to merge with existing stacks // First, try to merge with existing stacks
for (int i = 0; i < inventory.size(); i++) { for (int i = 0; i < inventory.size(); i++) {

@ -3,7 +3,6 @@ package systems.brn.server_storage.screens;
import eu.pb4.sgui.api.ClickType; import eu.pb4.sgui.api.ClickType;
import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.elements.GuiElementBuilder;
import eu.pb4.sgui.api.elements.GuiElementInterface; import eu.pb4.sgui.api.elements.GuiElementInterface;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.SlotActionType;
@ -11,10 +10,8 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import systems.brn.server_storage.blockentities.StorageBlockEntity; import systems.brn.server_storage.blockentities.StorageBlockEntity;
import systems.brn.server_storage.lib.ConnectedChests;
import systems.brn.server_storage.lib.PagedGui; import systems.brn.server_storage.lib.PagedGui;
import static systems.brn.server_storage.lib.StorageOperations.*; import static systems.brn.server_storage.lib.StorageOperations.*;
@ -22,19 +19,12 @@ import static systems.brn.server_storage.lib.Util.addCountToLore;
import static systems.brn.server_storage.lib.Util.removeCountFromLore; import static systems.brn.server_storage.lib.Util.removeCountFromLore;
public class StorageScreen extends PagedGui { public class StorageScreen extends PagedGui {
private final BlockPos pos;
private final ServerPlayerEntity player; private final ServerPlayerEntity player;
private final World world;
private ConnectedChests chests;
private final StorageBlockEntity blockEntity; private final StorageBlockEntity blockEntity;
private String searchString;
private Boolean sortAlphabetically;
public StorageScreen(ServerPlayerEntity player, BlockPos pos, @Nullable Runnable closeCallback) { public StorageScreen(ServerPlayerEntity player, BlockPos pos, @Nullable Runnable closeCallback) {
super(player, closeCallback); super(player, closeCallback);
this.player = player; this.player = player;
this.pos = pos;
this.world = player.getWorld();
this.setLockPlayerInventory(false); this.setLockPlayerInventory(false);
this.blockEntity = (StorageBlockEntity) player.getWorld().getBlockEntity(pos); this.blockEntity = (StorageBlockEntity) player.getWorld().getBlockEntity(pos);
assert blockEntity != null; assert blockEntity != null;
@ -43,23 +33,21 @@ public class StorageScreen extends PagedGui {
@Override @Override
public boolean open() { public boolean open() {
page = blockEntity.page; page = blockEntity.page;
searchString = blockEntity.searchString; this.blockEntity.openStorageScreens.add(this);
sortAlphabetically = blockEntity.sortAlphabetically; this.blockEntity.rescanChests();
this.updateDisplay();
return super.open(); return super.open();
} }
@Override @Override
public void updateDisplay() { public void updateDisplay() {
this.chests = new ConnectedChests(world, pos, sortAlphabetically); String title = blockEntity.chests.containerUsedSlots +
String title = chests.containerUsedSlots +
"u/" + "u/" +
chests.containerSlots + blockEntity.chests.containerSlots +
"t(" + "t(" +
chests.containerFreeSlots + blockEntity.chests.containerFreeSlots +
"f)" + "f)" +
"[" + "[" +
chests.containerCount + blockEntity.chests.containerCount +
"c]"; "c]";
setTitle(Text.of(title)); setTitle(Text.of(title));
@ -68,16 +56,13 @@ public class StorageScreen extends PagedGui {
@Override @Override
protected int getPageAmount() { protected int getPageAmount() {
int sizeX = 9; return Math.ceilDivExact(blockEntity.chests.inventory.size(), 9 * 6);
int sizeY = 6;
return Math.ceilDivExact(filterInventory(chests.inventory, searchString, sortAlphabetically).size(), sizeX * sizeY);
} }
@Override @Override
protected DisplayElement getElement(int id) { protected DisplayElement getElement(int id) {
if (chests.inventory.size() > id) { if (blockEntity.chests.inventory.size() > id) {
Inventory filteredInventory = filterInventory(chests.inventory, searchString, sortAlphabetically); ItemStack itemStack = blockEntity.chests.inventory.getStack(id);
ItemStack itemStack = filteredInventory.getStack(id);
ItemStack newStack = addCountToLore(itemStack.getCount(), itemStack); ItemStack newStack = addCountToLore(itemStack.getCount(), itemStack);
GuiElementBuilder guiElement = new GuiElementBuilder(newStack); GuiElementBuilder guiElement = new GuiElementBuilder(newStack);
return DisplayElement.of(guiElement); return DisplayElement.of(guiElement);
@ -112,10 +97,11 @@ public class StorageScreen extends PagedGui {
int insertCount = canInsertItemIntoPlayerInventory(player, noLoreStack); int insertCount = canInsertItemIntoPlayerInventory(player, noLoreStack);
ItemStack insertingStack = noLoreStack.copy(); ItemStack insertingStack = noLoreStack.copy();
insertingStack.setCount(insertCount); insertingStack.setCount(insertCount);
if (canRemoveFromInventory(chests.inventory, noLoreStack) && insertCount > 0) { blockEntity.rescanChests();
if (blockEntity.chests.canRemove(noLoreStack) && insertCount > 0) {
player.getInventory().insertStack(insertingStack.copy()); player.getInventory().insertStack(insertingStack.copy());
chests.removeItemStack(insertingStack); blockEntity.chests.removeItemStack(insertingStack);
blockEntity.updateDisplays(); blockEntity.rescanChests();
} }
} }
} }
@ -124,13 +110,30 @@ public class StorageScreen extends PagedGui {
@Override @Override
public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) { public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
if (chests.tryPutItemStack(stack)) { blockEntity.rescanChests();
if (blockEntity.chests.tryPutItemStack(stack)) {
removeFromInventory(player.getInventory(), stack, stack.getCount()); removeFromInventory(player.getInventory(), stack, stack.getCount());
} }
blockEntity.updateDisplays(); blockEntity.rescanChests();
return super.insertItem(stack, startIndex, endIndex, fromLast); return super.insertItem(stack, startIndex, endIndex, fromLast);
} }
@Override
protected DisplayElement settings() {
return DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable(this.blockEntity.allInventories ? "gui.all" : "options.fov.min").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(GUI_SETTINGS)
.setCallback((x, y, z) -> {
this.blockEntity.allInventories ^= true;
this.blockEntity.markDirty();
this.blockEntity.rescanChests();
playClickSound(getPlayer());
})
);
}
@Override @Override
protected DisplayElement search() { protected DisplayElement search() {
return DisplayElement.of( return DisplayElement.of(
@ -150,13 +153,13 @@ public class StorageScreen extends PagedGui {
protected DisplayElement sorting() { protected DisplayElement sorting() {
return DisplayElement.of( return DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD) new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable(sortAlphabetically ? "A->Z" : "9->1").formatted(Formatting.WHITE)) .setName(Text.translatable(this.blockEntity.sortAlphabetically ? "A->Z" : "9->1").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults() .hideDefaultTooltip().noDefaults()
.setSkullOwner(sortAlphabetically ? GUI_A : GUI_1) .setSkullOwner(this.blockEntity.sortAlphabetically ? GUI_A : GUI_1)
.setCallback((x, y, z) -> { .setCallback((x, y, z) -> {
this.sortAlphabetically ^= true; this.blockEntity.sortAlphabetically ^= true;
playClickSound(getPlayer()); playClickSound(getPlayer());
updateDisplay(); this.blockEntity.rescanChests();
}) })
); );
} }
@ -179,9 +182,9 @@ public class StorageScreen extends PagedGui {
} }
public void doSearch(String query) { public void doSearch(String query) {
this.searchString = query; this.blockEntity.searchString = query;
this.blockEntity.rescanChests();
this.page = 0; this.page = 0;
updateDisplay();
} }
@Override @Override
@ -194,8 +197,8 @@ public class StorageScreen extends PagedGui {
.setCallback((x, y, z) -> { .setCallback((x, y, z) -> {
playClickSound(player); playClickSound(player);
this.page = 0; this.page = 0;
this.searchString = ""; this.blockEntity.searchString = "";
updateDisplay(); this.blockEntity.rescanChests();
}) })
); );
} }
@ -203,9 +206,8 @@ public class StorageScreen extends PagedGui {
@Override @Override
public void onClose() { public void onClose() {
this.blockEntity.page = page; this.blockEntity.page = page;
this.blockEntity.searchString = searchString;
this.blockEntity.sortAlphabetically = sortAlphabetically;
this.blockEntity.markDirty(); this.blockEntity.markDirty();
this.blockEntity.removeScreen(this);
super.onClose(); super.onClose();
} }
} }

@ -1,3 +1,4 @@
{ {
"block.serverstorage.storage": "Chest storage controller" "block.serverstorage.storage": "Chest storage controller",
"block.serverstorage.fast_hopper": "Fast hopper"
} }