tracktwo / xcomsave

46 stars 16 forks source link

Add support for XCOM:EW Android port #12

Closed hubslave closed 6 years ago

hubslave commented 6 years ago

In Android port, the checksum is a single CRC32, not CRC32B! offset 0xBE Compressed data block were compressed using zlib.

Can you possibly add support for Android, thanks!

Save file link: https://a.pomf.cat/tjttpv

If you don't mind, can you code in a function to compress as LZO (like pc saves) for experimentation?

tracktwo commented 6 years ago

Thanks for the save! I can try to add this, sure. But I'm having a little bit of trouble verifying the CRC based on the info you gave me, and it'd save me some time if you've already done the reverse engineering so I don't have to do it myself -- what subset of the save is CRCd? On PC the compressed data crc only checks the compressed data chunks from offset 1024 to the end of the file, but I'm not getting a match with the value at 0xbe using normal CRC32 on that subset of the file.

Igmat commented 6 years ago

@tracktwo are there any progress with this issue? Or, is there anything that can be done to help you resolve it? I would love to but I'm JS dev and not very familiar with formats you're talking about. Probably you may give some links that will explain it, do you?

tracktwo commented 6 years ago

@Igmat I was away visiting family for a few weeks so not much progress lately. It is pretty slow going unless @hubslave has already done some of the legwork because I don't have the game for Android or an Android device that can play it, so I'm working blind. Even just trying to figure out what portion of the save is CRC'd would be much easier if I could load up the game myself to see if changes to the save file work or not.

Igmat commented 6 years ago

@tracktwo I have Android device and game, and few saves for testing. I was able to build your app and even made few changes in it and test against my saves - but unfortunately due to lack of knowledge in this particular topic and C++ (I was unable even to debug the app:( ) no real progress was made. We may try to collaborate using something like Skype if you have time for it.

tracktwo commented 6 years ago

@Igmat I have a pretty unreliable schedule (kids!) but if you're willing to do a little back-and-forth with saves I'd be willing to work on it. It might be easiest to do a little differential analysis of the saves, so if you can do a few things for me and send me all the resulting saves that'd be really helpful. As a first batch, maybe the following:

  1. A geoscape save, can be anything.
  2. Immediately save the game again without passing any time on the geoscape, so as little changes as possible between the two saves. Use exactly the same name as 1 for the name of the save file.
  3. Save again, again without passing any time, but this time change only one character in the save description.
  4. Pass a little time on the geoscape and then save again. Doesn't really matter what the save is called for this one.

Doesn't matter which language you're playing the game in for your saves, but use the same one for all of them.

For example, make a save "save 1", another one called "save 1", another called "save 2", and finally one called "save 3" and send me all four. From those I can try to figure out what changes between saves in the headers.

Once I take a look at those I'll probably send you back a batch of saves to try. Some of them will have bad checksums and either won't show up in the save list at all or won't load correctly, but that will help me to track down what parts of the save are checksummed.

Igmat commented 6 years ago

xcom-saves.zip

Android version doesn't give you any option to affect filename or description. So save4 is for 1. save4 1 is for 2 (I've rewritten previously copied save4). save5 is for 3 (no time passed, just saved in another slot). save6 is for 4 (little time passed, also saved in another slot).

I hope it'll help.

tracktwo commented 6 years ago

Great, thank you. Can you try the following three saves to see if any of them show up in the save list at all and/or can be successfully loaded? They are all based on your save4.

save7 -> If it shows up it may show up as "Game 239" instead of "Game 238" (if the android version shows this info in the save list). save8 -> May show the game date as 2016 instead of 2015. save9 -> Should be indistinguishable, if it shows up at all.

I expect all three of these to fail to show up in the list at all, but please do let me know if they do appear or if they are loadable. new_saves.zip

Igmat commented 6 years ago

screenshot_20180104-114205 All this saves appeared in list and all was loadable, but without any changes. For save7 it probably could change game id, but seems that save name is plain text, so I can't be sure, because it shows Игра 238 (it translates to English as Game 238)

Igmat commented 6 years ago

Also, save8 haven't changed date in game after loading save.

tracktwo commented 6 years ago

@Igmat Great, that's useful stuff. I didn't expect 8 to change the in-game date, there is some redundant information in the save header and it looks like the Android version really only uses one string that includes all the text you see in that save. It's been a long time but IIRC the PC version has a 2nd line of info under the save title with the game number or date or both, but that doesn't seem to be in the Android one, possibly because you can't change the save description in Android?

Anyway this is great info, thanks. I'll give you another one later that should hopefully load and also have a difference visible in the save description, and another that should not load at all.

tracktwo commented 6 years ago

@Igmat Here's another set:

If save10 loads it should show up as game 999 in the list. Save11 should have a corrupted checksum and I expect it to either not show up at all or fail to load. saves_1011.zip

tracktwo commented 6 years ago

I made some good progress today with that info you gave me earlier. I can now read and write an android save file, hopefully correctly. It passes my little round-trip test case I use for all my gathered saves, at least: Convert to json, back out to a save file, back out to json again, and diff the two json files to make sure they are the same.

Can you try loading the attached modded save? It's based off your "save4" and I've altered the aim stat of the character "Helene Thomas" to be 99. Hopefully she isn't dead :)

save12.zip

Igmat commented 6 years ago

All you said about saves 10 and 11 is correct. First has changed title, second is shown in list but throws error, when you try to load it.

Save12 is working and "Helene Thomas" has 99 aim, but there is some weird thing. In Android version you have so called "Profiles" screenshot_20180105-114818 Saves are located under them. And save4 initially was in third profile. And all saves you gave me always appeared there, except save12 - it was shown under first profile. It's not a big deal, but may probably be useful for you.

Igmat commented 6 years ago

@tracktwo and are there any branch where I can try your latest solution?:)

tracktwo commented 6 years ago

@Igmat I haven't committed the changes yet since they're a real mess, but I plan to do so soon, maybe later tonight.

The profile thing is interesting. Do you have the ability to move saves between profiles, or can you get me two similar saves from different profiles so I can try to figure out where that info is kept?

It's also possible that the game records which save is in which profile outside the save itself, and when it encounters a save file it doesn't know about it just puts it in the 1st one. The main difference between save12 and the others is I had to modify the compressed data and recompute a new checksum for that save, the others used the original checksums.

EDIT: Actually I think I found where the profile may be stored.

There is an extra bit of information in the Android save that isn't present in the PC saves, so in the save12 I sent you my repacking code stripped it out. It has two fields in it. The first is a number (2, likely corresponding to profile 3) and a text string with what looks like a date. In Save 4 it has the text:

6 мар. 2015

That same string also appears in the description of the save. I'm not sure how that date is used in the profile screen, if at all, but the number 2 I am fairly confident is your profile number.

tracktwo commented 6 years ago

I've pushed the new code up on the android branch and drafted a preview release with binaries built from this branch if you can try them out. Bear in mind that it still doesn't have the profile stuff worked out so they'll all probably go to profile 1.

tracktwo commented 6 years ago

Also, this is pretty cool:

20180106124400_1

I also changed the language to INT so I could get english menus rather than trying to navigate Russian menus, but all the already-created text strings remain in Russian from the save.

tracktwo commented 6 years ago

Android beta 2 binaries are now in the release tab with what I think is profile support. Let me know if a roundtrip through this version keeps the same profile information or not.

hubslave commented 6 years ago

@tracktwo sorry for bailing the issue, the game can be cruel sometimes so I kind of lost interest for several month, and finally picked up xcom again. I'm glad that the android support is done. unfortunately I don't have a jailbroken iOS device to submit save. tesnexus says they are using zlib special for ios.

tracktwo commented 6 years ago

@hubslave No problem. I'm curious if Android and iOS use the same version and save structure, but so far I haven't had anyone send me an iOS save to look at. They may be harder to get if you need a jailbroken device to get at the saves on iOS, I don't know if the Android ones are accessible without root or not.

At any rate I think the Android support is in a place where I can consider this issue closed. If there are further bugs we can open new ones.

hubslave commented 6 years ago

The Android port of EW saves the save file to internal storage, that's why we are able to supply saves.