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) { if (server.Length > 15) { Console.WriteLine("Server {0} has length > 15, skipping.", server); continue; } 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 // add padding for (int i = 0; i < 15 - data.Length; i++) { writer.Write((byte)0);//write it } } } else { Console.WriteLine("No working master server found... RIP."); } 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 = "g.hipstercat.fr"; rootNode.AppendChild(msNode); msNode = xmlDoc.CreateElement("masterserver"); msNode.InnerText = "gm.vankerkom.be"; rootNode.AppendChild(msNode); msNode = xmlDoc.CreateElement("masterserver"); msNode.InnerText = "ms.giantswd.org"; 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; } if (!client.Connected) { 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; } } }