完善 WebSocket 支持;防止 SQL 注入;修改 Json 自定义转换器基类 (#104)

* 更换任务计划实现方式;修改自定义 Json 转换器基类

* RunTimeController 添加 HTTPClient(WebSocket)支持;SQL 查询修改为参数化,防止注入
This commit is contained in:
milimoe 2025-01-11 01:09:49 +08:00 committed by GitHub
parent 1168f5dd7b
commit 18854781a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 536 additions and 206 deletions

View File

@ -18,6 +18,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
public abstract SQLServerInfo ServerInfo { get; } public abstract SQLServerInfo ServerInfo { get; }
public abstract int UpdateRows { get; } public abstract int UpdateRows { get; }
public abstract DataSet DataSet { get; } public abstract DataSet DataSet { get; }
public abstract Dictionary<string, object> Parameters { get; }
public bool Success => Result == SQLResult.Success; public bool Success => Result == SQLResult.Success;
/// <summary> /// <summary>

View File

@ -12,7 +12,6 @@ namespace Milimoe.FunGame.Core.Api.Utility
private readonly List<ScheduledTask> _tasks = []; private readonly List<ScheduledTask> _tasks = [];
private readonly List<RecurringTask> _recurringTasks = []; private readonly List<RecurringTask> _recurringTasks = [];
private readonly Timer _timer;
private readonly Lock _lock = new(); private readonly Lock _lock = new();
/// <summary> /// <summary>
@ -20,8 +19,14 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// </summary> /// </summary>
public TaskScheduler() public TaskScheduler()
{ {
_timer = new Timer(CheckAndRunTasks, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); Task.Factory.StartNew(async () =>
_timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1)); {
while (true)
{
CheckAndRunTasks();
await Task.Delay(1000);
}
}, TaskCreationOptions.LongRunning);
} }
/// <summary> /// <summary>
@ -158,8 +163,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <summary> /// <summary>
/// 执行任务 /// 执行任务
/// </summary> /// </summary>
/// <param name="state"></param> private void CheckAndRunTasks()
private void CheckAndRunTasks(object? state)
{ {
lock (_lock) lock (_lock)
{ {
@ -172,7 +176,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
if (now.TimeOfDay >= task.TimeOfDay && now.TimeOfDay < task.TimeOfDay.Add(TimeSpan.FromSeconds(10))) if (now.TimeOfDay >= task.TimeOfDay && now.TimeOfDay < task.TimeOfDay.Add(TimeSpan.FromSeconds(10)))
{ {
task.LastRun = now; task.LastRun = now;
ThreadPool.QueueUserWorkItem(_ => Task.Run(() =>
{ {
try try
{ {
@ -193,7 +197,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
{ {
recurringTask.LastRun = now; recurringTask.LastRun = now;
recurringTask.NextRun = recurringTask.NextRun.Add(recurringTask.Interval); recurringTask.NextRun = recurringTask.NextRun.Add(recurringTask.Interval);
ThreadPool.QueueUserWorkItem(_ => Task.Run(() =>
{ {
try try
{ {

View File

@ -17,6 +17,11 @@ namespace Milimoe.FunGame.Core.Controller
/// 与服务器的连接套接字实例 /// 与服务器的连接套接字实例
/// </summary> /// </summary>
public Socket? Socket => _Socket; public Socket? Socket => _Socket;
/// <summary>
/// 与服务器的连接套接字实例WebSocket
/// </summary>
public HTTPClient? WebSocket => _WebSocket;
/// <summary> /// <summary>
/// 套接字是否已经连接 /// 套接字是否已经连接
@ -32,6 +37,11 @@ namespace Milimoe.FunGame.Core.Controller
/// 用于类内赋值 /// 用于类内赋值
/// </summary> /// </summary>
protected Socket? _Socket; protected Socket? _Socket;
/// <summary>
/// 用于类内赋值
/// </summary>
protected HTTPClient? _WebSocket;
/// <summary> /// <summary>
/// 是否正在接收服务器信息 /// 是否正在接收服务器信息
@ -79,88 +89,196 @@ namespace Milimoe.FunGame.Core.Controller
} }
/// <summary> /// <summary>
/// 连接服务器 /// 连接服务器 [ 可选参数需要根据连接方式提供 ]
/// 建议使用异步版,此方法为兼容性处理
/// </summary> /// </summary>
/// <param name="addr"></param> /// <param name="type"></param>
/// <param name="address"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="ssl"></param>
/// <param name="subUrl"></param>
/// <returns></returns> /// <returns></returns>
public ConnectResult Connect(string addr, int port) public ConnectResult Connect(TransmittalType type, string address, int port, bool ssl = false, string subUrl = "")
{ {
ArrayList ConnectArgs = []; return Task.Run(() => ConnectAsync(type, address, port, ssl, subUrl)).Result;
if (!BeforeConnect(ref addr, ref port, ConnectArgs)) }
/// <summary>
/// 连接服务器 [ 异步版,可选参数需要根据连接方式提供 ]
/// </summary>
/// <param name="type"></param>
/// <param name="address"></param>
/// <param name="port"></param>
/// <param name="ssl"></param>
/// <param name="subUrl"></param>
/// <returns></returns>
public async Task<ConnectResult> ConnectAsync(TransmittalType type, string address, int port = 0, bool ssl = false, string subUrl = "")
{
ArrayList connectArgs = [];
if (!BeforeConnect(ref address, ref port, connectArgs))
{ {
return ConnectResult.ConnectFailed; return ConnectResult.ConnectFailed;
} }
ConnectResult result = ConnectResult.Success; ConnectResult result = ConnectResult.Success;
string msg = ""; string msg;
string servername = ""; string serverName = "";
string notice = ""; string notice = "";
// 检查服务器IP地址和端口是否正确 // 检查服务器地址和端口是否正确
if (addr == "" || port <= 0) if (address == "" || (type == TransmittalType.Socket && port <= 0) || (type == TransmittalType.WebSocket && port < 0))
{ {
result = ConnectResult.FindServerFailed; result = ConnectResult.FindServerFailed;
} }
if (result == ConnectResult.Success) if (result == ConnectResult.Success)
{ {
// 与服务器建立连接 // 与服务器建立连接
_Socket?.Close(); if (type == TransmittalType.Socket)
_Socket = Socket.Connect(addr, port);
if (_Socket != null && _Socket.Connected)
{ {
if (_Socket.Send(SocketMessageType.Connect, ConnectArgs.Cast<object>().ToArray()) == SocketResult.Success) connectArgs = await Connect_Socket(connectArgs, address, port);
{ }
SocketObject[] objs = _Socket.Receive(); else if (type == TransmittalType.WebSocket)
foreach (SocketObject obj in objs) {
{ connectArgs = await Connect_WebSocket(connectArgs, address, ssl, port, subUrl);
if (obj.SocketType == SocketMessageType.Connect) }
{ else
bool success = obj.GetParam<bool>(0); {
msg = obj.GetParam<string>(1) ?? ""; result = ConnectResult.FindServerFailed;
result = success ? ConnectResult.Success : ConnectResult.ConnectFailed; msg = "连接服务器失败,未指定连接方式。";
if (success) connectArgs = [result, msg, serverName, notice];
{
_Socket.Token = obj.GetParam<Guid>(2);
servername = obj.GetParam<string>(3) ?? "";
notice = obj.GetParam<string>(4) ?? "";
StartReceiving();
Task.Run(() =>
{
while (true)
{
if (_IsReceiving)
{
break;
}
}
});
}
}
}
}
else result = ConnectResult.ConnectFailed;
} }
else _Socket?.Close();
} }
ConnectArgs.Clear(); AfterConnect(connectArgs);
ConnectArgs = [result, msg, servername, notice];
AfterConnect(ConnectArgs);
// 允许修改数组中的result强行改变连接的结果 // 允许修改数组中的result强行改变连接的结果
if (ConnectArgs.Count > 0) if (connectArgs.Count > 0)
{ {
result = (ConnectResult?)ConnectArgs[0] ?? result; result = (ConnectResult?)connectArgs[0] ?? result;
} }
return result; return result;
} }
/// <summary>
/// 使用 Socket 方式连接服务器
/// </summary>
/// <param name="connectArgs"></param>
/// <param name="address"></param>
/// <param name="port"></param>
/// <returns></returns>
private async Task<ArrayList> Connect_Socket(ArrayList connectArgs, string address, int port)
{
ConnectResult result = ConnectResult.Success;
string msg = "";
string serverName = "";
string notice = "";
_Socket?.Close();
_Socket = Socket.Connect(address, port);
if (_Socket != null && _Socket.Connected)
{
if (_Socket.Send(SocketMessageType.Connect, connectArgs.Cast<object>().ToArray()) == SocketResult.Success)
{
SocketObject[] objs = _Socket.Receive();
foreach (SocketObject obj in objs)
{
if (obj.SocketType == SocketMessageType.Connect)
{
bool success = obj.GetParam<bool>(0);
msg = obj.GetParam<string>(1) ?? "";
result = success ? ConnectResult.Success : ConnectResult.ConnectFailed;
if (success)
{
_Socket.Token = obj.GetParam<Guid>(2);
serverName = obj.GetParam<string>(3) ?? "";
notice = obj.GetParam<string>(4) ?? "";
StartReceiving();
await Task.Run(() =>
{
while (true)
{
if (_IsReceiving)
{
break;
}
}
});
}
}
}
}
else result = ConnectResult.ConnectFailed;
}
else _Socket?.Close();
return [result, msg, serverName, notice];
}
/// <summary>
/// 使用 WebSocket 方式连接服务器
/// </summary>
/// <param name="connectArgs"></param>
/// <param name="address"></param>
/// <param name="ssl"></param>
/// <param name="port"></param>
/// <param name="subUrl"></param>
/// <returns></returns>
private async Task<ArrayList> Connect_WebSocket(ArrayList connectArgs, string address, bool ssl, int port, string subUrl)
{
ConnectResult result = ConnectResult.Success;
string msg = "";
string serverName = "";
string notice = "";
_WebSocket?.Close();
_WebSocket = await HTTPClient.Connect(address, ssl, port, subUrl, connectArgs.Cast<object>().ToArray());
if (_WebSocket.Connected)
{
bool webSocketConnected = false;
_WebSocket.AddSocketObjectHandler(obj =>
{
try
{
if (obj.SocketType == SocketMessageType.Connect)
{
bool success = obj.GetParam<bool>(0);
msg = obj.GetParam<string>(1) ?? "";
result = success ? ConnectResult.Success : ConnectResult.ConnectFailed;
if (success)
{
_WebSocket.Token = obj.GetParam<Guid>(2);
serverName = obj.GetParam<string>(3) ?? "";
notice = obj.GetParam<string>(4) ?? "";
}
webSocketConnected = true;
return;
}
HandleSocketMessage(TransmittalType.WebSocket, obj);
}
catch (Exception e)
{
Error(e);
}
});
while (!webSocketConnected)
{
await Task.Delay(100);
}
}
else
{
_WebSocket?.Close();
result = ConnectResult.ConnectFailed;
}
return [result, msg, serverName, notice];
}
/// <summary> /// <summary>
/// 获取服务器地址 /// 获取服务器地址
/// </summary> /// </summary>
/// <returns>stringIP地址int端口号</returns> /// <returns>string服务器地址int端口号</returns>
/// <exception cref="FindServerFailedException"></exception> /// <exception cref="FindServerFailedException"></exception>
public (string, int) GetServerAddress() public (string, int) GetServerAddress()
{ {
@ -188,11 +306,11 @@ namespace Milimoe.FunGame.Core.Controller
/// 此方法将在连接服务器前触发<para/> /// 此方法将在连接服务器前触发<para/>
/// 客户端可以重写此方法 /// 客户端可以重写此方法
/// </summary> /// </summary>
/// <param name="ip">服务器IP</param> /// <param name="address">服务器地址</param>
/// <param name="port">服务器端口</param> /// <param name="port">服务器端口</param>
/// <param name="args">重写时可以提供额外的连接参数</param> /// <param name="args">重写时可以提供额外的连接参数</param>
/// <returns>false中止连接</returns> /// <returns>false中止连接</returns>
public virtual bool BeforeConnect(ref string ip, ref int port, ArrayList args) public virtual bool BeforeConnect(ref string address, ref int port, ArrayList args)
{ {
return true; return true;
} }
@ -211,13 +329,16 @@ namespace Milimoe.FunGame.Core.Controller
/// <summary> /// <summary>
/// 客户端需要自行实现自动登录的事务 /// 客户端需要自行实现自动登录的事务
/// </summary> /// </summary>
public abstract void AutoLogin(string Username, string Password, string AutoKey); public virtual void AutoLogin(string Username, string Password, string AutoKey)
{
}
/// <summary> /// <summary>
/// 关闭所有连接 /// 关闭 Socket 连接
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool Close() public bool Close_Socket()
{ {
try try
{ {
@ -240,6 +361,28 @@ namespace Milimoe.FunGame.Core.Controller
} }
return true; return true;
} }
/// <summary>
/// 关闭 WebSocket 连接
/// </summary>
/// <returns></returns>
public bool Close_WebSocket()
{
try
{
if (_WebSocket != null)
{
_WebSocket.Close();
_WebSocket = null;
}
}
catch (Exception e)
{
WritelnSystemInfo(e.GetErrorInfo());
return false;
}
return true;
}
/// <summary> /// <summary>
/// 输出消息 /// 输出消息
@ -267,6 +410,11 @@ namespace Milimoe.FunGame.Core.Controller
DataRequest request = new(_Socket, RequestType); DataRequest request = new(_Socket, RequestType);
return request; return request;
} }
else if (_WebSocket != null)
{
DataRequest request = new(_WebSocket, RequestType);
return request;
}
throw new ConnectFailedException(); throw new ConnectFailedException();
} }
@ -283,6 +431,11 @@ namespace Milimoe.FunGame.Core.Controller
DataRequest request = new(_Socket, RequestType, true); DataRequest request = new(_Socket, RequestType, true);
return request; return request;
} }
else if (_WebSocket != null)
{
DataRequest request = new(_WebSocket, RequestType, true);
return request;
}
throw new ConnectFailedException(); throw new ConnectFailedException();
} }
@ -300,6 +453,11 @@ namespace Milimoe.FunGame.Core.Controller
DataRequest request = new(_Socket, RequestType, false, SocketRuntimeType.Addon); DataRequest request = new(_Socket, RequestType, false, SocketRuntimeType.Addon);
return request; return request;
} }
else if (_WebSocket != null)
{
DataRequest request = new(_WebSocket, RequestType, false, SocketRuntimeType.Addon);
return request;
}
throw new ConnectFailedException(); throw new ConnectFailedException();
} }
@ -317,6 +475,11 @@ namespace Milimoe.FunGame.Core.Controller
DataRequest request = new(_Socket, RequestType, true, SocketRuntimeType.Addon); DataRequest request = new(_Socket, RequestType, true, SocketRuntimeType.Addon);
return request; return request;
} }
else if (_WebSocket != null)
{
DataRequest request = new(_WebSocket, RequestType, true, SocketRuntimeType.Addon);
return request;
}
throw new ConnectFailedException(); throw new ConnectFailedException();
} }
@ -334,6 +497,11 @@ namespace Milimoe.FunGame.Core.Controller
DataRequest request = new(_Socket, GamingType, false, SocketRuntimeType.Addon); DataRequest request = new(_Socket, GamingType, false, SocketRuntimeType.Addon);
return request; return request;
} }
else if (_WebSocket != null)
{
DataRequest request = new(_WebSocket, GamingType, false, SocketRuntimeType.Addon);
return request;
}
throw new ConnectFailedException(); throw new ConnectFailedException();
} }
@ -351,11 +519,16 @@ namespace Milimoe.FunGame.Core.Controller
DataRequest request = new(_Socket, GamingType, true, SocketRuntimeType.Addon); DataRequest request = new(_Socket, GamingType, true, SocketRuntimeType.Addon);
return request; return request;
} }
else if (_WebSocket != null)
{
DataRequest request = new(_WebSocket, GamingType, true, SocketRuntimeType.Addon);
return request;
}
throw new ConnectFailedException(); throw new ConnectFailedException();
} }
/// <summary> /// <summary>
/// 开始接收服务器信息 /// 开始接收服务器信息 [ Socket Only ]
/// </summary> /// </summary>
protected void StartReceiving() protected void StartReceiving()
{ {
@ -372,7 +545,7 @@ namespace Milimoe.FunGame.Core.Controller
} }
/// <summary> /// <summary>
/// 获取服务器已发送的信息为SocketObject数组 /// 获取服务器已发送的信息为SocketObject数组 [ Socket Only ]
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
protected SocketObject[] GetServerMessage() protected SocketObject[] GetServerMessage()
@ -385,7 +558,7 @@ namespace Milimoe.FunGame.Core.Controller
} }
/// <summary> /// <summary>
/// 具体接收服务器信息以及处理信息的方法 /// 具体接收服务器信息以及处理信息的方法 [ Socket Only ]
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
protected SocketMessageType Receiving() protected SocketMessageType Receiving()
@ -394,60 +567,11 @@ namespace Milimoe.FunGame.Core.Controller
SocketMessageType result = SocketMessageType.Unknown; SocketMessageType result = SocketMessageType.Unknown;
try try
{ {
SocketObject[] ServerMessages = GetServerMessage(); SocketObject[] messages = GetServerMessage();
foreach (SocketObject ServerMessage in ServerMessages) foreach (SocketObject obj in messages)
{ {
SocketMessageType type = ServerMessage.SocketType; result = HandleSocketMessage(TransmittalType.Socket, obj);
object[] objs = ServerMessage.Parameters;
result = type;
switch (type)
{
case SocketMessageType.Disconnect:
Close();
SocketHandler_Disconnect(ServerMessage);
break;
case SocketMessageType.System:
SocketHandler_System(ServerMessage);
break;
case SocketMessageType.HeartBeat:
SocketHandler_HeartBeat(ServerMessage);
break;
case SocketMessageType.ForceLogout:
SocketHandler_ForceLogout(ServerMessage);
break;
case SocketMessageType.Chat:
SocketHandler_Chat(ServerMessage);
break;
case SocketMessageType.UpdateRoomMaster:
SocketHandler_UpdateRoomMaster(ServerMessage);
break;
case SocketMessageType.MatchRoom:
SocketHandler_MatchRoom(ServerMessage);
break;
case SocketMessageType.StartGame:
SocketHandler_StartGame(ServerMessage);
break;
case SocketMessageType.EndGame:
SocketHandler_EndGame(ServerMessage);
break;
case SocketMessageType.Gaming:
SocketHandler_Gaming(ServerMessage);
break;
case SocketMessageType.Unknown:
default:
break;
}
} }
} }
catch (Exception e) catch (Exception e)
@ -458,6 +582,73 @@ namespace Milimoe.FunGame.Core.Controller
return result; return result;
} }
/// <summary>
/// 处理接收到的信息
/// </summary>
/// <param name="transmittalType"></param>
/// <param name="obj"></param>
/// <returns></returns>
protected SocketMessageType HandleSocketMessage(TransmittalType transmittalType, SocketObject obj)
{
SocketMessageType type = obj.SocketType;
SocketMessageType result = type;
switch (type)
{
case SocketMessageType.Disconnect:
if (transmittalType == TransmittalType.Socket)
{
Close_Socket();
}
else if (transmittalType == TransmittalType.WebSocket)
{
Close_WebSocket();
}
SocketHandler_Disconnect(obj);
break;
case SocketMessageType.System:
SocketHandler_System(obj);
break;
case SocketMessageType.HeartBeat:
SocketHandler_HeartBeat(obj);
break;
case SocketMessageType.ForceLogout:
SocketHandler_ForceLogout(obj);
break;
case SocketMessageType.Chat:
SocketHandler_Chat(obj);
break;
case SocketMessageType.UpdateRoomMaster:
SocketHandler_UpdateRoomMaster(obj);
break;
case SocketMessageType.MatchRoom:
SocketHandler_MatchRoom(obj);
break;
case SocketMessageType.StartGame:
SocketHandler_StartGame(obj);
break;
case SocketMessageType.EndGame:
SocketHandler_EndGame(obj);
break;
case SocketMessageType.Gaming:
SocketHandler_Gaming(obj);
break;
case SocketMessageType.Unknown:
default:
break;
}
return result;
}
/// <summary> /// <summary>
/// 客户端接收服务器断开连接的通知 /// 客户端接收服务器断开连接的通知
/// </summary> /// </summary>
@ -468,54 +659,81 @@ namespace Milimoe.FunGame.Core.Controller
/// 客户端接收并处理服务器系统消息 /// 客户端接收并处理服务器系统消息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_System(SocketObject ServerMessage); protected virtual void SocketHandler_System(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理服务器心跳 /// 客户端接收并处理服务器心跳
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_HeartBeat(SocketObject ServerMessage); protected virtual void SocketHandler_HeartBeat(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收强制退出登录的通知 /// 客户端接收强制退出登录的通知
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_ForceLogout(SocketObject ServerMessage); protected virtual void SocketHandler_ForceLogout(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理聊天信息 /// 客户端接收并处理聊天信息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_Chat(SocketObject ServerMessage); protected virtual void SocketHandler_Chat(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理更换房主信息 /// 客户端接收并处理更换房主信息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_UpdateRoomMaster(SocketObject ServerMessage); protected virtual void SocketHandler_UpdateRoomMaster(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理匹配房间成功信息 /// 客户端接收并处理匹配房间成功信息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_MatchRoom(SocketObject ServerMessage); protected virtual void SocketHandler_MatchRoom(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理开始游戏信息 /// 客户端接收并处理开始游戏信息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_StartGame(SocketObject ServerMessage); protected virtual void SocketHandler_StartGame(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理游戏结束信息 /// 客户端接收并处理游戏结束信息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_EndGame(SocketObject ServerMessage); protected virtual void SocketHandler_EndGame(SocketObject ServerMessage)
{
}
/// <summary> /// <summary>
/// 客户端接收并处理局内消息 /// 客户端接收并处理局内消息
/// </summary> /// </summary>
/// <param name="ServerMessage"></param> /// <param name="ServerMessage"></param>
protected abstract void SocketHandler_Gaming(SocketObject ServerMessage); protected virtual void SocketHandler_Gaming(SocketObject ServerMessage)
{
}
} }
} }

View File

@ -104,9 +104,8 @@ namespace Milimoe.FunGame.Core.Entity
/// <param name="inventory"></param> /// <param name="inventory"></param>
/// <param name="itemsDefined"></param> /// <param name="itemsDefined"></param>
/// <param name="skillsDefined"></param> /// <param name="skillsDefined"></param>
/// <param name="recovery"></param>
/// <returns>构建的新角色</returns> /// <returns>构建的新角色</returns>
public Character Build(IEnumerable<Skill> skills, IEnumerable<Item> items, bool newItemGuid = true, EquipSlot? equips = null, Inventory? inventory = null, IEnumerable<Item>? itemsDefined = null, IEnumerable<Skill>? skillsDefined = null, bool recovery = true) public Character Build(IEnumerable<Skill> skills, IEnumerable<Item> items, bool newItemGuid = true, EquipSlot? equips = null, Inventory? inventory = null, IEnumerable<Item>? itemsDefined = null, IEnumerable<Skill>? skillsDefined = null)
{ {
Character character = Factory.GetCharacter(); Character character = Factory.GetCharacter();
character.Id = Id; character.Id = Id;
@ -227,7 +226,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
} }
if (recovery) character.Recovery(); character.Recovery();
return character; return character;
} }
@ -245,7 +244,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <returns>构建的新角色</returns> /// <returns>构建的新角色</returns>
public static Character Build(Character reference, bool newItemGuid = true, bool copyLevel = true, Inventory? inventory = null, IEnumerable<Item>? itemsDefined = null, IEnumerable<Skill>? skillsDefined = null, bool recovery = true) public static Character Build(Character reference, bool newItemGuid = true, bool copyLevel = true, Inventory? inventory = null, IEnumerable<Item>? itemsDefined = null, IEnumerable<Skill>? skillsDefined = null, bool recovery = true)
{ {
Character character = new CharacterBuilder(reference).Build(reference.Skills, reference.Items, newItemGuid, reference.EquipSlot, inventory, itemsDefined, skillsDefined, recovery); Character character = new CharacterBuilder(reference).Build(reference.Skills, reference.Items, newItemGuid, reference.EquipSlot, inventory, itemsDefined, skillsDefined);
if (copyLevel) if (copyLevel)
{ {
character.Level = reference.Level; character.Level = reference.Level;
@ -255,6 +254,11 @@ namespace Milimoe.FunGame.Core.Entity
character.NormalAttack.Level = reference.NormalAttack.Level; character.NormalAttack.Level = reference.NormalAttack.Level;
character.NormalAttack.HardnessTime = reference.NormalAttack.HardnessTime; character.NormalAttack.HardnessTime = reference.NormalAttack.HardnessTime;
character.NormalAttack.SetMagicType(reference.NormalAttack.IsMagic, reference.NormalAttack.MagicType); character.NormalAttack.SetMagicType(reference.NormalAttack.IsMagic, reference.NormalAttack.MagicType);
if (!recovery)
{
character.HP = reference.HP;
character.MP = reference.MP;
}
return character; return character;
} }
} }

View File

@ -1,4 +1,5 @@
using System.Text; using System.Text;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model; using Milimoe.FunGame.Core.Model;
@ -57,7 +58,7 @@ namespace Milimoe.FunGame.Core.Entity
_character = Characters.First(); _character = Characters.First();
return _character; return _character;
} }
throw new GetInstanceException(); return Factory.GetCharacter();
} }
set set
{ {

View File

@ -6,6 +6,8 @@ namespace Milimoe.FunGame.Core.Interface.Base
{ {
public T NewInstance(); public T NewInstance();
public void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref T result); public void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref T result, Dictionary<string, object> convertingContext);
public void AfterConvert(ref T result, Dictionary<string, object> convertingContext);
} }
} }

View File

@ -57,7 +57,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
public bool Authenticate(string username, string password) public bool Authenticate(string username, string password)
{ {
if (!BeforeAuthenticator(AuthenticationType.Username, username, password)) return false; if (!BeforeAuthenticator(AuthenticationType.Username, username, password)) return false;
SQLHelper.ExecuteDataSet(UserQuery.Select_Users_LoginQuery(username, password)); SQLHelper.ExecuteDataSet(UserQuery.Select_Users_LoginQuery(SQLHelper, username, password));
if (SQLHelper.Success) if (SQLHelper.Success)
{ {
DataSet ds = SQLHelper.DataSet; DataSet ds = SQLHelper.DataSet;

View File

@ -9,6 +9,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{ {
T? result = default; T? result = default;
Dictionary<string, object> convertingContext = [];
while (reader.Read()) while (reader.Read())
{ {
@ -19,15 +20,25 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
result ??= NewInstance(); result ??= NewInstance();
string propertyName = reader.GetString() ?? ""; string propertyName = reader.GetString() ?? "";
reader.Read(); reader.Read();
ReadPropertyName(ref reader, propertyName, options, ref result); ReadPropertyName(ref reader, propertyName, options, ref result, convertingContext);
} }
} }
if (result != null)
{
AfterConvert(ref result, convertingContext);
}
return result; return result;
} }
public abstract T NewInstance(); public abstract T NewInstance();
public abstract void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref T result); public abstract void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref T result, Dictionary<string, object> convertingContext);
public virtual void AfterConvert(ref T result, Dictionary<string, object> convertingContext)
{
// do nothing
}
} }
} }

View File

@ -13,7 +13,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return Factory.GetCharacter(); return Factory.GetCharacter();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Character result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Character result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {
@ -87,13 +87,13 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
result.ExMPPercentage = reader.GetDouble(); result.ExMPPercentage = reader.GetDouble();
break; break;
case nameof(Character.HP): case nameof(Character.HP):
result.HP = reader.GetDouble(); convertingContext[nameof(Character.HP)] = reader.GetDouble();
break; break;
case nameof(Character.MP): case nameof(Character.MP):
result.MP = reader.GetDouble(); convertingContext[nameof(Character.MP)] = reader.GetDouble();
break; break;
case nameof(Character.EP): case nameof(Character.EP):
result.EP = reader.GetDouble(); convertingContext[nameof(Character.EP)] = reader.GetDouble();
break; break;
case nameof(Character.InitialATK): case nameof(Character.InitialATK):
result.InitialATK = reader.GetDouble(); result.InitialATK = reader.GetDouble();
@ -303,5 +303,20 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
writer.WriteEndObject(); writer.WriteEndObject();
} }
public override void AfterConvert(ref Character result, Dictionary<string, object> convertingContext)
{
if (convertingContext.TryGetValue(nameof(Character.HP), out object? value) && value is double hp)
{
result.HP = hp;
}
if (convertingContext.TryGetValue(nameof(Character.MP), out value) && value is double mp)
{
result.MP = mp;
}
if (convertingContext.TryGetValue(nameof(Character.EP), out value) && value is double ep)
{
result.EP = ep;
}
}
} }
} }

View File

@ -12,7 +12,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new(); return new();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Club result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Club result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -11,7 +11,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new(); return new();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Effect result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Effect result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -13,7 +13,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new(); return new();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref EquipSlot result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref EquipSlot result, Dictionary<string, object> convertingContext)
{ {
Item temp; Item temp;
switch (propertyName) switch (propertyName)

View File

@ -12,7 +12,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return Factory.GetInventory(); return Factory.GetInventory();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Inventory result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Inventory result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -13,7 +13,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new(); return new();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Item result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Item result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -11,7 +11,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new(); return new();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref MagicResistance result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref MagicResistance result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -13,7 +13,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new NormalAttack(Factory.GetCharacter()); return new NormalAttack(Factory.GetCharacter());
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref NormalAttack result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref NormalAttack result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -14,7 +14,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return Factory.GetRoom(); return Factory.GetRoom();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Room result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Room result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -13,7 +13,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return new OpenSkill(0, "", []); return new OpenSkill(0, "", []);
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Skill result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Skill result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -15,7 +15,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
return Factory.GetUser(); return Factory.GetUser();
} }
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref User result) public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref User result, Dictionary<string, object> convertingContext)
{ {
switch (propertyName) switch (propertyName)
{ {

View File

@ -23,7 +23,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
private bool _receiving = false; private bool _receiving = false;
private readonly HashSet<Action<SocketObject>> _boundEvents = []; private readonly HashSet<Action<SocketObject>> _boundEvents = [];
private HTTPClient(System.Net.WebSockets.ClientWebSocket instance, string serverAddress, int serverPort, params object[] args) private HTTPClient(ClientWebSocket instance, string serverAddress, int serverPort, params object[] args)
{ {
Instance = instance; Instance = instance;
ServerAddress = serverAddress; ServerAddress = serverAddress;
@ -33,11 +33,10 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
Task.Factory.StartNew(async () => await StartListening(args)); Task.Factory.StartNew(async () => await StartListening(args));
} }
public static async Task<HTTPClient> Connect(string serverAddress, int serverPort, bool ssl, string subUrl = "", params object[] args) public static async Task<HTTPClient> Connect(string serverAddress, bool ssl, int serverPort = 0, string subUrl = "", params object[] args)
{ {
string ServerIP = Api.Utility.NetworkUtility.GetIPAddress(serverAddress); Uri uri = new((ssl ? "wss://" : "ws://") + serverAddress + ":" + (serverPort != 0 ? serverPort : "") + "/" + subUrl.Trim('/') + "/");
Uri uri = new((ssl ? "wss://" : "ws://") + ServerIP + ":" + serverPort + "/" + subUrl.Trim('/') + "/"); ClientWebSocket? socket = await HTTPManager.Connect(uri);
System.Net.WebSockets.ClientWebSocket? socket = await HTTPManager.Connect(uri);
if (socket != null && socket.State == WebSocketState.Open) if (socket != null && socket.State == WebSocketState.Open)
{ {
HTTPClient client = new(socket, serverAddress, serverPort, args); HTTPClient client = new(socket, serverAddress, serverPort, args);

View File

@ -1,4 +1,6 @@
namespace Milimoe.FunGame.Core.Library.SQLScript using Milimoe.FunGame.Core.Api.Transmittal;
namespace Milimoe.FunGame.Core.Library.SQLScript
{ {
public class Constant public class Constant
{ {
@ -37,9 +39,12 @@ namespace Milimoe.FunGame.Core.Library.SQLScript.Common
public const string Column_LoginTime = "LoginTime"; public const string Column_LoginTime = "LoginTime";
public const string Column_LastTime = "LastTime"; public const string Column_LastTime = "LastTime";
public static string Insert_ServerLoginLogs(string ServerName, string ServerKey) public static string Insert_ServerLoginLogs(SQLHelper SQLHelper, string ServerName, string ServerKey)
{ {
return $"{Command_Insert} {Command_Into} {TableName} ({Column_ServerName}, {Column_ServerKey}, {Column_LoginTime}) {Command_Values} ('{ServerName}', '{ServerKey}', '{DateTime.Now}')"; SQLHelper.Parameters["@ServerName"] = ServerName;
SQLHelper.Parameters["@ServerKey"] = ServerKey;
SQLHelper.Parameters["@LoginTime"] = DateTime.Now;
return $"{Command_Insert} {Command_Into} {TableName} ({Column_ServerName}, {Column_ServerKey}, {Column_LoginTime}) {Command_Values} (@ServerName, @ServerKey, @LoginTime)";
} }
public static string Select_GetLastLoginTime() public static string Select_GetLastLoginTime()

View File

@ -1,4 +1,6 @@
namespace Milimoe.FunGame.Core.Library.SQLScript.Common using Milimoe.FunGame.Core.Api.Transmittal;
namespace Milimoe.FunGame.Core.Library.SQLScript.Common
{ {
public class RegVerifyCodes : Constant public class RegVerifyCodes : Constant
{ {
@ -8,24 +10,35 @@
public const string Column_RegVerifyCode = "RegVerifyCode"; public const string Column_RegVerifyCode = "RegVerifyCode";
public const string Column_RegTime = "RegTime"; public const string Column_RegTime = "RegTime";
public static string Insert_RegVerifyCode(string Username, string Email, string RegVerifyCodes) public static string Insert_RegVerifyCode(SQLHelper SQLHelper, string Username, string Email, string RegVerifyCodes)
{ {
return $"{Command_Insert} {Command_Into} {TableName} ({Column_Username}, {Column_Email}, {Column_RegVerifyCode}, {Column_RegTime}) {Command_Values} ('{Username}', '{Email}', '{RegVerifyCodes}', '{DateTime.Now}')"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
SQLHelper.Parameters["@RegVerifyCodes"] = RegVerifyCodes;
SQLHelper.Parameters["@RegTime"] = DateTime.Now;
return $"{Command_Insert} {Command_Into} {TableName} ({Column_Username}, {Column_Email}, {Column_RegVerifyCode}, {Column_RegTime}) {Command_Values} (@Username, @Email, @RegVerifyCodes, @RegTime)";
} }
public static string Select_RegVerifyCode(string Username, string Email, string RegVerifyCode) public static string Select_RegVerifyCode(SQLHelper SQLHelper, string Username, string Email, string RegVerifyCode)
{ {
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{Email}' and {Column_RegVerifyCode} = '{RegVerifyCode}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
SQLHelper.Parameters["@RegVerifyCode"] = RegVerifyCode;
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email and {Column_RegVerifyCode} = @RegVerifyCode";
} }
public static string Select_HasSentRegVerifyCode(string Username, string Email) public static string Select_HasSentRegVerifyCode(SQLHelper SQLHelper, string Username, string Email)
{ {
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{Email}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email";
} }
public static string Delete_RegVerifyCode(string Username, string Email) public static string Delete_RegVerifyCode(SQLHelper SQLHelper, string Username, string Email)
{ {
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{Email}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email";
} }
} }
@ -37,24 +50,35 @@
public const string Column_ForgetVerifyCode = "ForgetVerifyCode"; public const string Column_ForgetVerifyCode = "ForgetVerifyCode";
public const string Column_SendTime = "SendTime"; public const string Column_SendTime = "SendTime";
public static string Insert_ForgetVerifyCode(string Username, string Email, string ForgetVerifyCodes) public static string Insert_ForgetVerifyCode(SQLHelper SQLHelper, string Username, string Email, string ForgetVerifyCodes)
{ {
return $"{Command_Insert} {Command_Into} {TableName} ({Column_Username}, {Column_Email}, {Column_ForgetVerifyCode}, {Column_SendTime}) {Command_Values} ('{Username}', '{Email}', '{ForgetVerifyCodes}', '{DateTime.Now}')"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
SQLHelper.Parameters["@ForgetVerifyCodes"] = ForgetVerifyCodes;
SQLHelper.Parameters["@SendTime"] = DateTime.Now;
return $"{Command_Insert} {Command_Into} {TableName} ({Column_Username}, {Column_Email}, {Column_ForgetVerifyCode}, {Column_SendTime}) {Command_Values} (@Username, @Email, @ForgetVerifyCodes, @SendTime)";
} }
public static string Select_ForgetVerifyCode(string Username, string Email, string ForgetVerifyCode) public static string Select_ForgetVerifyCode(SQLHelper SQLHelper, string Username, string Email, string ForgetVerifyCode)
{ {
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{Email}' and {Column_ForgetVerifyCode} = '{ForgetVerifyCode}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
SQLHelper.Parameters["@ForgetVerifyCode"] = ForgetVerifyCode;
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email and {Column_ForgetVerifyCode} = @ForgetVerifyCode";
} }
public static string Select_HasSentForgetVerifyCode(string Username, string Email) public static string Select_HasSentForgetVerifyCode(SQLHelper SQLHelper, string Username, string Email)
{ {
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{Email}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email";
} }
public static string Delete_ForgetVerifyCode(string Username, string Email) public static string Delete_ForgetVerifyCode(SQLHelper SQLHelper, string Username, string Email)
{ {
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{Email}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = Email;
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email";
} }
} }
} }

View File

@ -1,4 +1,6 @@
namespace Milimoe.FunGame.Core.Library.SQLScript.Entity using Milimoe.FunGame.Core.Api.Transmittal;
namespace Milimoe.FunGame.Core.Library.SQLScript.Entity
{ {
public class RoomQuery : Constant public class RoomQuery : Constant
{ {
@ -19,38 +21,58 @@
public const string Select_Rooms = $"{Command_Select} {TableName}.{Command_All}, {UserQuery.TableName}.{UserQuery.Column_Username} {Command_As} {Column_RoomMasterName} " + public const string Select_Rooms = $"{Command_Select} {TableName}.{Command_All}, {UserQuery.TableName}.{UserQuery.Column_Username} {Command_As} {Column_RoomMasterName} " +
$"{Command_From} {TableName} {Command_LeftJoin} {UserQuery.TableName} {Command_On} {UserQuery.TableName}.{UserQuery.Column_UID} = {TableName}.{Column_RoomMaster}"; $"{Command_From} {TableName} {Command_LeftJoin} {UserQuery.TableName} {Command_On} {UserQuery.TableName}.{UserQuery.Column_UID} = {TableName}.{Column_RoomMaster}";
public static string Insert_CreateRoom(string roomid, long roomMaster, Library.Constant.RoomType roomType, string gameModule, string gameMap, bool isRank, string password, int maxUsers) public static string Insert_CreateRoom(SQLHelper SQLHelper, string roomid, long roomMaster, Library.Constant.RoomType roomType, string gameModule, string gameMap, bool isRank, string password, int maxUsers)
{ {
Library.Constant.RoomState RoomState = Library.Constant.RoomState.Created; Library.Constant.RoomState RoomState = Library.Constant.RoomState.Created;
DateTime NowTime = DateTime.Now; DateTime NowTime = DateTime.Now;
bool HasPass = password.Trim() != ""; bool HasPass = password.Trim() != "";
SQLHelper.Parameters["@roomid"] = roomid;
SQLHelper.Parameters["@CreateTime"] = NowTime;
SQLHelper.Parameters["@roomMaster"] = roomMaster;
SQLHelper.Parameters["@roomType"] = (int)roomType;
SQLHelper.Parameters["@gameModule"] = gameModule;
SQLHelper.Parameters["@gameMap"] = gameMap;
SQLHelper.Parameters["@RoomState"] = (int)RoomState;
SQLHelper.Parameters["@isRank"] = isRank ? 1 : 0;
SQLHelper.Parameters["@HasPass"] = HasPass ? 1 : 0;
SQLHelper.Parameters["@password"] = password;
SQLHelper.Parameters["@maxUsers"] = maxUsers;
return $"{Command_Insert} {Command_Into} {TableName} ({Column_RoomID}, {Column_CreateTime}, {Column_RoomMaster}, {Column_RoomType}, {Column_GameModule}, {Column_GameMap}, {Column_RoomState}, {Column_IsRank}, {Column_HasPass}, {Column_Password}, {Column_MaxUsers})" + return $"{Command_Insert} {Command_Into} {TableName} ({Column_RoomID}, {Column_CreateTime}, {Column_RoomMaster}, {Column_RoomType}, {Column_GameModule}, {Column_GameMap}, {Column_RoomState}, {Column_IsRank}, {Column_HasPass}, {Column_Password}, {Column_MaxUsers})" +
$" {Command_Values} ('{roomid}', '{NowTime}', {roomMaster}, {(int)roomType}, '{gameModule}', '{gameMap}', {(int)RoomState}, {(isRank ? 1 : 0)}, {(HasPass ? 1 : 0)}, '{password}', {maxUsers})"; $" {Command_Values} (@roomid, @CreateTime, @roomMaster, @roomType, @gameModule, @gameMap, @RoomState, @isRank, @HasPass, @password, @maxUsers)";
} }
public static string Delete_Rooms(params string[] roomids) public static string Delete_Rooms(SQLHelper SQLHelper, params string[] roomids)
{ {
if (roomids.Length != 0) if (roomids.Length != 0)
{ {
string where = string.Join("', '", roomids); string where = string.Join("', '", roomids);
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_RoomID} {Command_In} ('{where}')"; SQLHelper.Parameters["@roomids"] = where;
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_RoomID} {Command_In} (@roomids)";
} }
return $"{Command_Delete} {Command_From} {TableName}"; return $"{Command_Delete} {Command_From} {TableName}";
} }
public static string Delete_QuitRoom(string roomID, long roomMaster) public static string Delete_QuitRoom(SQLHelper SQLHelper, string roomID, long roomMaster)
{ {
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_RoomID} = '{roomID}' {Command_And} {Column_RoomMaster} = {roomMaster}"; SQLHelper.Parameters["@roomID"] = roomID;
SQLHelper.Parameters["@roomMaster"] = roomMaster;
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_RoomID} = @roomID {Command_And} {Column_RoomMaster} = @roomMaster";
} }
public static string Update_QuitRoom(string roomid, long oldRoomMaster, long newRoomMaster) public static string Update_QuitRoom(SQLHelper SQLHelper, string roomid, long oldRoomMaster, long newRoomMaster)
{ {
return $"{Command_Update} {TableName} {Command_Set} {Column_RoomMaster} = {newRoomMaster} {Command_Where} {Column_RoomID} = '{roomid}' {Command_And} {Column_RoomMaster} = {oldRoomMaster}"; SQLHelper.Parameters["@roomid"] = roomid;
SQLHelper.Parameters["@oldRoomMaster"] = oldRoomMaster;
SQLHelper.Parameters["@newRoomMaster"] = newRoomMaster;
return $"{Command_Update} {TableName} {Command_Set} {Column_RoomMaster} = @newRoomMaster {Command_Where} {Column_RoomID} = @roomid {Command_And} {Column_RoomMaster} = @oldRoomMaster";
} }
public static string Select_IsExistRoom(string roomid) public static string Select_IsExistRoom(SQLHelper SQLHelper, string roomid)
{ {
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_RoomID} = '{roomid}'"; SQLHelper.Parameters["@roomid"] = roomid;
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_RoomID} = @roomid";
} }
} }
} }

View File

@ -1,4 +1,6 @@
namespace Milimoe.FunGame.Core.Library.SQLScript.Entity using Milimoe.FunGame.Core.Api.Transmittal;
namespace Milimoe.FunGame.Core.Library.SQLScript.Entity
{ {
public class UserQuery : Constant public class UserQuery : Constant
{ {
@ -18,55 +20,77 @@
public const string Column_AutoKey = "AutoKey"; public const string Column_AutoKey = "AutoKey";
public const string Select_Users = $"{Command_Select} {Command_All} {Command_From} {TableName}"; public const string Select_Users = $"{Command_Select} {Command_All} {Command_From} {TableName}";
public static string Select_Users_LoginQuery(string Username, string Password) public static string Select_Users_LoginQuery(SQLHelper SQLHelper, string Username, string Password)
{ {
return $"{Select_Users} {Command_Where} {Column_Username} = '{Username}' and {Column_Password} = '{Password}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Password"] = Password;
return $"{Select_Users} {Command_Where} {Column_Username} = @Username and {Column_Password} = @Password";
} }
public static string Select_IsExistEmail(string Email) public static string Select_IsExistEmail(SQLHelper SQLHelper, string Email)
{ {
return $"{Select_Users} {Command_Where} {Column_Email} = '{Email}'"; SQLHelper.Parameters["@Email"] = Email;
return $"{Select_Users} {Command_Where} {Column_Email} = @Email";
} }
public static string Select_IsExistUsername(string Username) public static string Select_IsExistUsername(SQLHelper SQLHelper, string Username)
{ {
return $"{Select_Users} {Command_Where} {Column_Username} = '{Username}'"; SQLHelper.Parameters["@Username"] = Username;
return $"{Select_Users} {Command_Where} {Column_Username} = @Username";
} }
public static string Select_CheckEmailWithUsername(string Username, string email) public static string Select_CheckEmailWithUsername(SQLHelper SQLHelper, string Username, string email)
{ {
return $"{Select_Users} {Command_Where} {Column_Username} = '{Username}' and {Column_Email} = '{email}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Email"] = email;
return $"{Select_Users} {Command_Where} {Column_Username} = @Username and {Column_Email} = @Email";
} }
public static string Select_Users_Where(string Where) public static string Select_Users_Where(SQLHelper SQLHelper, string Where)
{ {
return $"{Select_Users} {Command_Where} {Where}"; SQLHelper.Parameters["@Where"] = Where;
return $"{Select_Users} {Command_Where} @Where";
} }
public static string Select_CheckAutoKey(string Username, string AutoKey) public static string Select_CheckAutoKey(SQLHelper SQLHelper, string Username, string AutoKey)
{ {
return $"{Select_Users} {Command_Where} {Column_Username} = '{Username}' and {Column_AutoKey} = '{AutoKey}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@AutoKey"] = AutoKey;
return $"{Select_Users} {Command_Where} {Column_Username} = @Username and {Column_AutoKey} = @AutoKey";
} }
public static string Update_CheckLogin(string Username, string IP) public static string Update_CheckLogin(SQLHelper SQLHelper, string Username, string IP)
{ {
return $"{Command_Update} {TableName} {Command_Set} {Column_LastTime} = '{DateTime.Now}', {Column_LastIP} = '{IP}' {Command_Where} {Column_Username} = '{Username}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@LastTime"] = DateTime.Now;
SQLHelper.Parameters["@LastIP"] = IP;
return $"{Command_Update} {TableName} {Command_Set} {Column_LastTime} = @LastTime, {Column_LastIP} = @LastIP {Command_Where} {Column_Username} = @Username";
} }
public static string Update_Password(string Username, string Password) public static string Update_Password(SQLHelper SQLHelper, string Username, string Password)
{ {
return $"{Command_Update} {TableName} {Command_Set} {Column_Password} = '{Password}' {Command_Where} {Column_Username} = '{Username}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Password"] = Password;
return $"{Command_Update} {TableName} {Command_Set} {Column_Password} = @Password {Command_Where} {Column_Username} = @Username";
} }
public static string Update_GameTime(string Username, int GameTimeMinutes) public static string Update_GameTime(SQLHelper SQLHelper, string Username, int GameTimeMinutes)
{ {
return $"{Command_Update} {TableName} {Command_Set} {Column_GameTime} = {Column_GameTime} + {GameTimeMinutes} {Command_Where} {Column_Username} = '{Username}'"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@GameTimeMinutes"] = GameTimeMinutes;
return $"{Command_Update} {TableName} {Command_Set} {Column_GameTime} = {Column_GameTime} + @GameTimeMinutes {Command_Where} {Column_Username} = @Username";
} }
public static string Insert_Register(string Username, string Password, string Email, string IP) public static string Insert_Register(SQLHelper SQLHelper, string Username, string Password, string Email, string IP)
{ {
DateTime Now = DateTime.Now; DateTime Now = DateTime.Now;
return $"{Command_Insert} {Command_Into} {TableName} ({Column_Username}, {Column_Password}, {Column_Email}, {Column_RegTime}, {Column_LastTime}, {Column_LastIP}) {Command_Values} ('{Username}', '{Password}', '{Email}', '{Now}', '{Now}', '{IP}')"; SQLHelper.Parameters["@Username"] = Username;
SQLHelper.Parameters["@Password"] = Password;
SQLHelper.Parameters["@Email"] = Email;
SQLHelper.Parameters["@RegTime"] = Now;
SQLHelper.Parameters["@LastTime"] = Now;
SQLHelper.Parameters["@LastIP"] = IP;
return $"{Command_Insert} {Command_Into} {TableName} ({Column_Username}, {Column_Password}, {Column_Email}, {Column_RegTime}, {Column_LastTime}, {Column_LastIP}) {Command_Values} (@Username, @Password, @Email, @RegTime, @LastTime, @LastIP)";
} }
} }
} }