This repository has been archived by the owner on Sep 5, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
1,399 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace LightReflectiveMirror | ||
{ | ||
class Config | ||
{ | ||
public string TransportDLL = "SimpleWebSocketTransportCompiled.dll"; | ||
public string TransportClass = "Mirror.SimpleWeb.SimpleWebTransport"; | ||
public string AuthenticationKey = "Secret Auth Key"; | ||
public int UpdateLoopTime = 50; | ||
public int UpdateHeartbeatInterval = 20; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace LightReflectiveMirror | ||
{ | ||
public static class DataHandler | ||
{ | ||
public static void WriteByte(this byte[] data, ref int position, byte value) | ||
{ | ||
data[position] = value; | ||
position += 1; | ||
} | ||
|
||
public static byte ReadByte(this byte[] data, ref int position) | ||
{ | ||
byte value = data[position]; | ||
position += 1; | ||
return value; | ||
} | ||
|
||
public static void WriteBool(this byte[] data, ref int position, bool value) | ||
{ | ||
unsafe | ||
{ | ||
fixed(byte* dataPtr = &data[position]) | ||
{ | ||
bool* valuePtr = (bool*)dataPtr; | ||
*valuePtr = value; | ||
position += 1; | ||
} | ||
} | ||
} | ||
|
||
public static bool ReadBool(this byte[] data, ref int position) | ||
{ | ||
bool value = BitConverter.ToBoolean(data, position); | ||
position += 1; | ||
return value; | ||
} | ||
|
||
public static void WriteString(this byte[] data, ref int position, string value) | ||
{ | ||
data.WriteInt(ref position, value.Length); | ||
for (int i = 0; i < value.Length; i++) | ||
data.WriteChar(ref position, value[i]); | ||
} | ||
|
||
public static string ReadString(this byte[] data, ref int position) | ||
{ | ||
string value = default; | ||
|
||
int stringSize = data.ReadInt(ref position); | ||
|
||
for (int i = 0; i < stringSize; i++) | ||
value += data.ReadChar(ref position); | ||
|
||
return value; | ||
} | ||
|
||
public static void WriteBytes(this byte[] data, ref int position, byte[] value) | ||
{ | ||
data.WriteInt(ref position, value.Length); | ||
for (int i = 0; i < value.Length; i++) | ||
data.WriteByte(ref position, value[i]); | ||
} | ||
|
||
public static byte[] ReadBytes(this byte[] data, ref int position) | ||
{ | ||
int byteSize = data.ReadInt(ref position); | ||
|
||
byte[] value = new byte[byteSize]; | ||
|
||
for (int i = 0; i < byteSize; i++) | ||
value[i] = data.ReadByte(ref position); | ||
|
||
return value; | ||
} | ||
|
||
public static void WriteChar(this byte[] data, ref int position, char value) | ||
{ | ||
unsafe | ||
{ | ||
fixed (byte* dataPtr = &data[position]) | ||
{ | ||
char* valuePtr = (char*)dataPtr; | ||
*valuePtr = value; | ||
position += 2; | ||
} | ||
} | ||
} | ||
|
||
public static char ReadChar(this byte[] data, ref int position) | ||
{ | ||
char value = BitConverter.ToChar(data, position); | ||
position += 2; | ||
return value; | ||
} | ||
|
||
public static void WriteInt(this byte[] data, ref int position, int value) | ||
{ | ||
unsafe | ||
{ | ||
fixed (byte* dataPtr = &data[position]) | ||
{ | ||
int* valuePtr = (int*)dataPtr; | ||
*valuePtr = value; | ||
position += 4; | ||
} | ||
} | ||
} | ||
|
||
public static int ReadInt(this byte[] data, ref int position) | ||
{ | ||
int value = BitConverter.ToInt32(data, position); | ||
position += 4; | ||
return value; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Reflection; | ||
using System.Threading.Tasks; | ||
using Mirror; | ||
using Newtonsoft.Json; | ||
|
||
namespace LightReflectiveMirror | ||
{ | ||
class Program | ||
{ | ||
public static Config conf; | ||
RelayHandler relay; | ||
public static Transport transport; | ||
MethodInfo awakeMethod; | ||
MethodInfo startMethod; | ||
MethodInfo updateMethod; | ||
MethodInfo lateUpdateMethod; | ||
List<int> _currentConnections = new List<int>(); | ||
int _currentHeartbeatTimer = 0; | ||
|
||
public static void Main(string[] args) | ||
=> new Program().MainAsync().GetAwaiter().GetResult(); | ||
|
||
public async Task MainAsync() | ||
{ | ||
|
||
if (!File.Exists("config.json")) | ||
{ | ||
File.WriteAllText("config.json", JsonConvert.SerializeObject(new Config(), Formatting.Indented)); | ||
WriteLogMessage("A config.json file was generated. Please configure it to the proper settings and re-run!", ConsoleColor.Yellow); | ||
Console.ReadKey(); | ||
Environment.Exit(0); | ||
} | ||
else | ||
{ | ||
conf = JsonConvert.DeserializeObject<Config>(File.ReadAllText("config.json")); | ||
try | ||
{ | ||
Console.WriteLine(Directory.GetCurrentDirectory()); | ||
var asm = Assembly.LoadFile(Directory.GetCurrentDirectory() + @"\" + conf.TransportDLL); | ||
WriteLogMessage($"Loaded Assembly: {asm.FullName}", ConsoleColor.Green); | ||
transport = (Transport)asm.CreateInstance(conf.TransportClass); | ||
|
||
if (transport != null) | ||
{ | ||
WriteLogMessage($"Loaded Transport: {asm.GetType(conf.TransportClass).Name}! Loading Methods...", ConsoleColor.Green); | ||
CheckMethods(asm.GetType(conf.TransportClass)); | ||
|
||
if (awakeMethod != null) | ||
{ | ||
awakeMethod.Invoke(transport, null); | ||
WriteLogMessage("Called Awake on transport.", ConsoleColor.Yellow); | ||
} | ||
|
||
if (startMethod != null) | ||
{ | ||
awakeMethod.Invoke(transport, null); | ||
WriteLogMessage("Called Start on transport.", ConsoleColor.Yellow); | ||
} | ||
|
||
WriteLogMessage("Starting Transport...", ConsoleColor.Green); | ||
|
||
transport.OnServerError = (clientID, error) => { | ||
WriteLogMessage($"Transport Error, Client: {clientID}, Error: {error}", ConsoleColor.Red); | ||
}; | ||
|
||
transport.OnServerConnected = (clientID) => | ||
{ | ||
WriteLogMessage($"Transport Connected, Client: {clientID}", ConsoleColor.Cyan); | ||
_currentConnections.Add(clientID); | ||
relay.ClientConnected(clientID); | ||
}; | ||
|
||
relay = new RelayHandler(transport.GetMaxPacketSize(0)); | ||
|
||
transport.OnServerDataReceived = relay.HandleMessage; | ||
transport.OnServerDisconnected = (clientID) => | ||
{ | ||
_currentConnections.Remove(clientID); | ||
relay.HandleDisconnect(clientID); | ||
}; | ||
|
||
transport.ServerStart(); | ||
|
||
WriteLogMessage("Transport Started!", ConsoleColor.Green); | ||
} | ||
else | ||
{ | ||
WriteLogMessage("Transport Class not found! Please make sure to include namespaces.", ConsoleColor.Red); | ||
Console.ReadKey(); | ||
Environment.Exit(0); | ||
} | ||
} | ||
catch(Exception e) | ||
{ | ||
WriteLogMessage("Exception: " + e, ConsoleColor.Red); | ||
Console.ReadKey(); | ||
Environment.Exit(0); | ||
} | ||
} | ||
|
||
while (true) | ||
{ | ||
if (updateMethod != null) | ||
updateMethod.Invoke(transport, null); | ||
|
||
if (lateUpdateMethod != null) | ||
lateUpdateMethod.Invoke(transport, null); | ||
|
||
_currentHeartbeatTimer++; | ||
|
||
if(_currentHeartbeatTimer >= conf.UpdateHeartbeatInterval) | ||
{ | ||
_currentHeartbeatTimer = 0; | ||
|
||
for(int i = 0; i < _currentConnections.Count; i++) | ||
{ | ||
transport.ServerSend(_currentConnections[i], 0, new ArraySegment<byte>(new byte[] { 200 })); | ||
} | ||
} | ||
|
||
await Task.Delay(conf.UpdateLoopTime); | ||
} | ||
} | ||
|
||
static void WriteLogMessage(string message, ConsoleColor color = ConsoleColor.White) | ||
{ | ||
Console.ForegroundColor = color; | ||
Console.WriteLine(message); | ||
} | ||
|
||
void CheckMethods(Type type) | ||
{ | ||
awakeMethod = type.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | ||
startMethod = type.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | ||
updateMethod = type.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | ||
lateUpdateMethod = type.GetMethod("LateUpdate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | ||
|
||
if (awakeMethod != null) | ||
WriteLogMessage("'Awake' Loaded!", ConsoleColor.Yellow); | ||
|
||
if (startMethod != null) | ||
WriteLogMessage("'Start' Loaded!", ConsoleColor.Yellow); | ||
|
||
if (updateMethod != null) | ||
WriteLogMessage("'Update' Loaded!", ConsoleColor.Yellow); | ||
|
||
if (lateUpdateMethod != null) | ||
WriteLogMessage("'LateUpdate' Loaded!", ConsoleColor.Yellow); | ||
} | ||
} | ||
} |
Oops, something went wrong.