diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 73ea97eba..25076b54c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -16,6 +16,7 @@ import ru.dbotthepony.mc.otm.capability.AndroidCapability; import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.drive.DrivePool; +import ru.dbotthepony.mc.otm.capability.drive.MatteryDrive; import ru.dbotthepony.mc.otm.client.AndroidGui; import ru.dbotthepony.mc.otm.client.EventHandler; import ru.dbotthepony.mc.otm.item.ItemPortableCondensationDrive; @@ -23,6 +24,7 @@ import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.network.MatteryNetworking; +import java.util.UUID; import java.util.stream.Collectors; // The value here should match an entry in the META-INF/mods.toml file @@ -77,6 +79,8 @@ public class OverdriveThatMatters { }; } + private static MatteryDrive drive; + private void setup(final FMLCommonSetupEvent event) { // some preinit code MatteryCapability.register(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/DrivePool.java b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/DrivePool.java index 042234838..75856edb0 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/DrivePool.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/DrivePool.java @@ -7,6 +7,7 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; import net.minecraft.server.MinecraftServer; import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fmlserverevents.FMLServerStartedEvent; import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent; @@ -48,8 +49,6 @@ public class DrivePool { public final UUID id; public final IMatteryDrive drive; public long last_access = System.currentTimeMillis(); - public long soft_sync_on = last_access + 8_000; // soft sync in 4 seconds - public long hard_sync_on = last_access + 30_000; // hard sync in 4 seconds Entry(UUID id, IMatteryDrive drive) { this.id = id; @@ -57,31 +56,19 @@ public class DrivePool { } @Nullable - public CompoundTag sync(boolean force) { + public CompoundTag sync() { if (!drive.isDirty()) { - soft_sync_on = System.currentTimeMillis() + 8_000; - hard_sync_on = System.currentTimeMillis() + 30_000; - next_save = Math.min(next_save, soft_sync_on); return null; } - if (force || hard_sync_on <= System.currentTimeMillis() || soft_sync_on <= System.currentTimeMillis()) { - var tag = drive.serializeNBT(); - drive.markClean(); - soft_sync_on = System.currentTimeMillis() + 8_000; - hard_sync_on = System.currentTimeMillis() + 30_000; - next_save = Math.min(next_save, soft_sync_on); - last_access = System.currentTimeMillis(); - return tag; - } - - return null; + var tag = drive.serializeNBT(); + drive.markClean(); + last_access = System.currentTimeMillis(); + return tag; } public IMatteryDrive access() { last_access = System.currentTimeMillis(); - soft_sync_on = last_access + 8_000; - next_save = Math.min(hard_sync_on, Math.min(next_save, soft_sync_on)); return drive; } } @@ -92,8 +79,6 @@ public class DrivePool { private static ReportedException exception; public static final String DATA_PATH = "data/otm_drives"; - private static long next_save = Long.MAX_VALUE; - public static T get(UUID id, Function factory_stored, Supplier factory_empty) { var get = pool.get(id); @@ -159,16 +144,13 @@ public class DrivePool { if (exception != null) { throw exception; } - - //if (next_save < System.currentTimeMillis()) { - writeBacklog(true); - //} } } @SubscribeEvent public static void serverStartEvent(FMLServerStartedEvent event) { if (thread != null && thread.isAlive()) { + LOGGER.error("FMLServerStartedEvent fired twice."); LOGGER.error("Attempting to start another DrivePool I/O thread when already running one!"); return; } @@ -179,7 +161,7 @@ public class DrivePool { base_directory = new File(server.storageSource.getWorldDir().toFile(), DATA_PATH); base_directory.mkdirs(); - thread = new Thread(null, () -> DrivePool.thread(server), "Overdrive That Matters DrivePool I/O"); + thread = new Thread(null, () -> DrivePool.thread(server), "Overdrive That Matters DrivePool IO"); thread.start(); } @@ -190,21 +172,28 @@ public class DrivePool { LockSupport.unpark(thread); } - writeBacklog(true); - sync(); + if (exception == null) { + writeBacklog(); + sync(); + } pool.clear(); } - public static void writeBacklog(boolean force) { + @SubscribeEvent + public static void onWorldSave(WorldEvent.Save event) { + writeBacklog(); + } + + public static void writeBacklog() { var sync_required = false; ArrayList remove_keys = null; for (var entry : pool.entrySet()) { - var tag = entry.getValue().sync(force); + var tag = entry.getValue().sync(); if (tag != null) { - LOGGER.info("Syncing {}", entry.getKey()); + LOGGER.info("Serializing OTM Drive {}", entry.getKey()); var index = backlog.indexOf(entry.getKey()); @@ -233,10 +222,6 @@ public class DrivePool { if (sync_required) { LockSupport.unpark(thread); } - - if (pool.size() == 0) { - next_save = Long.MAX_VALUE; - } } public static void sync() { @@ -245,8 +230,23 @@ public class DrivePool { for (var entry : copy) { try { - var file = new File(base_directory, entry.file.toString() + ".dat"); - LOGGER.info("Writing {}", entry.file); + LOGGER.info("Syncing OTM Drive {}", entry.file); + var old_file = new File(base_directory, entry.file + ".dat_old"); + + if (old_file.exists()) { + if (!old_file.delete()) { + throw new IllegalStateException("Unable to delete old dat file"); + } + } + + var file = new File(base_directory, entry.file + ".dat"); + + if (file.exists()) { + if (!file.renameTo(old_file)) { + throw new IllegalStateException("Unable to move old dat file"); + } + } + NbtIo.writeCompressed(entry.tag, file); } catch(Throwable error) { var report = new CrashReport("Syncing OTM Drives state to disk", error); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java index a0a77822c..2c1dd20b3 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java @@ -42,7 +42,12 @@ public interface IMatteryDrive { ItemStack insertItem(@Nonnull ItemStack item, boolean simulate); @Nonnull - ItemStack extractItem(@Nonnull UUID id, int amount, boolean simulate); + default ItemStack extractItem(@Nonnull UUID id, int amount, boolean simulate) { + return extractItem(id, amount, true, simulate); + } + + @Nonnull + ItemStack extractItem(@Nonnull UUID id, int amount, boolean obey_stack_size, boolean simulate); // not extending INBTSerializable to avoid serializing it as forgecaps CompoundTag serializeNBT(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/MatteryDrive.java b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/MatteryDrive.java index 1867e3e8b..ebb2f8d58 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/MatteryDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/MatteryDrive.java @@ -106,10 +106,12 @@ public class MatteryDrive implements IMatteryDrive { } var build_list = new ArrayList(amount); + var i = 0; for (var _stack : list) { if (ItemStack.tagMatches(_stack.stack(), stack)) { - build_list.add(_stack); + build_list.set(i, _stack); + i++; } } @@ -167,7 +169,7 @@ public class MatteryDrive implements IMatteryDrive { @Nonnull @Override - public ItemStack extractItem(@Nonnull UUID id, int amount, boolean simulate) { + public ItemStack extractItem(@Nonnull UUID id, int amount, boolean obey_stack_size, boolean simulate) { var get = items_uuid.get(id); if (get == null) @@ -175,6 +177,9 @@ public class MatteryDrive implements IMatteryDrive { var extract = Math.min(amount, get.stack().getCount()); + if (obey_stack_size) + extract = Math.min(extract, get.stack().getItem().getItemStackLimit(get.stack())); + if (extract <= 0) return ItemStack.EMPTY; diff --git a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java index 1ace58cfe..149386306 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java @@ -1,15 +1,22 @@ package ru.dbotthepony.mc.otm.item; +import net.minecraft.ChatFormatting; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.stats.Stats; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.event.entity.player.EntityItemPickupEvent; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.SubscribeEvent; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.MatteryCapability; @@ -19,6 +26,7 @@ import ru.dbotthepony.mc.otm.capability.drive.MatteryDrive; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; import java.util.UUID; public class ItemPortableCondensationDrive extends Item { @@ -28,21 +36,48 @@ public class ItemPortableCondensationDrive extends Item { @SubscribeEvent public static void onPickupEvent(EntityItemPickupEvent event) { + if ( + event.getItem().getOwner() != null && + !event.getItem().getOwner().equals(event.getPlayer().getUUID()) && + event.getItem().getAge() < 200 + ) { + return; + } + + var amount = event.getItem().getItem().getCount(); + var item = event.getItem().getItem().getItem(); + for (var stack : event.getPlayer().getInventory().items) { if (stack.getItem() instanceof ItemPortableCondensationDrive) { var cap = stack.getCapability(MatteryCapability.DRIVE).resolve().get(); + var copy = event.getItem().getItem().copy(); var remaining = cap.insertItem(event.getItem().getItem(), false); if (remaining.getCount() == event.getItem().getItem().getCount()) { continue; } + copy.setCount(copy.getCount() - remaining.getCount()); + event.setCanceled(true); + net.minecraftforge.fmllegacy.hooks.BasicEventHooks.firePlayerItemPickupEvent(event.getPlayer(), event.getItem(), copy); + if (remaining.getCount() > 0) { event.getItem().getItem().setCount(remaining.getCount()); + event.getPlayer().take(event.getItem(), amount - remaining.getCount()); + + event.getPlayer().awardStat(Stats.ITEM_PICKED_UP.get(item), amount - remaining.getCount()); + event.getPlayer().onItemPickup(event.getItem()); + + amount = remaining.getCount(); } else { + event.getPlayer().take(event.getItem(), amount); + + event.getPlayer().awardStat(Stats.ITEM_PICKED_UP.get(item), amount); + event.getPlayer().onItemPickup(event.getItem()); + event.getItem().discard(); return; } @@ -87,6 +122,19 @@ public class ItemPortableCondensationDrive extends Item { } } + @Override + public void appendHoverText(ItemStack stack, @Nullable Level p_41422_, List p_41423_, TooltipFlag p_41424_) { + super.appendHoverText(stack, p_41422_, p_41423_, p_41424_); + + if (stack.getTag() != null) { + var uuid = stack.getTag().getLongArray("uuid"); + + if (uuid.length == 2) { + p_41423_.add(new TextComponent(new UUID(uuid[0], uuid[1]).toString()).withStyle(ChatFormatting.GRAY)); + } + } + } + @Nullable @Override public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) { diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index 9f1f2e3ab..3fc19bac8 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -129,7 +129,9 @@ "item.overdrive_that_matters.pill_android": "Android pill", "item.overdrive_that_matters.pill_humane": "Humane pill", - + + "item.overdrive_that_matters.portable_condensation_drive": "Portable condensation drive", + "item.overdrive_that_matters.nutrient_paste": "Nutrient paste", "item.overdrive_that_matters.battery_crude": "Crude Battery",