From c15e8307dc14d7ea6915e0092314ea25444b227f Mon Sep 17 00:00:00 2001 From: samo_lego <34912839+samolego@users.noreply.github.com> Date: Sun, 25 Oct 2020 22:37:42 +0100 Subject: [PATCH] Auto-migrate player data (#23) --- gradle.properties | 2 +- .../org/samo_lego/simpleauth/SimpleAuth.java | 6 +- .../mixin/MixinServerLoginNetworkHandler.java | 2 + .../mixin/MixinWorldSaveHandler.java | 88 +++++++++++++++++++ src/main/resources/mixins.simpleauth.json | 3 +- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/samo_lego/simpleauth/mixin/MixinWorldSaveHandler.java diff --git a/gradle.properties b/gradle.properties index bef0df10..cb1b5621 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ loader_version=0.10.1+build.209 fabric_version=0.24.0+build.411-1.16 # Mod Properties -mod_version = 1.6.2 +mod_version = 1.6.3 maven_group = org.samo_lego archives_base_name = simpleauth diff --git a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java index aba3eb20..734185e6 100644 --- a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java +++ b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java @@ -50,15 +50,15 @@ public class SimpleAuth implements DedicatedServerModInitializer { */ public static HashSet mojangAccountNamesCache = new HashSet<>(); - public static HashSet accountStatusCache = new HashSet<>(); - // Getting game directory public static final Path gameDirectory = FabricLoader.getInstance().getGameDir(); // Server properties public static Properties serverProp = new Properties(); - // Mod config + /** + * Config of the SimpleAuth mod. + */ public static AuthConfig config; @Override diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerLoginNetworkHandler.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerLoginNetworkHandler.java index 0d183c2d..7e33ad7f 100644 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerLoginNetworkHandler.java +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerLoginNetworkHandler.java @@ -7,6 +7,7 @@ import net.minecraft.text.TranslatableText; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -30,6 +31,7 @@ public class MixinServerLoginNetworkHandler { /** * Fake state of current player. */ + @Unique private boolean acceptCrackedPlayer = false; /** diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinWorldSaveHandler.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinWorldSaveHandler.java new file mode 100644 index 00000000..ff5a83cc --- /dev/null +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinWorldSaveHandler.java @@ -0,0 +1,88 @@ +package org.samo_lego.simpleauth.mixin; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.world.WorldSaveHandler; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import static org.samo_lego.simpleauth.SimpleAuth.config; +import static org.samo_lego.simpleauth.SimpleAuth.mojangAccountNamesCache; + +@Mixin(WorldSaveHandler.class) +public class MixinWorldSaveHandler { + + @Final + @Shadow + private File playerDataDir; + + @Unique + private boolean fileExists; + + @Final + @Shadow + private static Logger LOGGER; + + /** + * Saves whether player save file exists. + * + * @param playerEntity + * @param cir + * @param compoundTag + * @param file + */ + @Inject( + method = "loadPlayerData(Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/nbt/CompoundTag;", + at = @At( + value = "INVOKE", + target = "Ljava/io/File;exists()Z" + ), + locals = LocalCapture.CAPTURE_FAILHARD + ) + private void fileExists(PlayerEntity playerEntity, CallbackInfoReturnable cir, CompoundTag compoundTag, File file) { + // @ModifyVariable cannot capture locals + this.fileExists = file.exists(); + } + + /** + * Loads offline-uuid player data to compoundTag in order to migrate from offline to online. + * + * @param compoundTag null compound tag. + * @param player player who might need migration of datd. + * @return compoundTag containing migrated data. + */ + @ModifyVariable( + method = "loadPlayerData(Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/nbt/CompoundTag;", + at = @At( + value = "INVOKE", + target = "Ljava/io/File;exists()Z" + ) + ) + private CompoundTag migratePlayerData(CompoundTag compoundTag, PlayerEntity player) { + // Checking for offline player data only if online doesn't exist yet + if(config.experimental.premiumAutologin && mojangAccountNamesCache.contains(player.getGameProfile().getName()) && !this.fileExists) { + File file = new File(this.playerDataDir, PlayerEntity.getOfflinePlayerUuid(player.getGameProfile().getName()) + ".dat"); + if (file.exists() && file.isFile()) + try { + compoundTag = NbtIo.readCompressed(new FileInputStream(file)); + } + catch (IOException e) { + LOGGER.warn("Failed to load player data for {}", player.getGameProfile().getName()); + } + } + return compoundTag; + } +} diff --git a/src/main/resources/mixins.simpleauth.json b/src/main/resources/mixins.simpleauth.json index c069d4aa..0539766c 100644 --- a/src/main/resources/mixins.simpleauth.json +++ b/src/main/resources/mixins.simpleauth.json @@ -8,7 +8,8 @@ "MixinPlayerManager", "MixinServerLoginNetworkHandler", "MixinServerPlayNetworkHandler", - "MixinSlot" + "MixinSlot", + "MixinWorldSaveHandler" ], "injectors": { "defaultRequire": 1