One of the features of my iOS game is a level editor, so users can create their own levels. The plan is for users to create levels then submit them to me (via email). I will then take those levels and add them to the application bundle and update the app so everyone gets to play them.
The hard part turned out to be easy and the easy part turned out to be hard. Creating the email itself was easy - only a few lines of code. I could even easily create attachments, including the PNG of the level which my app already creates for the user created levels. The hard part turned out to be sending the level data as an attachment.
After much fussing around with various serialization standards (e.g. JSON, XML), I decided to KISS and use a simple key value format. Originally I used key=value<eol>, but I later changed it to key<tab>value<eol> in case someone put an = into their level title. The idea is to make the attachment transparent to avoid any concerns about collecting user data. The problem with this is the user could potentially change the file before sending it to me - making it unsolvable. (The game won't let you submit a level until you've successfully completed it.) So I needed to add some kind of checksum to the file to detect and discourage changes.
I decided to kill two birds with one program and code up a MacOS app (in Swift) which would read the file, verify the checksum, and update the SQLite database which would get included into the iOS app.
My first attempt was to use the hashValue property built into Swift. I figured even if it wasn't a full-blown cryptographic hash, it would be "good enough". Unfortunately, it turns out the hashValue isn't a true hash of the value, but instead is just the address of the object. (Which might be good enough for some purposes, but is far from being an actual hash.) So I went looking for a real hash function and learned Apple provides a library of crypto functions (including hashes). They are C functions, but so is SQLite.
Of course, that didn't work the first time. The function produced output, but the output didn't match - although the input looked the same. So I changed the iOS app to send a Bas64 version of the input as the checksum and had the MacOS app do the same thing. Bingo - the start of the input was the same, but it deviated along the way.
After more debug printing, I managed to identify the problem - somewhere, somehow, the end of lines in the KVP file were being changed from LF to CR+LF and the CRs weren't being stripped out of the input to the hash. Once I modified the MacOS app to remove the extra CRs the "checksum" matched and so did the hash value.
-
entries
334 -
comments
900 -
views
258,190
-
Recently Browsing 0 members
- No registered users viewing this page.
2 Comments
Recommended Comments