From 992f3d69816c4a551fddd0cbc7bfc836f2060daa Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Thu, 14 Jun 2018 20:16:17 +0200 Subject: [PATCH] 1.5 -> 1.6 migration: storage disks. #1816 --- .../refinedstorage/api/IRSAPI.java | 9 ++ .../storage/disk/IStorageDiskProvider.java | 12 ++ .../api/util/IOneSixMigrationHelper.java | 39 ++++++ .../refinedstorage/apiimpl/API.java | 14 ++- .../node/diskdrive/NetworkNodeDiskDrive.java | 5 + .../NetworkNodeDiskManipulator.java | 9 ++ .../apiimpl/util/OneSixMigrationHelper.java | 115 ++++++++++++++++++ .../item/ItemFluidStorageDisk.java | 28 ++++- .../refinedstorage/item/ItemStorageDisk.java | 28 ++++- .../tile/DirectionHandlerTile.java | 2 +- .../tile/grid/portable/PortableGrid.java | 5 + 11 files changed, 249 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/api/util/IOneSixMigrationHelper.java create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OneSixMigrationHelper.java diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java b/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java index 6207e49fd..8cf4a5a1c 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java @@ -18,6 +18,7 @@ import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper; import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter; import com.raoulvdberge.refinedstorage.api.util.IStackList; import net.minecraft.entity.player.EntityPlayer; @@ -148,6 +149,7 @@ public interface IRSAPI { * @param capacity the capacity * @return a storage disk */ + @Nonnull IStorageDisk createDefaultItemDisk(World world, int capacity); /** @@ -155,8 +157,15 @@ public interface IRSAPI { * @param capacity the capacity in mB * @return a fluid storage disk */ + @Nonnull IStorageDisk createDefaultFluidDisk(World world, int capacity); + /** + * @return the 1.6.x migration helper + */ + @Nonnull + IOneSixMigrationHelper getOneSixMigrationHelper(); + /** * Opens a wireless grid for the given player. * diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/disk/IStorageDiskProvider.java b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/disk/IStorageDiskProvider.java index b8e235470..e5fbf02e2 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/disk/IStorageDiskProvider.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/disk/IStorageDiskProvider.java @@ -15,12 +15,24 @@ public interface IStorageDiskProvider { */ UUID getId(ItemStack disk); + /** + * @param disk the disk + * @param id the id to set + */ + void setId(ItemStack disk, UUID id); + /** * @param disk the disk * @return true if the given disk has an id set, false otherwise */ boolean isValid(ItemStack disk); + /** + * @param disk the disk + * @return the capacity of the given disk + */ + int getCapacity(ItemStack disk); + /** * @return the storage type */ diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/util/IOneSixMigrationHelper.java b/src/main/java/com/raoulvdberge/refinedstorage/api/util/IOneSixMigrationHelper.java new file mode 100644 index 000000000..08f8fbf4b --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/util/IOneSixMigrationHelper.java @@ -0,0 +1,39 @@ +package com.raoulvdberge.refinedstorage.api.util; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.items.IItemHandlerModifiable; + +import java.util.UUID; + +/** + * A helper for the changes in 1.6. + */ +public interface IOneSixMigrationHelper { + /** + * Migrates this disk over to the new 1.6 format *IF POSSIBLE*. + * The given disk item needs to implement {@link com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider}! + * This will call {@link com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider#setId(ItemStack, UUID)} on the disk, so make sure + * a call to this method clears previous 1.5 and lower data, or this method will keep migrating constantly! + *

+ * This will *ONLY* work with disks that were made using the IStorageDiskBehavior 1.5 API. + * If you were using another method, you'll have to implement the migration code yourself. + * + * @param world the world + * @param disk the disk to attempt to migrate + * @return true if it migrated, false otherwise + */ + boolean migrateDisk(World world, ItemStack disk); + + /** + * Migrates an entire inventory. + * Loops over every slot in the inventory and calls {@link #migrateDisk(World, ItemStack)}. + * All the docs from {@link #migrateDisk(World, ItemStack)} apply here as well! + * Don't forget to mark your tile dirty if this call returns true! + * + * @param world the world + * @param handler the inventory + * @return true if it migrated something in the inventory, false otherwise + */ + boolean migrateDiskInventory(World world, IItemHandlerModifiable handler); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java index 8203b1f30..1dfcf32ff 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java @@ -22,6 +22,7 @@ import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper; import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementList; @@ -35,10 +36,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriter import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterHandlerRegistry; import com.raoulvdberge.refinedstorage.apiimpl.solderer.SoldererRegistry; import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.*; -import com.raoulvdberge.refinedstorage.apiimpl.util.Comparer; -import com.raoulvdberge.refinedstorage.apiimpl.util.QuantityFormatter; -import com.raoulvdberge.refinedstorage.apiimpl.util.StackListFluid; -import com.raoulvdberge.refinedstorage.apiimpl.util.StackListItem; +import com.raoulvdberge.refinedstorage.apiimpl.util.*; import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -72,6 +70,7 @@ public class API implements IRSAPI { private IWirelessGridRegistry gridRegistry = new WirelessGridRegistry(); private IStorageDiskRegistry storageDiskRegistry = new StorageDiskRegistry(); private IStorageDiskSync storageDiskSync = new StorageDiskSync(); + private IOneSixMigrationHelper oneSixMigrationHelper = new OneSixMigrationHelper(); public static IRSAPI instance() { return INSTANCE; @@ -228,15 +227,22 @@ public class API implements IRSAPI { } @Override + @Nonnull public IStorageDisk createDefaultItemDisk(World world, int capacity) { return new StorageDiskItem(world, capacity); } @Override + @Nonnull public IStorageDisk createDefaultFluidDisk(World world, int capacity) { return new StorageDiskFluid(world, capacity); } + @Override + public IOneSixMigrationHelper getOneSixMigrationHelper() { + return oneSixMigrationHelper; + } + @Override public void openWirelessGrid(EntityPlayer player, EnumHand hand, int networkDimension, int id) { player.openGui(RS.INSTANCE, RSGui.WIRELESS_GRID, player.getEntityWorld(), hand.ordinal(), networkDimension, id); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java index be2b077f2..e13105c1c 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java @@ -9,6 +9,7 @@ import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskContainerContext; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.network.node.IGuiStorage; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid; @@ -147,6 +148,10 @@ public class NetworkNodeDiskDrive extends NetworkNode implements IGuiStorage, IS super.read(tag); StackUtils.readItems(disks, 0, tag); + + if (API.instance().getOneSixMigrationHelper().migrateDiskInventory(world, disks)) { + markDirty(); + } } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskmanipulator/NetworkNodeDiskManipulator.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskmanipulator/NetworkNodeDiskManipulator.java index dd86e8aa0..f60bddf49 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskmanipulator/NetworkNodeDiskManipulator.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskmanipulator/NetworkNodeDiskManipulator.java @@ -5,6 +5,7 @@ import com.raoulvdberge.refinedstorage.api.storage.AccessType; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskContainerContext; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode; import com.raoulvdberge.refinedstorage.apiimpl.network.node.diskdrive.NetworkNodeDiskDrive; import com.raoulvdberge.refinedstorage.inventory.*; @@ -460,6 +461,14 @@ public class NetworkNodeDiskManipulator extends NetworkNode implements IComparab StackUtils.readItems(upgrades, 3, tag); StackUtils.readItems(inputDisks, 4, tag); StackUtils.readItems(outputDisks, 5, tag); + + if (API.instance().getOneSixMigrationHelper().migrateDiskInventory(world, inputDisks)) { + markDirty(); + } + + if (API.instance().getOneSixMigrationHelper().migrateDiskInventory(world, outputDisks)) { + markDirty(); + } } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OneSixMigrationHelper.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OneSixMigrationHelper.java new file mode 100644 index 000000000..90e10cdc0 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OneSixMigrationHelper.java @@ -0,0 +1,115 @@ +package com.raoulvdberge.refinedstorage.apiimpl.util; + +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider; +import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper; +import com.raoulvdberge.refinedstorage.apiimpl.API; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.items.IItemHandlerModifiable; + +import java.util.UUID; + +public class OneSixMigrationHelper implements IOneSixMigrationHelper { + // 1.5.x NBT keys + private static final String NBT_ITEMS = "Items"; + private static final String NBT_ITEM_TYPE = "Type"; + private static final String NBT_ITEM_QUANTITY = "Quantity"; + private static final String NBT_ITEM_DAMAGE = "Damage"; + private static final String NBT_ITEM_NBT = "NBT"; + private static final String NBT_ITEM_CAPS = "Caps"; + + private static final String NBT_FLUIDS = "Fluids"; + + @Override + public boolean migrateDisk(World world, ItemStack disk) { + IStorageDiskProvider provider = (IStorageDiskProvider) disk.getItem(); + + switch (provider.getType()) { + case ITEM: + if (disk.hasTagCompound() && disk.getTagCompound().hasKey(NBT_ITEMS)) { + UUID id = UUID.randomUUID(); + + IStorageDisk newDisk = API.instance().createDefaultItemDisk(world, provider.getCapacity(disk)); + + NBTTagList list = (NBTTagList) disk.getTagCompound().getTag(NBT_ITEMS); + + for (int i = 0; i < list.tagCount(); ++i) { + NBTTagCompound tag = list.getCompoundTagAt(i); + + ItemStack stack = new ItemStack( + Item.getItemById(tag.getInteger(NBT_ITEM_TYPE)), + tag.getInteger(NBT_ITEM_QUANTITY), + tag.getInteger(NBT_ITEM_DAMAGE), + tag.hasKey(NBT_ITEM_CAPS) ? tag.getCompoundTag(NBT_ITEM_CAPS) : null + ); + + stack.setTagCompound(tag.hasKey(NBT_ITEM_NBT) ? tag.getCompoundTag(NBT_ITEM_NBT) : null); + + if (!stack.isEmpty()) { + newDisk.insert(stack, stack.getCount(), false); + } + } + + API.instance().getStorageDiskManager(world).set(id, newDisk); + API.instance().getStorageDiskManager(world).markForSaving(); + + provider.setId(disk, id); + + return true; + } + + break; + case FLUID: + if (disk.hasTagCompound() && disk.getTagCompound().hasKey(NBT_FLUIDS)) { + UUID id = UUID.randomUUID(); + + IStorageDisk newDisk = API.instance().createDefaultFluidDisk(world, provider.getCapacity(disk)); + + NBTTagList list = (NBTTagList) disk.getTagCompound().getTag(NBT_FLUIDS); + + for (int i = 0; i < list.tagCount(); ++i) { + FluidStack stack = FluidStack.loadFluidStackFromNBT(list.getCompoundTagAt(i)); + + if (stack != null) { + newDisk.insert(stack, stack.amount, false); + } + } + + API.instance().getStorageDiskManager(world).set(id, newDisk); + API.instance().getStorageDiskManager(world).markForSaving(); + + provider.setId(disk, id); + + return true; + } + + break; + } + + return false; + } + + @Override + public boolean migrateDiskInventory(World world, IItemHandlerModifiable handler) { + boolean migrated = false; + + for (int i = 0; i < handler.getSlots(); ++i) { + ItemStack disk = handler.getStackInSlot(i); + + if (!disk.isEmpty() && disk.getItem() instanceof IStorageDiskProvider) { + if (migrateDisk(world, disk)) { + handler.setStackInSlot(i, disk); // Trigger a onContentsChanged + + migrated = true; + } + } + } + + return migrated; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemFluidStorageDisk.java b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemFluidStorageDisk.java index 9670cf868..25bb308fe 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemFluidStorageDisk.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemFluidStorageDisk.java @@ -57,14 +57,19 @@ public class ItemFluidStorageDisk extends ItemBase implements IStorageDiskProvid public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected) { super.onUpdate(stack, world, entity, slot, selected); - if (!world.isRemote && !stack.hasTagCompound()) { - UUID id = UUID.randomUUID(); + if (!world.isRemote) { + if (!isValid(stack)) { + API.instance().getOneSixMigrationHelper().migrateDisk(world, stack); + } - stack.setTagCompound(new NBTTagCompound()); - stack.getTagCompound().setUniqueId(NBT_ID, id); + if (!stack.hasTagCompound()) { + UUID id = UUID.randomUUID(); - API.instance().getStorageDiskManager(world).set(id, API.instance().createDefaultFluidDisk(world, FluidStorageType.getById(stack.getItemDamage()).getCapacity())); - API.instance().getStorageDiskManager(world).markForSaving(); + API.instance().getStorageDiskManager(world).set(id, API.instance().createDefaultFluidDisk(world, getCapacity(stack))); + API.instance().getStorageDiskManager(world).markForSaving(); + + setId(stack, id); + } } } @@ -126,11 +131,22 @@ public class ItemFluidStorageDisk extends ItemBase implements IStorageDiskProvid return disk.getTagCompound().getUniqueId(NBT_ID); } + @Override + public void setId(ItemStack disk, UUID id) { + disk.setTagCompound(new NBTTagCompound()); + disk.getTagCompound().setUniqueId(NBT_ID, id); + } + @Override public boolean isValid(ItemStack disk) { return disk.hasTagCompound() && disk.getTagCompound().hasUniqueId(NBT_ID); } + @Override + public int getCapacity(ItemStack disk) { + return FluidStorageType.getById(disk.getItemDamage()).getCapacity(); + } + @Override public StorageDiskType getType() { return StorageDiskType.FLUID; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemStorageDisk.java b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemStorageDisk.java index 148ae3b6a..09d688b3d 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemStorageDisk.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemStorageDisk.java @@ -57,14 +57,19 @@ public class ItemStorageDisk extends ItemBase implements IStorageDiskProvider { public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected) { super.onUpdate(stack, world, entity, slot, selected); - if (!world.isRemote && !stack.hasTagCompound()) { - UUID id = UUID.randomUUID(); + if (!world.isRemote) { + if (!isValid(stack)) { + API.instance().getOneSixMigrationHelper().migrateDisk(world, stack); + } - stack.setTagCompound(new NBTTagCompound()); - stack.getTagCompound().setUniqueId(NBT_ID, id); + if (!stack.hasTagCompound()) { + UUID id = UUID.randomUUID(); - API.instance().getStorageDiskManager(world).set(id, API.instance().createDefaultItemDisk(world, ItemStorageType.getById(stack.getItemDamage()).getCapacity())); - API.instance().getStorageDiskManager(world).markForSaving(); + API.instance().getStorageDiskManager(world).set(id, API.instance().createDefaultItemDisk(world, getCapacity(stack))); + API.instance().getStorageDiskManager(world).markForSaving(); + + setId(stack, id); + } } } @@ -126,11 +131,22 @@ public class ItemStorageDisk extends ItemBase implements IStorageDiskProvider { return disk.getTagCompound().getUniqueId(NBT_ID); } + @Override + public void setId(ItemStack disk, UUID id) { + disk.setTagCompound(new NBTTagCompound()); + disk.getTagCompound().setUniqueId(NBT_ID, id); + } + @Override public boolean isValid(ItemStack disk) { return disk.hasTagCompound() && disk.getTagCompound().hasUniqueId(NBT_ID); } + @Override + public int getCapacity(ItemStack disk) { + return ItemStorageType.getById(disk.getItemDamage()).getCapacity(); + } + @Override public StorageDiskType getType() { return StorageDiskType.ITEM; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/DirectionHandlerTile.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/DirectionHandlerTile.java index cea604933..1d23c6818 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/DirectionHandlerTile.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/DirectionHandlerTile.java @@ -6,7 +6,7 @@ import net.minecraft.util.EnumFacing; public class DirectionHandlerTile implements IDirectionHandler { public static final String NBT_DIRECTION = "Direction"; - private EnumFacing direction; + private EnumFacing direction = EnumFacing.NORTH; @Override public void setDirection(EnumFacing direction) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java index 9cd728499..d63cf99a6 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java @@ -134,6 +134,11 @@ public class PortableGrid implements IGrid, IPortableGrid, IStorageDiskContainer if (player != null) { StackUtils.readItems(disk, 4, stack.getTagCompound()); + + if (!player.getEntityWorld().isRemote) { + API.instance().getOneSixMigrationHelper().migrateDiskInventory(player.getEntityWorld(), disk); + } + StackUtils.readItems(filter, 0, stack.getTagCompound()); drainEnergy(RS.INSTANCE.config.portableGridOpenUsage);