diff --git a/source/CubeMS/AcMasterserver.csproj b/source/CubeMS/AcMasterserver.csproj new file mode 100644 index 00000000..624f81d1 --- /dev/null +++ b/source/CubeMS/AcMasterserver.csproj @@ -0,0 +1,90 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {A00CFDD5-210C-415F-A172-386E92A52D9B} + {349C5851-65DF-11DA-9384-00065B846F21};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + AcMasterserver + + + true + full + false + bin + DEBUG + prompt + 4 + + + none + false + bin + prompt + 4 + + + + + + + + False + ..\..\..\Desktop\master\Bin\ActionCube.dll + + + False + ..\..\..\Desktop\master\Bin\API.dll + + + False + ..\..\..\Desktop\master\Bin\Cube.dll + + + False + ..\..\..\Desktop\master\Bin\CubeEngineBase.dll + + + + + False + ..\..\..\Desktop\mysql-connector-net-6.1.2-noinstall\mysql.data.dll + + + + + + + + + + + + + + + + + + + + + + + Default.aspx + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/CubeMS/AcMasterserver.pidb b/source/CubeMS/AcMasterserver.pidb new file mode 100644 index 00000000..e1e660c7 Binary files /dev/null and b/source/CubeMS/AcMasterserver.pidb differ diff --git a/source/CubeMS/App_Code/CubeMasterDAL.cs b/source/CubeMS/App_Code/CubeMasterDAL.cs new file mode 100644 index 00000000..045c0fcc --- /dev/null +++ b/source/CubeMS/App_Code/CubeMasterDAL.cs @@ -0,0 +1,235 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Configuration; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; + +using System.Net; +using System.Xml; +using System.IO; +//using System.Data.SqlClient; +using System.Text; +using System.Linq; +using MySql.Data.MySqlClient; + + +using AHSoftware.CubeMon; +using AHSoftware.CubeMon.Games.ActionCube.v094; + +/// +/// Summary description for CubeMS +/// +public class CubeMasterDAL +{ + string connectionString; + //DbProviderFactory factory; + + public string ConnectionString + { + get { return connectionString; } + set { connectionString = value; } + } + + public CubeMasterDAL() + { + // factory = new MySql.Data.MySqlClient.MySqlClientFactory(); + } + + IDbConnection CreateConnection() + { + IDbConnection con = new MySqlConnection(); //factory.CreateConnection(); + con.ConnectionString = ConnectionString; + //con.Open(); + return con; + } + + private void AddServer(IPEndPoint address, string name, string description) + { + //SqlConnection con = new SqlConnection(connectionString); + //SqlCommand cmd = new SqlCommand("AddServer", con); + + IDbConnection con = CreateConnection(); + IDbCommand cmd = con.CreateCommand(); + cmd.CommandText = "DELETE FROM Servers WHERE IP=@IP AND Port=@Port; INSERT INTO Servers VALUES(@IP, @Port, @Name, @Description, @Date)"; + + var param = cmd.CreateParameter(); + param.ParameterName = "IP"; + param.Value = IPTools.IPToInt(address.Address); + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "Port"; + param.Value = address.Port; + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "Name"; + param.Value = name; + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "Description"; + param.Value = description; + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "Date"; + param.Value = DateTime.Now; + cmd.Parameters.Add(param); + + Console.WriteLine("opening"); + con.Open(); + cmd.ExecuteNonQuery(); + Console.WriteLine("done"); + } + + public void Register(IPEndPoint address) + { + Client c = new Client(); + c.Socket = new IPEndPoint(address.Address, address.Port + 1); + ServerInfo info = null; + try + { + info = (ServerInfo)c.RequestInfo(); + } + catch + { + throw new ApplicationException("Could not ping you. Make sure your server is accessible from the internet."); + } + + string name = string.Empty; + try + { + name = Dns.GetHostEntry(info.Socket.Address).HostName; + } + catch { }; + + if (info.MaxClients > 20) + { + throw new ApplicationException("Your server must have a maxclients setting of 20 or less. Check your configuration."); + } + + AddServer(address, name, info.Description); + } + + public string GetServers(bool xml) + { + System.Diagnostics.Debug.Assert(xml == false); + + + + IDbConnection con = CreateConnection(); + IDbCommand cmd = con.CreateCommand(); //new SqlCommand(xml ? "GetServersXML" : "GetServers", con); + cmd.CommandText = "DELETE FROM Servers WHERE LastModified + INTERVAL 70 MINUTE < NOW(); SELECT * FROM Servers;"; // fixme, xml + + try + { + con.Open(); + IDataReader r = cmd.ExecuteReader(); + StringBuilder sb = new StringBuilder(); + + if(xml) + { + // sql server handles xml conversion for us, just embed in a new xmldoc + sb.AppendLine(""); + sb.AppendLine(""); + if(r.Read()) + { + sb.AppendLine(r[0] as string); + } + sb.AppendLine(""); + } + else + { + // construct server list as cubescript + while(r.Read()) + { + sb.AppendFormat("addserver {0} {1};{2}", IPTools.IntToIp((int)r["IP"]).ToString(), r["Port"], Environment.NewLine); + } + } + + return sb.ToString(); + } + catch + { + return null; + } + finally + { + con.Close(); + } + } + + public string GetClientScript(string HTTPAgent) + { + IDbConnection con = CreateConnection(); + IDbCommand cmd = con.CreateCommand(); // new SqlCommand("GetClientScript", con); + //cmd.Parameters.AddWithValue("HTTPAgent", HTTPAgent); + cmd.CommandText = "SELECT * FROM ClientScripts WHERE HTTPAgent = @HTTPAgent"; + + var param = cmd.CreateParameter(); + param.ParameterName = "HTTPAgent"; + param.Value = HTTPAgent; + cmd.Parameters.Add(param); + + try + { + con.Open(); + IDataReader r = cmd.ExecuteReader(); + r.Read(); + return r["Script"] as string; + } + catch + { + return null; + } + finally + { + con.Close(); + } + } + + public enum EventType : int + { + RegistrationFailed = 0, + RegistrationSuceeeded, + RetrieveServers, + Exception, + } + + public void AddEvent(EventType type, string data, IPEndPoint address) + { + IDbConnection con = CreateConnection(); + IDbCommand cmd = con.CreateCommand(); //new SqlCommand("AddEvent", con); + cmd.CommandText = "INSERT INTO Events (Type, Data, IP, Time) VALUES (@Type, @Data, @IP, @Time)"; + + var param = cmd.CreateParameter(); + param.ParameterName = "Type"; + param.Value = type; + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "Data"; + param.Value = data; + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "IP"; + param.Value = IPTools.IPToInt(address.Address); + cmd.Parameters.Add(param); + + param = cmd.CreateParameter(); + param.ParameterName = "Time"; + param.Value = DateTime.Now; + cmd.Parameters.Add(param); + + con.Open(); + cmd.ExecuteNonQuery(); + con.Close(); + } +} diff --git a/source/CubeMS/App_Code/CubeMsRequestHandler.cs b/source/CubeMS/App_Code/CubeMsRequestHandler.cs index f8cf8c6a..39638ef6 100644 --- a/source/CubeMS/App_Code/CubeMsRequestHandler.cs +++ b/source/CubeMS/App_Code/CubeMsRequestHandler.cs @@ -22,15 +22,17 @@ using AHSoftware.CubeMon.Games.ActionCube.v094; /// public class CubeMsRequestHandler : IHttpHandler { - Log log = new Log(); - CubeMS master; + CubeMasterDAL masterDal; + ServerBlacklist blacklist; int serverListCacheMinutes; - CubeMsRequestHandler() + public CubeMsRequestHandler() { - master = new CubeMS(); - master.ConnectionString = WebConfigurationManager.ConnectionStrings["CubeMS"].ConnectionString; + masterDal = new CubeMasterDAL(); + masterDal.ConnectionString = WebConfigurationManager.ConnectionStrings["CubeMS"].ConnectionString; serverListCacheMinutes = int.Parse(WebConfigurationManager.AppSettings["ServerListCacheMinutes"] ?? "0"); + + blacklist = new ServerBlacklist(HttpContext.Current.Server.MapPath("/Blacklist.xml")); } #region IHttpHandler Members @@ -42,14 +44,18 @@ public class CubeMsRequestHandler : IHttpHandler public void ProcessRequest(HttpContext context) { - IPEndPoint address = new IPEndPoint(IPAddress.Parse(context.Request.UserHostAddress), 0); + + string serverAddress = context.Request.UserHostAddress; + + IPEndPoint address = new IPEndPoint(IPAddress.Parse(serverAddress), 0); string requestFile = Path.GetFileName(context.Request.FilePath); try { if(requestFile == "register.do" && context.Request.QueryString["action"] == "add") { - context.Response.ContentType = "text/plain"; + // fixme + //context.Response.ContentType = "text/plain"; try { @@ -58,28 +64,65 @@ public class CubeMsRequestHandler : IHttpHandler catch { context.Response.Write("Server not registered, invalid request. Maybe you use an older server version?"); - log.AddEvent(Log.EventType.RegistrationFailed, "invalid request", address); + masterDal.AddEvent(CubeMasterDAL.EventType.RegistrationFailed, "invalid request", address); return; } - if(master.Register(address)) + if (blacklist.IsBlacklisted(serverAddress) || context.Request.QueryString["bansample"] == "1") { + /* + context.Response.Write(RickRoll.RickRollMeNow()); + context.Response.Flush(); + */ + + + string lyrics = RickRoll.RickRollMeNow(); + + using(StringReader reader = new StringReader(lyrics)) + { + string line = reader.ReadLine(); + while(line != null) + { + // rick roll them.. line by line + context.Response.Write(line); + context.Response.Write(Environment.NewLine); + context.Response.Flush(); + + //System.Threading.Thread.Sleep(250); + line = reader.ReadLine(); + } + } + + + context.Response.Write(Environment.NewLine); + context.Response.Write("Behave and try again in a few days.."); + masterDal.AddEvent(CubeMasterDAL.EventType.RegistrationFailed, "blacklisted", address); + return; + } + + try + { + masterDal.Register(address); + // TODO: *DOS safety context.Response.Write("Registration successful. Due to caching it might take a few minutes to see the your server in the serverlist"); - log.AddEvent(Log.EventType.RegistrationSuceeeded, null, address); - } - else + masterDal.AddEvent(CubeMasterDAL.EventType.RegistrationSuceeeded, null, address); + } + catch (Exception ex) { - context.Response.Write("Server not registered, could not ping you. Make sure your server is accessible from the internet."); - log.AddEvent(Log.EventType.RegistrationFailed, "ping", address); + context.Response.Write("Server not registered: " + ex.Message + ex.StackTrace); + masterDal.AddEvent(CubeMasterDAL.EventType.RegistrationFailed, null, address); } } else if(requestFile == "retrieve.do") { + string type = context.Request.QueryString["item"]; if(type == "list") { - context.Response.ContentType = "text/plain"; + // fixme + context.Response.ContentType = "text/plain"; + try { @@ -88,13 +131,13 @@ public class CubeMsRequestHandler : IHttpHandler string servers = context.Cache[type] as string; if(servers == null || servers.Length == 0) // empty cache, or empty server list { - servers = master.GetServers(false); + servers = masterDal.GetServers(false); if(serverListCacheMinutes > 0) context.Cache.Add(type, servers, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, serverListCacheMinutes, 0), CacheItemPriority.Normal, null); } - context.Response.Write(servers); + context.Response.Write(servers); context.Response.Flush(); - log.AddEvent(Log.EventType.RetrieveServers, "list", address); + masterDal.AddEvent(CubeMasterDAL.EventType.RetrieveServers, "list", address); // append client script if its an older or unknown client if(bool.Parse((WebConfigurationManager.AppSettings["EnableClientScripts"] ?? "false")) && context.Request.UserAgent != WebConfigurationManager.AppSettings["ClientAgent"]) @@ -102,7 +145,7 @@ public class CubeMsRequestHandler : IHttpHandler string script = context.Cache["script"] as string; if(script == null) { - if((script = master.GetClientScript(context.Request.UserAgent)) != null) + if((script = masterDal.GetClientScript(context.Request.UserAgent)) != null) { int cacheminutes = int.Parse(WebConfigurationManager.AppSettings["ClientScriptCacheMinutes"] ?? "0"); context.Cache.Add("script", script, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, cacheminutes, 0), CacheItemPriority.Normal, null); @@ -113,10 +156,11 @@ public class CubeMsRequestHandler : IHttpHandler { context.Response.Write(script); context.Response.Flush(); - log.AddEvent(Log.EventType.RetrieveServers, "script", address); + masterDal.AddEvent(CubeMasterDAL.EventType.RetrieveServers, "script", address); } } } + /* catch { // send error to the client @@ -124,6 +168,10 @@ public class CubeMsRequestHandler : IHttpHandler context.Response.Flush(); throw; // log errors globally } + */ + finally + { + } } else if(context.Request.QueryString["item"] == "xml") { @@ -132,17 +180,18 @@ public class CubeMsRequestHandler : IHttpHandler string serversXml = context.Cache[type] as string; if(serversXml == null || serversXml.Length == 0) // empty cache, or empty server list { - serversXml = master.GetServers(true); + serversXml = masterDal.GetServers(true); if(serverListCacheMinutes > 0) context.Cache.Add(type, serversXml, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, serverListCacheMinutes, 0), CacheItemPriority.Normal, null); } context.Response.Write(serversXml); context.Response.Flush(); - log.AddEvent(Log.EventType.RetrieveServers, "xml", address); + masterDal.AddEvent(CubeMasterDAL.EventType.RetrieveServers, "xml", address); } } } + /* catch(Exception ex) { try @@ -151,7 +200,10 @@ public class CubeMsRequestHandler : IHttpHandler // log.AddEvent(Log.EventType.Exception, ex.Message, address); } catch { } - } + }*/ + finally + { + } } #endregion diff --git a/source/CubeMS/App_Code/RickRoll.cs b/source/CubeMS/App_Code/RickRoll.cs new file mode 100644 index 00000000..e8c33acf --- /dev/null +++ b/source/CubeMS/App_Code/RickRoll.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +/// +/// Summary description for RickRoll +/// +public static class RickRoll +{ + + static readonly string lyrics = @"Never gonna give you up. +Never gonna let you down. +Never gonna run around and desert you. +Never gonna make you cry. +Never gonna say goodbye. +Never gonna tell a lie and hurt you. "; + + public static string RickRollMeNow() + { + return lyrics; + } + +} diff --git a/source/CubeMS/App_Code/ServerBlacklist.cs b/source/CubeMS/App_Code/ServerBlacklist.cs new file mode 100644 index 00000000..7c26aaa8 --- /dev/null +++ b/source/CubeMS/App_Code/ServerBlacklist.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Xml.Linq; + +/// +/// Summary description for ServerBlacklist +/// +public class ServerBlacklist +{ + List serverIps = new List(); + + public ServerBlacklist(string blacklistFile) + { + XDocument document = XDocument.Load(blacklistFile); + var servers = document.Descendants("Server"); + foreach (var server in servers) + { + serverIps.Add(server.Attribute("IP").Value); + } + } + + public bool IsBlacklisted(string serverIp) + { + return serverIps.Contains(serverIp); + } + +} diff --git a/source/CubeMS/Bin/mysql.data.dll b/source/CubeMS/Bin/mysql.data.dll new file mode 100644 index 00000000..209cf282 Binary files /dev/null and b/source/CubeMS/Bin/mysql.data.dll differ diff --git a/source/CubeMS/Blacklist.xml b/source/CubeMS/Blacklist.xml new file mode 100644 index 00000000..6225e37c --- /dev/null +++ b/source/CubeMS/Blacklist.xml @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/CubeMS/Default.aspx b/source/CubeMS/Default.aspx index 088c33b1..e7faac2a 100644 --- a/source/CubeMS/Default.aspx +++ b/source/CubeMS/Default.aspx @@ -12,13 +12,14 @@

AssaultCube Master Server

Server List

  - - <%# IPTools.IntToIp((int)DataBinder.Eval(Container.DataItem, "IP")).ToString() %> + <%-- <%# IPTools.IntToIp((int)DataBinder.Eval(Container.DataItem, "IP")).ToString() %> --%> @@ -35,14 +36,8 @@ - -

Interfaces

-

- You can retrieve the server list data using those url's: -

diff --git a/source/CubeMS/cgi-bin/actioncube.pl/info.txt b/source/CubeMS/cgi-bin/actioncube.pl/info.txt new file mode 100644 index 00000000..cb66f106 --- /dev/null +++ b/source/CubeMS/cgi-bin/actioncube.pl/info.txt @@ -0,0 +1,6 @@ +This directory is required to fool apache. + +The masterserver http handler dispatches requests matching *.do +However apache always checks if the requested file/dir actually exists, +if not the request is being aborted. Therefore we need this directory +to ensure that the request reaches our http handler. diff --git a/source/CubeMS/web.config b/source/CubeMS/web.config index 756e0402..6920d689 100644 --- a/source/CubeMS/web.config +++ b/source/CubeMS/web.config @@ -8,16 +8,32 @@ \Windows\Microsoft.Net\Framework\v2.x\Config --> + + + + +
+ +
+
+
+
+ + + + - - - - - + + + + + - + + - + + + + + + + - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +