chinese_chess/Scripts/Lib/RPClient.cs
ZZY 327c2df94d refactor(chess): 重构象棋程序基础结构,使用Nullable重构核心代码
- 更新了多个文件的代码结构和类型定义,提高了代码的健壮性和可维护性
- 优化了事件处理、棋子管理和移动逻辑,为后续功能扩展打下坚实基础
- 修复了一些潜在的空指针异常问题,提高了程序的稳定性
- 修复部分bug
2024-11-22 23:51:32 +08:00

328 lines
10 KiB
C#

using Godot;
using Godot.Collections;
namespace RPPackage {
public partial class RPClientBaseEDWS : EventDrivenWebSocket {
public delegate void RPClientEventHandler(string cmd, Dictionary? data);
public delegate void RPClientErrorHandler(string errCode, string type, string cmd, string errMsg);
public event RPClientEventHandler? OnRPCUser;
public event RPClientEventHandler? OnRPCRegion;
public event RPClientEventHandler? OnRPCSession;
public event RPClientEventHandler? OnRPCMsg;
public event RPClientErrorHandler? OnRPCError;
public RPClientBaseEDWS() : base() {
OnText += (text) => {
// GD.Print($"response: {text}");
RPMessage? msg = RPHelper.HandleIncomingMessage(text);
if (msg == null) {
MakeRPCError("9999", "Unknown Msg", "Error", null);
return;
}
if (msg.Code != "0000") {
OnRPCError?.Invoke(msg.Code ?? "9999", msg.Type, msg.Cmd,
msg.Data?.ToString() ?? "");
return;
}
switch (msg.Type) {
case "user":
OnRPCUser?.Invoke(msg.Cmd, msg.Data);
break;
case "region":
OnRPCRegion?.Invoke(msg.Cmd, msg.Data);
break;
case "session":
OnRPCSession?.Invoke(msg.Cmd, msg.Data);
break;
case "msg":
OnRPCMsg?.Invoke(msg.Cmd, msg.Data);
break;
default:
MakeRPCError(msg.Code, "unknown", msg.Cmd, msg.Data?.ToString());
break;
}
};
}
protected void MakeRPCError(string errCode, string type, string cmd, string? errMsg) {
OnRPCError?.Invoke(errCode, type, cmd, errMsg ?? "null");
}
}
public partial class RPClientEDWS : RPClientBaseEDWS {
string? userName;
string? userId;
string? userToken;
string? regionId;
public string? GetUserId() { return userId; }
public delegate void SessionRecvHandle(Dictionary? msg);
public event SessionRecvHandle? OnPRCSessionRecv;
public event RPClientEventHandler? OnPRCSessionExit;
public RPClientEDWS() : base() {
OnRPCUser += (cmd, msg) => {
if (msg == null) {
MakeRPCError("0000", "User", "unknown", "unknown");
return;
}
switch (cmd) {
case "init":
userId = msg["userId"].AsString();
userToken = msg["token"].AsString();
_userInitCallback?.Invoke();
break;
case "rename":
userName = msg["_"].AsString();
break;
default:
MakeRPCError("0000", "user", "unknown", msg?.ToString());
break;
}
};
OnRPCRegion += (cmd, msg) => {
switch (cmd) {
case "add":
break;
case "inspect":
// var regions = msg["_"].AsGodotArray<Dictionary>();
_regionRecvCallback?.Invoke(cmd, msg);
break;
case "list":
// var users = msg["_"].AsGodotArray<Dictionary>();
_regionRecvCallback?.Invoke(cmd, msg);
break;
default:
MakeRPCError("0000", "region", "unknown", msg?.ToString());
break;
}
};
OnRPCSession += (cmd, msg) => {
switch (cmd) {
case "sendAll":
OnPRCSessionRecv?.Invoke(msg);
break;
case "create":
break;
case "ackCreate":
// GD.PrintErr($"{cmd} {msg} {__SessionAckCreateCallback__ == null}");
_sessionAckCreateCallback?.Invoke(cmd, msg);
break;
case "exit":
OnPRCSessionExit?.Invoke(cmd, msg);
break;
default:
break;
}
};
OnRPCMsg += (cmd, msg) => {
switch(cmd) {
case "echo":
GD.Print(msg?["_"].AsString());
break;
default:
break;
}
};
OnRPCError += (code, type, cmd, msg) => {
};
}
public static void ClearRPCClientFunc() {
}
public bool IsOnline() {
return GetIsConnected() && userId != null;
}
public static void ConnectServer(string url) {
}
public void ExitServer() {
this.SendRPMessage(new RPMessage {
Type = "user",
Cmd = "exit",
Uid = userId,
Token = userToken,
});
userId = null;
userToken = null;
this.Close();
}
public delegate bool UserInitCallback();
private UserInitCallback? _userInitCallback;
public bool UserInit(string userName, string fingerPrint, UserInitCallback callback) {
if (this.GetIsConnected() == false) {
return false;
}
this.SendRPMessage(new RPMessage{
Type = "user",
Cmd = "init",
Data = new Dictionary {
{ "userName", userName },
{ "fingerPrint", fingerPrint }
}
});
_userInitCallback = null;
if (callback != null) _userInitCallback += callback;
return true;
}
public bool UserRename(string newName) {
if (this.GetIsConnected() == false) {
return false;
}
this.SendRPMessage(new RPMessage{
Type = "user",
Cmd = "rename",
Uid = userId,
Token = userToken,
Data = new Dictionary {
{ "_", newName }
}
});
return true;
}
public bool RegionAdd(string regionId) {
if (this.GetIsConnected() == false || this.userId == null) {
return false;
}
this.SendRPMessage(new RPMessage{
Type = "region",
Cmd = "add",
Uid = userId,
Token = userToken,
Data = new Dictionary {
{ "regionId", regionId }
}
});
return true;
}
public delegate bool RegionInspectCallback(
Array<Dictionary<string, string>> _
);
private RPClientEventHandler? _regionRecvCallback;
public bool RegionInspect(string regionId, RegionInspectCallback callback) {
if (this.GetIsConnected() == false || this.userId == null) {
return false;
}
_regionRecvCallback = null;
_regionRecvCallback += (cmd, msg) => {
if (cmd != "inspect" || msg == null) {
return;
}
callback(msg["_"].AsGodotArray<Dictionary<string, string>>());
};
this.SendRPMessage(new RPMessage{
Type = "region",
Cmd = "inspect",
Uid = userId,
Token = userToken,
Data = new Dictionary {
{ "regionId", regionId }
}
});
return true;
}
public delegate bool SessionAckCreateCallback(
string sessionId,
bool res,
string? reqUserId,
string? reqUserName
);
private RPClientEventHandler? _sessionAckCreateCallback;
public void RegSessionAckCreateCallback(SessionAckCreateCallback recvCallback) {
_sessionAckCreateCallback = null;
_sessionAckCreateCallback += (cmd, msg) => {
if (msg == null) return;
string sessionId = msg["sessionId"].AsString();
bool res = msg.ContainsKey("res") && msg["res"].AsBool();
string? reqUserId = msg.ContainsKey("reqUserId") ? msg["reqUserId"].AsString() : null;
string? reqUserName = msg.ContainsKey("reqUserName") ? msg["reqUserName"].AsString() : null;
recvCallback(sessionId, res, reqUserId, reqUserName);
};
}
public bool SessionCreate(string[] usersId) {
if (this.GetIsConnected() == false || this.userId == null) {
return false;
}
this.SendRPMessage(new RPMessage {
Type = "session",
Cmd = "create",
Uid = userId,
Token = userToken,
Data = new Dictionary {
{ "_", usersId }
}
});
return true;
}
public bool SessionAckCreate(string sessionId, bool response)
{
if (this.GetIsConnected() == false || this.userId == null) {
return false;
}
// 根据响应情况发送确认消息给服务器
string code = response ? "0000" : "0001";
this.SendRPMessage(new RPMessage {
Type = "session",
Cmd = "ackCreate",
Uid = userId,
Token = userToken,
Code = code,
Data = new Dictionary {
{ "sessionId", sessionId },
{ "res", response }
}
});
return true;
}
public bool SendSessionToAll(string sessionId, Variant data) {
if (this.GetIsConnected() == false || this.userId == null || sessionId == null) {
return false;
}
this.SendRPMessage(new RPMessage{
Type = "session",
Cmd = "sendAll",
Uid = userId,
Token = userToken,
Data = new Dictionary {
{ "sessionId", sessionId },
{ "msg", data },
}
});
return true;
}
// ws.OnOpen += (eventName, args) => {
// ws.SendRPMessage(new RPMessage{
// Type = "user",
// Cmd = "tmp",
// });
// };
// ws.OnError += (eventName, args) => {
// GD.PrintErr(args);
// // SetProcess(false);
// };
// ws.OnClose += (eventName, args) => {
// // GD.Print("close");
// SetProcess(false);
// };
}
}