xNul / palworld-host-save-fix

Fixes the bug which forces a player to create a new character when they already have a save. Useful for migrating maps from co-op to dedicated servers and from one dedicated server to another.
MIT License
887 stars 69 forks source link

Add change host method in Co-op game #50

Open Aues6uen11Z opened 7 months ago

Aues6uen11Z commented 7 months ago

Hi! I've added a feature to your codebase that enables changing the host in 4-player Co-op game.

Recently, I encountered a rather frustrating issue where, as the host, I invited friends to play in my world for a few days. However, sometimes when I'm unavailable to play but they are, they can't access our saved progress since it's all stored on my end. This led me to ponder the possibility of transferring host privileges to them. Fortunately, I stumbled upon your code that fixes save files, and noticed that running it twice could effectively facilitate a host transfer.

To make this process more convenient, I decided to integrate your code and wrote a new script called change_coop_host.py. One thing worth noting is that due to Python's module naming conventions which disallow hyphens ("-") in module names, I had to rename your file to fix_host_save.py.

guksg commented 7 months ago

if i use multi-byte characters in the player name, will this function properly ?

Zennara commented 7 months ago

How does this work? Its not entirely clear. Sure it will change the host, but how does it correctly assign the correct playerdata to the old host?

Edit: I understand how to fill it in (I think) but I am still getting tons of errors no matter what I do. If I validate the json by using \\ instead of \, it will show:

Traceback (most recent call last):
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 163, in <module>
    main()
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 156, in main
    old_host_guid = old_host(player_list, Path(save_path)/'Players')
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 14, in old_host
    return old_host.pop()
           ^^^^^^^^^^^^^^
KeyError: 'pop from an empty set'
Aues6uen11Z commented 7 months ago

if i use multi-byte characters in the player name, will this function properly ?

As long as the name doesn't conflict with another player's GUID, the script should operate correctly.

Aues6uen11Z commented 7 months ago

How does this work? Its not entirely clear. Sure it will change the host, but how does it correctly assign the correct playerdata to the old host?

Edit: I understand how to fill it in (I think) but I am still getting tons of errors no matter what I do. If I validate the json by using \\ instead of \, it will show:

Traceback (most recent call last):
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 163, in <module>
    main()
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 156, in main
    old_host_guid = old_host(player_list, Path(save_path)/'Players')
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 14, in old_host
    return old_host.pop()
           ^^^^^^^^^^^^^^
KeyError: 'pop from an empty set'

\\ should indeed be used in JSON. I originally wrote it this way in README, but for some reason it still appears as \. The issue with popping from an empty set likely stems from an incorrect configuration; could you provide the contents of your config file and the contents within the "Players" directory of your save?

Zennara commented 7 months ago

How does this work? Its not entirely clear. Sure it will change the host, but how does it correctly assign the correct playerdata to the old host? Edit: I understand how to fill it in (I think) but I am still getting tons of errors no matter what I do. If I validate the json by using \\ instead of \, it will show:

Traceback (most recent call last):
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 163, in <module>
    main()
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 156, in main
    old_host_guid = old_host(player_list, Path(save_path)/'Players')
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 14, in old_host
    return old_host.pop()
           ^^^^^^^^^^^^^^
KeyError: 'pop from an empty set'

\\ should indeed be used in JSON. I originally wrote it this way in README, but for some reason it still appears as \. The issue with popping from an empty set likely stems from an incorrect configuration; could you provide the contents of your config file and the contents within the "Players" directory of your save?

{
   "uesave_path":"C:\\Program Files\\uesave\\bin\\uesave.exe",
   "save_path":"C:\\Users\\Keagan\\AppData\\Local\\Pal\\Saved\\SaveGames\\76561198193660883\\0BF238BF42712D7F8A80D6A753989022",
   "player_list":[
      {
         "GUID":"84FEF77F000000000000000000000000",
         "name":"Spoofle"
      },
      {
         "GUID":"4B20926D000000000000000000000000",
         "name":"Shadowsilver262"
      },
      {
         "GUID":"2945FBA8000000000000000000000000",
         "name":"Zennara"
      },
      {
         "GUID":"A47597CC000000000000000000000000",
         "name":"Arch-Duke"
      },
      {
         "GUID":"",
         "name":""
      },
      {
         "GUID":"",
         "name":""
      }
   ]
}

My save file players folder: image Currently when I run the server, I am playing as the old hosts save. I had the old host join in order to get his GUID of A47597CC000000000000000000000000. My old GUID is 2945FBA8000000000000000000000000

Aues6uen11Z commented 7 months ago

The principle behind changing the host is quite straightforward: since the GUID of the original host is anomalously set to '00...01', all that's required is to assign a standard GUID to the former host and then set the new host's GUID to this '00...01' value. This can be accomplished by simply running the fix_host_save.py script twice.

Aues6uen11Z commented 7 months ago

How does this work? Its not entirely clear. Sure it will change the host, but how does it correctly assign the correct playerdata to the old host? Edit: I understand how to fill it in (I think) but I am still getting tons of errors no matter what I do. If I validate the json by using \\ instead of \, it will show:

Traceback (most recent call last):
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 163, in <module>
    main()
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 156, in main
    old_host_guid = old_host(player_list, Path(save_path)/'Players')
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 14, in old_host
    return old_host.pop()
           ^^^^^^^^^^^^^^
KeyError: 'pop from an empty set'

\\ should indeed be used in JSON. I originally wrote it this way in README, but for some reason it still appears as \. The issue with popping from an empty set likely stems from an incorrect configuration; could you provide the contents of your config file and the contents within the "Players" directory of your save?

{
   "uesave_path":"C:\\Program Files\\uesave\\bin\\uesave.exe",
   "save_path":"C:\\Users\\Keagan\\AppData\\Local\\Pal\\Saved\\SaveGames\\76561198193660883\\0BF238BF42712D7F8A80D6A753989022",
   "player_list":[
      {
         "GUID":"84FEF77F000000000000000000000000",
         "name":"Spoofle"
      },
      {
         "GUID":"4B20926D000000000000000000000000",
         "name":"Shadowsilver262"
      },
      {
         "GUID":"2945FBA8000000000000000000000000",
         "name":"Zennara"
      },
      {
         "GUID":"A47597CC000000000000000000000000",
         "name":"Arch-Duke"
      },
      {
         "GUID":"",
         "name":""
      },
      {
         "GUID":"",
         "name":""
      }
   ]
}

My save file players folder: image Currently when I run the server, I am playing as the old hosts save. I had the old host join in order to get his GUID of A47597CC000000000000000000000000. My old GUID is 2945FBA8000000000000000000000000

Remove A47597CC000000000000000000000000.sav will work, the save files themselves do not require any manual adjustments; everything necessary can be handled through config.

Zennara commented 7 months ago

How does this work? Its not entirely clear. Sure it will change the host, but how does it correctly assign the correct playerdata to the old host? Edit: I understand how to fill it in (I think) but I am still getting tons of errors no matter what I do. If I validate the json by using \\ instead of \, it will show:

Traceback (most recent call last):
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 163, in <module>
    main()
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 156, in main
    old_host_guid = old_host(player_list, Path(save_path)/'Players')
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Keagan\Downloads\palworld-host-save-fix-feature-change-coop-host\palworld-host-save-fix-feature-change-coop-host\change_coop_host.py", line 14, in old_host
    return old_host.pop()
           ^^^^^^^^^^^^^^
KeyError: 'pop from an empty set'

\\ should indeed be used in JSON. I originally wrote it this way in README, but for some reason it still appears as \. The issue with popping from an empty set likely stems from an incorrect configuration; could you provide the contents of your config file and the contents within the "Players" directory of your save?

{
   "uesave_path":"C:\\Program Files\\uesave\\bin\\uesave.exe",
   "save_path":"C:\\Users\\Keagan\\AppData\\Local\\Pal\\Saved\\SaveGames\\76561198193660883\\0BF238BF42712D7F8A80D6A753989022",
   "player_list":[
      {
         "GUID":"84FEF77F000000000000000000000000",
         "name":"Spoofle"
      },
      {
         "GUID":"4B20926D000000000000000000000000",
         "name":"Shadowsilver262"
      },
      {
         "GUID":"2945FBA8000000000000000000000000",
         "name":"Zennara"
      },
      {
         "GUID":"A47597CC000000000000000000000000",
         "name":"Arch-Duke"
      },
      {
         "GUID":"",
         "name":""
      },
      {
         "GUID":"",
         "name":""
      }
   ]
}

My save file players folder: image Currently when I run the server, I am playing as the old hosts save. I had the old host join in order to get his GUID of A47597CC000000000000000000000000. My old GUID is 2945FBA8000000000000000000000000

Remove A47597CC000000000000000000000000.sav will work, the save files themselves do not require any manual adjustments; everything necessary can be handled through config.

That seemed to work, however, do you have any clue why our day would set to 40? We were on day 9 before.

Aues6uen11Z commented 7 months ago

The official releases patch v0.1.3.0 yesterday and it seems they fixed that bug where the game was showing fewer days than it should've. Could be the reason for what we're seeing.

Zennara commented 7 months ago

The official releases patch v0.1.3.0 yesterday and it seems they fixed that bug where the game was showing fewer days than it should've. Could be the reason for what we're seeing.

You are an absolute godsend. Thank you.

Aues6uen11Z commented 7 months ago

The official releases patch v0.1.3.0 yesterday and it seems they fixed that bug where the game was showing fewer days than it should've. Could be the reason for what we're seeing.

You are an absolute godsend. Thank you.

I'm glad I could be of help : )

ClaTron1x commented 7 months ago

I'm not familiar with python, and I'm having some trouble. Could someone clear this up for me?

I've imported change_coop_host.py to my scripts folder, configured the config.json file to contain the user GUIDs and the names, and then put the config file in a folder. What I don't understand is how to make it so the script can find the config folder and execute the commands. I just get a syntax error when I try to run the script:

python change_coop_host.py Cla_Tronix File "", line 1 python change_coop_host.py Cla_Tronix ^^^^^^^^^^^^^^^^ SyntaxError: invalid syntax

Aues6uen11Z commented 7 months ago

I'm not familiar with python, and I'm having some trouble. Could someone clear this up for me?

I've imported change_coop_host.py to my scripts folder, configured the config.json file to contain the user GUIDs and the names, and then put the config file in a folder. What I don't understand is how to make it so the script can find the config folder and execute the commands. I just get a syntax error when I try to run the script:

python change_coop_host.py Cla_Tronix File "", line 1 python change_coop_host.py Cla_Tronix ^^^^^^^^^^^^^^^^ SyntaxError: invalid syntax

Have you edited this script? It seems that you add this command to the code.

ClaTron1x commented 7 months ago

I'm not familiar with python, and I'm having some trouble. Could someone clear this up for me? I've imported change_coop_host.py to my scripts folder, configured the config.json file to contain the user GUIDs and the names, and then put the config file in a folder. What I don't understand is how to make it so the script can find the config folder and execute the commands. I just get a syntax error when I try to run the script: python change_coop_host.py Cla_Tronix File "", line 1 python change_coop_host.py Cla_Tronix ^^^^^^^^^^^^^^^^ SyntaxError: invalid syntax

Have you edited this script? It seems that you add this command to the code.

No, this is what happens when I try to run "python change_coop_host.py Name" in the Python cmd window. I haven't edited the script at all, only the config.json file.

Zennara commented 7 months ago

I'm not familiar with python, and I'm having some trouble. Could someone clear this up for me? I've imported change_coop_host.py to my scripts folder, configured the config.json file to contain the user GUIDs and the names, and then put the config file in a folder. What I don't understand is how to make it so the script can find the config folder and execute the commands. I just get a syntax error when I try to run the script: python change_coop_host.py Cla_Tronix File "", line 1 python change_coop_host.py Cla_Tronix ^^^^^^^^^^^^^^^^ SyntaxError: invalid syntax

Have you edited this script? It seems that you add this command to the code.

No, this is what happens when I try to run "python change_coop_host.py Name" in the Python cmd window. I haven't edited the script at all, only the config.json file.

Is the config file and the python file in the same directory?

ClaTron1x commented 7 months ago

I'm not familiar with python, and I'm having some trouble. Could someone clear this up for me? I've imported change_coop_host.py to my scripts folder, configured the config.json file to contain the user GUIDs and the names, and then put the config file in a folder. What I don't understand is how to make it so the script can find the config folder and execute the commands. I just get a syntax error when I try to run the script: python change_coop_host.py Cla_Tronix File "", line 1 python change_coop_host.py Cla_Tronix ^^^^^^^^^^^^^^^^ SyntaxError: invalid syntax

Have you edited this script? It seems that you add this command to the code.

No, this is what happens when I try to run "python change_coop_host.py Name" in the Python cmd window. I haven't edited the script at all, only the config.json file.

Is the config file and the python file in the same directory?

Yes. It looks like the syntax error is directed towards the "change_coop_host" part of the command. It might be because I haven't configured Python correctly and that it can't find the script I'm trying to run. I store my data on two drives, so that might be the problem. I have my scripts in the Scripts file that came when I installed python "D:\Python\Scripts"

Edit: I'm dumb and was running the commands in the python interpreter, and not cmd/powershell. I've managed to get the 'pop from an empty set' error and will try fixing it by following what was said above about the error.

trinityuniverse commented 7 months ago

I just wanted to say that your script worked perfectly for me. Had a few syntax errors at the beginning, but I was able to resolve them with ChatGPT. :)

Swapped two players and haven't been able to find any bugs so far.

Zennara commented 7 months ago

I just wanted to say that your script worked perfectly for me. Had a few syntax errors at the beginning, but I was able to resolve them with ChatGPT. :)

Swapped two players and haven't been able to find any bugs so far.

Mine worked too but there was one small bug where all of our pals weren't correctly registering to our guild. Therefore we couldn't pick them up when they were working. The fix was to just put all pals in the base and your palbox into your inventory, drop them on the ground, then put them back in. Do you have that issue as well?

guksg commented 7 months ago

I found fatal bug any player can't lift pals after script execute. tried put them back to box and replaced but still can't lift. plus new host's map is overwritten by old host's map.

is that cause of my bad procedure?

Zennara commented 7 months ago

I found fatal bug any player can't lift pals after script execute. tried put them back to box and replaced but still can't lift. plus new host's map is overwritten by old host's map.

is that cause of my bad procedure?

Pick up the pal, drop in on the ground (the actual item), then pick it back up. It will fix it then. Make sure to do this with ALL pals in your base, team, and palbox.

Aues6uen11Z commented 7 months ago

Yes, this script has the same Pal bug with what is mentioned in README. And I also found the map bug, this can be fixed by replacing the LocalData.sav from the modified save file with that from the original save file of the new host. LocalData.sav saves personal map and tutorial data, so replace it will work, I will update this to readme.

guksg commented 7 months ago

スクリプト実行後にどのプレイヤーも仲間を持ち上げることができない致命的なバグを発見しました。 箱に戻して交換してみましたが、やはり持ち上げられません。 さらに、新しいホストのマップは古いホストのマップによって上書きされます。 私の手順が悪いのが原因でしょうか?

仲間を拾い上げ、地面(現物)に落としてから拾い直します。そうすれば解決します。必ずベース、チーム、パルボックス内のすべての仲間に対してこれを行ってください。

that works! thank you so much