internal void LoadBinary() {
using( PlayerDB.GetWriteLock() ) {
if( File.Exists( Paths.PlayerDBFileName + ".bin" ) ) {
using( FileStream fs = OpenRead( Paths.PlayerDBFileName + ".bin" ) ) {
BinaryReader reader = new BinaryReader( fs );
int version = reader.ReadInt32();
if( version > FormatVersion ) {
Logger.Log( LogType.Warning,
"PlayerDB.LoadBinary: Attempting to load unsupported PlayerDB format ({0}). Errors may occur.",
version );
} else if( version < FormatVersion ) {
Logger.Log( LogType.Warning,
"PlayerDB.LoadBinary: Converting PlayerDB to a newer format (version {0} to {1}).",
version, FormatVersion );
}
maxID = reader.ReadInt32();
int rankCount = reader.ReadInt32();
rankMapping = new Dictionary<int, Rank>( rankCount );
for( int i = 0; i < rankCount; i++ ) {
byte rankIndex = reader.ReadByte();
string rankName = reader.ReadString();
Rank rank = Rank.Parse( rankName );
if( rank == null ) {
Logger.Log( LogType.Error,
"PlayerDB.LoadBinary: Could not parse rank: \"{0}\". Assigning rank {1} instead.",
rankName, RankManager.DefaultRank );
rank = RankManager.DefaultRank;
}
rankMapping.Add( rankIndex, rank );
}
int records = reader.ReadInt32();
int emptyRecords = 0;
for( int i = 0; i < records; i++ ) {
#if !DEBUG
try {
#endif
PlayerInfo info = LoadBinaryFormat0( reader );
if( info.ID > maxID ) {
maxID = info.ID;
Logger.Log( LogType.Warning,
"PlayerDB.LoadBinary: Adjusting wrongly saved MaxID ({0} to {1})." );
}
// A record is considered "empty" if the player has never logged in.
// Empty records may be created by /Import, /Ban, and /Rank commands on typos.
// Deleting such records should have no negative impact on DB completeness.
if( ( info.LastIP.Equals( IPAddress.None ) || info.LastIP.Equals( IPAddress.Any ) ||
info.TimesVisited == 0 ) &&
!info.IsBanned && info.Rank == RankManager.DefaultRank ) {
Logger.Log( LogType.SystemActivity,
"PlayerDB.LoadBinary: Skipping an empty record for player \"{0}\"",
info.Name );
emptyRecords++;
continue;
}
// Check for duplicates. Unless PlayerDB.txt was altered externally, this does not happen.
if( trie.ContainsKey( info.Name ) ) {
Logger.Log( LogType.Error,
"PlayerDB.LoadBinary: Duplicate record for player \"{0}\" skipped.",
info.Name );
} else {
trie.Add( info.Name, info );
}
#if !DEBUG
} catch( Exception ex ) {
Logger.LogAndReportCrash( "Error while parsing PlayerInfo record",
"fCraft",
ex,
false );
}
#endif
}
if( emptyRecords > 0 ) {
Logger.Log( LogType.Warning,
"PlayerDB.LoadBinary: Skipped {0} empty records.", emptyRecords );
}
}
} else {
Logger.Log( LogType.Warning, "PlayerDB.Load: No player DB file found." );
}
}
}