From 75f26f4ed9011e9dd12f5b49b26b94f8f4dacac1 Mon Sep 17 00:00:00 2001 From: Keuin Date: Fri, 15 Jan 2021 00:42:54 +0800 Subject: Version 1.4.0: supports reintroducing llama item duplication. Add configuration file. --- gradle.properties | 10 +- .../keuin/ohmyvanillamc/OhMyVanillaMinecraft.java | 60 +++++++++++- .../com/keuin/ohmyvanillamc/OmvmConfiguration.java | 58 ++++++++++++ .../ohmyvanillamc/mixin/DisableFishSchooling.java | 6 +- .../mixin/DisablePhantomSpawning.java | 2 +- .../mixin/DisableWanderingTraderSpawning.java | 11 ++- .../mixin/ReintroduceLlamaItemDuping.java | 102 +++++++++++++++++++++ src/main/resources/fabric.mod.json | 2 +- src/main/resources/ohmyvanillamc.mixins.json | 3 +- 9 files changed, 237 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java create mode 100644 src/main/java/com/keuin/ohmyvanillamc/mixin/ReintroduceLlamaItemDuping.java diff --git a/gradle.properties b/gradle.properties index 414f89e..7242478 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,13 +2,13 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use -minecraft_version=1.15.2 -yarn_mappings=1.15.2+build.17 -loader_version=0.10.8 +minecraft_version=1.16.4 +yarn_mappings=1.16.4+build.9 +loader_version=0.11.0 # Mod Properties -mod_version=1.3.1 +mod_version=1.4.0 maven_group=com.keuin.omvm archives_base_name=oh-my-vanilla-mc # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api -fabric_version=0.23.1+1.15 +fabric_version=0.29.3+1.16 \ No newline at end of file diff --git a/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java b/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java index a3d5c90..f76321a 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java +++ b/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java @@ -1,15 +1,31 @@ package com.keuin.ohmyvanillamc; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonIOException; import net.fabricmc.api.ModInitializer; import net.minecraft.server.network.EntityTrackerEntry; +import java.io.*; import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.logging.Logger; public class OhMyVanillaMinecraft implements ModInitializer { - public static boolean disableFishSchooling = true; - public static boolean disablePhantomSpawning = false; - public static boolean disableWanderingTraderSpawning = false; + private static final Logger LOGGER = Logger.getLogger("OhMyVanillaMinecraft"); + + private static OmvmConfiguration configuration = null; + private static final OmvmConfiguration defaultConfiguration = new OmvmConfiguration( + false, + false, + false, + false + ); + + public static OmvmConfiguration getConfiguration() { + return configuration != null ? configuration : defaultConfiguration; + } private static void disableEntityTrackerEntrySpamming() { try { @@ -35,7 +51,43 @@ public class OhMyVanillaMinecraft implements ModInitializer { // However, some things (like resources) may still be uninitialized. // Proceed with mild caution. - System.out.println("OhMyVanillaMinecraft is loading..."); + LOGGER.info("Loading configuration..."); + + // load configuration + + final String fileName = "omvm.json"; + final File file = new File(fileName); + if (!file.exists()) { + LOGGER.info("Configuration file does not exist! Use default configuration."); + try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { + final String jsonString = (new GsonBuilder().setPrettyPrinting().create()).toJson(defaultConfiguration); + try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream)) { + outputStreamWriter.write(jsonString); + } + } catch (FileNotFoundException e) { + LOGGER.severe("Cannot write default configuration to file `" + fileName + "`: " + e); + } catch (IOException e) { + LOGGER.severe("Failed to write default configuration to file `" + fileName + "`: " + e); + } + } else { + try (FileInputStream fileInputStream = new FileInputStream(file)) { + try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8)) { + try (BufferedReader reader = new BufferedReader(inputStreamReader)) { + configuration = (new Gson()).fromJson(reader, OmvmConfiguration.class); + } + } + } catch (IOException e) { + LOGGER.severe("Failed to read config file `" + fileName + "`: " + e); + } catch (JsonIOException e) { + LOGGER.severe("Failed to decode config json file `" + fileName + "`: " + e); + } + } + + if (configuration == null) { + configuration = defaultConfiguration; + } + + LOGGER.info("Configuration: \n==========\n" + configuration + "\n=========="); } } diff --git a/src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java b/src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java new file mode 100644 index 0000000..4992f9b --- /dev/null +++ b/src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java @@ -0,0 +1,58 @@ +package com.keuin.ohmyvanillamc; + +import java.util.Objects; + +public class OmvmConfiguration { + + private final boolean disableFishSchooling; + private final boolean disablePhantomSpawning; + private final boolean disableWanderingTraderSpawning; + private final boolean reintroduceLlamaItemDuplicating; + + public OmvmConfiguration(boolean disableFishSchooling, boolean disablePhantomSpawning, boolean disableWanderingTraderSpawning, boolean reintroduceLlamaItemDuplicating) { + this.disableFishSchooling = disableFishSchooling; + this.disablePhantomSpawning = disablePhantomSpawning; + this.disableWanderingTraderSpawning = disableWanderingTraderSpawning; + this.reintroduceLlamaItemDuplicating = reintroduceLlamaItemDuplicating; + } + + public boolean isDisableFishSchooling() { + return disableFishSchooling; + } + + public boolean isDisablePhantomSpawning() { + return disablePhantomSpawning; + } + + public boolean isDisableWanderingTraderSpawning() { + return disableWanderingTraderSpawning; + } + + public boolean isReintroduceLlamaItemDuplicating() { + return reintroduceLlamaItemDuplicating; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OmvmConfiguration that = (OmvmConfiguration) o; + return disableFishSchooling == that.disableFishSchooling && + disablePhantomSpawning == that.disablePhantomSpawning && + disableWanderingTraderSpawning == that.disableWanderingTraderSpawning && + reintroduceLlamaItemDuplicating == that.reintroduceLlamaItemDuplicating; + } + + @Override + public int hashCode() { + return Objects.hash(disableFishSchooling, disablePhantomSpawning, disableWanderingTraderSpawning, reintroduceLlamaItemDuplicating); + } + + @Override + public String toString() { + return "Disable Fish Schooling: " + disableFishSchooling + "\n" + + "Disable Phantom Spawning: " + disablePhantomSpawning + "\n" + + "Disable Wandering Trader Spawning: " + disableWanderingTraderSpawning + "\n" + + "Reintroduce Llama Item Duplicating: " + reintroduceLlamaItemDuplicating; + } +} diff --git a/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableFishSchooling.java b/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableFishSchooling.java index c30ab02..c2de0d5 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableFishSchooling.java +++ b/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableFishSchooling.java @@ -2,6 +2,7 @@ package com.keuin.ohmyvanillamc.mixin; import com.keuin.ohmyvanillamc.OhMyVanillaMinecraft; import net.minecraft.entity.EntityType; +import net.minecraft.entity.ai.goal.FollowGroupLeaderGoal; import net.minecraft.entity.passive.FishEntity; import net.minecraft.entity.passive.SchoolingFishEntity; import net.minecraft.world.World; @@ -25,7 +26,7 @@ public abstract class DisableFishSchooling extends FishEntity { */ @Overwrite public void moveTowardLeader() { - if (!OhMyVanillaMinecraft.disableFishSchooling) { + if (!OhMyVanillaMinecraft.getConfiguration().isDisableFishSchooling()) { if (this.hasLeader()) { this.getNavigation().startMovingTo(this.leader, 1.0D); } @@ -39,5 +40,8 @@ public abstract class DisableFishSchooling extends FishEntity { @Overwrite public void initGoals() { super.initGoals(); + if (!OhMyVanillaMinecraft.getConfiguration().isDisableFishSchooling()) { + this.goalSelector.add(5, new FollowGroupLeaderGoal((SchoolingFishEntity) (Object) this)); + } } } diff --git a/src/main/java/com/keuin/ohmyvanillamc/mixin/DisablePhantomSpawning.java b/src/main/java/com/keuin/ohmyvanillamc/mixin/DisablePhantomSpawning.java index ea97857..d14fc3e 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/mixin/DisablePhantomSpawning.java +++ b/src/main/java/com/keuin/ohmyvanillamc/mixin/DisablePhantomSpawning.java @@ -16,7 +16,7 @@ public class DisablePhantomSpawning { */ @Inject(method = "spawn", at = @At("HEAD"), cancellable = true) public void spawn(ServerWorld serverWorld, boolean spawnMonsters, boolean spawnAnimals, CallbackInfoReturnable cir) { - if (OhMyVanillaMinecraft.disablePhantomSpawning) + if (OhMyVanillaMinecraft.getConfiguration().isDisablePhantomSpawning()) cir.setReturnValue(0); } } diff --git a/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableWanderingTraderSpawning.java b/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableWanderingTraderSpawning.java index 040c352..3af7941 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableWanderingTraderSpawning.java +++ b/src/main/java/com/keuin/ohmyvanillamc/mixin/DisableWanderingTraderSpawning.java @@ -5,17 +5,20 @@ import net.minecraft.world.WanderingTraderManager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(WanderingTraderManager.class) public class DisableWanderingTraderSpawning { /** * Disable ticking + * * @author trueKeuin */ - @Inject(method = "tick", at = @At("HEAD"), cancellable = true) - public void tick(CallbackInfo ci) { - if (OhMyVanillaMinecraft.disableWanderingTraderSpawning) + @Inject(method = "spawn", at = @At("HEAD"), cancellable = true) + public void tick(CallbackInfoReturnable ci) { + if (OhMyVanillaMinecraft.getConfiguration().isDisableWanderingTraderSpawning()) { + ci.setReturnValue(0); ci.cancel(); + } } } diff --git a/src/main/java/com/keuin/ohmyvanillamc/mixin/ReintroduceLlamaItemDuping.java b/src/main/java/com/keuin/ohmyvanillamc/mixin/ReintroduceLlamaItemDuping.java new file mode 100644 index 0000000..29ed03a --- /dev/null +++ b/src/main/java/com/keuin/ohmyvanillamc/mixin/ReintroduceLlamaItemDuping.java @@ -0,0 +1,102 @@ +package com.keuin.ohmyvanillamc.mixin; + +import com.keuin.ohmyvanillamc.OhMyVanillaMinecraft; +import net.minecraft.advancement.PlayerAdvancementTracker; +import net.minecraft.entity.Entity; +import net.minecraft.network.Packet; +import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.stat.ServerStatHandler; +import net.minecraft.stat.Stats; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Mixin(PlayerManager.class) +public abstract class ReintroduceLlamaItemDuping { + + @Shadow + protected abstract void savePlayerData(ServerPlayerEntity player); + + @Shadow + @Final + private static Logger LOGGER; + + @Shadow + @Final + private List players; + + @Shadow + @Final + private MinecraftServer server; + + @Shadow + @Final + private Map playerMap; + + @Shadow + @Final + private Map statisticsMap; + + @Shadow + @Final + private Map advancementTrackers; + + @Shadow + public abstract void sendToAll(Packet packet); + + /** + * @reason re-introduce llama item duplicating glitch. + * @author trueKeuin + */ + @Overwrite + public void remove(ServerPlayerEntity player) { + ServerWorld serverWorld = player.getServerWorld(); + player.incrementStat(Stats.LEAVE_GAME); + this.savePlayerData(player); + if (player.hasVehicle()) { + Entity entity = player.getRootVehicle(); + if (entity.hasPlayerRider()) { + LOGGER.debug("Removing player mount"); + player.stopRiding(); + serverWorld.removeEntity(entity); + // entity.removed = true + entity.removed = !OhMyVanillaMinecraft.getConfiguration().isReintroduceLlamaItemDuplicating() || entity.removed; + + Entity entity2; + for (Iterator var4 = entity.getPassengersDeep().iterator(); var4.hasNext(); // entity2.removed = true + entity2.removed = !OhMyVanillaMinecraft.getConfiguration().isReintroduceLlamaItemDuplicating() || entity2.removed) { + entity2 = (Entity) var4.next(); + serverWorld.removeEntity(entity2); + } + + serverWorld.getChunk(player.chunkX, player.chunkZ).markDirty(); + } + } + + player.detach(); + serverWorld.removePlayer(player); + player.getAdvancementTracker().clearCriteria(); + this.players.remove(player); + this.server.getBossBarManager().onPlayerDisconnect(player); + UUID uUID = player.getUuid(); + ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) this.playerMap.get(uUID); + if (serverPlayerEntity == player) { + this.playerMap.remove(uUID); + this.statisticsMap.remove(uUID); + this.advancementTrackers.remove(uUID); + } + + this.sendToAll(new PlayerListS2CPacket(PlayerListS2CPacket.Action.REMOVE_PLAYER, new ServerPlayerEntity[]{player})); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1ad45f2..134a44c 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -25,7 +25,7 @@ "depends": { "fabricloader": ">=0.7.4", "fabric": "*", - "minecraft": "1.15.x" + "minecraft": "1.16.x" }, "suggests": { "another-mod": "*" diff --git a/src/main/resources/ohmyvanillamc.mixins.json b/src/main/resources/ohmyvanillamc.mixins.json index 39f20a3..70db4c5 100644 --- a/src/main/resources/ohmyvanillamc.mixins.json +++ b/src/main/resources/ohmyvanillamc.mixins.json @@ -7,7 +7,8 @@ "DisableEntityTrackerEntrySpamming", "DisableFishSchooling", "DisablePhantomSpawning", - "DisableWanderingTraderSpawning" + "DisableWanderingTraderSpawning", + "ReintroduceLlamaItemDuping" ], "injectors": { "defaultRequire": 1 -- cgit v1.2.3