This repository has been archived on 2019-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
giantslauncher/Program.cs

215 lines
7.4 KiB
C#

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<string> 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<string> 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<string> array = new List<string>();
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;
}
}
}