public static class UpdaterConnector
{
private static Dictionary<string, string> hashes = new Dictionary<string, string>();
private static int port = 44123;
private static int tcpPort = 44321;
public static void Start()
{
Console.Title = "Cat-X Updater Server";
Console.BackgroundColor = ConsoleColor.DarkBlue;
Console.ForegroundColor = ConsoleColor.Green;
Console.Clear();
Console.WriteLine("███████████████████████████");
Console.WriteLine("█ Setting up directories: █");
Console.WriteLine("███████████████████████████");
Console.WriteLine("");
Settings.workDir = Directory.GetCurrentDirectory();
Console.WriteLine($"Working directory = {Settings.workDir}");
Settings.clientDir = Path.Combine(Settings.workDir, "client");
Console.WriteLine($"Client directory = {Settings.clientDir}");
Settings.hashFile = Path.Combine(Settings.workDir, "hashlist.dat");
Console.WriteLine($"Hashlist File = {Settings.hashFile}");
Console.WriteLine("");
Console.WriteLine("█████████████████████████");
Console.WriteLine("█ Hashing client files: █");
Console.WriteLine("█████████████████████████");
HashClient();
Console.WriteLine("█████████████████████████████████");
Console.WriteLine("█ Waiting for incoming requests █");
Console.WriteLine("█████████████████████████████████");
Console.WriteLine("");
Listener(port);
Console.WriteLine("Up and running. For exit type quit. If you changed client files, type reload.");
Console.WriteLine("");
Commands("");
}
private static void HashClient()
{
hashes = new Dictionary<string, string>();
Console.WriteLine("");
Console.Write("Read in Client directory... ");
string[] filesList = Directory.GetFiles(Settings.clientDir, "*.*", SearchOption.AllDirectories);
Console.WriteLine($"{filesList.Length} files found.");
Console.WriteLine($"Creating hash file list (could take a while)... ");
if (File.Exists(Settings.hashFile)) { File.Delete(Settings.hashFile); }
File.AppendAllText(Settings.hashFile, $"#################################{Environment.NewLine}");
File.AppendAllText(Settings.hashFile, $"# Cat-X Update Server Hash List #{Environment.NewLine}");
File.AppendAllText(Settings.hashFile, $"#################################{Environment.NewLine}");
File.AppendAllText(Settings.hashFile, $" {Environment.NewLine}");
int i = 1;
foreach (string file in filesList)
{
string hash = GetMD5Checksum(file);
string fileHelper = file.Replace(Settings.clientDir + "\\", "");
string parser = $"{hash}|{fileHelper}{Environment.NewLine}";
hashes.Add(fileHelper, hash);
File.AppendAllText(Settings.hashFile, parser);
Console.Write($"Written File {i}/{filesList.Length}\r");
i++;
}
Console.WriteLine("");
Console.WriteLine("done.");
Console.WriteLine("");
}
public static string GetMD5Checksum(string filename)
{
using (var md5 = System.Security.Cryptography.MD5.Create())
{
using (var stream = System.IO.File.OpenRead(filename))
{
var hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "");
}
}
}
private static void ReloadHashes()
{
Console.Clear();
Console.WriteLine("");
Console.WriteLine("█████████████████████████");
Console.WriteLine("█ Hashing client files: █");
Console.WriteLine("█████████████████████████");
Console.WriteLine("");
HashClient();
Console.WriteLine("████████████████████████████████████████████████");
Console.WriteLine("█ Waiting for incoming requests on port {port} █");
Console.WriteLine("████████████████████████████████████████████████");
Console.WriteLine("");
Console.WriteLine("Up and running. For exit type quit. If you changed client files, type reload.");
Console.WriteLine("");
Commands("");
}
private static void Commands(string command)
{
if(command.ToLower() != "quit")
{
if (command.ToLower() != "reload")
{
string waiter = Console.ReadLine();
Commands(waiter);
}
ReloadHashes();
return;
}
else
{
Environment.Exit(0);
}
}
private static void DoExternalCommand(string data, string ip)
{
if (data.Contains("|"))
{
string[] d = data.Split('|');
switch (d[0].ToLower())
{
case "getlist":
SendFileToClient(Settings.hashFile, ip);
break;
case "downloadfile":
SendFileToClient(d[1], ip);
break;
default:
break;
}
}
}
private static bool CheckFile(string filename, string hash)
{
bool result = false;
string parser = string.Empty;
try { parser = hashes[filename]; }catch(Exception) { result = false; }
if(hash == parser) { result = true; }
return result;
}
private static void SendFileToClient(string file, string ip)
{
Console.WriteLine($"Sending {file} to {ip}.");
string parser = Settings.clientDir + "\\" + file;
new Thread(delegate () { SendFileToClient(parser, ip); }).Start();
}
public static void SendFileToClientTCP(string file, string ip)
{
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipe = IPAddress.Parse(ip);
client.Connect(ipe, tcpPort);
Console.WriteLine($"Sending {file} to {ip}.");
client.SendFile(file);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
private static void Listener(int port)
{
new Thread(delegate () { Receiver(port); }).Start();
}
private static void ReceivedMessageParse(byte[] data, string ip)
{
string request = Encoding.ASCII.GetString(data);
DoExternalCommand(request, ip);
}
public static void Receiver(int port)
{
UdpClient Udpclient = new UdpClient(port);
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
try
{
byte[] receiveBytes = Udpclient.Receive(ref RemoteIpEndPoint);
UpdaterConnector.ReceivedMessageParse(receiveBytes, RemoteIpEndPoint.ToString());
Udpclient.Close();
UpdaterConnector.Listener(port);
}
catch (Exception)
{
Udpclient.Close();
UpdaterConnector.Listener(port);
}
}
private static void SendData(string data, string ip)
{
byte[] parser = Encoding.ASCII.GetBytes(data);
Send(ip, parser);
}
public static void Send(string ip, byte[] data)
{
new Thread(delegate () { UdpSend(port, data, ip); }).Start();
}
private static void UdpSend(int port, byte[] data, string serveradress)
{
UdpClient udpClient = new UdpClient(serveradress, port);
try
{
udpClient.Send(data, data.Length);
udpClient.Close();
}
catch (Exception)
{
udpClient.Close();
}
}
}