Skip to content

Commit

Permalink
fix personal storage inventory crafting with contents on servers
Browse files Browse the repository at this point in the history
  • Loading branch information
thiakil committed Oct 29, 2023
1 parent 7888bb8 commit ad8e146
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class PersonalStorageItemContainer extends MekanismItemContainer {
public PersonalStorageItemContainer(int id, Inventory inv, InteractionHand hand, ItemStack stack, boolean isRemote) {
super(MekanismContainerTypes.PERSONAL_STORAGE_ITEM, id, inv, hand, stack);
//We have to initialize this before actually adding the slots
itemInventory = !isRemote ? PersonalStorageManager.getInventoryFor(stack) : new ClientSidePersonalStorageInventory();
itemInventory = !isRemote ? PersonalStorageManager.getInventoryFor(stack).orElseThrow(()->new IllegalStateException("Inventory not available")) : new ClientSidePersonalStorageInventory();
super.addSlotsAndOpen();
}

Expand Down Expand Up @@ -82,4 +82,4 @@ public void clicked(int slotId, int dragType, @NotNull ClickType clickType, @Not
}
super.clicked(slotId, dragType, clickType, player);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import java.util.Set;
import mekanism.api.annotations.ParametersAreNotNullByDefault;
import mekanism.api.inventory.IInventorySlot;
import mekanism.common.lib.inventory.personalstorage.PersonalStorageItemInventory;
import mekanism.common.lib.inventory.personalstorage.AbstractPersonalStorageItemInventory;
import mekanism.common.lib.inventory.personalstorage.ClientSidePersonalStorageInventory;
import mekanism.common.lib.inventory.personalstorage.PersonalStorageManager;
import mekanism.common.tile.TileEntityPersonalStorage;
import net.minecraft.MethodsReturnNonnullByDefault;
Expand All @@ -19,6 +20,7 @@
import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType;
import net.minecraft.world.level.storage.loot.parameters.LootContextParam;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraftforge.fml.util.thread.EffectiveSide;

/**
* Loot function which copies the Personal Storage inventory to the saved data and adds an inv id to the stack
Expand Down Expand Up @@ -47,7 +49,12 @@ public ItemStack apply(ItemStack itemStack, LootContext lootContext) {
BlockEntity blockEntity = lootContext.getParam(LootContextParams.BLOCK_ENTITY);
if (blockEntity instanceof TileEntityPersonalStorage personalStorage && !personalStorage.isInventoryEmpty()) {
List<IInventorySlot> tileSlots = personalStorage.getInventorySlots(null);
PersonalStorageItemInventory destInv = PersonalStorageManager.getInventoryFor(itemStack);
AbstractPersonalStorageItemInventory destInv;
if (EffectiveSide.get().isClient()) {
destInv = new ClientSidePersonalStorageInventory();
} else {
destInv = PersonalStorageManager.getInventoryFor(itemStack).orElseThrow(()->new IllegalStateException("Inventory not available?!"));
}
for (int i = 0; i < tileSlots.size(); i++) {
IInventorySlot tileSlot = tileSlots.get(i);
if (!tileSlot.isEmpty()) {
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/mekanism/common/lib/MekanismSavedData.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.function.Supplier;
import mekanism.common.Mekanism;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.level.storage.DimensionDataStorage;
import net.minecraftforge.server.ServerLifecycleHooks;
Expand Down Expand Up @@ -33,7 +34,11 @@ public void save(@NotNull File file) {
* Note: This should only be called from the server side
*/
public static <DATA extends MekanismSavedData> DATA createSavedData(Supplier<DATA> createFunction, String name) {
DimensionDataStorage dataStorage = ServerLifecycleHooks.getCurrentServer().overworld().getDataStorage();
MinecraftServer currentServer = ServerLifecycleHooks.getCurrentServer();
if (currentServer == null) {
throw new IllegalStateException("Current server is null");
}
DimensionDataStorage dataStorage = currentServer.overworld().getDataStorage();
return createSavedData(dataStorage, createFunction, name);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import mekanism.api.NBTConstants;
import mekanism.api.annotations.ParametersAreNotNullByDefault;
import mekanism.api.inventory.IInventorySlot;
import mekanism.common.Mekanism;
import mekanism.common.inventory.slot.BasicInventorySlot;
import mekanism.common.lib.MekanismSavedData;
import mekanism.common.util.ItemDataUtils;
Expand All @@ -22,6 +23,8 @@
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fml.util.thread.EffectiveSide;
import net.minecraftforge.server.ServerLifecycleHooks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -30,8 +33,11 @@
public class PersonalStorageManager {
private static final Map<UUID, PersonalStorageData> STORAGE_BY_PLAYER_UUID = new HashMap<>();

private static PersonalStorageData forOwner(UUID playerUUID) {
return STORAGE_BY_PLAYER_UUID.computeIfAbsent(playerUUID, uuid->MekanismSavedData.createSavedData(PersonalStorageData::new, "personal_storage" + File.separator + uuid));
private static Optional<PersonalStorageData> forOwner(UUID playerUUID) {
if (EffectiveSide.get().isClient()) {
return Optional.empty();
}
return Optional.of(STORAGE_BY_PLAYER_UUID.computeIfAbsent(playerUUID, uuid->MekanismSavedData.createSavedData(PersonalStorageData::new, "personal_storage" + File.separator + uuid)));
}

/**
Expand All @@ -40,22 +46,24 @@ private static PersonalStorageData forOwner(UUID playerUUID) {
* @param stack Personal storage ItemStack (type not checked) - will be modified if it didn't have an inventory id
* @return the existing or new inventory
*/
public static PersonalStorageItemInventory getInventoryFor(ItemStack stack) {
public static Optional<AbstractPersonalStorageItemInventory> getInventoryFor(ItemStack stack) {
UUID owner = SecurityUtils.get().getOwnerUUID(stack);
if (owner == null) {
throw new IllegalStateException("Stack has no owner!");
Mekanism.logger.error("Storage inventory asked for but stack has no owner! {}", stack, new Exception());
return Optional.empty();
}
UUID invId = getInventoryId(stack);
PersonalStorageItemInventory storageItemInventory = forOwner(owner).getOrAddInventory(invId);

//TODO - After 1.20: Remove legacy loading
ListTag legacyData = ItemDataUtils.getList(stack, NBTConstants.ITEMS);
if (!legacyData.isEmpty()) {
DataHandlerUtils.readContainers(storageItemInventory.getInventorySlots(null), legacyData);
ItemDataUtils.removeData(stack, NBTConstants.ITEMS);
}
return forOwner(owner).map(data->{
AbstractPersonalStorageItemInventory storageItemInventory = data.getOrAddInventory(invId);
//TODO - After 1.20: Remove legacy loading
ListTag legacyData = ItemDataUtils.getList(stack, NBTConstants.ITEMS);
if (!legacyData.isEmpty()) {
DataHandlerUtils.readContainers(storageItemInventory.getInventorySlots(null), legacyData);
ItemDataUtils.removeData(stack, NBTConstants.ITEMS);
}

return storageItemInventory;
return storageItemInventory;
});
}

public static boolean createInventoryFor(ItemStack stack, List<IInventorySlot> contents) {
Expand All @@ -66,7 +74,7 @@ public static boolean createInventoryFor(ItemStack stack, List<IInventorySlot> c
}
//Get a new inventory id
UUID invId = getInventoryId(stack);
forOwner(owner).addInventory(invId, contents);
forOwner(owner).ifPresent(inv->inv.addInventory(invId, contents));
return true;
}

Expand All @@ -79,19 +87,19 @@ public static boolean createInventoryFor(ItemStack stack, List<IInventorySlot> c
* @param stack Personal storage ItemStack
* @return the existing or converted inventory, or an empty optional if none exists in saved data nor legacy data
*/
public static Optional<PersonalStorageItemInventory> getInventoryIfPresent(ItemStack stack) {
public static Optional<AbstractPersonalStorageItemInventory> getInventoryIfPresent(ItemStack stack) {
UUID owner = SecurityUtils.get().getOwnerUUID(stack);
UUID invId = getInventoryIdNullable(stack);
//TODO - After 1.20: Remove legacy loading
boolean hasLegacyData = ItemDataUtils.hasData(stack, NBTConstants.ITEMS, Tag.TAG_LIST);
return Optional.ofNullable(owner != null && (invId != null || hasLegacyData) ? getInventoryFor(stack) : null);
return owner != null && (invId != null || hasLegacyData) ? getInventoryFor(stack) : Optional.empty();
}

public static void deleteInventory(ItemStack stack) {
UUID owner = SecurityUtils.get().getOwnerUUID(stack);
UUID invId = getInventoryIdNullable(stack);
if (owner != null && invId != null) {
forOwner(owner).removeInventory(invId);
forOwner(owner).ifPresent(handler->handler.removeInventory(invId));
}
}

Expand Down

0 comments on commit ad8e146

Please sign in to comment.