Interlude: Modifying Saves

I wrote last time that I was going to modify a save in order to test what range of values was acceptable. Time to get to work on that. Well, actually, time to continue work.

I’ve written a program that can extract information from the saves and (in principle) write it back to them. I’ve been using Ross Ridge’s mymc utility to get the save file off the memory card. It seemed pretty convenient, since mymc is written in python, as is my program (inventively called “dothacksaveparser.py”). I figured that when it came time to actually modify files, I’d just import mymc do my magic, and problem solved.

It was not to be.

First, mymc is an interactive program, and there’s no easy way to use it as a library—in fact, if you try to import it, it’ll just kill your program. Bad. There important initialization stuff done in the main function, so I can’t just just wrap it all in if name == “main“, either. Maybe I’ll eventually get it sorted out into a more useful form, but for now, importing is out.

No problem, I though, I can just run the thing and have take its input from stdin and print to stdout, and it’ll be pretty much the same thing. So I try it. And… I’m getting files of the wrong size.

The save files for .hack//Infection are 34096 bytes. Somehow, when I had the files output to stdout, a hundred or so bytes were getting added. Mysterious. I compare the files, and notice that they look pretty similar, but misaligned. In fact, there are extraneous 0x0D bytes added throughout. A little closer look reveals that each extra 0x0D occurs before a 0x0A that was in the original file. Now, those are some low bytes… control codes… I look it up, and, indeed, python is adding a carriage return before each ‘line feed’. Of course, since it’s a binary file, there aren’t actually any line feeds, but… there you have it.

Some research revealed the right solution to that problem, though:

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

Useful snippet of code.

So, problem solved… almost there. Now I can read the files in, and I know how to calculate the checksum and export the files again. One problem: the function for adding files to a memory card will not accept input from stdin. Why not? Why can I get files extracted to stdout but not added from stdin?

Fine. I’ll write the files to disk so that they can be added.

I do all that, and it’s time for a test. No modifications. Just read the file in and spit it back out. And… failure. Bizarrely, a huge number of bytes have been modified in the memory card file, but I can’t see why. Executing the same commands manually works fine. What’s happening? I try again, and… it works. Let it be known that the worst words to hear are “intermittent error”. I have no clue what went wrong the first time. I’m going to hope that it was… I don’t know… solar flares.

Anyway, this story’s drawing to a close. Having a successful test on unmodified files, what’s left is to try a simple modification. How about giving Kite 15000GP?

.hack//Infection lots of money

I’m rich. As Kite is my witness, I’ll never go hungry again!

Written by Tracy Poff on Mon 02 September 2013.