static void LoadInternal(StreamReader reader, string header) { int version = IdentifyFormatVersion(header); if (version > FormatVersion) { Logger.Log(LogType.Warning, "PlayerDB.Load: Attempting to load unsupported PlayerDB format ({0}). Errors may occur.", version); } else if (version < FormatVersion) { Logger.Log(LogType.Warning, "PlayerDB.Load: Converting PlayerDB to a newer format (version {0} to {1}).", version, FormatVersion); } int emptyRecords = 0; while (true) { string line = reader.ReadLine(); if (line == null) { break; } string[] fields = line.Split(','); if (fields.Length >= PlayerInfo.MinFieldCount) { #if !DEBUG try { #endif PlayerInfo info; switch (version) { case 0: info = PlayerInfo.LoadFormat0(fields, true); break; case 1: info = PlayerInfo.LoadFormat1(fields); break; default: // Versions 2-5 differ in semantics only, not in actual serialization format. info = PlayerInfo.LoadFormat2(fields); break; } if (info.ID > maxID) { maxID = info.ID; Logger.Log(LogType.Warning, "PlayerDB.Load: 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.Load: 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.Load: Duplicate record for player \"{0}\" skipped.", info.Name); } else { Trie.Add(info.Name, info); list.Add(info); } #if !DEBUG } catch (Exception ex) { Logger.LogAndReportCrash("Error while parsing PlayerInfo record: " + line, "fCraft", ex, false); } #endif } else { Logger.Log(LogType.Error, "PlayerDB.Load: Unexpected field count ({0}), expecting at least {1} fields for a PlayerDB entry.", fields.Length, PlayerInfo.MinFieldCount); } } if (emptyRecords > 0) { Logger.Log(LogType.Warning, "PlayerDB.Load: Skipped {0} empty records.", emptyRecords); } RunCompatibilityChecks(version); }
internal static void Load() { //LoadBinary(); //return; lock ( SaveLoadLocker ) { if (File.Exists(Paths.PlayerDBFileName)) { Stopwatch sw = Stopwatch.StartNew(); using (FileStream fs = OpenRead(Paths.PlayerDBFileName)) { using (StreamReader reader = new StreamReader(fs, Encoding.UTF8, true, BufferSize)) { string header = reader.ReadLine(); if (header == null) { return; // if PlayerDB is an empty file } lock ( AddLocker ) { int version = IdentifyFormatVersion(header); if (version > FormatVersion) { Logger.Log(LogType.Warning, "PlayerDB.Load: Attempting to load unsupported PlayerDB format ({0}). Errors may occur.", version); } else if (version < FormatVersion) { Logger.Log(LogType.Warning, "PlayerDB.Load: Converting PlayerDB to a newer format (version {0} to {1}).", version, FormatVersion); } int emptyRecords = 0; while (true) { string line = reader.ReadLine(); if (line == null) { break; } string[] fields = line.Split(','); if (fields.Length >= PlayerInfo.MinFieldCount) { #if !DEBUG try { #endif PlayerInfo info; switch (version) { case 0: info = PlayerInfo.LoadFormat0(fields, true); break; case 1: info = PlayerInfo.LoadFormat1(fields); break; default: // Versions 2-5 differ in semantics only, not in actual serialization format. info = PlayerInfo.LoadFormat2(fields); break; } if (info.ID > maxID) { maxID = info.ID; Logger.Log(LogType.Warning, "PlayerDB.Load: 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.Load: 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.Load: Duplicate record for player \"{0}\" skipped.", info.Name); } else { Trie.Add(info.Name, info); list.Add(info); } #if !DEBUG } catch (Exception ex) { Logger.LogAndReportCrash("Error while parsing PlayerInfo record", "fCraft", ex, false); } #endif } else { Logger.Log(LogType.Error, "PlayerDB.Load: Unexpected field count ({0}), expecting at least {1} fields for a PlayerDB entry.", fields.Length, PlayerInfo.MinFieldCount); } } if (emptyRecords > 0) { Logger.Log(LogType.Warning, "PlayerDB.Load: Skipped {0} empty records.", emptyRecords); } RunCompatibilityChecks(version); } } } sw.Stop(); Logger.Log(LogType.Debug, "PlayerDB.Load: Done loading player DB ({0} records) in {1}ms. MaxID={2}", Trie.Count, sw.ElapsedMilliseconds, maxID); } else { Logger.Log(LogType.Warning, "PlayerDB.Load: No player DB file found."); } UpdateCache(); IsLoaded = true; } }
internal static void Load() { lock ( SaveLoadLocker ) { if (File.Exists(Paths.PlayerDBFileName)) { Stopwatch sw = Stopwatch.StartNew(); using (StreamReader reader = File.OpenText(Paths.PlayerDBFileName)) { string header = reader.ReadLine(); if (header == null) { return; // if PlayerDB is an empty file } lock ( AddLocker ) { int version = IdentifyFormatVersion(header); while (!reader.EndOfStream) { string[] fields = reader.ReadLine().Split(','); if (fields.Length >= PlayerInfo.MinFieldCount) { #if !DEBUG try { #endif PlayerInfo info; if (version == 0) { info = PlayerInfo.LoadOldFormat(fields, true); } else { info = PlayerInfo.Load(fields); } if (Trie.ContainsKey(info.Name)) { Logger.Log("PlayerDB.Load: Duplicate record for player \"{0}\" skipped.", LogType.Error, info.Name); } else { Trie.Add(info.Name, info); List.Add(info); } #if !DEBUG } catch (Exception ex) { Logger.LogAndReportCrash("Error while parsing PlayerInfo record", "fCraft", ex, false); } #endif } else { Logger.Log("PlayerDB.Load: Unexpected field count ({0}), expecting at least {1} fields for a PlayerDB entry.", LogType.Error, fields.Length, PlayerInfo.MinFieldCount); } } } } List.TrimExcess(); sw.Stop(); Logger.Log("PlayerDB.Load: Done loading player DB ({0} records) in {1}ms.", LogType.Debug, Trie.Count, sw.ElapsedMilliseconds); } else { Logger.Log("PlayerDB.Load: No player DB file found.", LogType.Warning); } UpdateCache(); IsLoaded = true; } }