Added REST api functionality

This commit is contained in:
cxxpxr 2021-03-31 15:08:29 -04:00
parent 964c3deeb2
commit ec875235aa
5 changed files with 126 additions and 33 deletions

View file

@ -11,5 +11,7 @@ namespace LightReflectiveMirror
public string AuthenticationKey = "Secret Auth Key";
public int UpdateLoopTime = 10;
public int UpdateHeartbeatInterval = 100;
public bool UseEndpoint = false;
public ushort EndpointPort = 6969;
}
}

View file

@ -0,0 +1,70 @@
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);
}
}
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;
}
}
}
}

View file

@ -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<int> _currentConnections = new List<int>();
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<Room> 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
{

View file

@ -7,7 +7,7 @@ namespace LightReflectiveMirror
{
public class RelayHandler
{
private List<Room> _rooms = new List<Room>();
public List<Room> rooms = new List<Room>();
private List<int> _pendingAuthentication = new List<int>();
private ArrayPool<byte> _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<byte>(sendJoinBuffer, 0, sendJoinPos));
Program.transport.ServerSend(_rooms[i].hostId, 0, new ArraySegment<byte>(sendJoinBuffer, 0, sendJoinPos));
Program.transport.ServerSend(rooms[i].hostId, 0, new ArraySegment<byte>(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<byte>(sendBuffer, 0, pos));
for(int x = 0; x < rooms[i].clients.Count; x++)
Program.transport.ServerSend(rooms[i].clients[x], 0, new ArraySegment<byte>(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<byte>(sendBuffer, 0, pos));
Program.transport.ServerSend(rooms[i].hostId, 0, new ArraySegment<byte>(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;

View file

@ -4,7 +4,7 @@ using System.Text;
namespace LightReflectiveMirror
{
class Room
public class Room
{
public int serverId;
public int hostId;