Darkhax-Minecraft / Game-Stages

An API for universal player based progression.
https://minecraft.curseforge.com/projects/game-stages
GNU Lesser General Public License v2.1
63 stars 17 forks source link

Gamestages clearing saved stages when Soulus is present #44

Closed jelaw21 closed 4 years ago

jelaw21 commented 4 years ago

Gamestages version: 2.0.115 Minecraft: 1.12.2 Forge: 14.23.5.2847 Modpack: Skyblock Billionaire

I've contacted the Soulus Dev about the issue as well. It seems that when Game Stages and Soulus are installed, it clears Game Stages data when a player disconnects.

This only occurs on a SERVER. It works fine in single player.

[23:18:57] [Server thread/INFO] [gamestages]: Saved 1 stages for The_Law_21.
[23:18:57] [Server thread/INFO] [gamestages]: Saved 2 stages for Spinkxy.
[23:18:57] [Server thread/INFO] [gamestages]: Saved 1 stages for LadyConfido.
[23:19:02] [Server thread/INFO] [net.minecraft.server.dedicated.DedicatedServer]: [EMPLOYEE]<The_Law_21>: ok, for reals, going to bed.
[23:19:05] [Server thread/INFO] [net.minecraft.network.NetHandlerPlayServer]: The_Law_21 lost connection: Disconnected
[23:19:05] [Server thread/INFO] [net.minecraft.server.dedicated.DedicatedServer]: The_Law_21 left the game
[23:19:05] [Server thread/INFO] [soulus]: Reloaded client-side configs.
[23:19:05] [Server thread/INFO] [soulus]: Reloaded configs.
[23:19:05] [Server thread/INFO] [soulus]: Synced configs to clients.
[23:19:05] [Server thread/INFO] [gamestages]: Saved 0 stages for The_Law_21.

You can see from the logs that stages are saved prior, (saved 1 stages for The_Law_21) but when I disconnect, it shows 0 stages saved, after running the soulus configs. Here is a synopsis from the Soulus dev on Discord:

"i don't think it has anything to do with soulus. i've removed everything from soulus that deals with gamestages and I can still repro."

Darkhax commented 4 years ago

This issue likely has nothing to do with vanilla game stages. It can not be reproduced using the latest version of the mod on the latest version of forge for 1.12.2. It may not be Solus causing this issue, but it is certainly something introduced by Solus or another mod in the pack.

[18:29:28] [Server thread/INFO] [minecraft/DedicatedServer]: Player577 joined the game
[18:29:29] [Server thread/INFO] [gamestages]: Syncing 0 stages for Player577.
[18:29:51] [Server thread/INFO] [minecraft/DedicatedServer]: Opped Player577
[18:30:02] [Server thread/INFO] [gamestages]: Syncing 1 stages for Player577.
[18:30:10] [Server thread/INFO] [gamestages]: Saved 1 stages for Player577.
[18:30:20] [Server thread/INFO] [minecraft/NetHandlerPlayServer]: Player577 lost connection: Disconnected
[18:30:20] [Server thread/INFO] [minecraft/DedicatedServer]: Player577 left the game
[18:30:26] [Netty Server IO #4/INFO] [FML]: Client protocol version 2
[18:30:26] [Netty Server IO #4/INFO] [FML]: Client attempting to join with 8 mods : minecraft@1.12.2,crafttweaker@4.1.9,ctgui@1.0.0,FML@8.0.99.99,bookshelf@2.3.585,forge@14.23.5.2847,gamestages@@VERSION@,mcp@9.42
[18:30:26] [Server thread/INFO] [FML]: [Server thread] Server side modded connection established
[18:30:26] [Server thread/INFO] [gamestages]: Loaded 1 stages for Player577.
[18:30:26] [Server thread/INFO] [minecraft/PlayerList]: Player577[/127.0.0.1:53934] logged in with entity id 522 at (-59.77838405956393, 67.0, -238.92575282116545)
[18:30:26] [Server thread/INFO] [minecraft/DedicatedServer]: Player577 joined the game
[18:30:26] [Server thread/INFO] [gamestages]: Syncing 1 stages for Player577.

Edit: Versions used Forge: 14.23.5.2847 Bookshelf: 2.3.585 Game Stages: 2.0.117

ChiriVulpes commented 4 years ago

From investigation and testing by myself and Jelaw we've found this was caused by two different things:

  1. Stages don't save directly after receiving them, instead only every 45 seconds, meaning you can get a stage and immediately DC and your stage will not be saved. (Or at least, that's what was happening in my testing environment. That's why I thought I was reproing still but was actually reproing something else.)
  2. When a mod tries to get the stages of a player that is currently disconnecting, Game Stages resets them. (It's funny, this is what I guessed the bug was initially, but then in my testing since I could still "repro" after removing all Game Stages stuff, I thought my idea was wrong)

I've committed a change on Soulus's end that stores which player is disconnecting and skips checking their stages, it seems to fix the problem. Up to you whether you want to take further action on this, I guess.

LTCatt commented 4 years ago

When a mod tries to get the stages of a player that is currently disconnecting, Game Stages resets them.

That actually happened in my server. When a player disconnected, all of his stages may lost...

Darkhax commented 4 years ago

@Yuudaari GameStages does not save on a scheduled timer. It uses the player load and player save events which Forge is responsible for. As of 1.15.2 I return null if you try to get info for a disconnected player.

LTCatt commented 4 years ago

@Yuudaari GameStages does not save on a scheduled timer. It uses the player load and player save events which Forge is responsible for. As of 1.15.2 I return null if you try to get info for a disconnected player.

But actually, when player is offline, it may clear all stages of him. That ALWAYS happen that I have to save stages with scoreboard tags...

Darkhax commented 4 years ago

@LTCatt Getting the stages of an offline player is not a supported feature. Trying to do so in newer versions will not give you access to any data and avoids the save handling logic entirely.

LTCatt commented 4 years ago

@LTCatt Getting the stages of an offline player is not a supported feature. Trying to do so in newer versions will not give you access to any data and avoids the save handling logic entirely.

Well, maybe this is an issue with the old version. Now using 1.12.2-2.0.115.

If someone is still using the old 1.12.2 version and has the same problem, here is my solution: While adding a stage for player, also adding a scoreboard tag like this:

/gamestage silentadd @s teststage
/scoreboard players tag @s add teststage

And use this CraftTweaker2 .zs script to restore stages:

import crafttweaker.events.IEventManager;
import crafttweaker.player.IPlayer;
import crafttweaker.server.IServer;
import crafttweaker.world.IWorld;
events.onPlayerTick(function(event as crafttweaker.event.PlayerTickEvent){
    var player = event.player;
    if (!player.world.isRemote()) {
        if (!player.hasGameStage("mark")) {
            player.addGameStage("mark");
            for tag in player.tags {
                player.addGameStage(tag);
            }
        }
    }
});
events.onPlayerLoggedIn(function(event as crafttweaker.event.PlayerLoggedInEvent){
    var player = event.player;
    if (!player.world.isRemote()) {
        player.addGameStage("mark");
        for tag in player.tags {
            player.addGameStage(tag);
        }
    }
});