215 lines
7.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|