Luohuayu / CatServer

高性能和高兼容性的1.12.2/1.16.5/1.18.2版本Forge+Bukkit+Spigot服务端 (A high performance and high compatibility 1.12.2/1.16.5/1.18.2 version Forge+Bukkit+Spigot server)
https://catmc.org
GNU Lesser General Public License v3.0
1.95k stars 204 forks source link

[1.12.2] Mods that use Sponge Mixins interfere with CatServer patches #818

Open AngryCarrot789 opened 10 months ago

AngryCarrot789 commented 10 months ago

Environment

Minecraft version(1.12.2): Build version(Get from /version command): Mods/Plugins:

Describe the bug I'm building the CatServer jar from source (I run genPatches after modifying the actual game code) and then I run build, and finally run outputJar, and then I use that .jar file as my server's main jar (e.g. found in build/distributions/<jar>).

However, it seems like code patches don't seem to get applied, specially the player data patch: whenever a player joins, the CraftPlayer's readExtraData never gets called, meaning hasPlayedBefore is always false, meaning plugins like EssentialsX think a player is always joining for the first time.

I also further know this because in the saved .dat file for each player, there's no compound called bukkit which according to the code should always be created when a player's data is saved (I even tried leaving then re-joining, but that didn't help)

I also just downloaded the jar from the cat server website (which has a smaller file size if that matters), but that also did not work; no bukkit data is saved or loaded, hasPlayedBefore is always false

Expected behavior CraftPlayer.readExtraData() should get called by the EntityPlayerMP.readEntityFromNBT function, but that doesn't seem to happen.

To Reproduce Download The 1.12.2 Pack's server, then just run the cat server jar instead of the forge jar. The server loads normally and doesn't crash, but as mentioned above, player data loading does not work correctly

Screenshot/Video (If it doesn't exist you can ignore it)

AngryCarrot789 commented 10 months ago

I looked at the source code that the LaunchClassLoader saves to a file (when you provide the 3 flags to the server startup args) and it appears to be caused by a mod using sponge's mixin library. A mod is injecting what looks to be something that prevents the player's recipe book being read from NBT. I guess the patches don't assume multiple returns possible from the function, so it just finds the last return statement and adds the readExtraData before it instead of adding that call before all returns? Or maybe because the patches are run first, the mixin library just kinda breaks the patches outright

public void func_70037_a(NBTTagCompound compound) {
    super.func_70037_a(compound);
    if (compound.func_150297_b("playerGameType", 99))
        if (func_184102_h().func_104056_am()) {
            this.field_71134_c.func_73076_a(func_184102_h().func_71265_f());
        }
        else {
            this.field_71134_c.func_73076_a(GameType.func_77146_a(compound.func_74762_e("playerGameType")));
        }
    if (compound.func_150297_b("enteredNetherPosition", 10)) {
        NBTTagCompound nbttagcompound = compound.func_74775_l("enteredNetherPosition");
        this.field_193110_cw = new Vec3d(nbttagcompound.func_74769_h("x"), nbttagcompound.func_74769_h("y"), nbttagcompound.func_74769_h("z"));
    }
    this.field_192040_cp = compound.func_74767_n("seenCredits");
    callbackInfo3 = new CallbackInfo("func_70037_a", true);
    handler$zfe000$UniversalTweaks_1_12_2_1_9_0_358$utRecipeBookReadEntityFromNBT(compound, callbackInfo3);
    if (callbackInfo3.isCancelled())
        return;
    if (compound.func_150297_b("recipeBook", 10))
        this.field_192041_cq.func_192825_a(compound.func_74775_l("recipeBook"));
    getBukkitEntity().readExtraData(compound);
}