diff --git a/App.config b/App.config index 2474c97..66647a9 100644 --- a/App.config +++ b/App.config @@ -16,6 +16,9 @@ + + + diff --git a/DFPl.csproj b/DFPl.csproj index f12320b..298068d 100644 --- a/DFPl.csproj +++ b/DFPl.csproj @@ -73,14 +73,26 @@ Form1.cs + + Form + + + Form2.cs + + + Form1.cs + Designer Form1.cs + + Form2.cs + ResXFileCodeGenerator Resources.Designer.cs @@ -92,6 +104,9 @@ True + + PreserveNewest + SettingsSingleFileGenerator Settings.Designer.cs @@ -106,6 +121,9 @@ + + 5.1.0 + 1.2.5 diff --git a/DFPl.sln b/DFPl.sln new file mode 100644 index 0000000..1a3f6f0 --- /dev/null +++ b/DFPl.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32519.379 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFPl", "DFPl.csproj", "{F45DC1BE-8065-435C-85FC-0E6BD4B76424}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + Share|Any CPU = Share|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F45DC1BE-8065-435C-85FC-0E6BD4B76424}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F45DC1BE-8065-435C-85FC-0E6BD4B76424}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F45DC1BE-8065-435C-85FC-0E6BD4B76424}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F45DC1BE-8065-435C-85FC-0E6BD4B76424}.Release|Any CPU.Build.0 = Release|Any CPU + {F45DC1BE-8065-435C-85FC-0E6BD4B76424}.Share|Any CPU.ActiveCfg = Share|Any CPU + {F45DC1BE-8065-435C-85FC-0E6BD4B76424}.Share|Any CPU.Build.0 = Share|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7E103C92-EA0E-4625-9188-6D17B0AD5E4B} + EndGlobalSection +EndGlobal diff --git a/Form1.Designer.cs b/Form1.Designer.cs index 4f5303b..51b43e2 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -38,6 +38,11 @@ private void InitializeComponent() this.button2 = new System.Windows.Forms.Button(); this.button4 = new System.Windows.Forms.Button(); this.listBox1 = new System.Windows.Forms.ListBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.button5 = new System.Windows.Forms.Button(); + this.button6 = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); // @@ -92,14 +97,54 @@ private void InitializeComponent() this.listBox1.FormattingEnabled = true; this.listBox1.Items.AddRange(new object[] { resources.GetString("listBox1.Items"), - resources.GetString("listBox1.Items1")}); + resources.GetString("listBox1.Items1"), + resources.GetString("listBox1.Items2"), + resources.GetString("listBox1.Items3"), + resources.GetString("listBox1.Items4")}); resources.ApplyResources(this.listBox1, "listBox1"); this.listBox1.Name = "listBox1"; // + // groupBox1 + // + resources.ApplyResources(this.groupBox1, "groupBox1"); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.TabStop = false; + // + // groupBox2 + // + resources.ApplyResources(this.groupBox2, "groupBox2"); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.TabStop = false; + // + // label1 + // + resources.ApplyResources(this.label1, "label1"); + this.label1.ForeColor = System.Drawing.Color.Indigo; + this.label1.Name = "label1"; + // + // button5 + // + resources.ApplyResources(this.button5, "button5"); + this.button5.Name = "button5"; + this.button5.UseVisualStyleBackColor = true; + this.button5.Click += new System.EventHandler(this.button5_Click); + // + // button6 + // + resources.ApplyResources(this.button6, "button6"); + this.button6.Name = "button6"; + this.button6.UseVisualStyleBackColor = true; + this.button6.Click += new System.EventHandler(this.button6_Click); + // // Form1 // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; resources.ApplyResources(this, "$this"); + this.Controls.Add(this.button6); + this.Controls.Add(this.button5); + this.Controls.Add(this.label1); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); this.Controls.Add(this.listBox1); this.Controls.Add(this.button4); this.Controls.Add(this.button2); @@ -110,6 +155,7 @@ private void InitializeComponent() this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Name = "Form1"; this.ShowIcon = false; + this.Load += new System.EventHandler(this.Form1_Load); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -127,6 +173,11 @@ private void InitializeComponent() private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button4; private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button5; + private System.Windows.Forms.Button button6; } } diff --git a/Form1.cs b/Form1.cs index 3ef1486..aebb070 100644 --- a/Form1.cs +++ b/Form1.cs @@ -1,168 +1,231 @@ using System; +using System.Diagnostics; using System.IO; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; +using System.IO.Compression; using System.Windows.Forms; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Threading; -using System.Reflection; -using Reloaded.Injector; +using DFPl.Models; using IWshRuntimeLibrary; -using System.IO.Compression; +using NLog; +using Reloaded.Injector; namespace DFPl { public partial class Form1 : Form { - string Version = "DFPL 0.1.0"; - public Form1(string[] Ags) + // Constants + private const string Version = "DFPL 0.1.3"; + private const string GamePathSetting = "Gamepath"; + private const string ShortcutName = "Запуск DF.lnk"; + private const string ShortcutIcon = "ico\\DFPLQS.ico"; + private const string QuietStartArg = "-quiet_start"; + private const string GameVersionStr = "@Версия игры "; + private const string GameVersionStrN = "неизвестна"; + + // Fields + private readonly string[] _args; + private readonly Logger _logger; + + + + public Form1(string args = "") + { + _args = args.Split('|'); + _logger = LogManager.GetCurrentClassLogger(); + _logger.Info("App started with args: " + String.Join(", ", args)); + + InitializeComponent(); + textBox2.Text = DFPl.Properties.Settings.Default[GamePathSetting].ToString(); + this.Text = Version; + } + + private void button1_Click(object sender, EventArgs e) { - bool SL = false; - foreach (string A in Ags) + DFPl.Properties.Settings.Default[GamePathSetting] = textBox2.Text; + DFPl.Properties.Settings.Default.Save(); + + try { - if (A == "-quiet_start") - SL = true; + var game = new Game(DFPl.Properties.Settings.Default[GamePathSetting].ToString(), _logger); + game.Start(); } - if (SL) + catch (Exception ex) { - DFSTART(); - Application.Exit(); + _logger.Error("Failed to start game", ex); + MessageBox.Show("Failed to start game!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); } - else + } + + private void button2_Click(object sender, EventArgs e) + { + try { - InitializeComponent(); + CreateQuietStartShortcut(); + } + catch (Exception ex) + { + _logger.Error("Failed to create quiet start shortcut", ex); + MessageBox.Show("Failed to create quiet start shortcut!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); } - textBox2.Text = DFPl.Properties.Settings.Default["Gamepath"].ToString(); - this.Text = Version; - } private void button3_Click(object sender, EventArgs e) { folderBrowserDialog1.ShowDialog(); textBox2.Text = folderBrowserDialog1.SelectedPath; + DFPl.Properties.Settings.Default[GamePathSetting] = folderBrowserDialog1.SelectedPath; + DFPl.Properties.Settings.Default.Save(); + _logger.Info("New path set and saved. Path: " + DFPl.Properties.Settings.Default[GamePathSetting].ToString()); + var game = new Game(DFPl.Properties.Settings.Default[GamePathSetting].ToString(), _logger); + string GV = game.DeterminingGameVersion(); + if (GV != "") + label1.Text = GameVersionStr + GV; + else + label1.Text = GameVersionStr + GameVersionStrN; } - private void button1_Click(object sender, EventArgs e) + + // TODO + // 1. Download localization from the server + // 2. Request avalible versions from the server + private void button4_Click(object sender, EventArgs e) { - DFPl.Properties.Settings.Default["Gamepath"] = textBox2.Text; + string gamePath = textBox2.Text; + DFPl.Properties.Settings.Default["Gamepath"] = gamePath; DFPl.Properties.Settings.Default.Save(); - DFSTART(); - } - private void DFSTART() - { - string GP = DFPl.Properties.Settings.Default["Gamepath"].ToString(); - if (System.IO.File.Exists(GP + "\\Dwarf Fortress.exe")) + + if (!System.IO.File.Exists(gamePath + "\\Dwarf Fortress.exe")) + { + _logger.Error("Game file not found at path: " + gamePath); + MessageBox.Show("Game file not found at path!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + string localizationFile = ""; + + switch (listBox1.SelectedItem?.ToString()) { - String strDLLName = GP + "\\df-steam-translate-hook.dll"; - if (System.IO.File.Exists(GP + "\\df-steam-translate-hook.dll")) + case ("Dwarf Fortress v50.02 - Локализация DFRUS v0.1"): + localizationFile = "Dwarf Fortress v50.02__v0.1_DFRUS.zip"; + break; + case ("Dwarf Fortress v50.03 - Локализация DFRUS v0.1"): + localizationFile = "Dwarf Fortress v50.03__v0.1_DFRUS.zip"; + break; + case ("Dwarf Fortress v50.03 - Локализация DFRUS v0.2"): + localizationFile = "Dwarf Fortress v50.03__v0.2_DFRUS.zip"; + break; + case ("Переводы из мастерской - UNIT"): + localizationFile = "WorkshopMod.zip"; + break; + case ("Dwarf Fortress v50.03 - Локализация DFRUS v0.3"): + localizationFile = "Dwarf Fortress v50.03__v0.3_DFRUS.zip"; + break; + } + + if (localizationFile == "") + { + _logger.Error("No localization file selected"); + MessageBox.Show("No localization file selected!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + string localizationArchivePath = Environment.CurrentDirectory + @"\loc\" + localizationFile; + if (!System.IO.File.Exists(localizationArchivePath)) + { + _logger.Error("Localization archive not found at path: " + localizationArchivePath); + MessageBox.Show("Localization archive not found!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + try + { + using (ZipArchive archive = ZipFile.OpenRead(localizationArchivePath)) { - try + foreach (var archiveEntry in archive.Entries) { - ProcessStartInfo startInfo = new ProcessStartInfo(); - startInfo.FileName = GP + "\\Dwarf Fortress.exe"; - startInfo.CreateNoWindow = false; - startInfo.UseShellExecute = true; - startInfo.WorkingDirectory = GP; - Process DF = Process.Start(startInfo); - int ProcID = DF.Id; - try + string fullPath = Path.Combine(gamePath, archiveEntry.FullName); + if (archiveEntry.Name == "") { - Injector injector = new Injector(DF); - injector.Inject(strDLLName); - injector.Dispose(); + Directory.CreateDirectory(fullPath); } - catch + else { - MessageBox.Show("Неудалось применить моды!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); + archiveEntry.ExtractToFile(fullPath, true); } } - catch - { - MessageBox.Show("Не удалось запустить игру!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - } - else - { - MessageBox.Show("Перевод не найден!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); } + + _logger.Info("Localization installed at path: " + gamePath); + MessageBox.Show("Localization installed!", "Done!", MessageBoxButtons.OK, MessageBoxIcon.Information); } - else + catch (Exception ex) { - MessageBox.Show("Файл игры не найден!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.Error("Error installing localization", ex); + MessageBox.Show("Error installing localization!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void button2_Click(object sender, EventArgs e) + private void CreateQuietStartShortcut() { - object shDesktop = (object)"Desktop"; + string appPath = Application.StartupPath; + string shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), ShortcutName); + string exePath = Path.Combine(appPath, "DFPl.exe"); + + if (System.IO.File.Exists(shortcutPath)) + { + System.IO.File.Delete(shortcutPath); + } + WshShell shell = new WshShell(); - string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + @"\Запуск DF.lnk"; - IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress); - shortcut.TargetPath = Environment.CurrentDirectory + @"\DFPL.exe"; - shortcut.Arguments = "-quiet_start"; - shortcut.IconLocation = Environment.CurrentDirectory + @"\ico\DFPLQS.ico"; + IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath); + shortcut.Description = "DFPl Quiet Start"; + shortcut.TargetPath = exePath; + shortcut.WorkingDirectory = appPath; + shortcut.Arguments = QuietStartArg; + shortcut.IconLocation = Path.Combine(appPath, ShortcutIcon); shortcut.Save(); } - private void button4_Click(object sender, EventArgs e) + private void Form1_Load(object sender, EventArgs e) { - DFPl.Properties.Settings.Default["Gamepath"] = textBox2.Text; - DFPl.Properties.Settings.Default.Save(); - string GP = DFPl.Properties.Settings.Default["Gamepath"].ToString(); - if (System.IO.File.Exists(GP + "\\Dwarf Fortress.exe")) + //globalKeyboardHook gkh = new globalKeyboardHook(); + ////Keys[] keys = {Keys.LShiftKey, Keys.F5}; + //gkh.HookedKeys.Add(Keys.PageDown); + //gkh.KeyUp += new KeyEventHandler(gkh_KeyUp); + if (_args.Length > 0 && _args[0] == QuietStartArg) { - string NMLOC = ""; - switch (listBox1.SelectedItem.ToString()) - { - case ("Dwarf Fortress v50.02 - Локализация DFRUS"): - NMLOC = "Dwarf Fortress v50.02__v1_DFRUS.zip"; - break; - case ("Dwarf Fortress v50.03 - Локализация DFRUS"): - NMLOC = "Dwarf Fortress v50.03__v1_DFRUS.zip"; - break; - } - if (NMLOC != "") + DFPl.Properties.Settings.Default[GamePathSetting] = textBox2.Text; + DFPl.Properties.Settings.Default.Save(); + + try { - try - { - using (ZipArchive archive = ZipFile.OpenRead(Environment.CurrentDirectory + @"\loc\" + NMLOC)) - { - foreach (var archiveEntry in archive.Entries) - { - string fullPath = Path.Combine(GP, archiveEntry.FullName); - if (archiveEntry.Name == "") - { - Directory.CreateDirectory(fullPath); - } - else - { - archiveEntry.ExtractToFile(fullPath, true); - } - } - } - MessageBox.Show("Локализация установлена!", "Успех!", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - catch - { - MessageBox.Show("Неудалось установить локализацию!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); - } + var game = new Game(DFPl.Properties.Settings.Default[GamePathSetting].ToString(), _logger); + game.Start(); } - else + catch (Exception ex) { - MessageBox.Show("Необходимо выбрать версию!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.Error("Failed to start game", ex); + MessageBox.Show("Failed to start game!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Information); } + + //Close(); } - else - { - MessageBox.Show("Файл игры не найден!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information); - } + } + + private void gkh_KeyUp(object sender, KeyEventArgs e) + { + var game = new Game(DFPl.Properties.Settings.Default[GamePathSetting].ToString(), _logger); + game.INEJ(); + } + + private void button5_Click(object sender, EventArgs e) + { + + } + + private void button6_Click(object sender, EventArgs e) + { + var game = new Game(DFPl.Properties.Settings.Default[GamePathSetting].ToString(), _logger); + game.INEJ(); } } } diff --git a/Form1.resx b/Form1.resx index 94db228..56d2995 100644 --- a/Form1.resx +++ b/Form1.resx @@ -119,7 +119,7 @@ - 270, 145 + 266, 255 75, 23 @@ -141,7 +141,7 @@ $this - 6 + 11 @@ -169,7 +169,7 @@ $this - 4 + 9 12, 57 @@ -190,7 +190,7 @@ $this - 5 + 10 17, 17 @@ -220,10 +220,10 @@ $this - 3 + 8 - 170, 145 + 166, 255 94, 23 @@ -244,13 +244,13 @@ $this - 2 + 7 - 12, 145 + 85, 166 - 152, 23 + 175, 23 10 @@ -268,19 +268,28 @@ $this - 1 + 6 - Dwarf Fortress v50.02 - Локализация DFRUS + Переводы из мастерской - UNIT - Dwarf Fortress v50.03 - Локализация DFRUS + Dwarf Fortress v50.03 - Локализация DFRUS v0.3 + + + Dwarf Fortress v50.03 - Локализация DFRUS v0.2 + + + Dwarf Fortress v50.03 - Локализация DFRUS v0.1 + + + Dwarf Fortress v50.02 - Локализация DFRUS v0.1 - 42, 83 + 42, 104 - 265, 56 + 270, 56 11 @@ -295,13 +304,139 @@ $this + 5 + + + -9, 83 + + + 376, 10 + + + 12 + + + groupBox1 + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 4 + + + -9, 195 + + + 376, 10 + + + 13 + + + groupBox2 + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + True + + + 12, 260 + + + 145, 13 + + + 14 + + + @Версия игры неизвестна + + + label1 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + False + + + 283, 226 + + + 58, 23 + + + 15 + + + FAQ + + + button5 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + False + + + NoControl + + + 166, 226 + + + 111, 23 + + + 17 + + + Горячий OFF/ON + + + button6 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + 0 True - 357, 178 + 357, 293 @@ -380,10 +515,10 @@ - 373, 217 + 373, 332 - 373, 217 + 373, 332 DFPL 0.1.0 diff --git a/Form2.Designer.cs b/Form2.Designer.cs new file mode 100644 index 0000000..f0b0f58 --- /dev/null +++ b/Form2.Designer.cs @@ -0,0 +1,63 @@ +namespace DFPl +{ + partial class FAQ + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(12, 12); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox1.Size = new System.Drawing.Size(379, 426); + this.textBox1.TabIndex = 0; + this.textBox1.Text = "В: Игра вылетает при переходе на карту, в меню и т.д\r\nО: "; + // + // FAQ + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(403, 450); + this.Controls.Add(this.textBox1); + this.Name = "FAQ"; + this.ShowIcon = false; + this.Text = "Form2"; + this.Load += new System.EventHandler(this.FAQ_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox textBox1; + } +} \ No newline at end of file diff --git a/Form2.cs b/Form2.cs new file mode 100644 index 0000000..c7b297b --- /dev/null +++ b/Form2.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace DFPl +{ + public partial class FAQ : Form + { + public FAQ() + { + InitializeComponent(); + } + + private void FAQ_Load(object sender, EventArgs e) + { + + } + } +} diff --git a/Form2.resx b/Form2.resx new file mode 100644 index 0000000..29dcb1b --- /dev/null +++ b/Form2.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Models/Game.cs b/Models/Game.cs new file mode 100644 index 0000000..eadc7b0 --- /dev/null +++ b/Models/Game.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using IWshRuntimeLibrary; +using NLog; +using Reloaded.Injector; +using Reloaded.Injector.Interop.Structures; +using Reloaded.Injector.Interop; + +namespace DFPl.Models +{ + public class Game + { + // Constants + private const string GameExe = "Dwarf Fortress.exe"; + private const string TranslationDll = "df-steam-translate-hook.dll"; + private const string GameInfoPath = @"\data\vanilla\vanilla_creatures_graphics\info.txt"; + + // Fields + private readonly string _gamePath; + private readonly Logger _logger; + + static private bool LocT = false; + static public Injector injector; + static public string injectorP; + static public string _injectionDllPath; + public Game(string gamePath, Logger logger) + { + _gamePath = gamePath; + _logger = logger; + } + + public void Start() + { + try + { + _logger.Info("Starting Game. Path: " + _gamePath); + + if (!CheckGameFilesExist()) + { + + LocT = false; + _logger.Error("Required game files not found!"); + throw new Exception("Required game files not found!"); + } + + ProcessStartInfo startInfo = new ProcessStartInfo + { + FileName = Path.Combine(_gamePath, GameExe), + CreateNoWindow = false, + UseShellExecute = true, + WorkingDirectory = _gamePath + }; + Process df = Process.Start(startInfo); + int procId = df.Id; + try + { + _logger.Info("Injecting Game"); + injector = new Injector(df); + injectorP = Path.Combine(_gamePath, TranslationDll); + injector.Inject(injectorP); + //injector.CallFunction(injectorP, "Spam", default); + LocT = true; + } + catch (Exception ex) + { + + LocT = false; + _logger.Error("Failed to apply mods", ex); + throw new Exception("Failed to apply mods!", ex); + } + } + catch (Exception ex) + { + + LocT = false; + _logger.Error("Failed to start game", ex); + throw new Exception("Failed to start game!", ex); + } + } + + private bool CheckGameFilesExist() + { + return System.IO.File.Exists(Path.Combine(_gamePath, GameExe)) && + System.IO.File.Exists(Path.Combine(_gamePath, TranslationDll)); + } + + public string DeterminingGameVersion() + { + string GV = ""; + if (!CheckGameFilesExist()) + { + _logger.Error("Required game files not found!"); + throw new Exception("Required game files not found!"); + } + var secondLine = System.IO.File.ReadLines(_gamePath + GameInfoPath); + foreach (string lines in secondLine) + { + string[] plines = lines.Split(':'); + if (plines[0] == "[DISPLAYED_VERSION") + { + GV = plines[1].Split(']')[0]; + } + } + return GV; + } + + public void INEJ() + { + if (LocT) + { + Eject(); + } + else + { + Inject(); + } + } + public void Eject() + { + try + { + injector.Eject(_injectionDllPath); + injector.Dispose(); + } + catch (Exception ex) + { + _logger.Error("Failed to off mods", ex); + throw new Exception("Failed to off mods!", ex); + } + } + + public void Inject() + { + try + { + injector.Inject(injectorP); + } + catch (Exception ex) + { + _logger.Error("Failed to on mods", ex); + throw new Exception("Failed to on mods!", ex); + } + } + + //public static List TryGetModules(Process targetProcess, int timeout = 1000) + //{ + // List modules = new List(); + // Stopwatch watch = new Stopwatch(); + // watch.Start(); + + // while (watch.ElapsedMilliseconds < timeout) + // { + // try + // { + // modules = ModuleCollector.CollectModules(targetProcess); + // break; + // } + // catch { /* ignored */ } + // } + + // if (modules.Count == 0) + // throw new Exception($"Failed to find information on any of the modules inside the process " + + // $"using EnumProcessModulesEx within the { timeout } millisecond timeout. " + + // "The process has likely not yet initialized."); + + // return modules; + //} + } +} diff --git a/Program.cs b/Program.cs index 5b07cb0..8a01e4f 100644 --- a/Program.cs +++ b/Program.cs @@ -15,7 +15,12 @@ static void Main(string[] Ags) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1(Ags)); + string Agss = ""; + for(int i = 0; i < Ags.Length; i++) + { + Agss += Ags[i] + "|"; + } + Application.Run(new Form1(Agss)); } } } diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs index 644fe47..2f05281 100644 --- a/Properties/Settings.Designer.cs +++ b/Properties/Settings.Designer.cs @@ -46,5 +46,17 @@ public string DLLpath { this["DLLpath"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DF_VER { + get { + return ((string)(this["DF_VER"])); + } + set { + this["DF_VER"] = value; + } + } } } diff --git a/Properties/Settings.settings b/Properties/Settings.settings index 19f28d5..f682150 100644 --- a/Properties/Settings.settings +++ b/Properties/Settings.settings @@ -8,5 +8,8 @@ + + + \ No newline at end of file diff --git a/README.md b/README.md index c80e1ea..3c66d1c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# DFPL - -#### Проект лаунчера для игры Dwarf Fortress Steam c поддержкой модификаций -#### Сайт https://vk.com/dwarffortresspluslauncher - -# Поддержать проект - -#### Сбер: https://www.sberbank.com/ru/person/dl/jc?linkname=VINhW8MouCVwpK7uZ -#### Donationalerts: https://www.donationalerts.com/r/ben_dizer - -# Инструкция - -#### 1) Скачать последнюю версию программы из релиза -#### 2) Распаковать архив в любое удобное место -#### 3) Запустить DFLP.exe -#### 4) При первом запуске необходимо указать папку с игрой нажав на "..." -#### 5) Выбрать версию игры и локализации из списка -#### 6) Нажать кнопку "Установить локализацию" -#### 7) (Опционально) создать ярлык для быстрого запуска игры с модификациями -#### 8) Играть - -# Контакты - -#### E-MAIL: andtu6@gmail.com +# DFPL + +#### Проект лаунчера для игры Dwarf Fortress Steam c поддержкой модификаций +#### Сайт https://vk.com/dwarffortresspluslauncher + +# Поддержать проект + +#### Сбер: https://www.sberbank.com/ru/person/dl/jc?linkname=VINhW8MouCVwpK7uZ +#### Donationalerts: https://www.donationalerts.com/r/ben_dizer + +# Инструкция + +#### 1) Скачать последнюю версию программы из релиза +#### 2) Распаковать архив в любое удобное место +#### 3) Запустить DFLP.exe +#### 4) При первом запуске необходимо указать папку с игрой нажав на "..." +#### 5) Выбрать версию игры и локализации из списка +#### 6) Нажать кнопку "Установить локализацию" +#### 7) (Опционально) создать ярлык для быстрого запуска игры с модификациями +#### 8) Играть + +# Контакты + +#### E-MAIL: andtu6@gmail.com diff --git a/globalKeyboardHook.cs b/globalKeyboardHook.cs new file mode 100644 index 0000000..c9ac5eb --- /dev/null +++ b/globalKeyboardHook.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace DFPl +{ + class globalKeyboardHook + { + #region Constant, Structure and Delegate Definitions + /// + /// defines the callback type for the hook + /// + public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam); + + public struct keyboardHookStruct + { + public int vkCode; + public int scanCode; + public int flags; + public int time; + public int dwExtraInfo; + } + + const int WH_KEYBOARD_LL = 13; + const int WM_KEYDOWN = 0x100; + const int WM_KEYUP = 0x101; + const int WM_SYSKEYDOWN = 0x104; + const int WM_SYSKEYUP = 0x105; + #endregion + + #region Instance Variables + /// + /// The collections of keys to watch for + /// + public List HookedKeys = new List(); + /// + /// Handle to the hook, need this to unhook and call the next hook + /// + IntPtr hhook = IntPtr.Zero; + #endregion + + #region Events + /// + /// Occurs when one of the hooked keys is pressed + /// + public event KeyEventHandler KeyDown; + /// + /// Occurs when one of the hooked keys is released + /// + public event KeyEventHandler KeyUp; + #endregion + + #region Constructors and Destructors + /// + /// Initializes a new instance of the class and installs the keyboard hook. + /// + public globalKeyboardHook() + { + hook(); + } + + /// + /// Releases unmanaged resources and performs other cleanup operations before the + /// is reclaimed by garbage collection and uninstalls the keyboard hook. + /// + ~globalKeyboardHook() + { + unhook(); + } + #endregion + + #region Public Methods + /// + /// Installs the global hook + /// + public void hook() + { + IntPtr hInstance = LoadLibrary("User32"); + hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0); + } + + /// + /// Uninstalls the global hook + /// + public void unhook() + { + UnhookWindowsHookEx(hhook); + } + + /// + /// The callback for the keyboard hook + /// + /// The hook code, if it isn't >= 0, the function shouldn't do anyting + /// The event type + /// The keyhook event information + /// + public int hookProc(int code, int wParam, ref keyboardHookStruct lParam) + { + if (code >= 0) + { + Keys key = (Keys)lParam.vkCode; + if (HookedKeys.Contains(key)) + { + KeyEventArgs kea = new KeyEventArgs(key); + if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null)) + { + KeyDown(this, kea); + } + else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null)) + { + KeyUp(this, kea); + } + if (kea.Handled) + return 1; + } + } + return CallNextHookEx(hhook, code, wParam, ref lParam); + } + #endregion + + #region DLL imports + /// + /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null + /// + /// The id of the event you want to hook + /// The callback. + /// The handle you want to attach the event to, can be null + /// The thread you want to attach the event to, can be null + /// a handle to the desired hook + [DllImport("user32.dll")] + static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId); + + /// + /// Unhooks the windows hook. + /// + /// The hook handle that was returned from SetWindowsHookEx + /// True if successful, false otherwise + [DllImport("user32.dll")] + static extern bool UnhookWindowsHookEx(IntPtr hInstance); + + /// + /// Calls the next hook. + /// + /// The hook id + /// The hook code + /// The wparam. + /// The lparam. + /// + [DllImport("user32.dll")] + static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam); + + /// + /// Loads the library. + /// + /// Name of the library + /// A handle to the library + [DllImport("kernel32.dll")] + static extern IntPtr LoadLibrary(string lpFileName); + #endregion + } +} diff --git a/nlog.config b/nlog.config new file mode 100644 index 0000000..b646e42 --- /dev/null +++ b/nlog.config @@ -0,0 +1,21 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/obj/Debug/.NETFramework,Version=v4.5.2.AssemblyAttributes.cs b/obj/Debug/.NETFramework,Version=v4.5.2.AssemblyAttributes.cs new file mode 100644 index 0000000..f1a77a1 --- /dev/null +++ b/obj/Debug/.NETFramework,Version=v4.5.2.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5.2", FrameworkDisplayName = ".NET Framework 4.5.2")] diff --git a/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs b/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs new file mode 100644 index 0000000..3871b18 --- /dev/null +++ b/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] diff --git a/obj/Debug/.NETFramework,Version=v4.8.1.AssemblyAttributes.cs b/obj/Debug/.NETFramework,Version=v4.8.1.AssemblyAttributes.cs new file mode 100644 index 0000000..0af6d86 --- /dev/null +++ b/obj/Debug/.NETFramework,Version=v4.8.1.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] diff --git a/obj/Debug/.NETFramework,Version=v4.8.AssemblyAttributes.cs b/obj/Debug/.NETFramework,Version=v4.8.AssemblyAttributes.cs new file mode 100644 index 0000000..15efebf --- /dev/null +++ b/obj/Debug/.NETFramework,Version=v4.8.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] diff --git a/obj/Debug/DFPl.Form1.resources b/obj/Debug/DFPl.Form1.resources index a7e63e4..613bac2 100644 Binary files a/obj/Debug/DFPl.Form1.resources and b/obj/Debug/DFPl.Form1.resources differ diff --git a/obj/Debug/DFPl.csproj.GenerateResource.cache b/obj/Debug/DFPl.csproj.GenerateResource.cache index 3ed3092..d044957 100644 Binary files a/obj/Debug/DFPl.csproj.GenerateResource.cache and b/obj/Debug/DFPl.csproj.GenerateResource.cache differ diff --git a/obj/Debug/DFPl.exe b/obj/Debug/DFPl.exe index 0e5555a..2021f0d 100644 Binary files a/obj/Debug/DFPl.exe and b/obj/Debug/DFPl.exe differ diff --git a/obj/Debug/DFPl.exe.config b/obj/Debug/DFPl.exe.config index 1bc8c44..b6013ba 100644 --- a/obj/Debug/DFPl.exe.config +++ b/obj/Debug/DFPl.exe.config @@ -16,6 +16,9 @@ + + + diff --git a/obj/Debug/DFPl.pdb b/obj/Debug/DFPl.pdb index 635a16c..3fea948 100644 Binary files a/obj/Debug/DFPl.pdb and b/obj/Debug/DFPl.pdb differ diff --git a/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll b/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll index 8dde005..146ab0d 100644 Binary files a/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll and b/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/obj/Debug/ru/DFPl.resources.dll b/obj/Debug/ru/DFPl.resources.dll index 0ba4ca5..5ede9c9 100644 Binary files a/obj/Debug/ru/DFPl.resources.dll and b/obj/Debug/ru/DFPl.resources.dll differ diff --git a/obj/Share/.NETFramework,Version=v4.8.AssemblyAttributes.cs b/obj/Share/.NETFramework,Version=v4.8.AssemblyAttributes.cs new file mode 100644 index 0000000..15efebf --- /dev/null +++ b/obj/Share/.NETFramework,Version=v4.8.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] diff --git a/obj/Share/DFPl.Form1.resources b/obj/Share/DFPl.Form1.resources index a7e63e4..613bac2 100644 Binary files a/obj/Share/DFPl.Form1.resources and b/obj/Share/DFPl.Form1.resources differ diff --git a/obj/Share/DFPl.csproj.GenerateResource.cache b/obj/Share/DFPl.csproj.GenerateResource.cache index 3ed3092..d044957 100644 Binary files a/obj/Share/DFPl.csproj.GenerateResource.cache and b/obj/Share/DFPl.csproj.GenerateResource.cache differ diff --git a/obj/Share/DFPl.exe b/obj/Share/DFPl.exe index c71470f..e762c3a 100644 Binary files a/obj/Share/DFPl.exe and b/obj/Share/DFPl.exe differ diff --git a/obj/Share/DFPl.exe.config b/obj/Share/DFPl.exe.config index 1bc8c44..b6013ba 100644 --- a/obj/Share/DFPl.exe.config +++ b/obj/Share/DFPl.exe.config @@ -16,6 +16,9 @@ + + + diff --git a/obj/Share/DFPl.pdb b/obj/Share/DFPl.pdb index 3310830..294dd10 100644 Binary files a/obj/Share/DFPl.pdb and b/obj/Share/DFPl.pdb differ diff --git a/obj/Share/TempPE/Properties.Resources.Designer.cs.dll b/obj/Share/TempPE/Properties.Resources.Designer.cs.dll index 1b76e96..122358b 100644 Binary files a/obj/Share/TempPE/Properties.Resources.Designer.cs.dll and b/obj/Share/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/obj/Share/ru/DFPl.resources.dll b/obj/Share/ru/DFPl.resources.dll index ec63385..c820077 100644 Binary files a/obj/Share/ru/DFPl.resources.dll and b/obj/Share/ru/DFPl.resources.dll differ