diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/Config.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/Config.cs index 02b85ce..7e54ad1 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/Config.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/Config.cs @@ -11,5 +11,8 @@ namespace LightReflectiveMirror public string AuthenticationKey = "Secret Auth Key"; public int UpdateLoopTime = 10; public int UpdateHeartbeatInterval = 100; + public bool UseEndpoint = false; + public ushort EndpointPort = 6969; + public bool EndpointServerList = false; } } diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/Endpoint.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/Endpoint.cs new file mode 100644 index 0000000..459db41 --- /dev/null +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/Endpoint.cs @@ -0,0 +1,84 @@ +using Grapevine; +using Newtonsoft.Json; +using System; +using System.Threading.Tasks; + +namespace LightReflectiveMirror.Endpoints +{ + [Serializable] + struct RelayStats + { + public int ConnectedClients; + public int RoomCount; + public int PublicRoomCount; + public TimeSpan Uptime; + } + + [RestResource] + public class Endpoint + { + [RestRoute("Get", "/api/stats")] + public async Task Stats(IHttpContext context) + { + RelayStats stats = new RelayStats + { + ConnectedClients = Program.instance.GetConnections(), + RoomCount = Program.instance.GetRooms().Count, + PublicRoomCount = Program.instance.GetPublicRoomCount(), + Uptime = Program.instance.GetUptime() + }; + + string json = JsonConvert.SerializeObject(stats, Formatting.Indented); + await context.Response.SendResponseAsync(json); + } + + [RestRoute("Get", "/api/servers")] + public async Task ServerList(IHttpContext context) + { + if (Program.conf.EndpointServerList) + { + string json = JsonConvert.SerializeObject(Program.instance.GetRooms(), Formatting.Indented); + await context.Response.SendResponseAsync(json); + } + else + { + await context.Response.SendResponseAsync("Access Denied"); + } + } + } + + public class EndpointServer + { + public bool Start(ushort port = 6969) + { + try + { + var server = RestServerBuilder.UseDefaults().Build(); + server.Prefixes.Remove($"http://localhost:{1234}/"); + server.Prefixes.Add($"http://*:{port}/"); + server.Router.Options.SendExceptionMessages = false; + + server.AfterStarting += (s) => + { + string startup = @" +******************************************************************************** +* Endpoint Server listening on "+$"{string.Join(", ", server.Prefixes)}" + @" +* Be sure to Port Forward! :^) +******************************************************************************** +"; + Console.WriteLine(startup); + }; + + server.Start(); + + return true; + } + catch + { + return false; + } + + } + } +} + diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/Program.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/Program.cs index 95effd8..e9ae165 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/Program.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/Program.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Threading.Tasks; +using LightReflectiveMirror.Endpoints; using Mirror; using Newtonsoft.Json; @@ -11,6 +13,7 @@ namespace LightReflectiveMirror class Program { public static Transport transport; + public static Program instance; public static Config conf; private RelayHandler _relay; @@ -19,17 +22,25 @@ namespace LightReflectiveMirror private MethodInfo _updateMethod; private MethodInfo _lateUpdateMethod; + private DateTime _startupTime; + private List _currentConnections = new List(); private int _currentHeartbeatTimer = 0; private const string CONFIG_PATH = "config.json"; - public static void Main(string[] args) - => new Program().MainAsync().GetAwaiter().GetResult(); + public static void Main(string[] args) => new Program().MainAsync().GetAwaiter().GetResult(); + + public int GetConnections() => _currentConnections.Count; + public TimeSpan GetUptime() => DateTime.Now - _startupTime; + public int GetPublicRoomCount() => _relay.rooms.Where(x => x.isPublic).Count(); + public List GetRooms() => _relay.rooms; public async Task MainAsync() { WriteTitle(); + instance = this; + _startupTime = DateTime.Now; if (!File.Exists(CONFIG_PATH)) { @@ -93,6 +104,16 @@ namespace LightReflectiveMirror transport.ServerStart(); WriteLogMessage("Transport Started!", ConsoleColor.Green); + + if (conf.UseEndpoint) + { + var endpoint = new EndpointServer(); + + if (endpoint.Start(conf.EndpointPort)) + WriteLogMessage("Endpoint Service Started!", ConsoleColor.Green); + else + WriteLogMessage("Endpoint failure, please run as administrator.", ConsoleColor.Red); + } } else { diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/RelayHandler.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/RelayHandler.cs index 9becbaf..0ffbe76 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/RelayHandler.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/RelayHandler.cs @@ -7,7 +7,7 @@ namespace LightReflectiveMirror { public class RelayHandler { - private List _rooms = new List(); + public List rooms = new List(); private List _pendingAuthentication = new List(); private ArrayPool _sendBuffers; private int _maxPacketSize = 0; @@ -115,16 +115,16 @@ namespace LightReflectiveMirror int pos = 0; var buffer = _sendBuffers.Rent(500); buffer.WriteByte(ref pos, (byte)OpCodes.ServerListReponse); - for(int i = 0; i < _rooms.Count; i++) + for(int i = 0; i < rooms.Count; i++) { - if (_rooms[i].isPublic) + if (rooms[i].isPublic) { buffer.WriteBool(ref pos, true); - buffer.WriteString(ref pos, _rooms[i].serverName); - buffer.WriteString(ref pos, _rooms[i].serverData); - buffer.WriteInt(ref pos, _rooms[i].serverId); - buffer.WriteInt(ref pos, _rooms[i].maxPlayers); - buffer.WriteInt(ref pos, _rooms[i].clients.Count + 1); + buffer.WriteString(ref pos, rooms[i].serverName); + buffer.WriteString(ref pos, rooms[i].serverData); + buffer.WriteInt(ref pos, rooms[i].serverId); + buffer.WriteInt(ref pos, rooms[i].maxPlayers); + buffer.WriteInt(ref pos, rooms[i].clients.Count + 1); } } buffer.WriteBool(ref pos, false); @@ -172,13 +172,13 @@ namespace LightReflectiveMirror Room GetRoomForPlayer(int clientId) { - for(int i = 0; i < _rooms.Count; i++) + for(int i = 0; i < rooms.Count; i++) { - if (_rooms[i].hostId == clientId) - return _rooms[i]; + if (rooms[i].hostId == clientId) + return rooms[i]; - if (_rooms[i].clients.Contains(clientId)) - return _rooms[i]; + if (rooms[i].clients.Contains(clientId)) + return rooms[i]; } return null; @@ -188,13 +188,13 @@ namespace LightReflectiveMirror { LeaveRoom(clientId); - for(int i = 0; i < _rooms.Count; i++) + for(int i = 0; i < rooms.Count; i++) { - if(_rooms[i].serverId == serverId) + if(rooms[i].serverId == serverId) { - if(_rooms[i].clients.Count < _rooms[i].maxPlayers) + if(rooms[i].clients.Count < rooms[i].maxPlayers) { - _rooms[i].clients.Add(clientId); + rooms[i].clients.Add(clientId); int sendJoinPos = 0; byte[] sendJoinBuffer = _sendBuffers.Rent(5); @@ -203,7 +203,7 @@ namespace LightReflectiveMirror sendJoinBuffer.WriteInt(ref sendJoinPos, clientId); Program.transport.ServerSend(clientId, 0, new ArraySegment(sendJoinBuffer, 0, sendJoinPos)); - Program.transport.ServerSend(_rooms[i].hostId, 0, new ArraySegment(sendJoinBuffer, 0, sendJoinPos)); + Program.transport.ServerSend(rooms[i].hostId, 0, new ArraySegment(sendJoinBuffer, 0, sendJoinPos)); _sendBuffers.Return(sendJoinBuffer); return; } @@ -236,7 +236,7 @@ namespace LightReflectiveMirror serverId = GetRandomServerID() }; - _rooms.Add(room); + rooms.Add(room); int pos = 0; byte[] sendBuffer = _sendBuffers.Rent(5); @@ -250,28 +250,28 @@ namespace LightReflectiveMirror void LeaveRoom(int clientId, int requiredHostId = -1) { - for(int i = 0; i < _rooms.Count; i++) + for(int i = 0; i < rooms.Count; i++) { - if(_rooms[i].hostId == clientId) + if(rooms[i].hostId == clientId) { int pos = 0; byte[] sendBuffer = _sendBuffers.Rent(1); sendBuffer.WriteByte(ref pos, (byte)OpCodes.ServerLeft); - for(int x = 0; x < _rooms[i].clients.Count; x++) - Program.transport.ServerSend(_rooms[i].clients[x], 0, new ArraySegment(sendBuffer, 0, pos)); + for(int x = 0; x < rooms[i].clients.Count; x++) + Program.transport.ServerSend(rooms[i].clients[x], 0, new ArraySegment(sendBuffer, 0, pos)); _sendBuffers.Return(sendBuffer); - _rooms[i].clients.Clear(); - _rooms.RemoveAt(i); + rooms[i].clients.Clear(); + rooms.RemoveAt(i); return; } else { - if (requiredHostId >= 0 && _rooms[i].hostId != requiredHostId) + if (requiredHostId >= 0 && rooms[i].hostId != requiredHostId) continue; - if(_rooms[i].clients.RemoveAll(x => x == clientId) > 0) + if(rooms[i].clients.RemoveAll(x => x == clientId) > 0) { int pos = 0; byte[] sendBuffer = _sendBuffers.Rent(5); @@ -279,7 +279,7 @@ namespace LightReflectiveMirror sendBuffer.WriteByte(ref pos, (byte)OpCodes.PlayerDisconnected); sendBuffer.WriteInt(ref pos, clientId); - Program.transport.ServerSend(_rooms[i].hostId, 0, new ArraySegment(sendBuffer, 0, pos)); + Program.transport.ServerSend(rooms[i].hostId, 0, new ArraySegment(sendBuffer, 0, pos)); _sendBuffers.Return(sendBuffer); } } @@ -311,8 +311,8 @@ namespace LightReflectiveMirror bool DoesServerIdExist(int id) { - for (int i = 0; i < _rooms.Count; i++) - if (_rooms[i].serverId == id) + for (int i = 0; i < rooms.Count; i++) + if (rooms[i].serverId == id) return true; return false; diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/Room.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/Room.cs index a284c10..32c032b 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/Room.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/Room.cs @@ -4,7 +4,8 @@ using System.Text; namespace LightReflectiveMirror { - class Room + [Serializable] + public class Room { public int serverId; public int hostId;