diff --git a/TShockAPI/Rest.cs b/TShockAPI/Rest.cs new file mode 100644 index 00000000..55d8408b --- /dev/null +++ b/TShockAPI/Rest.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using HttpServer; +using HttpServer.Headers; +using HttpListener = HttpServer.HttpListener; + +namespace TShockAPI +{ + /// + /// Rest command delegate + /// + /// Parameters in the url + /// Http request + /// Response body or null to not handle request + public delegate string RestCommandD(IParameterCollection parameters, RequestEventArgs request); + public class Rest : IDisposable + { + List commands = new List(); + HttpListener listener; + + public Rest(IPAddress ip, int port) + { + listener = HttpListener.Create(ip, port); + listener.RequestReceived += OnRequest; + } + + public void Start() + { + listener.Start(int.MaxValue); + } + public void Stop() + { + listener.Stop(); + } + + public void Register(string path, RestCommandD callback) + { + Register(new RestCommand(path, callback)); + } + + public void Register(RestCommand com) + { + commands.Add(com); + } + + void OnRequest(object sender, RequestEventArgs e) + { + var coms = commands.Where(r => r.Path.ToLower().Equals(e.Request.Uri.AbsolutePath.ToLower())); + foreach (var com in coms) + { + var str = com.Callback(e.Request.Parameters, e); + if (str != null) + { + e.Response.Connection.Type = ConnectionType.Close; + e.Response.Body.Write(Encoding.ASCII.GetBytes(str), 0, str.Length); + e.Response.Status = HttpStatusCode.OK; + return; + } + } + string error = "Error: Invalid request"; + e.Response.Connection.Type = ConnectionType.Close; + e.Response.Body.Write(Encoding.ASCII.GetBytes(error), 0, error.Length); + e.Response.Status = HttpStatusCode.InternalServerError; + } + + #region Dispose + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + protected void Dispose(bool disposing) + { + if (disposing) + { + if (listener != null) + { + listener.Stop(); + listener = null; + } + } + } + ~Rest() + { + Dispose(false); + } + + #endregion + } + + public class RestCommand + { + public string Path { get; protected set; } + public RestCommandD Callback { get; protected set; } + + public RestCommand(string path, RestCommandD callback) + { + Path = path; + Callback = callback; + } + } +} diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 89038817..a5488dbc 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -36,6 +36,7 @@ using System.Reflection; using System.Linq; using System.Threading; using Community.CsharpSqlite.SQLiteClient; +using HttpServer; using MySql.Data.MySqlClient; using Terraria; using TerrariaAPI; @@ -67,6 +68,7 @@ namespace TShockAPI public static bool OverridePort; public static PacketBufferer PacketBuffer; public static MaxMind.GeoIPCountry Geo; + public static Rest RestApi; /// /// Called after TShock is initialized. Useful for plugins that needs hooks before tshock but also depend on tshock being loaded. @@ -172,6 +174,7 @@ namespace TShockAPI Regions = new RegionManager(DB); Itembans = new ItemManager(DB); RememberedPos = new RemeberedPosManager(DB); + RestApi = new Rest(IPAddress.Any, 8080); if (Config.EnableGeoIP) Geo = new MaxMind.GeoIPCountry(Path.Combine(SavePath, "GeoIP.dat")); @@ -200,6 +203,8 @@ namespace TShockAPI if (Initialized != null) Initialized(); + + RestApi.Register(new RestCommand("/users", usertest)); } catch (Exception ex) { @@ -226,9 +231,23 @@ namespace TShockAPI Console.WriteLine("Thanks for using TShock! Process ID file is now being destroyed."); File.Delete(Path.Combine(SavePath, "tshock.pid")); } + RestApi.Dispose(); //RconHandler.ShutdownAllThreads(); } + //http://127.0.0.1:8080/users?type=status + string usertest(IParameterCollection parameters, RequestEventArgs request) + { + var type = parameters["type"]; + if (type == null) + return "Invalid Type"; + if (type == "status") + { + return "Users online here"; + } + return null; + } + /// /// Handles exceptions that we didn't catch or that Red fucked up /// @@ -353,6 +372,7 @@ namespace TShockAPI AuthToken = 0; } Regions.ReloadAllRegions(); + RestApi.Start(); } diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index 523752e5..f6dfb3e8 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -52,6 +52,9 @@ False ..\SqlBins\Community.CsharpSqlite.SQLiteClient.dll + + ..\HttpBins\HttpServer.dll + False ..\SqlBins\MySql.Data.dll @@ -121,6 +124,7 @@ True Resources.resx + @@ -177,7 +181,7 @@ - +