mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2025-04-21 03:29:36 +08:00

* 添加SQLite模式 * 将Hashtable转为Dictionary<string, object>,因为它具有性能优势 * 添加GamingRequest用于区分Gaming * 模组中AfterLoad方法现已移动至加载器完全加载完毕后触发 * 删除了服务器对GameModule的加载,现在只会加载GameModuleServer
234 lines
9.0 KiB
C#
234 lines
9.0 KiB
C#
using System.Net;
|
|
using System.Net.WebSockets;
|
|
using System.Text;
|
|
using Milimoe.FunGame.Core.Api.Utility;
|
|
using Milimoe.FunGame.Core.Library.Common.Network;
|
|
using Milimoe.FunGame.Core.Library.Constant;
|
|
using Milimoe.FunGame.Core.Library.Exception;
|
|
|
|
namespace Milimoe.FunGame.Core.Service
|
|
{
|
|
internal class HTTPManager
|
|
{
|
|
internal static HttpListener? ServerSocket => _ServerSocket;
|
|
private static HttpListener? _ServerSocket = null;
|
|
|
|
internal static HttpListener StartListening(int port = 22227, bool ssl = false)
|
|
{
|
|
HttpListener listener = new();
|
|
listener.Prefixes.Add((ssl ? "https://" : "http://") + "localhost:" + port + "/ws");
|
|
listener.Start();
|
|
return listener;
|
|
}
|
|
|
|
internal static async Task<System.Net.WebSockets.ClientWebSocket?> Connect(Uri uri)
|
|
{
|
|
System.Net.WebSockets.ClientWebSocket socket = new();
|
|
await socket.ConnectAsync(uri, CancellationToken.None);
|
|
if (socket.State == WebSocketState.Open)
|
|
{
|
|
return socket;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
internal static async Task<SocketResult> Send(System.Net.WebSockets.ClientWebSocket socket, SocketObject obj)
|
|
{
|
|
if (socket != null)
|
|
{
|
|
try
|
|
{
|
|
await socket.SendAsync(new ArraySegment<byte>(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))), WebSocketMessageType.Text, true, CancellationToken.None);
|
|
return SocketResult.Success;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
|
return SocketResult.Fail;
|
|
}
|
|
}
|
|
return SocketResult.NotSent;
|
|
}
|
|
|
|
internal static async Task<SocketResult> Send(WebSocket socket, SocketObject obj)
|
|
{
|
|
if (socket != null)
|
|
{
|
|
try
|
|
{
|
|
await socket.SendAsync(new ArraySegment<byte>(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))), WebSocketMessageType.Text, true, CancellationToken.None);
|
|
return SocketResult.Success;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
|
return SocketResult.Fail;
|
|
}
|
|
}
|
|
return SocketResult.NotSent;
|
|
}
|
|
|
|
internal static async Task Receiving(HTTPListener listener)
|
|
{
|
|
if (ServerSocket != null)
|
|
{
|
|
try
|
|
{
|
|
while (true)
|
|
{
|
|
HttpListenerContext context = await ServerSocket.GetContextAsync();
|
|
if (context.Request.IsWebSocketRequest)
|
|
{
|
|
TaskUtility.NewTask(async () => await AddClientWebSocket(listener, context));
|
|
}
|
|
else
|
|
{
|
|
context.Response.StatusCode = 400;
|
|
context.Response.Close();
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
_ServerSocket = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static async Task<bool> ReceiveMessage(HTTPClient client)
|
|
{
|
|
if (client.Instance is null) return false;
|
|
|
|
byte[] buffer = new byte[General.SocketByteSize];
|
|
WebSocketReceiveResult result = await client.Instance.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
string msg = Encoding.UTF8.GetString(buffer).Replace("\0", "").Trim();
|
|
SocketObject[] objs = await GetSocketObjects(client.Instance, result, msg);
|
|
|
|
foreach (SocketObject obj in objs)
|
|
{
|
|
SocketObject sendobject = client.SocketObject_Handler(obj);
|
|
if (obj.SocketType == SocketMessageType.Connect)
|
|
{
|
|
return true;
|
|
}
|
|
else if (obj.SocketType == SocketMessageType.Disconnect)
|
|
{
|
|
await client.Instance.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, result.CloseStatusDescription, CancellationToken.None);
|
|
return true;
|
|
}
|
|
await Send(client.Instance, sendobject);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private static async Task AddClientWebSocket(HTTPListener listener, HttpListenerContext context)
|
|
{
|
|
HttpListenerWebSocketContext socketContext = await context.AcceptWebSocketAsync(null);
|
|
WebSocket socket = socketContext.WebSocket;
|
|
|
|
byte[] buffer = new byte[General.SocketByteSize];
|
|
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
string msg = Encoding.UTF8.GetString(buffer).Replace("\0", "").Trim();
|
|
|
|
SocketObject sendobject = new(SocketMessageType.Unknown, Guid.Empty);
|
|
SocketObject[] objs = await GetSocketObjects(socket, result, msg);
|
|
bool isConnect = false;
|
|
|
|
foreach (SocketObject obj in objs)
|
|
{
|
|
if (obj.SocketType == SocketMessageType.Connect)
|
|
{
|
|
isConnect = listener.CheckClientConnection(obj);
|
|
}
|
|
else if (listener.ClientSockets.ContainsKey(obj.Token))
|
|
{
|
|
sendobject = listener.SocketObject_Handler(obj);
|
|
isConnect = true;
|
|
}
|
|
}
|
|
|
|
if (isConnect)
|
|
{
|
|
Guid token = Guid.NewGuid();
|
|
listener.ClientSockets.TryAdd(token, socket);
|
|
await Send(socket, sendobject);
|
|
|
|
while (socket.State == WebSocketState.Open)
|
|
{
|
|
try
|
|
{
|
|
buffer = new byte[General.SocketByteSize];
|
|
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
|
|
if (result.CloseStatus.HasValue)
|
|
{
|
|
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
|
return;
|
|
}
|
|
|
|
msg = Encoding.UTF8.GetString(buffer).Replace("\0", "").Trim();
|
|
objs = await GetSocketObjects(socket, result, msg);
|
|
foreach (SocketObject obj in objs)
|
|
{
|
|
sendobject = listener.SocketObject_Handler(obj);
|
|
if (obj.SocketType == SocketMessageType.Disconnect)
|
|
{
|
|
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Disconnect received", CancellationToken.None);
|
|
return;
|
|
}
|
|
await Send(socket, sendobject);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// 处理其他异常
|
|
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
|
await socket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Server Error", CancellationToken.None);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static async Task<SocketObject[]> GetSocketObjects(WebSocket socket, WebSocketReceiveResult result, string msg)
|
|
{
|
|
List<SocketObject> objs = [];
|
|
|
|
if (JsonManager.IsCompleteJson<SocketObject>(msg))
|
|
{
|
|
foreach (SocketObject obj in JsonManager.GetObjects<SocketObject>(msg))
|
|
{
|
|
objs.Add(obj);
|
|
}
|
|
return [.. objs];
|
|
}
|
|
else
|
|
{
|
|
await Task.Delay(20);
|
|
while (true)
|
|
{
|
|
if (!result.CloseStatus.HasValue)
|
|
{
|
|
byte[] buffer = new byte[General.SocketByteSize];
|
|
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
msg += General.DefaultEncoding.GetString(buffer).Replace("\0", "").Trim();
|
|
if (JsonManager.IsCompleteJson<SocketObject>(msg))
|
|
{
|
|
break;
|
|
}
|
|
await Task.Delay(20);
|
|
}
|
|
else break;
|
|
}
|
|
foreach (SocketObject obj in JsonManager.GetObjects<SocketObject>(msg))
|
|
{
|
|
objs.Add(obj);
|
|
}
|
|
}
|
|
|
|
return [.. objs];
|
|
}
|
|
}
|
|
}
|