commit 3da514d0f47483824447f49f01b6c1ca7f431b93 Author: HipsterCat Date: Fri Feb 8 17:55:09 2019 +0100 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..394706c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vs/ +bin/ +obj/ \ No newline at end of file diff --git a/App.config b/App.config new file mode 100644 index 0000000..731f6de --- /dev/null +++ b/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/GiantsLauncher.csproj b/GiantsLauncher.csproj new file mode 100644 index 0000000..c85e191 --- /dev/null +++ b/GiantsLauncher.csproj @@ -0,0 +1,60 @@ + + + + + Debug + AnyCPU + {C78FA352-3E44-40FD-854D-93A83520E801} + Exe + GiantsLauncher + GiantsLauncher + v4.6.1 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + giants_citizen_kabuto.ico + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GiantsLauncher.sln b/GiantsLauncher.sln new file mode 100644 index 0000000..cd456c8 --- /dev/null +++ b/GiantsLauncher.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.329 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantsLauncher", "GiantsLauncher.csproj", "{C78FA352-3E44-40FD-854D-93A83520E801}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C78FA352-3E44-40FD-854D-93A83520E801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C78FA352-3E44-40FD-854D-93A83520E801}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C78FA352-3E44-40FD-854D-93A83520E801}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C78FA352-3E44-40FD-854D-93A83520E801}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2952AF63-3169-4FAC-90E3-8BC05E8E9568} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..03f5789 --- /dev/null +++ b/Program.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.IO; +using System.Diagnostics; +using System.Xml; +using System.Windows.Forms; + +namespace GiantsLauncher +{ + class GiantsLauncher + { + [STAThread] + static void Main(string[] args) + { + List SERVERS = ReadServers(); + //string[] SERVERS = new string[] {"gckms.no-ip.org", "ahipstercat.fr"}; + string GIANTS_PATH = Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Software\PlanetMoon\Giants", "DestDir", "").ToString(); + GIANTS_PATH += "\\Giants.exe"; + if (!File.Exists(GIANTS_PATH)) + { + GIANTS_PATH = SetPath(); + GIANTS_PATH += "\\Giants.exe"; + } + if (File.Exists(GIANTS_PATH)) + { + Console.WriteLine("Giants path: {0}", GIANTS_PATH); + // check version + int version = GetGameBuild(GIANTS_PATH); + if (version != 1497) + { + // gtfo + Console.WriteLine("Game version is not 1.497. Found: {0}", version); + return; + } + string server_ok = ""; + foreach (string server in SERVERS) + { + Console.WriteLine("Testing {0}", server); + if (TestServer(server)) + { + server_ok = server; + break; + } + } + + if (server_ok != "") + { + Console.WriteLine("Writing master server: {0}", server_ok); + using (BinaryWriter writer = new BinaryWriter(File.Open(GIANTS_PATH, FileMode.Open, FileAccess.ReadWrite))) + { + int offset = 0x157954; // position of master server in binary + Byte[] data = System.Text.Encoding.ASCII.GetBytes(server_ok); + writer.Seek(offset, SeekOrigin.Begin); //move cursor to the position + writer.Write(data);//write it + } + } + Process.Start(GIANTS_PATH); + } + } + + static List ReadServers() + { + // Loading from a file, you can also load from a stream + try + { + XmlDocument xml = new XmlDocument(); + xml.Load("giantslauncher.xml"); + XmlNodeList elemList = xml.GetElementsByTagName("masterserver"); + List array = new List(); + for (int i = 0; i < elemList.Count; i++) + { + array.Add(elemList[i].InnerXml); + } + + if (array == null || array.Count < 1) + { + WriteInitialConfig(); + return ReadServers(); + } + + return array; + } + catch (System.IO.FileNotFoundException) + { + WriteInitialConfig(); + return ReadServers(); + } + } + + static void WriteInitialConfig() + { + XmlDocument xmlDoc = new XmlDocument(); + XmlNode rootNode = xmlDoc.CreateElement("masterservers"); + xmlDoc.AppendChild(rootNode); + + XmlNode msNode = xmlDoc.CreateElement("masterserver"); + msNode.InnerText = "gckms.no-ip.org"; + rootNode.AppendChild(msNode); + + msNode = xmlDoc.CreateElement("masterserver"); + msNode.InnerText = "gckms.hipstercat.fr"; + rootNode.AppendChild(msNode); + + msNode = xmlDoc.CreateElement("masterserver"); + msNode.InnerText = "gckms.vankerkom.be"; + rootNode.AppendChild(msNode); + + msNode = xmlDoc.CreateElement("masterserver"); + msNode.InnerText = "gckms2.hipstercat.fr"; + rootNode.AppendChild(msNode); + + xmlDoc.Save("giantslauncher.xml"); + } + + static bool TestServer(string ip) + { + try + { + // Create a TcpClient. + // Note, for this client to work you need to have a TcpServer + // connected to the same address as specified by the server, port + // combination. + TcpClient client = new TcpClient(); + + var result = client.BeginConnect(ip, 28900, null, null); + + var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2)); + + if (!success) + { + client.Close(); + return false; + } + + NetworkStream stream = client.GetStream(); + + // Buffer to store the response bytes. + Byte[] data = new Byte[256]; + + // String to store the response ASCII representation. + String responseData = String.Empty; + + // Read the first batch of the TcpServer response bytes. + Int32 bytes = stream.Read(data, 0, data.Length); + responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); + Console.WriteLine("Received: {0}", responseData); + + // Close everything. + stream.Close(); + //client.EndConnect(result); + + return true; + } + catch (SocketException e) + { + Console.WriteLine("SocketException: {0}", e); + return false; + } + } + + static int GetGameBuild(string path) + { + using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open))) + { + int offset = 0x10da27; // position of game version as of 1497 + reader.BaseStream.Seek(offset, SeekOrigin.Begin); // move cursor to the position + byte[] version = reader.ReadBytes(2); // read it + return BitConverter.ToUInt16(version, 0); + } + } + static string SetPath() + { + string path = ""; + while (!File.Exists(path + "\\Giants.exe")) + { + FolderBrowserDialog fbd = new FolderBrowserDialog(); + fbd.Description = "Select your Giants game directory"; + DialogResult dr = fbd.ShowDialog(); + if (dr == DialogResult.OK) + { + path = fbd.SelectedPath; + } + else + { + Environment.Exit(1); + return ""; + } + } + + // add to registry + Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\Software\PlanetMoon\Giants", "DestDir", path); + return path; + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3b3909d --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("GiantsLauncher")] +[assembly: AssemblyDescription("Launch Giants")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("GiantsWD")] +[assembly: AssemblyProduct("GiantsLauncher")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("c78fa352-3e44-40fd-854d-93a83520e801")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/giants_citizen_kabuto.ico b/giants_citizen_kabuto.ico new file mode 100644 index 0000000..1b8e338 Binary files /dev/null and b/giants_citizen_kabuto.ico differ