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
888 stars 65 forks source link

How I manually fixed the "guild" problem - might help #154

Open BrotherCal opened 4 months ago

BrotherCal commented 4 months ago

Not sure if this helps but i was able to manually fix mine and another guild issue within the level.sav - posting in case this can help with your script in any way. - please note I've used values from my level.sav here as an example.

`reference objects:

c0f56c50-b3bc-41c4-ab9b-041a17e6dd0b (group ID a.k.a guild identifier) 3b866a4b-0000-0000-0000-000000000000 (old user ID) 86612e2c-0000-0000-0000-000000000000 (new user ID)`

within the level.sav you have the guild information, you need to replace this with your new character information and find the associated group_ID and attach that to your character e.g.

If you search your guild name you will find the below - the key is your (Group_ID), Guild name - self explanatory, admin/player uid should be copied from your player info as detailed later, ensure you replace the group_name with your new UID as well as the individual_character_handle_ids:

                            "key": "c0f56c50-b3bc-41c4-ab9b-041a17e6dd0b", (guild ID)
                            "value": {
                                "GroupType": {
                                    "id": null,
                                    "value": {
                                        "type": "EPalGroupType",
                                        "value": "EPalGroupType::Guild"
                                    },
                                    "type": "EnumProperty"
                                },
                                "RawData": {
                                    "array_type": "ByteProperty",
                                    "id": null,
                                    "value": {
                                        "group_type": "EPalGroupType::Guild",
                                        "group_id": "c0f56c50-b3bc-41c4-ab9b-041a17e6dd0b", (guild id)
                                        "group_name": "86612e2c000000000000000000000000", (replace old UID with new)
                                        "individual_character_handle_ids": [
                                            {
                                                "guid": "86612e2c-0000-0000-0000-000000000000", (replace old UID)
                                                "instance_id": "6dcbc7e3-fa25-416b-b194-4e7b1299ff5c"
                                            },
"org_type": 0,
                                        "base_ids": [
                                            "b7f8ff46-fcf4-486e-9ee7-5c26b65fbdcb",
                                            "29d72add-9af5-466a-a391-a2cb76905d60"
                                        ],
                                        "base_camp_level": 20,
                                        "map_object_instance_ids_base_camp_points": [
                                            "2c725ef0-7c17-4825-8814-8c74556d5e54",
                                            "5ae50443-2336-4206-a165-977f6d9dec30"
                                        ],
                                        "guild_name": "your guild name",
                                        "admin_player_uid": "86612e2c-0000-0000-0000-000000000000",(replace old UID)
                                        "players": [
                                            {
                                                "player_uid": "86612e2c-0000-0000-0000-000000000000",(replace old UID)
                                                "player_info": {
                                                    "last_online_real_time": 10574212330000,
                                                    "player_name": "insert player name"

for the character association with the group look within "struct_type": "PalIndividualCharacterSaveParameter", or search for "NickName" until you find yours, you want your old character to have the value of your new under the "PlayerUId"

                            "key": {
                                "PlayerUId": {
                                    "struct_type": "Guid",
                                    "struct_id": "00000000-0000-0000-0000-000000000000",
                                    "id": null,
                                    "value": "86612e2c-0000-0000-0000-000000000000", (should be your new characters UID)
                                    "type": "StructProperty"
                                },
                                "InstanceId": {
                                    "struct_type": "Guid",
                                    "struct_id": "00000000-0000-0000-0000-000000000000",
                                    "id": null,
                                    "value": "e4e7a8af-4e32-241e-f06f-ea8b431c3194",
                                    "type": "StructProperty"
                                },
                                "DebugName": {
                                    "id": null,
                                    "value": "",
                                    "type": "StrProperty"
                                }
                            },
                            "value": {
                                "RawData": {
                                    "array_type": "ByteProperty",
                                    "id": null,
                                    "value": {
                                        "object": {
                                            "SaveParameter": {
                                                "struct_type": "PalIndividualCharacterSaveParameter",
                                                "struct_id": "00000000-0000-0000-0000-000000000000",
                                                "id": null,
                                                "value": {
                                                    "Level": {
                                                        "id": null,
                                                        "value": 20,
                                                        "type": "IntProperty"
                                                    },
                                                    "Exp": {
                                                        "id": null,
                                                        "value": 40381,
                                                        "type": "IntProperty"
                                                    },
                                                    "NickName": {
                                                        "id": null,
                                                        "value": "BrotherCal",
                                                        "type": "StrProperty"

there will be towards the bottom "group_id": "ensure this matches your guilds Group_ID as found previously"

                                        "group_id": "c0f56c50-b3bc-41c4-ab9b-041a17e6dd0b" (add your old guild group ID)
                                    },
                                    "type": "ArrayProperty",
                                    "custom_type": ".worldSaveData.CharacterSaveParameterMap.Value.RawData"
                                }
                            }
                        },
Esewqe commented 4 months ago

It worked for me, ty

MexChiKilin commented 4 months ago

Hi, that is nice! I tried to fix mine but had no luck, I used the web editor "palworld. tf", what kind of editor or app could I use for this? By the way! great work! and thanks for sharing.

BrotherCal commented 4 months ago

Hi, that is nice! I tried to fix mine but had no luck, I used the web editor "palworld. tf", what kind of editor or app could I use for this? By the way! great work! and thanks for sharing.

I used this: https://github.com/cheahjs/palworld-save-tools

divytube commented 4 months ago

how did you rebuilt the code again?

BrotherCal commented 4 months ago

how did you rebuilt the code again?

drop it back on to convert again

ChekThom commented 4 months ago

It works, very epic.

divytube commented 4 months ago

@BrotherCal or @ChekThom, can you guys please help me move my save from co-op to a dedicated server? Any kind of help would be appreciated! Thanks in advance Discord - @divyfy

ChekThom commented 4 months ago

@divytube what part are you having trouble with ? Is it the guild issue ?

divytube commented 4 months ago

i was having issues with guild problem plus i had some friends also join my guild, so that's one more thing plus even after making the changes i was unable to build back the local.sav file. @ChekThom so i wanted to do everything from start

Matheo-Moinet commented 4 months ago

Hi! I think what you described here is pretty much the same procedure as https://gist.github.com/mojobojo/c9e1e3d05d074408ed4bd6fbe04e62ef which I automated at https://github.com/Matheo-Moinet/palworld-server-save-transfer Hope this helps !

ChekThom commented 4 months ago

@divytube Note that I am the host for the co-op and I only have another friend in my co-op. I am not sure whether my friend's progress is retained after migrating to the dedicated server. If you want you can try the tool @Matheo-Moinet provided since it includes fixing for other players as well. MAKE SURE YOU HAVE A BACKUP

Here is what I did from the beginning. Steps -

  1. I followed the steps here from 1 to 9.
  2. Before, going to step 10, I used this https://github.com/cheahjs/palworld-save-tools to convert the Level.sav to Level.sav.json (don't worry about the prerequisites for this, you should already have Python installed in order to do step 1). For this tool, I followed the Windows GUI steps. Essentially, Just drag and drop the Level.sav onto the convert.md, which will open the command prompt. It might take some time, but after a while the Level.sav.json will be created.
  3. Edit the Level.sav.json, according to the screenshot above. You can use NotePad++ or any editors that support editing JSON. I don't recommend using an online JSON editor, since the file may be too big and crush the editor.
  4. After editing the Level.sav.json file, just drag and drop Level.sav.json back on to convert.md. This will convert Level.sav.json back to Level.sav. (Important - this will override the Level.sav you have previously, make sure you have a backup)
  5. With the new Level.sav, continues from 10 to 12 in this guide.
  6. The guild issue should be fixed.
  7. GLHF
divytube commented 4 months ago

Hey @Matheo-Moinet, I tried your script it seems pretty easy at a glance though to use the script but I am still facing issues, would love your assistance, if you can guide me on a voice chat on discord. Thanks in advance for your help.

Discord - @divyfy

magicbear commented 4 months ago

The easyest way is use tool at https://github.com/magicbear/palworld-server-toolkit, will automate clone all characters, item, guild, and fix all the instance for those.

divytube commented 4 months ago

Hey @magicbear, can we connect on discord @divyfy, i tried your discord link but I think its broken, it's not opening any channels on discord. I can't speak Chinese but I am using google translate to convey my message, please drop me a message on discord, Thanks in Advance

sugaroverflow commented 4 months ago

We had a dedicated - dedicated server transfer where only some of the players moved off. There were 3 guilds on the original server and after the migration, we were all assigned to a guild that wasn't ours so we couldn't access our base anymore.

I followed the instructions suggested by @BrotherCal in https://github.com/xNul/palworld-host-save-fix/issues/154#issue-2122967802 and manually reassigned the guilds in the Level.sav.json and that fixed our issues.

Here's what I did in order for anyone else trying. I think there may have been a more efficient way to get the guilds sorted, but I was getting tired and just ran re-fixes on everyone and it worked:

  1. From the original server's files, documented all the player old_guids.
  2. Had everyone log into the new server and create a character. Documented the new_guids.
  3. Kept a backup of everything.
  4. Using the script, manually pushed each player into my new_guid to login and see who they were using
    python fix-host-save.py <save_path> <my_new_guid> <old_player_guid> <guild_fix>. Using guild_fix True didn't seem to help in our case as everyone was assigned to guild 3, instead of guild 1. It helps to git track the whole server file folder so you can keep track as you're migrating players. I also recommend fixing the solo base/guild players first as we ran into a weird issue with the solo player and his "unnamed guild" - his palbox was someone else's. They also didn't have the pal bug like the rest of us.
  5. Once you've matched the old_guid to the new_guid for each player, run the scripts again using their guide and not your's so their new player files get their old player data. I would recommend doing this one by one, fix a player file and then upload the player file + Level.sav to the server (or git track the change). Sometimes the Level.sav gets weird or you get an error, so it helps to stay on track and not have to rollback too far.
  6. After that, I converted the Level.sav to a .json using palworld-save-tools and the advice from @BrotherCal in the first post. Since those other players weren't joining us on the new server, I decided to update the guilds so that we each owned one so we could dismantle/clear out the abandoned ones.
  7. Converted the Level.sav.json back to the binary file and uploaded it to the server.
  8. A few of us started seeing new character screens so I repeated step 5.
  9. Everyone logged in and things were working 🎉 Guild members did have to drop + pick up their pals though.