public void ClearGameData(LogRecorderInterface log) { try { BeginTransaction(); using (SQLiteCommand cmd = GetConnection().CreateCommand()) { cmd.CommandText = "DELETE FROM HashList"; cmd.ExecuteNonQuery(); } using (SQLiteCommand cmd = GetConnection().CreateCommand()) { cmd.CommandText = "DELETE FROM HardPointList"; cmd.ExecuteNonQuery(); } using (SQLiteCommand cmd = GetConnection().CreateCommand()) { cmd.CommandText = "DELETE FROM EquipInfoList"; cmd.ExecuteNonQuery(); } using (SQLiteCommand cmd = GetConnection().CreateCommand()) { cmd.CommandText = "DELETE FROM ShipInfoList"; cmd.ExecuteNonQuery(); } EndTransaction(); } catch (Exception e) { log.AddLog(String.Format("Error '{0}' when updating db", e.Message)); } }
public void GenerateGeneralStatistics(BackgroundWorker bgWkr, LogRecorderInterface log) { GenerateOnlinePlayerStats(log); DateTime date = DateTime.Now; try { string filePath = String.Format("{0}\\general_{1:yyyyMMdd}.html", AppSettings.Default.setStatisticsDir, date); if (File.Exists(filePath)) { return; } using (DamDataSet ds = new DamDataSet()) { bgWkr.ReportProgress(60, "Creating general statistics..."); dataAccess.GetGeneralStatisticsTable((DamDataSet.GeneralStatisticsTableDataTable)ds.GeneralStatisticsTable); bgWkr.ReportProgress(70, "Generating general reports..."); string[] colTitles = new string[] { "Description", "Result" }; string[] colNames = new string[] { "Description", "Result" }; string title = String.Format("General Statistics - {0}", date); DataRow[] rows = ds.GeneralStatisticsTable.Select(); SaveAsHTML(filePath, title, rows, colTitles, colNames, 0, rows.Length); File.Copy(filePath, AppSettings.Default.setStatisticsDir + "\\general.html", true); } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when calculating general statistics", ex.Message)); } }
/// <summary> /// Calculate and generate statistics for factions. /// </summary> /// <param name="bgWkr"></param> /// <param name="log"></param> public void GenerateFactionActivity(BackgroundWorker bgWkr, LogRecorderInterface log) { DateTime endDate = DateTime.Today; DateTime startDate = endDate.Subtract(new TimeSpan(30, 0, 0, 0)); // If statistics are disabled, do nothing. if (AppSettings.Default.setStatisticsDir.Length == 0) { return; } // Produce activity statistics if they don't exist. string filePath = String.Format("{0}\\activity_summary_{1:yyyyMMdd}.html", AppSettings.Default.setStatisticsDir, endDate); if (File.Exists(filePath)) { return; } try { // Keep a summary table of all factions. UIDataSet summaryFactions = new UIDataSet(); // Crunch the data. bgWkr.ReportProgress(80, "Creating activity statistics..."); UIDataSet results = CalcActivity(startDate, endDate, bgWkr, log); // General overall activity report. string title = String.Format("Activity - {0} days to {1}", (endDate - startDate).Days, endDate); GenerateActivityReport(results, "", title, summaryFactions, endDate, true); // Save statistics for factions. bgWkr.ReportProgress(90, "Generating activity reports..."); string[] factionsFilter = AppSettings.Default.setStatsFactions.Split(' '); foreach (string factionFilter in factionsFilter) { string faction = factionFilter.Trim(); if (faction.Length > 0) { title = String.Format("Activity {0} - {1}", faction, endDate); GenerateActivityReport(results, faction, title, summaryFactions, DateTime.MinValue, false); } } // Write the index.html DataRow[] rows = summaryFactions.StatPlayer.Select("", "OnLineTime DESC"); SaveAsHTML(filePath, String.Format("Activity Summary - {0} days to {1}", (endDate - startDate).Days, endDate), rows, new string[] { "Name", "On Line Time" }, new string[] { "Name", "OnLineTime" }, 0, rows.Length); File.Copy(filePath, AppSettings.Default.setStatisticsDir + "\\activity_summary.html", true); } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when generating HTML", ex.Message)); try { File.Delete(filePath); } catch { }; } }
/// <summary> /// Start the log /// </summary> /// <param name="eventListener"></param> public FLHookEventSocket(FLHookListener eventListener, LogRecorderInterface log) { this.eventListener = eventListener; this.log = log; if (this.eventListener != null) { receiveEventThread = new Thread(new ThreadStart(ReceiveEventThread)); receiveEventThread.Name = "FLEventReceive"; receiveEventThread.IsBackground = true; receiveEventThread.Start(); cfgCheckerThread = new Thread(new ThreadStart(ConfigurationCheckerThread)); cfgCheckerThread.Name = "FLEventReceiveCfgChecker"; cfgCheckerThread.IsBackground = true; cfgCheckerThread.Start(); } }
/// <summary> /// Generate player stats in a format similar to FLStat. /// </summary> /// <param name="bgWkr"></param> /// <param name="log"></param> public void GeneratePlayerStats(BackgroundWorker bgWkr, LogRecorderInterface log) { DateTime date = DateTime.Now; try { string filePath = String.Format("{0}\\players_{1:yyyyMMdd}.html", AppSettings.Default.setStatisticsDir, date); if (File.Exists(filePath)) { return; } using (DamDataSet ds = new DamDataSet()) { dataAccess.GetCharacterList(ds.CharacterList); bgWkr.ReportProgress(75, "Generating player reports..."); //DataRow[] rows = ds.CharacterList.Select("IsDeleted = 'false'"); using (UIDataSet uds = new UIDataSet()) { foreach (DamDataSet.CharacterListRow cr in ds.CharacterList) { if (!cr.IsDeleted) { uds.StatPlayer.AddStatPlayerRow(cr.CharName, new TimeSpan(0, 0, cr.OnLineSecs), cr.Money, cr.Rank, cr.LastOnLine, cr.OnLineSecs); } } string[] colTitles = new string[] { "Name", "Rank", "Money", "Last On Line", "On Line Time" }; string[] colNames = new string[] { "Name", "Rank", "Money", "LastOnLine", "OnLineTime" }; string title = String.Format("Players - {0}", date); SaveAsHTML(filePath, title, uds.StatPlayer.Select("", "Rank DESC"), colTitles, colNames, 0, 2500); File.Copy(filePath, AppSettings.Default.setStatisticsDir + "\\players.html", true); } } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when calculating player statistics", ex.Message)); } }
public void LoadGameData(GameDataSet ds, LogRecorderInterface log) { try { ds.Clear(); using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM HashList", GetConnection())) adpt.Fill(ds.HashList); using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM HardPointList", GetConnection())) adpt.Fill(ds.HardPointList); using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM EquipInfoList", GetConnection())) adpt.Fill(ds.EquipInfoList); using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM ShipInfoList", GetConnection())) adpt.Fill(ds.ShipInfoList); } catch (Exception e) { log.AddLog(String.Format("Error '{0}' when updating db", e.Message)); } }
public void CommitGameData(GameDataSet ds, LogRecorderInterface log) { try { BeginTransaction(); using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM HashList", GetConnection())) { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(ds.HashList); } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM HardPointList", GetConnection())) { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(ds.HardPointList); } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM EquipInfoList", GetConnection())) { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(ds.EquipInfoList); } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM ShipInfoList", GetConnection())) { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(ds.ShipInfoList); } EndTransaction(); } catch (Exception e) { log.AddLog(String.Format("Error '{0}' when updating db", e.Message)); } }
/// <summary> /// Load a ion cross game data file that has a hash key /// </summary> /// <param name="items">The database to copy data into</param> /// <param name="ioncrossDir">The file </param> /// <param name="hashFile"></param> private void LoadIonCrossHashDesc(GameDataSet.HashListDataTable items, string filePath, LogRecorderInterface log) { try { FLDataFile ini = new FLDataFile(filePath, true); foreach (FLDataFile.Section s in ini.sections) { foreach (FLDataFile.Setting setting in s.settings) { try { GameDataSet.HashListRow itemRecord = GetItemByNickName(setting.settingName); if (itemRecord == null) itemRecord = GetItemByHash(Convert.ToUInt32(setting.settingName)); if (itemRecord != null) { if (setting.NumValues() > 1) itemRecord.IDSName = setting.Str(1); else if (setting.NumValues() > 0) itemRecord.IDSName = setting.Str(0); } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when reading {1}", ex.Message, setting.desc)); } } } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when reading {1}", ex.Message, filePath)); } }
/// <summary> /// Load an ion cross game data file that has a nickname key /// </summary> /// <param name="items">The database to copy data into</param> /// <param name="ioncrossDir">The file </param> /// <param name="hashFile"></param> private void LoadIonCrossNickNameDesc(GameDataSet.HashListDataTable items, string filePath, LogRecorderInterface log, bool isFaction) { try { FLDataFile ini = new FLDataFile(filePath, false); foreach (FLDataFile.Section s in ini.sections) { foreach (FLDataFile.Setting setting in s.settings) { try { GameDataSet.HashListRow itemRecord = GetItemByNickName(setting.settingName.ToLowerInvariant()); if (isFaction) itemRecord = GetItemByFactionNickName(setting.settingName.ToLowerInvariant()); if (itemRecord != null) { if (setting.NumValues() > 0) itemRecord.IDSName = setting.Str(0); } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when reading {1}", ex.Message, setting.desc)); } } } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when reading {1}", ex.Message, filePath)); } }
/// <summary> /// Scans the specified directory and recursively search for ini files that appear to contain /// hashcodes. /// </summary> /// <param name="flDataPath"></param> /// <param name="iniFilePath"></param> /// <remarks>Not used any more</remarks> private void ScanForHashCodes(GameDataSet dataStore, string flDataPath, BackgroundWorker bgw, LogRecorderInterface log) { // Scan the ini files. string[] iniFiles = Directory.GetFiles(flDataPath, "*.ini"); for (int i=0; i<iniFiles.Length; i++) { if (bgw.CancellationPending) return; string filePath = iniFiles[i]; bgw.ReportProgress(((i * 100) / iniFiles.Length), "Scanning " + filePath.Substring(flDataPath.Length + 1) + "..."); try { FLDataFile ini = new FLDataFile(filePath, true); foreach (FLDataFile.Section section in ini.sections) { foreach (FLDataFile.Setting e in section.settings) { if (e.NumValues() == 0) continue; string st = e.settingName.ToLowerInvariant(); if (st == "nickname" || st == "archetype" || st == "loadout" || st == "explosion_arch" || st == "fuse" || st == "zone" || st == "name" || st == "room" || st == "prop" || st == "msg_id_prefix" || st == "npc") { string nickName = e.Str(0); uint hashU = FLUtility.CreateID(nickName.ToLowerInvariant()); GameDataSet.HashListRow conflictingEntry = dataStore.HashList.FindByItemHash(hashU); if (conflictingEntry == null) { string keys = hashU.ToString() + " 0x" + hashU.ToString("X"); dataStore.HashList.AddHashListRow(hashU, nickName, GAMEDATA_GEN, "", "", "", "", "", keys); } } /* for (int j = 0; j < e.NumValues(); j++) { string nickName = e.Str(j); uint hashU = FLUtility.CreateID(nickName.ToLowerInvariant()); string keys = hashU.ToString() + " 0x" + hashU.ToString("X"); GameDataSet.HashListRow conflictingEntry = dataStore.HashList.FindByItemHash(hashU); if (conflictingEntry == null) { dataStore.HashList.AddHashListRow(hashU, nickName, GAMEDATA_GEN, "", "", "", "", ""); } } */ } } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when scanning {1}", ex.Message, filePath)); } } // Recurse through subdirectories. string[] dataDirs = Directory.GetDirectories(flDataPath); for (int i = 0; i < dataDirs.Length; i++ ) { ScanForHashCodes(dataStore, dataDirs[i], bgw, log); } }
/// <summary> /// Scan the goods files for the specifed shiphull to add the effects entries /// from the goods package to the ship as synthetic hardpoints. /// </summary> /// <param name="info"></param> /// <param name="loadout"></param> void AddFXFromGoods(FLDataFile flGoodsIni, string flDataPath, FLDataFile.Section shipPackageSection, LogRecorderInterface log) { try { string hullNickName = shipPackageSection.GetSetting("hull").Str(0); foreach (FLDataFile.Section section in flGoodsIni.sections) { if (section.sectionName.ToLowerInvariant() != "good") continue; if (section.GetSetting("category").Str(0)!="shiphull") continue; if (section.GetSetting("nickname").Str(0)!=hullNickName) continue; string shipNickName = section.GetSetting("ship").Str(0); uint shiphash = FLUtility.CreateID(shipNickName); long defaultSound = 0; long defaultPowerPlant = 0; long defaultEngine = 0; // Get the loadout for the ship. foreach (FLDataFile.Setting setting in shipPackageSection.settings) { try { if (setting.settingName.ToLowerInvariant() != "addon") continue; if (setting.NumValues() != 3) throw new Exception(setting.desc + "setting '" + setting.desc + "' should have 3 values"); string equipNickName = setting.Str(0); GameDataSet.HashListRow item = GetItemByNickName(equipNickName); if (item == null) throw new Exception(setting.desc + " cannot find " + equipNickName + " in game data table"); if (item.ItemType == GAMEDATA_LIGHTS) { if (setting.Str(1) == "internal") throw new Exception(setting.desc + " invalid hardpoint for " + equipNickName); DataStore.HardPointList.AddHardPointListRow(shiphash, setting.Str(1), item.ItemType, "", item.ItemHash); } else if (item.ItemType == GAMEDATA_FX) { if (setting.Str(1) == "internal") throw new Exception(setting.desc + " invalid hardpoint for " + equipNickName); DataStore.HardPointList.AddHardPointListRow(shiphash, setting.Str(1), item.ItemType, "", item.ItemHash); } else if (item.ItemType == GAMEDATA_SOUND) { defaultSound = item.ItemHash; } else if (item.ItemType == GAMEDATA_POWERGEN) { defaultPowerPlant = item.ItemHash; } else if (item.ItemType == GAMEDATA_ENGINES) { defaultEngine = item.ItemHash; } } catch (Exception e) { log.AddLog("Error '" + e.Message + "'"); } } DataStore.ShipInfoList.AddShipInfoListRow(shiphash, defaultEngine, defaultSound, defaultPowerPlant); } } catch (Exception e) { log.AddLog("Error '" + e.Message + "'"); } }
/// <summary> /// Parse the system file to extract base information. /// </summary> /// <param name="fileName"></param> void ParseSystem(string fileName, LogRecorderInterface log) { FLDataFile ini = new FLDataFile(fileName, true); foreach (FLDataFile.Section section in ini.sections) { string idsName = ""; string idsInfo = ""; string idsInfo1 = ""; string pos = ""; if (section.sectionName.ToLowerInvariant() == "object") { try { if (section.SettingExists("ids_name")) { idsName = GetIDString(section.GetSetting("ids_name").UInt(0)); } if (section.SettingExists("ids_info")) { uint value = section.GetSetting("ids_info").UInt(0); idsInfo = GetIDString(value); if (infocardMap.ContainsKey(value)) idsInfo1 = GetIDString(infocardMap[value]); } if (section.SettingExists("pos")) { pos = section.GetSetting("pos").Str(0) + "," + section.GetSetting("pos").Str(1) + "," + section.GetSetting("pos").Str(2); } if (section.SettingExists("base")) { string baseNick = section.GetSetting("base").Str(0); GameDataSet.HashListRow baseItem = GetItemByNickName(baseNick); if (baseItem != null) { if (baseItem.IDSInfo.Length == 0) baseItem.IDSInfo = idsInfo; if (baseItem.IDSInfo1.Length == 0) baseItem.IDSInfo1 = idsInfo1; if (baseItem.IDSInfo2.Length == 0) baseItem.IDSInfo2 = "Postion: " + pos; } } AddGameData(DataStore.HashList, section, GAMEDATA_OBJECT, false); } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + fileName); } } else if (section.sectionName.ToLowerInvariant() == "zone") { try { AddGameData(DataStore.HashList, section, GAMEDATA_ZONE, false); } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + fileName); } } } }
/// <summary> /// Load all game data. /// </summary> public void LoadAll(string flExePath, LogRecorderInterface log) { DataStore.Clear(); FLDataFile flIni = null; try { flIni = new FLDataFile(flExePath + Path.DirectorySeparatorChar + "Freelancer.ini", true); } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + flExePath); return; } string flDataPath = Path.GetFullPath(Path.Combine(flExePath, flIni.GetSetting("Freelancer", "data path").Str(0))); log.AddLog("Loading strings..."); // Load the string dlls. LoadLibrary(flExePath + Path.DirectorySeparatorChar + "resources.dll"); foreach (FLDataFile.Setting flIniEntry in flIni.GetSettings("Resources", "DLL")) LoadLibrary(flExePath + Path.DirectorySeparatorChar + flIniEntry.Str(0)); log.AddLog("Loading universe..."); // Scan ini files and parse base entries foreach (FLDataFile.Setting flIniEntry in flIni.GetSettings("Data", "universe")) { string iniPath = flDataPath + Path.DirectorySeparatorChar + flIniEntry.Str(0); try { FLDataFile ini = new FLDataFile(iniPath, true); foreach (FLDataFile.Section section in ini.sections) { try { string sectionName = section.sectionName.ToLowerInvariant(); if (sectionName == "base") { AddGameData(DataStore.HashList, section, GAMEDATA_BASES, true); string baseNick = section.GetSetting("nickname").Str(0); string baseFilePath = flDataPath + Path.DirectorySeparatorChar + section.GetSetting("file").Str(0); LoadRoomData(DataStore, baseNick, baseFilePath); } else if (sectionName == "system") { string baseNick = section.GetSetting("nickname").Str(0).ToLowerInvariant(); AddGameData(DataStore.HashList, section, GAMEDATA_SYSTEMS, true); string file = Directory.GetParent(ini.filePath).FullName + "\\" + section.GetSetting("file").Str(0); ParseSystem(file, log); } } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + iniPath); } } } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + iniPath); } } log.AddLog("Loading ships..."); // Scan ship files and parse ship entries foreach (FLDataFile.Setting flIniEntry in flIni.GetSettings("Data", "ships")) { string iniPath = flDataPath + Path.DirectorySeparatorChar + flIniEntry.Str(0); try { FLDataFile ini = new FLDataFile(iniPath, true); foreach (FLDataFile.Section section in ini.sections) { if (section.sectionName.ToLowerInvariant() == "ship") { AddGameData(DataStore.HashList, section, GAMEDATA_SHIPS, true); string nickName = section.GetSetting("nickname").Str(0); uint hash = FLUtility.CreateID(nickName.ToLowerInvariant()); foreach (FLDataFile.Setting setting in section.settings) { try { if (setting.settingName.ToLowerInvariant() == "da_archetype") { // UTF hardpoints are only really useful to validate the shiparch and ship default loadout. // Don't bother loading them. // UtfFile utf = new UtfFile(flDataPath + Path.DirectorySeparatorChar + setting.Str(0)); // foreach (string hp in utf.hardpoints) // { // DataStore.HardPointList.AddHardPointListRow(hash, hp, ""); // } } else if (setting.settingName.ToLowerInvariant() == "hp_type") { string type = setting.Str(0); for (int i = 1; i < setting.NumValues(); i++) { string hp = setting.Str(i); GameDataSet.HardPointListRow hpInfo = GetHardPointByShipAndHPName(hash, hp); if (hpInfo == null) hpInfo = DataStore.HardPointList.AddHardPointListRow(hash, hp, HardpointClassToGameDataClass(type), "", 0); hpInfo.MountableTypes += " " + type; } } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when reading {1}", ex.Message, setting.desc)); } } } } } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + iniPath); } } log.AddLog("Loading equipment..."); // Scan ini files and parse equipment entries. foreach (FLDataFile.Setting flIniEntry in flIni.GetSettings("Data", "equipment")) { string iniPath = flDataPath + Path.DirectorySeparatorChar + flIniEntry.Str(0); try { FLDataFile ini = new FLDataFile(iniPath, true); foreach (FLDataFile.Section section in ini.sections) { try { string sectionName = section.sectionName.ToLowerInvariant(); // Internal equipment; these are mounted internally. if (sectionName == "engine") { AddGameData(DataStore.HashList, section, GAMEDATA_ENGINES, true); } else if (sectionName == "power") { AddGameData(DataStore.HashList, section, GAMEDATA_POWERGEN, true); } else if (sectionName == "scanner") { AddGameData(DataStore.HashList, section, GAMEDATA_SCANNERS, true); } else if (sectionName == "tractor") { AddGameData(DataStore.HashList, section, GAMEDATA_TRACTORS, true); } else if (sectionName == "cloakingdevice") { AddGameData(DataStore.HashList, section, GAMEDATA_CLOAK, true); } else if (sectionName == "armor") { AddGameData(DataStore.HashList, section, GAMEDATA_ARMOR, true); } else if (sectionName == "internalfx") { if (section.SettingExists("use_sound")) { AddGameData(DataStore.HashList, section, GAMEDATA_SOUND, false); } } // External hardpoints. else if (sectionName == "attachedfx") { AddGameData(DataStore.HashList, section, GAMEDATA_FX, false); } else if (sectionName == "light") { AddGameData(DataStore.HashList, section, GAMEDATA_LIGHTS, false); } else if (sectionName == "gun") { if (section.SettingExists("hp_gun_type")) { string hpType = section.GetSetting("hp_gun_type").Str(0); AddGameData(DataStore.HashList, section, HardpointClassToGameDataClass(hpType), true); DataStore.EquipInfoList.AddEquipInfoListRow( FLUtility.CreateID(section.GetSetting("nickname").Str(0)), HardpointClassToGameDataClass(hpType), hpType); } // Probably an npc gun else { AddGameData(DataStore.HashList, section, GAMEDATA_GEN, false); } } else if (sectionName == "shieldgenerator") { if (section.SettingExists("hp_type")) { string hpType = section.GetSetting("hp_type").Str(0); AddGameData(DataStore.HashList, section, HardpointClassToGameDataClass(hpType), true); DataStore.EquipInfoList.AddEquipInfoListRow( FLUtility.CreateID(section.GetSetting("nickname").Str(0)), HardpointClassToGameDataClass(hpType), hpType); } // Probably an npc shield else { AddGameData(DataStore.HashList, section, GAMEDATA_GEN, false); } } else if (sectionName == "countermeasuredropper") { AddGameData(DataStore.HashList, section, GAMEDATA_CM, true); } else if (sectionName == "thruster") { AddGameData(DataStore.HashList, section, GAMEDATA_THRUSTERS, true); } else if (sectionName == "minedropper") { AddGameData(DataStore.HashList, section, GAMEDATA_MINES, true); } // Cargo and ammo. else if (sectionName == "munition") { AddGameData(DataStore.HashList, section, GAMEDATA_AMMO, true); } else if (sectionName == "repairkit") { AddGameData(DataStore.HashList, section, GAMEDATA_CARGO, true); } else if (sectionName == "countermeasure") { AddGameData(DataStore.HashList, section, GAMEDATA_AMMO, true); } else if (sectionName == "shieldbattery") { AddGameData(DataStore.HashList, section, GAMEDATA_CARGO, true); } else if (sectionName == "mine") { AddGameData(DataStore.HashList, section, GAMEDATA_AMMO, true); } else if (sectionName == "commodity") { AddGameData(DataStore.HashList, section, GAMEDATA_CARGO, true); } // Random stuff I don't know what to do with. else if (sectionName == "shield") { } // ignore this section else if (sectionName == "lootcrate") { } // ignore this section else if (sectionName == "lod") { } // ignore this section - it has no nickname else if (sectionName == "tradelane") { } // ignore this section else if (sectionName == "motor") { } // ignore this section else if (sectionName == "explosion") { } // ignore this section else if (sectionName == "cargopod") { } // ignore this section else if (sectionName == "tradelane") { } // ignore this section else { } } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + iniPath); } } } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + iniPath); } } log.AddLog("Loading factions..."); // Scan ini files and parse faction entries foreach (FLDataFile.Setting flIniEntry in flIni.GetSettings("Data", "groups")) { string iniPath = flDataPath + Path.DirectorySeparatorChar + flIniEntry.Str(0); try { FLDataFile ini = new FLDataFile(iniPath, true); foreach (FLDataFile.Section section in ini.sections) { if (section.sectionName.ToLowerInvariant() == "group") { AddGameData(DataStore.HashList, section, GAMEDATA_FACTIONS, true); } } } catch (Exception e) { log.AddLog("Error '" + e.Message + "' when parsing '" + iniPath); } } foreach (IntPtr hInstance in vDLLs) FreeLibrary(hInstance); vDLLs.Clear(); }
/// <summary> /// Commit pending changes on the CharacterList, BanList, IPList and LoginID /// </summary> /// <param name="dsTable"></param> public void CommitChanges(DamDataSet dsTable, LogRecorderInterface log) { BeginTransaction(); using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM CharacterList", GetConnection())) { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; try { adpt.Update(dsTable.CharacterList); } catch (Exception e) { log.AddLog(String.Format("Error '{0}' when updating db with {1} records", e.Message, dsTable.CharacterList.Count)); } } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM BanList", GetConnection())) { try { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(dsTable.BanList); } catch (Exception e) { log.AddLog("Update of database failed: " + e.Message); } } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM IPList", GetConnection())) { try { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(dsTable.IPList); } catch (Exception e) { log.AddLog("Update of database failed: " + e.Message); } } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM LoginIDList", GetConnection())) { try { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(dsTable.LoginIDList); } catch (Exception e) { log.AddLog("Update of database failed: " + e.Message); } } using (SQLiteDataAdapter adpt = new SQLiteDataAdapter("SELECT * FROM LoginIDBanList", GetConnection())) { try { SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adpt); builder.ConflictOption = ConflictOption.OverwriteChanges; adpt.Update(dsTable.LoginIDBanList); } catch (Exception e) { log.AddLog("Update of database failed: " + e.Message); } } EndTransaction(); }
/// <summary> /// generate online statistics for online players ... /// </summary> private void GenerateOnlinePlayerStats(LogRecorderInterface log) { //***** assemble the sorted lists for both tables ... SortedDictionary <string, FLHookSocket.PlayerInfo> char_list = new SortedDictionary <string, FLHookSocket.PlayerInfo>(); SortedDictionary <string, List <string> > system_list = new SortedDictionary <string, List <string> >(); string[] playerlistFields = AppSettings.Default.setStatPlayerListShowFields.Split(';'); bool column0 = true; int slots_in_use = -1; lock (m_flHookCmdr.playerInfoList) { slots_in_use = m_flHookCmdr.playerInfoList.Count; //***** store the hook characters information into both lists ... foreach (KeyValuePair <int, FLHookSocket.PlayerInfo> kvp in m_flHookCmdr.playerInfoList) { string character = HtmlEncode(kvp.Value.charname); if (character != "-") { string system = HtmlEncode(m_gameData.GetItemDescByNickNameX(kvp.Value.system)); char_list.Add(character, kvp.Value); if (!system_list.ContainsKey(system)) { system_list.Add(system, new List <string>()); } system_list[system].Add(character); } } } //***** generate the html contents ... string contents = "<html><head><title>Players Online</title><style type=text/css>";; contents += ".Column0 {FONT-FAMILY: Tahoma; FONT-SIZE: 10pt; TEXT-ALIGN: left; COLOR: #000000; BACKGROUND: #FFFFFF;}"; contents += ".Column1 {FONT-FAMILY: Tahoma; FONT-SIZE: 10pt; TEXT-ALIGN: left; COLOR: #000000; BACKGROUND: #FFFFFF;}"; contents += "</style>"; contents += "</head><body>"; if (AppSettings.Default.setStatPlayerListTimeUTC) { contents += "<i>last update: " + DateTime.UtcNow.ToString() + " [UTC]</i><br><br>"; } else { contents += "<i>last update: " + DateTime.Now.ToString() + "</i><br><br>"; } contents += "<i>used slots: " + String.Format("{0}", slots_in_use) + " </i><br><br><br><br>"; if (AppSettings.Default.setStatPlayerListShowCharsByName) { contents += "<size=5><b><u>Characters by Name</u></b></size><br><br>"; contents += "<table width=\"90%\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">"; contents += "<tr>"; foreach (string field in playerlistFields) { if (column0) { contents += "<th bgcolor=\"#ECE9D8\" align=\"left\"><font face=\"Tahoma\" color=\"#000000\" size=\"2\">"; } else { contents += "<th bgcolor=\"#ECE9D8\" align=\"left\"><font face=\"Tahoma\" color=\"#000000\" size=\"2\">"; } contents += field; contents += "</font></th>"; column0 = !column0; } column0 = true; contents += "</tr>"; foreach (KeyValuePair <string, FLHookSocket.PlayerInfo> kvp in char_list) { contents += "<tr>"; foreach (string field in playerlistFields) { string toAdd = string.Empty; switch (field) { case "Character": toAdd = kvp.Key; break; case "System": toAdd = m_gameData.GetItemDescByNickNameX(kvp.Value.system); break; case "ID": toAdd = kvp.Value.id.ToString(); break; case "IP": toAdd = kvp.Value.ip.ToString(); break; case "Ping": toAdd = kvp.Value.ping.ToString(); break; case "Loss": toAdd = kvp.Value.loss.ToString(); break; case "Fluct": toAdd = kvp.Value.ping_fluct.ToString(); break; case "Saturation": toAdd = kvp.Value.saturation.ToString(); break; case "TxQueue": toAdd = kvp.Value.txqueue.ToString(); break; case "Lag": toAdd = kvp.Value.lag.ToString(); break; } //toAdd = HtmlEncode(toAdd); contents += "<td class=\"column" + (column0 ? "0" : "1") + "\">"; contents += toAdd; contents += "</td>"; column0 = !column0; } contents += "</tr>"; } contents += "</table><br><br><br><br>"; } if (AppSettings.Default.setStatPlayerListShowCharsBySys) { contents += "<size=5><b><u>Characters by System</u></b></size><br><br>"; contents += "<table width=\"90%\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">"; contents += "<tr><th bgcolor=\"#ECE9D8\" align=\"left\"><font face=\"Tahoma\" color=\"#000000\" size=\"2\">Character</font></th><th bgcolor=\"#ECE9D8\" align=\"left\"><font face=\"Tahoma\" color=\"#000000\" size=\"2\">System</font></th></tr>"; foreach (KeyValuePair <string, List <string> > kvp in system_list) { kvp.Value.Sort(); foreach (string character in kvp.Value) { contents += "<tr><td class=\"column0\">" + character + "</td><td class=\"column1\">" + kvp.Key + "</td></tr>"; } } contents += "</table>"; } contents += "</body></html>"; //***** open the stream and write the contents ... String online_players_file = String.Format("{0}\\players_online.html", AppSettings.Default.setStatisticsDir); StreamWriter writer = new StreamWriter(online_players_file); try { writer.Write(contents); } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' in GenerateOnlinePlayerStats", ex.Message)); } finally { writer.Close(); } }
/// <summary> /// Scan the historical character lists and build a list containing the time each players /// was online within the specified time period. /// </summary> /// <returns>Returns the path to an HTML file cot </returns> private UIDataSet CalcActivity(DateTime startDate, DateTime endDate, BackgroundWorker bgWkr, LogRecorderInterface log) { UIDataSet results = new UIDataSet(); try { // Keep two tables; one containing the records when they are first detected and // the other with the most recent data. DamDataSet oldestData = new DamDataSet(); DamDataSet newestData = new DamDataSet(); Dictionary <string, int> onLineTimes = new Dictionary <string, int>(); // Scan from oldest date to newest reading character lists from the database // and building the online time list. for (DateTime date = startDate.Subtract(new TimeSpan(90, 0, 0, 0)); date <= endDate; date = date.AddDays(1)) { if (bgWkr.CancellationPending) { return(null); } using (DamDataSet tds = new DamDataSet()) { if (dataAccess.GetCharacterHistory(date, tds.CharacterList)) { foreach (DamDataSet.CharacterListRow tempCharRecord in tds.CharacterList) { if (bgWkr.CancellationPending) { return(null); } // Record the oldest data. Don't update if data is already present. DamDataSet.CharacterListRow oldCharRecord = oldestData.CharacterList.FindByCharPath(tempCharRecord.CharPath); if (oldCharRecord == null) { oldestData.CharacterList.AddCharacterListRow(tempCharRecord.CharName, tempCharRecord.CharPath, tempCharRecord.Created, tempCharRecord.Updated, tempCharRecord.AccID, tempCharRecord.IsDeleted, tempCharRecord.Location, tempCharRecord.Rank, tempCharRecord.Money, tempCharRecord.Ship, tempCharRecord.AccDir, tempCharRecord.OnLineSecs, tempCharRecord.LastOnLine); } // Keep updating to find the newest record from before the startDate else if (tempCharRecord.LastOnLine < startDate) { oldCharRecord.Created = tempCharRecord.Created; oldCharRecord.Updated = tempCharRecord.Updated; oldCharRecord.IsDeleted = tempCharRecord.IsDeleted; oldCharRecord.Location = tempCharRecord.Location; oldCharRecord.Rank = tempCharRecord.Rank; oldCharRecord.Money = tempCharRecord.Money; oldCharRecord.Ship = tempCharRecord.Ship; oldCharRecord.OnLineSecs = tempCharRecord.OnLineSecs; oldCharRecord.LastOnLine = tempCharRecord.LastOnLine; } } } } } newestData = oldestData.Copy() as DamDataSet; for (DateTime date = startDate; date <= endDate; date = date.AddDays(1)) { if (bgWkr.CancellationPending) { return(null); } using (DamDataSet tds = new DamDataSet()) { if (dataAccess.GetCharacterHistory(date, tds.CharacterList)) { foreach (DamDataSet.CharacterListRow tempCharRecord in tds.CharacterList) { if (bgWkr.CancellationPending) { return(null); } // Record the newest data. Keep updating with the most recent records. // Calculate the online seconds here to deal with the situation where // a character has been deleted then re-created. DamDataSet.CharacterListRow charRecord = newestData.CharacterList.FindByCharPath(tempCharRecord.CharPath); if (charRecord == null) { charRecord = newestData.CharacterList.AddCharacterListRow(tempCharRecord.CharName, tempCharRecord.CharPath, tempCharRecord.Created, tempCharRecord.Updated, tempCharRecord.AccID, tempCharRecord.IsDeleted, tempCharRecord.Location, tempCharRecord.Rank, tempCharRecord.Money, tempCharRecord.Ship, tempCharRecord.AccDir, tempCharRecord.OnLineSecs, tempCharRecord.LastOnLine); } else { int onLineTime = tempCharRecord.OnLineSecs - charRecord.OnLineSecs; if (onLineTime < 0) { onLineTime = 0; } if (onLineTimes.ContainsKey(charRecord.CharPath)) { onLineTimes[charRecord.CharPath] += onLineTime; } else { onLineTimes[charRecord.CharPath] = onLineTime; } charRecord.Created = tempCharRecord.Created; charRecord.Updated = tempCharRecord.Updated; charRecord.IsDeleted = tempCharRecord.IsDeleted; charRecord.Location = tempCharRecord.Location; charRecord.Rank = tempCharRecord.Rank; charRecord.Money = tempCharRecord.Money; charRecord.Ship = tempCharRecord.Ship; charRecord.OnLineSecs = tempCharRecord.OnLineSecs; charRecord.LastOnLine = tempCharRecord.LastOnLine; } } } } } // Build the results data set. This data set will be used to generate individual activity reports. foreach (DamDataSet.CharacterListRow newestCharRecord in newestData.CharacterList) { if (bgWkr.CancellationPending) { return(null); } DamDataSet.CharacterListRow oldestCharRecord = oldestData.CharacterList.FindByCharPath(newestCharRecord.CharPath); if (oldestCharRecord != null) { int rankDelta = newestCharRecord.Rank - oldestCharRecord.Rank; int moneyDelta = newestCharRecord.Money - oldestCharRecord.Money; int onLineSecsDelta = 0; if (onLineTimes.ContainsKey(oldestCharRecord.CharPath)) { onLineSecsDelta = onLineTimes[oldestCharRecord.CharPath]; } results.StatPlayer.AddStatPlayerRow(newestCharRecord.CharName, new TimeSpan(0, 0, onLineSecsDelta), moneyDelta, rankDelta, newestCharRecord.LastOnLine, onLineSecsDelta); } } } catch (Exception ex) { log.AddLog(String.Format("Error '{0}' when calculating activity statistics", ex.Message)); return(null); } return(results); }