/// <summary> /// エクスポート処理 /// </summary> /// <param name="WorkArea"></param> /// <returns></returns> public bool Export(IWorkArea WorkArea) { var sb = new StringBuilder(); var exists = false; sb.Append(@"http://www.x4-game.com/#/station-calculator?"); // モジュール情報を追加 sb.Append("l=@"); var modules = WorkArea.StationData.ModulesInfo.Modules .Where(x => x.Module.ModuleType.ModuleTypeID != "connectionmodule" && x.Module.ModuleType.ModuleTypeID != "ventureplatform" && x.Module.ID != "module_gen_dock_m_venturer_01"); foreach (var module in modules) { sb.Append($"$module-{module.Module.ID},count:{module.ModuleCount};,"); exists = true; } if (exists) { sb.Length -= 2; } SelectStringDialog.ShowDialog("Lang:StationCalculatorExport_Title", "Lang:StationCalculatorExport_Description", sb.ToString(), hideCancelButton: true); return(true); }
/// <summary> /// 製品価格を設定 /// </summary> /// <param name="WorkArea"></param> /// <param name="saveData"></param> private void SetWarePrice(IWorkArea WorkArea, SaveDataStationItem saveData) { foreach (var ware in saveData.XElement.XPathSelectElements("/economylog/*[not(self::cargo)]")) { var wareID = ware.Attribute("ware").Value; var prod = WorkArea.StationData.ProductsInfo.Products.FirstOrDefault(x => x.Ware.WareID == wareID); if (prod != null) { prod.UnitPrice = long.Parse(ware.Attribute("price").Value); } } }
/// <summary> /// インスタンス作成 /// </summary> /// <param name="path">読み込み対象ファイルパス</param> /// <param name="WorkArea">作業エリア</param> /// <returns>保存ファイル読み込みクラスのインスタンス</returns> public static ISaveDataReader CreateSaveDataReader(string path, IWorkArea WorkArea) { var version = GetVersion(path); ISaveDataReader ret = version switch { 0 => new SaveDataReader0(WorkArea), 1 => new SaveDataReader1(WorkArea), _ => new SaveDataReader2(WorkArea), }; ret.Path = path; return(ret); }
/// <summary> /// インポート実行メイン /// </summary> /// <param name="WorkArea"></param> /// <param name="saveData"></param> /// <returns></returns> private bool ImportMain(IWorkArea WorkArea, SaveDataStationItem saveData) { // モジュール一覧を設定 SetModules(WorkArea, saveData); // 製品価格を設定 SetWarePrice(WorkArea, saveData); // 保管庫割当状態を設定 SetStorageAssign(WorkArea, saveData); WorkArea.Title = saveData.StationName; return(true); }
/// <summary> /// 保管庫割当状態を設定 /// </summary> /// <param name="WorkArea"></param> /// <param name="saveData"></param> private void SetStorageAssign(IWorkArea WorkArea, SaveDataStationItem saveData) { foreach (var ware in saveData.XElement.XPathSelectElements("overrides/max/ware")) { var wareID = ware.Attribute("ware").Value; var storage = WorkArea.StationData.StorageAssignInfo.StorageAssign.FirstOrDefault(x => x.WareID == wareID); if (storage != null) { var amount = long.Parse(ware.Attribute("amount").Value); storage.AllocCount = amount; } } }
/// <summary> /// インポート実行 /// </summary> /// <param name="WorkArea">作業エリア</param> /// <returns>インポートに成功したか</returns> public bool Import(IWorkArea WorkArea) { bool ret; try { ret = ImportMain(WorkArea, Stations[_StationIdx]); _StationIdx++; } catch { ret = false; } return(ret); }
/// <summary> /// 上書き保存 /// </summary> /// <param name="WorkArea">作業エリア</param> public bool Save(IWorkArea WorkArea) { if (string.IsNullOrEmpty(SaveFilePath)) { return(SaveAs(WorkArea)); } try { SaveMain(WorkArea); return(true); } catch (Exception e) { LocalizedMessageBox.Show("Lang:MainWindow_SaveDataWriteFailureMessage", "Lang:Common_MessageBoxTitle_Error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, e.Message, e.StackTrace ?? ""); } return(false); }
/// <summary> /// 名前を付けて保存 /// </summary> /// <param name="WorkArea">作業エリア</param> public bool SaveAs(IWorkArea WorkArea) { var dlg = new SaveFileDialog(); dlg.Filter = "X4 Station calculator data (*.x4)|*.x4|All Files|*.*"; if (dlg.ShowDialog() == true) { SaveFilePath = dlg.FileName; try { SaveMain(WorkArea); WorkArea.Title = Path.GetFileNameWithoutExtension(SaveFilePath); return(true); } catch (Exception e) { LocalizedMessageBox.Show("Lang:MainWindow_SaveDataWriteFailureMessage", "Lang:Common_MessageBoxTitle_Error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, e.Message, e.StackTrace ?? ""); } } return(false); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="WorkArea">作業エリア</param> public SaveDataReader1(IWorkArea WorkArea) : base(WorkArea) { }
/// <summary> /// コンストラクタ /// </summary> /// <param name="WorkArea">作業エリア</param> public SaveDataReader0(IWorkArea WorkArea) { _WorkArea = WorkArea; }
/// <summary> /// 保存処理メイン /// </summary> /// <param name="WorkArea"></param> private void SaveMain(IWorkArea WorkArea) { // フォルダが無ければ作る Directory.CreateDirectory(Path.GetDirectoryName(SaveFilePath)); using var conn = new DBConnection(SaveFilePath); conn.BeginTransaction(db => { // 保存用テーブル初期化 db.Execute("DROP TABLE IF EXISTS Common"); db.Execute("DROP TABLE IF EXISTS Modules"); db.Execute("DROP TABLE IF EXISTS Equipments"); db.Execute("DROP TABLE IF EXISTS Products"); db.Execute("DROP TABLE IF EXISTS BuildResources"); db.Execute("DROP TABLE IF EXISTS StorageAssign"); db.Execute("DROP TABLE IF EXISTS StationSettings"); db.Execute("CREATE TABLE Common(Item TEXT, Value INTEGER)"); db.Execute("CREATE TABLE Modules(Row INTEGER, ModuleID TEXT, Count INTEGER)"); db.Execute("CREATE TABLE Equipments(Row INTEGER, EquipmentID TEXT)"); db.Execute("CREATE TABLE Products(WareID TEXT, Price INTEGER, NoBuy INTEGER, NoSell INTEGER)"); db.Execute("CREATE TABLE BuildResources(WareID TEXT, Price INTEGER, NoBuy INTEGER)"); db.Execute("CREATE TABLE StorageAssign(WareID TEXT, AllocCount INTEGER)"); db.Execute("CREATE TABLE StationSettings(Key TEXT, Value TEXT)"); // ファイルフォーマットのバージョン保存 db.Execute("INSERT INTO Common(Item, Value) VALUES('FormatVersion', 2)"); // ステーションの設定保存 db.Execute("INSERT INTO StationSettings(Key, Value) VALUES('IsHeadquarters', :IsHeadquarters)", new { IsHeadquarters = WorkArea.StationData.Settings.IsHeadquarters.ToString() }); db.Execute("INSERT INTO StationSettings(Key, Value) VALUES('Sunlight', :Sunlight)", WorkArea.StationData.Settings); db.Execute("INSERT INTO StationSettings(Key, Value) VALUES('ActualWorkforce', :Actual)", WorkArea.StationData.Settings.Workforce); db.Execute("INSERT INTO StationSettings(Key, Value) VALUES('AlwaysMaximumWorkforce', :AlwaysMaximum)", new { AlwaysMaximum = WorkArea.StationData.Settings.Workforce.AlwaysMaximum.ToString() }); // モジュール保存 foreach (var(module, i) in WorkArea.StationData.ModulesInfo.Modules.Select((module, i) => (module, i))) { const string sql1 = "INSERT INTO Modules(Row, ModuleID, Count) Values(:Row, :ModuleID, :ModuleCount)"; db.Execute(sql1, new { Row = i, ModuleID = module.Module.ID, ModuleCount = module.ModuleCount }); if (module.EditStatus == EditStatus.Edited) { module.EditStatus |= EditStatus.Saved; } const string sql2 = "INSERT INTO Equipments(Row, EquipmentID) Values(:Row, :EquipmentID)"; var param2 = module.Equipments.AllEquipments.Select(e => new { Row = i, EquipmentID = e.ID }); db.Execute(sql2, param2); } // 価格保存 SqlMapper.AddTypeHandler(new WareTypeHandler()); foreach (var product in WorkArea.StationData.ProductsInfo.Products) { if (product.EditStatus == EditStatus.Edited) { product.EditStatus |= EditStatus.Saved; } const string sql = "INSERT INTO Products(WareID, Price, NoBuy, NoSell) Values(:Ware, :UnitPrice, :NoBuy, :NoSell)"; db.Execute(sql, product); } // 建造リソース保存 foreach (var resource in WorkArea.StationData.BuildResourcesInfo.BuildResources) { const string sql = "INSERT INTO BuildResources(WareID, Price, NoBuy) Values(:Ware, :UnitPrice, :NoBuy)"; db.Execute(sql, resource); if (resource.EditStatus == EditStatus.Edited) { resource.EditStatus |= EditStatus.Saved; } } // 保管庫割当情報保存 foreach (var assign in WorkArea.StationData.StorageAssignInfo.StorageAssign) { const string sql = "INSERT INTO StorageAssign(WareID, AllocCount) Values(:WareID, :AllocCount)"; db.Execute(sql, assign); if (assign.EditStatus == EditStatus.Edited) { assign.EditStatus |= EditStatus.Saved; } } }); }
/// <summary> /// モジュール一覧を設定 /// </summary> /// <param name="WorkArea"></param> /// <param name="saveData"></param> private void SetModules(IWorkArea WorkArea, SaveDataStationItem saveData) { var modParam = new SQLiteCommandParameters(1); var eqParam = new SQLiteCommandParameters(3); var moduleCount = 0; foreach (var entry in saveData.XElement.XPathSelectElements("construction/sequence/entry")) { var index = int.Parse(entry.Attribute("index").Value); modParam.Add("macro", System.Data.DbType.String, entry.Attribute("macro").Value); foreach (var equipmet in entry.XPathSelectElements("upgrades/groups/*")) { eqParam.Add("index", System.Data.DbType.Int32, index); eqParam.Add("macro", System.Data.DbType.String, equipmet.Attribute("macro").Value); eqParam.Add("count", System.Data.DbType.Int32, int.Parse(equipmet.Attribute("exact")?.Value ?? "1")); } moduleCount++; } var modules = new List <ModulesGridItem>(moduleCount); // モジュール追加 { var query = @" SELECT ModuleID FROM Module WHERE Macro = :macro"; X4Database.Instance.ExecQuery(query, modParam, (dr, _) => { var module = Module.Get((string)dr["ModuleID"]); if (module != null) { modules.Add(new ModulesGridItem(module)); } }); } // 装備追加 { var query = @" SELECT EquipmentID, :index AS 'Index', :count AS Count FROM Equipment WHERE MacroName = :macro"; X4Database.Instance.ExecQuery(query, eqParam, (dr, _) => { var index = (int)(long)dr["Index"] - 1; var moduleEquipment = modules[index].ModuleEquipment; var equipment = Equipment.Get((string)dr["EquipmentID"]); if (equipment == null) { return; } var count = (long)dr["Count"]; moduleEquipment.AddEquipment(equipment, count); }); } // 同一モジュールをマージ var dict = new Dictionary <int, (int, Module, ModuleProduction, long)>(); foreach (var(module, idx) in modules.Select((x, idx) => (x, idx))) { var hash = HashCode.Combine(module.Module, module.SelectedMethod); if (dict.ContainsKey(hash)) { var tmp = dict[hash]; tmp.Item4 += module.ModuleCount; dict[hash] = tmp; } else { dict.Add(hash, (idx, module.Module, module.SelectedMethod, module.ModuleCount)); } } // モジュール一覧に追加 var range = dict.Select(x => (x.Value)).OrderBy(x => x.Item1).Select(x => new ModulesGridItem(x.Item2, x.Item3, x.Item4)); WorkArea.StationData.ModulesInfo.Modules.AddRange(range); }