using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; namespace MrAG { public class Serverlist { public class GamerServicesServerlistException : Exception{ public GamerServicesServerlistException(string msg): base(msg){ } } public class ServerInfo { public string Servername; public string IP; public string Meta; public int Users; public int MaxUsers; public int Port; } public class Server { public string Servername; public int Users; public int MaxUsers; public int Port; public int Timeout; public bool Legit; public bool Started; public byte[] Headers = new byte[] { 1, 3, 3, 7 }; public Delegate OnIncomingConnection; public Delegate OnFinishedConnection; private string Meta; private TcpListener Connection; private MrAG.Networking.TCPClient GSServerConnection; private double Lastupdate = 0; public void Start() { if (this.Started) this.Connection.Stop(); this.Started = true; this.Connection = new TcpListener(IPAddress.Any, Port); this.Connection.Start(); if (!this.Legit) return; this.Lastupdate = DateTime.Now.TimeOfDay.TotalSeconds; this.GSServerConnection = new MrAG.Networking.TCPClient("mrag.nl", 8443); this.GSServerConnection.Connection.Start_Send(); this.GSServerConnection.Connection.AddInt(0); this.GSServerConnection.Connection.Finish_Send(); this.GSServerConnection.Connection.Start_Recieve(); bool canconnect = this.GSServerConnection.Connection.ReadBool(); this.GSServerConnection.Connection.Finish_Recieve(); if (canconnect) { this.GSServerConnection.Connection.Start_Send(); this.GSServerConnection.Connection.AddBool(true); this.GSServerConnection.Connection.Finish_Send(); } else { throw new MrAG.Networking.GamerServicesNetworkingException("The masterserver dumped you in the ditch at the side of the road."); } this.GSServerConnection.Packets[0] = new Action(this.Packet_00); // Register this.GSServerConnection.Packets[1] = new Action(this.Packet_01); // Update this.GSServerConnection.Packets[2] = new Action(this.Packet_02); // Shutdown/remove this.GSServerConnection.Packets[3] = new Action(this.Packet_03); // Update Playerrcount this.GSServerConnection.Packets[4] = new Action(this.Packet_04); // Update Meta this.GSServerConnection.Connection.Send(0, 0, this.Servername, this.Meta, MrAG.Gamerservices.GetIdentifier(), this.Port, this.MaxUsers); } public void Stop() { this.Started = false; this.Connection.Stop(); if (this.Legit && this.GSServerConnection.Connected) { this.GSServerConnection.Send(2, 1); } } public void Close(){ this.Stop(); if (this.GSServerConnection != null) this.GSServerConnection.Close(); this.GSServerConnection = null; this.Connection = null; } public void Update(){ if (this.Legit && this.GSServerConnection.Connected) { this.GSServerConnection.Update(); if (Math.Abs(this.Lastupdate - DateTime.Now.TimeOfDay.TotalSeconds) > 10) { this.GSServerConnection.Send(1, 1); this.Lastupdate = DateTime.Now.TimeOfDay.TotalSeconds; } } start: while (Connection.Pending()) { Networking.TCPClient c = new Networking.TCPClient(Connection.AcceptTcpClient()); c.Connection.SetTimeout(Timeout); try { Networking.IncomingConnection newcon = new Networking.IncomingConnection(); newcon.Connection = c; string[] tmpipport = c.Connection.GetClient().Client.RemoteEndPoint.ToString().Split(':'); newcon.IP = tmpipport[0]; newcon.Port = uint.Parse(tmpipport[1]); c.Connection.Start_Recieve(); foreach(byte header in this.Headers){ if (header != c.Connection.ReadByte()){ c.Connection.Start_Send(); c.Connection.AddString("Invalid Headers"); c.Connection.Finish_Send(); c.Close(); goto start; } } newcon.Username = c.Connection.ReadString(64); c.Connection.Finish_Recieve(); /*if (this.Legit) { try { //this.GSServerConnection.Connection.Send(0, newcon.Username); string[] respons = Networking.PostData("serverlist", "sub=check&ip=" + newcon.IP + "&port=" + newcon.Port + "&servername=" + Servername + "&identifier=" + MrAG.Gamerservices.GetIdentifier() + "&user=" + newcon.Username); } catch { c.Connection.Start_Send(); c.Connection.AddBool(false); c.Connection.AddText("Error while validating."); c.Connection.Finish_Send(); c.Connection.Close(); goto start; } }*/ bool canconnect = true; if (OnIncomingConnection != null) { OnIncomingConnection.DynamicInvoke(newcon); if (newcon._KickReason != null) canconnect = newcon._KickReason.Length == 0; } double curtime = DateTime.Now.TimeOfDay.TotalMilliseconds; c.Connection.Start_Send(); c.Connection.AddBool(canconnect); c.Connection.Finish_Send(); if (canconnect) { c.Connection.Start_Recieve(); c.Connection.ReadBool(); c.Connection.Finish_Recieve(); newcon.Ping = (int)(DateTime.Now.TimeOfDay.TotalMilliseconds - curtime); if (OnFinishedConnection != null) { OnFinishedConnection.DynamicInvoke(newcon); } else { throw new Networking.GamerServicesNetworkingException("Unhandled connection."); } } else { c.Connection.Start_Send(); c.Connection.AddText(newcon._KickReason); c.Connection.Finish_Send(); c.Connection.Close(); } newcon.FinishedConnecting = true; } catch { c.Connection.Close(); } } } public void SetMeta(string meta) { this.Meta = meta; if (this.Legit) this.GSServerConnection.Send(4, 0, this.Meta); } public string GetMeta() { return this.Meta; } public void IncreeseUserCount() { this.Users++; this.GSServerConnection.Send(3, 0, this.Users); } public void DecreeseUserCount() { this.Users--; this.GSServerConnection.Send(3, 0, this.Users); } private void Packet_00(MrAG.Networking.Packet p) { if (!p.ReadBool()) { throw new MrAG.Networking.GamerServicesNetworkingException("Error while attempting to host: " + p.ReadString()); } } private void Packet_01(MrAG.Networking.Packet p) { if (!p.ReadBool()) { p.Send(0, 0, this.Servername, this.Meta, MrAG.Gamerservices.GetIdentifier(), this.Port, this.MaxUsers); p.Send(3, 9, this.Users); } } private void Packet_02(MrAG.Networking.Packet p) { p.Send(0, 0, this.Servername, this.Meta, MrAG.Gamerservices.GetIdentifier(), this.Port, this.MaxUsers); p.Send(3, 9, this.Users, this.MaxUsers); } private void Packet_03(MrAG.Networking.Packet p) { } private void Packet_04(MrAG.Networking.Packet p) { } } public static Server Host(string servername, int port, string meta, bool show_in_serverlist) { Server s = new Server(); s.Servername = servername; s.Port = port; s.SetMeta(meta); s.Legit = show_in_serverlist; s.Start(); return s; } public static void GetList(Action> callback) { MrAG.Gamerservices.ServerListCallback = callback; MrAG.Gamerservices.GetAPIConnection().Send(7, 0, MrAG.Gamerservices.GetIdentifier()); } public static MrAG.Networking.TCPClient Connect(string ip, int port) { return Connect(ip, port, new byte[] { 1, 3, 3, 7 }); } public static MrAG.Networking.TCPClient Connect(string ip, int port, byte[] headers) { //if (legit){ // string[] res = MrAG.Networking.PostData("serverlist", "sub=connect&ip" + ip + "&port=" + port + "&identifier=" + MrAG.Gamerservices.GetIdentifier()); //} MrAG.Networking.TCPClient c = new MrAG.Networking.TCPClient(ip, port); c.Connection.Start_Send(); foreach (byte b in headers) c.Connection.AddByte(b); c.Connection.AddString(MrAG.Gamerservices.GetUser()); c.Connection.Finish_Send(); c.Connection.Start_Recieve(); bool canconnect = c.Connection.ReadBool(); c.Connection.Finish_Recieve(); if (canconnect) { c.Connection.Start_Send(); c.Connection.AddBool(true); c.Connection.Finish_Send(); } else { c.Connection.Start_Recieve(); string reason = c.Connection.ReadString(); c.Connection.Finish_Recieve(); throw new MrAG.Networking.GamerServicesNetworkingException("Kicked: " + reason); } return c; } public static MrAG.Networking.TCPClient Connect(System.Net.Sockets.TcpClient c) { return Connect(c, new byte[] { 1, 3, 3, 7 }); } public static MrAG.Networking.TCPClient Connect(System.Net.Sockets.TcpClient tcpc, byte[] headers) { //if (legit){ // string[] res = MrAG.Networking.PostData("serverlist", "sub=connect&ip" + ip + "&port=" + port + "&identifier=" + MrAG.Gamerservices.GetIdentifier()); //} MrAG.Networking.TCPClient c = new MrAG.Networking.TCPClient(tcpc); c.Connection.Start_Send(); foreach (byte b in headers) c.Connection.AddByte(b); c.Connection.AddString(MrAG.Gamerservices.GetUser()); c.Connection.Finish_Send(); c.Connection.Start_Recieve(); bool canconnect = c.Connection.ReadBool(); c.Connection.Finish_Recieve(); if (canconnect) { c.Connection.Start_Send(); c.Connection.AddBool(true); c.Connection.Finish_Send(); } else { c.Connection.Start_Recieve(); string reason = c.Connection.ReadString(); c.Connection.Finish_Recieve(); throw new MrAG.Networking.GamerServicesNetworkingException("Kicked: " + reason); } return c; } } }