public static string LookUpGameId(GameSourceBase gameSource) { string hash = CalculateGameChecksum(gameSource); // Look it up! GameRecord gameRecord; GameRegistrar.gameDatabaseByCheckSum.TryGetValue(hash, out gameRecord); // If we found a record, we're done! if (gameRecord != null) { return(gameRecord.Id); } // (if we didn't, it gets messy...) ////////////////////// // Try desperately to come up with a game ID to fill in for this unknown, rogue game. // TODO: If at some point there's a nice (non-intrusive) way to let the user know // that this game is unknown, then we should do it here. This code will only be able // to come up with an Id that doesn't exist in the database. If there are two // games out there that don't exist in the database, there's a chance that they'll // use the same GameId, and therefore share save states. This isn't too likely, and // if it happens, most users won't notice unless they play a lot of both offending // games. That's why it would be good to notify users and hopefully get feedback // early. // But, of course, I really doubt this will ever be a problem. // Start with the first 8 characters of the hash. // (that's how the other items in the intial game database were made anyway). string candidateId = null; bool unique = false; bool firstTry = true; // As long as this game do { if (firstTry) { candidateId = hash.Substring(0, 8); } else { candidateId = GetNextId(candidateId); } firstTry = false; GameRecord existingRecord = null; GameRegistrar.gameDatabaseById.TryGetValue(candidateId, out existingRecord); unique = (existingRecord == null); } while (!unique); // Well, this key oughta do for now. return(candidateId); }
public static string CalculateGameChecksum(GameSourceBase gameSource) { ////////////////////// // Come up with MD5 hash of the first block of CD data. byte[] checkSumSourceData = new byte[2048 * INITIAL_SECTORS_TO_READ]; for (int x = 0; x < INITIAL_SECTORS_TO_READ; x++) { unsafe { fixed(byte *dataPtr = &checkSumSourceData[x * 2048]) { gameSource.ReadSector(new IntPtr((int)dataPtr), x); } } } return(GetHash(checkSumSourceData)); }