using System.Data;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.SQLScript.Common;
using Milimoe.FunGame.Core.Library.SQLScript.Entity;
using Milimoe.FunGame.Server.Model;
using Milimoe.FunGame.Server.Others;
using Milimoe.FunGame.Server.Services;
using ProjectRedbud.FunGame.SQLQueryExtension;
namespace Milimoe.FunGame.Server.Controller
{
///
/// 继承自
///
///
public class DataRequestController where T : ISocketMessageProcessor
{
public ServerModel Server { get; }
public SQLHelper? SQLHelper => Server.SQLHelper;
public MailSender? MailSender => Server.MailSender;
public Authenticator? Authenticator { get; }
public DataRequestType LastRequest => _lastRequest;
private DataRequestType _lastRequest = DataRequestType.UnKnown;
private readonly bool[] _isReadyCheckCD = [false, false];
protected string _username = "";
protected bool _isMatching;
///
/// 数据请求控制器
///
///
public DataRequestController(ServerModel server)
{
Server = server;
if (SQLHelper != null) Authenticator = new(Server, SQLHelper, MailSender);
}
///
/// 处理客户端的数据请求
///
///
///
///
public async Task> GetResultData(DataRequestType type, Dictionary data)
{
Dictionary result = [];
_lastRequest = type;
ServerHelper.WriteLine(Server.GetClientName() + " -> " + DataRequestSet.GetTypeString(_lastRequest), InvokeMessageType.DataRequest);
switch (type)
{
case DataRequestType.UnKnown:
break;
case DataRequestType.RunTime_Logout:
LogOut(data, result);
break;
case DataRequestType.Main_GetNotice:
GetServerNotice(result);
break;
case DataRequestType.Main_CreateRoom:
CreateRoom(data, result);
break;
case DataRequestType.Main_UpdateRoom:
UpdateRoom(result);
break;
case DataRequestType.Main_IntoRoom:
await IntoRoom(data, result);
break;
case DataRequestType.Main_QuitRoom:
await QuitRoom(data, result);
break;
case DataRequestType.Main_MatchRoom:
MatchRoom(data, result);
break;
case DataRequestType.Main_Chat:
await Chat(data);
break;
case DataRequestType.Main_Ready:
SetReady(data, result);
break;
case DataRequestType.Main_CancelReady:
CancelReady(data, result);
break;
case DataRequestType.Main_StartGame:
StartGame(data, result);
break;
case DataRequestType.Reg_Reg:
Reg(data, result);
break;
case DataRequestType.Login_Login:
await Login(data, result);
break;
case DataRequestType.Login_GetFindPasswordVerifyCode:
ForgetPassword(data, result);
break;
case DataRequestType.Login_UpdatePassword:
UpdatePassword(data, result);
break;
case DataRequestType.Room_UpdateRoomSettings:
UpdateRoomSettings(data, result);
break;
case DataRequestType.Room_GetRoomPlayerCount:
GetRoomPlayerCount(data, result);
break;
case DataRequestType.Room_UpdateRoomMaster:
await UpdateRoomMaster(data, result);
break;
case DataRequestType.UserCenter_UpdateUser:
UpdateUser(data, result);
break;
case DataRequestType.UserCenter_UpdatePassword:
UpdatePassword(data, result);
break;
case DataRequestType.UserCenter_DailySignIn:
DailySignIn(result);
break;
case DataRequestType.Inventory_GetStore:
GetStore(data, result);
break;
case DataRequestType.Inventory_GetMarket:
GetMarket(data, result);
break;
case DataRequestType.Inventory_StoreBuy:
StoreBuy(data, result);
break;
case DataRequestType.Inventory_MarketBuy:
MarketBuy(data, result);
break;
case DataRequestType.Inventory_UpdateInventory:
UpdateInventory(data, result);
break;
case DataRequestType.Inventory_Use:
Use(data, result);
break;
case DataRequestType.Inventory_StoreSell:
StoreSell(data, result);
break;
case DataRequestType.Inventory_MarketSell:
MarketSell(data, result);
break;
case DataRequestType.Inventory_MarketDelist:
MarketDelist(data, result);
break;
case DataRequestType.Inventory_UpdateMarketPrice:
UpdateMarketPrice(data, result);
break;
case DataRequestType.Inventory_GetOffer:
GetOffer(data, result);
break;
case DataRequestType.Inventory_MakeOffer:
MakeOffer(data, result);
break;
case DataRequestType.Inventory_ReviseOffer:
ReviseOffer(data, result);
break;
case DataRequestType.Inventory_RespondOffer:
RespondOffer(data, result);
break;
default:
break;
}
return result;
}
#region RunTime
///
/// 退出登录
///
///
///
private void LogOut(Dictionary requestData, Dictionary resultData)
{
string msg = "";
Guid key = Guid.Empty;
if (requestData.Count >= 1)
{
key = DataRequest.GetDictionaryJsonObject(requestData, "key");
if (Server.IsLoginKey(key))
{
// 从玩家列表移除
Server.RemoveUser();
Server.GetUsersCount();
msg = "你已成功退出登录! ";
}
}
resultData.Add("msg", msg);
resultData.Add("key", key);
}
#endregion
#region Main
///
/// 获取公告
///
///
private static void GetServerNotice(Dictionary resultData)
{
resultData.Add("notice", Config.ServerNotice);
}
///
/// 创建房间
///
///
///
private void CreateRoom(Dictionary requestData, Dictionary resultData)
{
Room room = General.HallInstance;
if (requestData.Count >= 3)
{
RoomType type = DataRequest.GetDictionaryJsonObject(requestData, "roomType");
string gameModule = DataRequest.GetDictionaryJsonObject(requestData, "moduleServer") ?? "";
string gameMap = DataRequest.GetDictionaryJsonObject(requestData, "map") ?? "";
bool isRank = DataRequest.GetDictionaryJsonObject(requestData, "isRank");
ServerHelper.WriteLine("[CreateRoom] " + RoomSet.GetTypeString(type) + " (" + string.Join(", ", [gameModule, gameMap]) + ")", InvokeMessageType.DataRequest);
if (gameModule == "" || gameMap == "" || FunGameSystem.GameModuleLoader is null || !FunGameSystem.GameModuleLoader.ModuleServers.ContainsKey(gameModule) || !FunGameSystem.GameModuleLoader.Maps.ContainsKey(gameMap))
{
ServerHelper.WriteLine("缺少对应的模组或地图,无法创建房间。");
resultData.Add("room", room);
return;
}
User user = DataRequest.GetDictionaryJsonObject(requestData, "master") ?? Factory.GetUser();
string password = DataRequest.GetDictionaryJsonObject(requestData, "password") ?? "";
int maxusers = DataRequest.GetDictionaryJsonObject(requestData, "maxUsers");
if (user.Id != 0)
{
string roomid;
while (true)
{
// 防止重复
roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7).ToUpper();
if (FunGameSystem.RoomList.GetRoom(roomid).Roomid == "-1")
{
break;
}
}
if (roomid != "-1" && SQLHelper != null)
{
SQLHelper.Execute(RoomQuery.Insert_CreateRoom(SQLHelper, roomid, user.Id, type, gameModule, gameMap, isRank, password, maxusers));
if (SQLHelper.Result == SQLResult.Success)
{
ServerHelper.WriteLine("[CreateRoom] Master: " + user.Username + " RoomID: " + roomid);
DataRow? dr = SQLHelper.ExecuteDataRow(RoomQuery.Select_IsExistRoom(SQLHelper, roomid));
if (dr != null)
{
room = Factory.GetRoom(dr, user);
FunGameSystem.RoomList.AddRoom(room);
}
}
}
}
}
resultData.Add("room", room);
}
///
/// 更新房间列表
///
///
private static void UpdateRoom(Dictionary resultData)
{
resultData.Add("rooms", FunGameSystem.RoomList.ListRoom); // 传RoomList
}
///
/// 退出房间,并更新房主
///
///
///
private async Task QuitRoom(Dictionary requestData, Dictionary resultData)
{
bool result = false;
if (requestData.Count >= 2)
{
string roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
bool isMaster = DataRequest.GetDictionaryJsonObject(requestData, "isMaster");
if (roomid != "-1" && FunGameSystem.RoomList.IsExist(roomid))
{
result = await Server.QuitRoom(roomid, isMaster);
}
}
resultData.Add("result", result);
}
///
/// 进入房间
///
///
///
private async Task IntoRoom(Dictionary requestData, Dictionary resultData)
{
bool result = false;
if (requestData.Count >= 1)
{
string roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
if (roomid != "-1")
{
if (SQLHelper != null)
{
SQLHelper.ExecuteDataSet(RoomQuery.Select_IsExistRoom(SQLHelper, roomid));
if (SQLHelper.Success)
{
FunGameSystem.RoomList.IntoRoom(roomid, Server.User);
Server.InRoom = FunGameSystem.RoomList[roomid];
Server.User.OnlineState = OnlineState.InRoom;
await Server.SendClients(Server.Listener.ClientList.Where(c => c != null && roomid == c.InRoom.Roomid && c.User.Id != 0),
SocketMessageType.Chat, Server.User.Username, DateTimeUtility.GetNowShortTime() + " [ " + Server.User.Username + " ] 进入了房间。");
result = true;
}
else
{
FunGameSystem.RoomList.RemoveRoom(roomid);
}
}
}
}
resultData.Add("result", result);
}
///
/// 匹配房间
///
///
///
private void MatchRoom(Dictionary requestData, Dictionary resultData)
{
bool result = true;
if (requestData.Count >= 1)
{
bool iscancel = DataRequest.GetDictionaryJsonObject(requestData, "isCancel");
if (!iscancel)
{
ServerHelper.WriteLine("[MatchRoom] Start", InvokeMessageType.DataRequest);
RoomType type = DataRequest.GetDictionaryJsonObject(requestData, "roomType");
User user = DataRequest.GetDictionaryJsonObject(requestData, "matcher") ?? Factory.GetUser();
StartMatching(type, user);
}
else
{
// 取消匹配
ServerHelper.WriteLine("[MatchRoom] Cancel", InvokeMessageType.DataRequest);
StopMatching();
}
}
resultData.Add("result", result);
}
///
/// 设置已准备状态
///
///
///
private void SetReady(Dictionary requestData, Dictionary resultData)
{
bool result = false;
string roomid = "-1";
if (requestData.Count >= 1)
{
roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
User user = Server.User;
if (roomid != "-1" && user.Id != 0 && user.Id != FunGameSystem.RoomList.GetRoomMaster(roomid).Id && !FunGameSystem.RoomList.GetReadyUserList(roomid).Contains(user))
{
FunGameSystem.RoomList.SetReady(roomid, user);
result = true;
}
}
resultData.Add("result", result);
resultData.Add("ready", FunGameSystem.RoomList.GetReadyUserList(roomid));
resultData.Add("notready", FunGameSystem.RoomList.GetNotReadyUserList(roomid));
}
///
/// 取消已准备状态
///
///
///
private void CancelReady(Dictionary requestData, Dictionary resultData)
{
bool result = false;
string roomid = "-1";
if (requestData.Count >= 1)
{
roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
User user = Server.User;
if (roomid != "-1" && user.Id != 0 && user.Id != FunGameSystem.RoomList.GetRoomMaster(roomid).Id && FunGameSystem.RoomList.GetReadyUserList(roomid).Contains(user))
{
FunGameSystem.RoomList.CancelReady(roomid, user);
result = true;
}
}
resultData.Add("result", result);
resultData.Add("ready", FunGameSystem.RoomList.GetReadyUserList(roomid));
resultData.Add("notready", FunGameSystem.RoomList.GetNotReadyUserList(roomid));
}
///
/// 发送聊天消息
///
///
private async Task Chat(Dictionary requestData)
{
if (requestData.Count >= 1)
{
string msg = DataRequest.GetDictionaryJsonObject(requestData, "msg") ?? "";
if (msg.Trim() != "")
{
await Server.SendClients(Server.Listener.ClientList.Where(c => c != null && Server.InRoom.Roomid == c.InRoom.Roomid && c.User.Id != 0),
SocketMessageType.Chat, Server.User.Username, msg);
}
}
}
///
/// 开始游戏
///
///
///
private void StartGame(Dictionary requestData, Dictionary resultData)
{
bool result = false;
if (requestData.Count >= 2)
{
string roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
bool isMaster = DataRequest.GetDictionaryJsonObject(requestData, "isMaster");
if (roomid != "-1")
{
if (isMaster)
{
string[] usernames = [.. FunGameSystem.RoomList.GetNotReadyUserList(roomid).Select(user => user.Username)];
if (usernames.Length > 0)
{
if (_isReadyCheckCD[0] == false)
{
// 提醒玩家准备
Server.SendSystemMessage(ShowMessageType.None, "还有玩家尚未准备,无法开始游戏。", "", 0, Server.User.Username);
Server.SendSystemMessage(ShowMessageType.Tip, "房主即将开始游戏,请准备!", "请准备就绪", 10, usernames);
_isReadyCheckCD[0] = true;
TaskUtility.RunTimer(() =>
{
_isReadyCheckCD[0] = false;
}, 15000);
}
else
{
Server.SendSystemMessage(ShowMessageType.None, "还有玩家尚未准备,无法开始游戏。15秒内只能发送一次准备提醒。", "", 0, Server.User.Username);
}
}
else
{
List users = FunGameSystem.RoomList.GetUsers(roomid);
if (users.Count < 2)
{
Server.SendSystemMessage(ShowMessageType.None, "玩家数量不足,无法开始游戏。", "", 0, Server.User.Username);
}
else
{
usernames = [.. users.Select(user => user.Username)];
Server.SendSystemMessage(ShowMessageType.None, "所有玩家均已准备,游戏将在10秒后开始。", "", 0, usernames);
StartGame(roomid, users, usernames);
result = true;
}
}
}
else if (_isReadyCheckCD[1] == false)
{
// 提醒房主开始游戏
Server.SendSystemMessage(ShowMessageType.None, "已提醒房主立即开始游戏。", "", 0, Server.User.Username);
Server.SendSystemMessage(ShowMessageType.Tip, "房间中的玩家已请求你立即开始游戏。", "请求开始", 10, FunGameSystem.RoomList[roomid].RoomMaster.Username);
_isReadyCheckCD[1] = true;
TaskUtility.RunTimer(() =>
{
_isReadyCheckCD[1] = false;
}, 15000);
}
else
{
Server.SendSystemMessage(ShowMessageType.None, "15秒内只能发送一次提醒,请稍后再试。", "", 0, Server.User.Username);
}
}
}
resultData.Add("result", result);
}
private void StartGame(string roomid, List users, params string[] usernames)
{
Room room = General.HallInstance;
if (roomid != "-1")
{
room = FunGameSystem.RoomList[roomid];
}
if (room.Roomid == "-1") return;
// 启动服务器
TaskUtility.NewTask(() =>
{
if (FunGameSystem.GameModuleLoader != null && FunGameSystem.GameModuleLoader.ModuleServers.ContainsKey(room.GameModule))
{
room.RoomState = RoomState.Gaming;
Server.NowGamingServer = FunGameSystem.GameModuleLoader.GetServerMode(room.GameModule);
Server.User.OnlineState = OnlineState.Gaming;
Dictionary all = Server.Listener.UserList.Cast().ToDictionary(k => k.User.Username, v => v);
// 给其他玩家赋值模组服务器
foreach (IServerModel model in all.Values.Where(s => s.User.Username != Server.User.Username))
{
model.NowGamingServer = Server.NowGamingServer;
model.User.OnlineState = OnlineState.Gaming;
}
GamingObject obj = new(room, users, Server, all);
if (Server.NowGamingServer.StartServer(obj))
{
Server.NowGamingServer.GamingObjects.TryAdd(room.Roomid, obj);
foreach (IServerModel serverTask in Server.Listener.UserList.Where(model => usernames.Contains(model.User.Username)))
{
if (serverTask != null && serverTask.Socket != null)
{
FunGameSystem.RoomList.CancelReady(roomid, serverTask.User);
serverTask.Send(SocketMessageType.StartGame, room, users);
}
}
}
}
});
}
#endregion
#region Reg
///
/// 接收并验证注册验证码
///
///
///
private void Reg(Dictionary requestData, Dictionary resultData)
{
string msg = "";
RegInvokeType returnType = RegInvokeType.None;
bool success = false;
if (requestData.Count >= 4)
{
string username = DataRequest.GetDictionaryJsonObject(requestData, "username") ?? "";
string password = DataRequest.GetDictionaryJsonObject(requestData, "password") ?? "";
string email = DataRequest.GetDictionaryJsonObject(requestData, "email") ?? "";
string verifycode = DataRequest.GetDictionaryJsonObject(requestData, "verifycode") ?? "";
(msg, returnType, success) = DataRequestService.Reg(Server, username, password, email, verifycode, Server.Socket?.ClientIP ?? "");
}
else
{
ServerHelper.WriteLine("客户端提供的参数不足。", InvokeMessageType.DataRequest, LogLevel.Warning);
}
resultData.Add("msg", msg);
resultData.Add("type", returnType);
resultData.Add("success", success);
}
#endregion
#region Login
///
/// 登录
///
///
///
private async Task Login(Dictionary requestData, Dictionary resultData)
{
string msg = "";
User user = Factory.GetUser();
string username = "";
string password = "";
string autokey = "";
Guid key = Guid.Empty;
if (requestData.Count >= 4)
{
username = DataRequest.GetDictionaryJsonObject(requestData, "username") ?? "";
password = DataRequest.GetDictionaryJsonObject(requestData, "password") ?? "";
autokey = DataRequest.GetDictionaryJsonObject(requestData, "autokey") ?? "";
key = DataRequest.GetDictionaryJsonObject(requestData, "key");
}
else
{
ServerHelper.WriteLine("客户端提供的参数不足。", InvokeMessageType.DataRequest, LogLevel.Warning);
}
// CheckLogin的情况
if (key != Guid.Empty)
{
if (Server.IsLoginKey(key))
{
await Server.CheckLogin();
user = Server.User;
}
else
{
msg = "客户端发送了错误的秘钥,不允许本次登录。";
ServerHelper.WriteLine(msg, InvokeMessageType.DataRequest, LogLevel.Warning);
}
}
else
{
// 进行预登录
(bool success, DataSet dsUser, msg, key) = DataRequestService.PreLogin(this, username, password, autokey);
if (success)
{
Server.PreLogin(dsUser, key);
resultData.Add("key", key);
}
}
resultData.Add("msg", msg);
resultData.Add("user", user);
}
///
/// 接收并验证找回密码时的验证码
///
///
///
private void ForgetPassword(Dictionary requestData, Dictionary resultData)
{
string msg = "无法找回您的密码,请稍后再试。"; // 返回的验证信息
if (requestData.Count >= 3)
{
string username = DataRequest.GetDictionaryJsonObject(requestData, "username") ?? "";
string email = DataRequest.GetDictionaryJsonObject(requestData, "email") ?? "";
string verifycode = DataRequest.GetDictionaryJsonObject(requestData, "forgetVerifyCode") ?? "";
// 客户端发来了验证码就进行验证,没有发就生成
if (verifycode.Trim() != "")
{
// 先检查验证码
if (SQLHelper != null)
{
DataRow? dr = SQLHelper.ExecuteDataRow(ForgetVerifyCodes.Select_ForgetVerifyCode(SQLHelper, username, email, verifycode));
if (dr != null)
{
// 检查验证码是否过期
if (!DateTime.TryParse(dr[ForgetVerifyCodes.Column_SendTime].ToString(), out DateTime SendTime))
{
SendTime = General.DefaultTime;
}
if ((DateTime.Now - SendTime).TotalMinutes >= 10)
{
ServerHelper.WriteLine(Server.GetClientName() + " 验证码已过期");
msg = "此验证码已过期,请重新找回密码。";
SQLHelper.Execute(ForgetVerifyCodes.Delete_ForgetVerifyCode(SQLHelper, username, email));
}
else
{
// 检查验证码是否正确
if (verifycode.Equals(dr[ForgetVerifyCodes.Column_ForgetVerifyCode]))
{
ServerHelper.WriteLine("[ForgerPassword] Username: " + username + " Email: " + email);
SQLHelper.Execute(ForgetVerifyCodes.Delete_ForgetVerifyCode(SQLHelper, username, email));
msg = "";
}
else msg = "验证码不正确,请重新输入!";
}
}
else msg = "验证码不正确,请重新输入!";
}
}
else
{
// 检查账号和邮箱是否匹配
if (SQLHelper != null)
{
SQLHelper.ExecuteDataSet(UserQuery.Select_CheckEmailWithUsername(SQLHelper, username, email));
if (SQLHelper.Result != SQLResult.Success)
{
msg = "此邮箱未绑定此账号,请重试!";
}
else
{
// 检查验证码是否发送过和是否过期
DataRow? dr = SQLHelper.ExecuteDataRow(ForgetVerifyCodes.Select_HasSentForgetVerifyCode(SQLHelper, username, email));
if (dr is null || (DateTime.TryParse(dr[ForgetVerifyCodes.Column_SendTime].ToString(), out DateTime SendTime) && (DateTime.Now - SendTime).TotalMinutes >= 10))
{
// 发送验证码,需要先删除之前过期的验证码
SQLHelper.Execute(ForgetVerifyCodes.Delete_ForgetVerifyCode(SQLHelper, username, email));
string forgetVerify = Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 6);
SQLHelper.Execute(ForgetVerifyCodes.Insert_ForgetVerifyCode(SQLHelper, username, email, forgetVerify));
if (SQLHelper.Result == SQLResult.Success)
{
if (MailSender != null)
{
// 发送验证码
string ServerName = Config.ServerName;
string Subject = $"[{ServerName}] 找回密码验证码";
string Body = $"亲爱的 {username},
您正在找回 [{ServerName}] 账号的密码,您的验证码是 {forgetVerify} ,10分钟内有效,请及时输入!
{ServerName}
{DateTimeUtility.GetDateTimeToString(TimeType.LongDateOnly)}";
string[] To = [email];
if (MailSender.Send(MailSender.CreateMail(Subject, Body, System.Net.Mail.MailPriority.Normal, true, To)) == MailSendResult.Success)
{
ServerHelper.WriteLine(Server.GetClientName() + $" 已向{email}发送验证码:{forgetVerify}");
msg = "";
}
else
{
ServerHelper.WriteLine(Server.GetClientName() + " 无法发送验证码");
ServerHelper.WriteLine(MailSender.ErrorMsg);
}
}
else // 不使用MailSender的情况
{
ServerHelper.WriteLine(Server.GetClientName() + $" 验证码为:{forgetVerify},但因 SMTP 服务未开启,请服务器管理员告知此用户");
msg = "";
}
}
}
else
{
// 发送过验证码且验证码没有过期
string ForgetVerifyCode = (string)dr[ForgetVerifyCodes.Column_ForgetVerifyCode];
ServerHelper.WriteLine(Server.GetClientName() + $" 十分钟内已向{email}发送过验证码:{ForgetVerifyCode}");
msg = "";
}
}
}
}
}
resultData.Add("msg", msg);
}
#endregion
#region Room
///
/// 更新房间设置
///
///
///
private void UpdateRoomSettings(Dictionary requestData, Dictionary resultData)
{
bool result = false;
string msg = "";
string room = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
RoomType newType = DataRequest.GetDictionaryJsonObject(requestData, "type");
string newPassword = DataRequest.GetDictionaryJsonObject(requestData, "password") ?? "";
int newMaxUsers = DataRequest.GetDictionaryJsonObject(requestData, "maxUsers");
string newModule = DataRequest.GetDictionaryJsonObject(requestData, "module") ?? "";
string newMap = DataRequest.GetDictionaryJsonObject(requestData, "map") ?? "";
User user = Server.User;
if (room != "-1" && FunGameSystem.RoomList.IsExist(room))
{
Room r = FunGameSystem.RoomList[room];
if (user.Id != r.RoomMaster.Id)
{
msg = "更新失败,只有房主才可以更新房间设置。";
}
else
{
result = true;
ServerHelper.WriteLine("[UpdateRoomSettings] User: " + user.Username + " RoomID: " + r.Roomid);
if (r.RoomState == RoomState.Created)
{
r.RoomType = newType;
r.Password = newPassword;
r.MaxUsers = newMaxUsers;
r.GameModule = newModule;
r.GameMap = newMap;
}
else
{
msg = "更新失败,只能在房间状态稳定时更新其设置。";
}
}
}
resultData.Add("result", result);
resultData.Add("msg", msg);
resultData.Add("room", room);
}
///
/// 获取房间内玩家数量
///
///
///
private static void GetRoomPlayerCount(Dictionary requestData, Dictionary resultData)
{
string roomid = "-1";
if (requestData.Count >= 1)
{
roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
}
resultData.Add("count", FunGameSystem.RoomList.GetUserCount(roomid));
}
///
/// 更新房主
///
///
///
///
private async Task UpdateRoomMaster(Dictionary requestData, Dictionary resultData)
{
bool result = false;
if (requestData.Count >= 2)
{
string roomid = DataRequest.GetDictionaryJsonObject(requestData, "roomid") ?? "-1";
User newMaster = DataRequest.GetDictionaryJsonObject(requestData, "newMaster") ?? Factory.GetUser();
if (roomid != "-1" && FunGameSystem.RoomList.IsExist(roomid) && newMaster.Id != 0)
{
Room room = FunGameSystem.RoomList[roomid];
User oldMaster = room.RoomMaster;
room.RoomMaster = newMaster;
result = true;
if (SQLHelper != null)
{
SQLHelper.UpdateRoomMaster(roomid, newMaster.Id);
if (SQLHelper.Result == SQLResult.Success)
{
await Server.SendClients(Server.Listener.ClientList.Where(c => c != null && c.InRoom.Roomid == roomid), SocketMessageType.UpdateRoomMaster, room);
ServerHelper.WriteLine($"[UpdateRoomMaster] RoomID: {roomid} 房主变更: {oldMaster.Username} -> {newMaster.Username}");
}
}
}
}
else
{
ServerHelper.WriteLine("客户端提供的参数不足。", InvokeMessageType.DataRequest, LogLevel.Warning);
}
// 返回结果
resultData.Add("result", result);
}
///
/// 开始匹配
///
///
///
private void StartMatching(RoomType type, User user)
{
_isMatching = true;
if (user.OnlineState == OnlineState.Online) user.OnlineState = OnlineState.Matching;
ServerHelper.WriteLine(Server.GetClientName() + " 开始匹配。类型:" + RoomSet.GetTypeString(type));
TaskUtility.NewTask(async () =>
{
if (_isMatching)
{
Room room = await MatchingRoom(type, user);
if (_isMatching && Server.Socket != null)
{
await Server.Send(SocketMessageType.MatchRoom, room);
}
_isMatching = false;
}
}).OnError(e =>
{
ServerHelper.Error(e);
_isMatching = false;
});
}
///
/// 终止匹配
///
private void StopMatching()
{
if (_isMatching)
{
ServerHelper.WriteLine(Server.GetClientName() + " 取消了匹配。");
if (Server.User.OnlineState == OnlineState.Matching) Server.User.OnlineState = OnlineState.Online;
_isMatching = false;
}
}
///
/// 匹配线程
///
///
///
///
private async Task MatchingRoom(RoomType roomtype, User user)
{
int i = 1; // Elo扩大系数
double time = 0; // 已经匹配的时间
double expandInterval = 10; // 扩大匹配范围的间隔时间
double maxTime = 50; // 最大匹配时间
bool isRefreshRoom = false; // 是否刷新房间列表
// 匹配房间类型(如果是All,则匹配所有房间)
List targets;
if (roomtype == RoomType.All)
{
targets = [.. FunGameSystem.RoomList.ListRoom.Where(r => r.RoomState == RoomState.Created || r.RoomState == RoomState.Matching)];
}
else
{
targets = [.. FunGameSystem.RoomList.ListRoom.Where(r => (r.RoomState == RoomState.Created || r.RoomState == RoomState.Matching) && r.RoomType == roomtype)];
}
while (_isMatching)
{
if (isRefreshRoom)
{
isRefreshRoom = false;
if (roomtype == RoomType.All)
{
targets = [.. FunGameSystem.RoomList.ListRoom.Where(r => r.RoomState == RoomState.Created || r.RoomState == RoomState.Matching)];
}
else
{
targets = [.. FunGameSystem.RoomList.ListRoom.Where(r => (r.RoomState == RoomState.Created || r.RoomState == RoomState.Matching) && r.RoomType == roomtype)];
}
}
// 如果匹配停止,则退出
if (!_isMatching) break;
foreach (Room room in targets)
{
// 获取当前房间的玩家列表
List players = FunGameSystem.RoomList.GetUsers(room.Roomid);
if (players.Count > 0)
{
// 计算房间平均Elo
double avgElo = players.Sum(u => u.Statistics.EloStats.TryGetValue(0, out double value) ? value : 0) / players.Count;
double userElo = user.Statistics.EloStats.TryGetValue(0, out double userValue) ? userValue : 0;
// 匹配Elo范围,随着时间增加,范围逐渐扩大
if (userElo >= avgElo - (300 * i) && userElo <= avgElo + (300 * i))
{
// 找到匹配的房间,立即返回
return room;
}
}
}
// 如果匹配停止,则退出
if (!_isMatching) break;
// 检查是否已经过了10秒,扩大匹配范围
if (time >= expandInterval * i)
{
i++;
// 刷新房间列表
isRefreshRoom = true;
}
// 达到最大匹配时间后不再匹配Elo,直接返回第一个房间
if (time >= maxTime)
{
return targets.FirstOrDefault() ?? General.HallInstance;
}
await Task.Delay(100);
time += 0.1;
}
return General.HallInstance;
}
#endregion
#region UserCenter
///
/// 更新用户(全部数据)
///
///
///
private void UpdateUser(Dictionary requestData, Dictionary resultData)
{
string msg = "无法更新用户数据,请稍后再试。";
if (SQLHelper != null && requestData.Count > 0)
{
User user = DataRequest.GetDictionaryJsonObject(requestData, "user") ?? Factory.GetUser();
SQLHelper.UpdateUser(user);
if (SQLHelper.Success)
{
msg = "";
}
}
resultData.Add("msg", msg);
}
///
/// 更新用户的密码
///
///
///
private void UpdatePassword(Dictionary requestData, Dictionary resultData)
{
string msg = "无法更新您的密码,请稍后再试。";
if (requestData.Count >= 2)
{
string username = DataRequest.GetDictionaryJsonObject(requestData, "username") ?? "";
string password = DataRequest.GetDictionaryJsonObject(requestData, "password") ?? "";
if (username.Trim() != "" && password.Trim() != "")
{
FunGameSystem.UpdateUserKey(username);
password = password.Encrypt(FunGameSystem.GetUserKey(username));
SQLHelper?.UpdatePassword(username, password);
if (SQLHelper?.Success ?? false)
{
// 更新成功返回空值
msg = "";
}
}
}
resultData.Add("msg", msg);
}
///
/// 每日签到
///
///
private void DailySignIn(Dictionary resultData)
{
if (SQLHelper != null)
{
long userId = Server.User.Id;
if (userId != 0)
{
DataRow? dr = SQLHelper.ExecuteDataRow(UserSignIns.Select_GetUserSignIn(SQLHelper, userId));
if (dr != null)
{
int days = Convert.ToInt32(dr[UserSignIns.Column_Days]) + 1;
bool isSigned = Convert.ToInt32(dr[UserSignIns.Column_IsSigned]) != 0;
if (dr[UserSignIns.Column_LastTime] != DBNull.Value && DateTime.TryParseExact(dr[UserSignIns.Column_LastTime].ToString(), General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out DateTime dt))
{
if (isSigned)
{
resultData.Add("msg", "今天已经签到过了,请明天再来。");
return;
}
if ((DateTime.Now - dt).TotalDays > 1)
{
days = 1;
}
}
SQLHelper.Execute(UserSignIns.Update_UserSignIn(SQLHelper, userId, days));
if (SQLHelper.Success)
{
resultData.Add("msg", $"签到成功!你已经连续签到 {days} 天!");
return;
}
}
}
}
resultData.Add("msg", "签到失败!");
}
#endregion
#region Inventory
///
/// 获取商店信息
///
///
///
private void GetStore(Dictionary requestData, Dictionary resultData)
{
List stores = [];
if (requestData.Count > 0)
{
long[] ids = DataRequest.GetDictionaryJsonObject(requestData, "ids") ?? [];
stores = SQLHelper?.GetStoresWithGoods(ids) ?? [];
}
resultData.Add("result", stores.Count > 0);
resultData.Add("stores", stores);
}
///
/// 获取市场信息
///
///
///
private void GetMarket(Dictionary requestData, Dictionary resultData)
{
List markets = [];
if (requestData.Count > 0)
{
long[] users = DataRequest.GetDictionaryJsonObject(requestData, "users") ?? [];
MarketItemState state = DataRequest.GetDictionaryJsonObject(requestData, "state");
if (users.Length > 0)
{
foreach (long userid in users)
{
markets.AddRange(SQLHelper?.GetAllMarketsItem(userid, state) ?? []);
}
}
else
{
markets = SQLHelper?.GetAllMarketsItem(0, state) ?? [];
}
long[] items = DataRequest.GetDictionaryJsonObject(requestData, "items") ?? [];
if (items.Length > 0)
{
markets = [.. markets.Where(i => items.Contains(i.Id))];
}
}
resultData.Add("result", markets.Count > 0);
resultData.Add("markets", markets);
}
///
/// 购买物品(商店)
///
///
///
private void StoreBuy(Dictionary requestData, Dictionary resultData)
{
bool result = true;
double totalCost = 0;
List buyResult = [];
if (SQLHelper != null && requestData.Count > 0)
{
long storeid = DataRequest.GetDictionaryJsonObject(requestData, "storeid");
long userid = DataRequest.GetDictionaryJsonObject(requestData, "userid");
string currency = DataRequest.GetDictionaryJsonObject(requestData, "currency") ?? "";
Dictionary counts = DataRequest.GetDictionaryJsonObject>(requestData, "counts") ?? [];
bool ignore = DataRequest.GetDictionaryJsonObject(requestData, "ignore");
Store? store = SQLHelper.GetStore(storeid);
User? user = SQLHelper.GetUserById(userid, true);
if (store != null && user != null)
{
try
{
SQLHelper.NewTransaction();
foreach (long goodsId in counts.Keys)
{
Goods goods = store.Goods[goodsId];
int count = counts[goodsId];
if (count > goods.Stock)
{
result = false;
buyResult.Add($"购买失败,原因:库存不足,当前库存为:{goods.Stock},购买数量:{count}。");
continue;
}
if (goods.GetPrice(currency, out double price))
{
bool subResult = true;
bool useCredits = true;
double totalPrice = price * count;
if (currency == General.GameplayEquilibriumConstant.InGameCurrency && user.Inventory.Credits >= totalPrice)
{
user.Inventory.Credits -= totalPrice;
}
else
{
subResult = false;
buyResult.Add($"购买失败,原因:需要花费 {totalPrice} {General.GameplayEquilibriumConstant.InGameCurrency},但是您只有 {user.Inventory.Credits} {General.GameplayEquilibriumConstant.InGameCurrency}。");
}
if (currency == General.GameplayEquilibriumConstant.InGameMaterial && user.Inventory.Materials >= totalPrice)
{
user.Inventory.Materials -= totalPrice;
useCredits = false;
}
else
{
subResult = false;
buyResult.Add($"购买失败,原因:需要花费 {totalPrice} {General.GameplayEquilibriumConstant.InGameMaterial},但是您只有 {user.Inventory.Credits} {General.GameplayEquilibriumConstant.InGameMaterial}。");
}
if (subResult)
{
goods.Stock -= count;
totalCost += totalPrice;
ProcessStoreBuy(goods, useCredits, price, count, user);
buyResult.Add($"成功消费:{totalPrice} {currency},购买了 {count} 个 {goods.Name}。");
}
else
{
result = false;
}
}
}
if (result || (!result && ignore))
{
SQLHelper.UpdateInventory(user.Inventory);
}
if (SQLHelper.Success)
{
SQLHelper.Commit();
}
else
{
SQLHelper.Rollback();
}
}
catch (Exception e)
{
SQLHelper.Rollback();
ServerHelper.Error(e);
buyResult.Add("暂时无法处理此购买,请稍后再试。");
}
}
}
resultData.Add("result", result);
resultData.Add("msg", string.Join("\r\n", buyResult));
}
///
/// 处理商店购买
///
///
///
///
///
///
private static void ProcessStoreBuy(Goods goods, bool useCredits, double price, int count, User user)
{
foreach (Item item in goods.Items)
{
for (int i = 0; i < count; i++)
{
Item newItem = item.Copy();
newItem.IsTradable = false;
newItem.NextTradableTime = DateTimeUtility.GetTradableTime();
newItem.Price = useCredits ? Calculation.Round2Digits(price * 0.35) : Calculation.Round2Digits(price * 7);
newItem.User = user;
newItem.EntityState = EntityState.Added;
user.Inventory.Items.Add(newItem);
}
}
}
///
/// 购买物品(市场)
///
///
///
private void MarketBuy(Dictionary requestData, Dictionary resultData)
{
bool result = false;
string msg = "无法购买此物品,请稍后再试。";
if (SQLHelper != null && requestData.Count > 0)
{
Guid itemGuid = DataRequest.GetDictionaryJsonObject(requestData, "itemGuid");
MarketItem? marketItem = SQLHelper.GetMarketItem(itemGuid);
if (marketItem != null)
{
long userid = DataRequest.GetDictionaryJsonObject(requestData, "userid");
double price = DataRequest.GetDictionaryJsonObject(requestData, "price");
try
{
User? buyer = SQLHelper.GetUserById(userid, true);
User? itemUser = SQLHelper.GetUserById(marketItem.User.Id, true);
if (itemUser != null && buyer != null && itemUser.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
if (buyer.Inventory.Credits >= price)
{
buyer.Inventory.Credits -= price;
double fee = Calculation.Round2Digits(price * 0.15);
itemUser.Inventory.Credits += price - fee;
result = true;
}
else
{
msg = $"购买失败,原因:需要花费 {price} {General.GameplayEquilibriumConstant.InGameCurrency},但是您只有 {buyer.Inventory.Credits} {General.GameplayEquilibriumConstant.InGameCurrency}。";
}
if (result)
{
SQLHelper.NewTransaction();
try
{
item.EntityState = EntityState.Deleted;
SQLHelper.DeleteMarketItem(itemGuid);
Item newItem = item.Copy();
newItem.IsTradable = false;
newItem.NextTradableTime = DateTimeUtility.GetTradableTime();
newItem.User = buyer;
newItem.EntityState = EntityState.Added;
buyer.Inventory.Items.Add(newItem);
SQLHelper.UpdateInventory(itemUser.Inventory);
SQLHelper.UpdateInventory(buyer.Inventory);
}
catch
{
result = false;
}
if (result)
{
msg = $"成功消费:{price} {General.GameplayEquilibriumConstant.InGameCurrency},购买了 {itemUser.Username} 出售的 {item.Name}。";
SQLHelper.Commit();
}
else
{
SQLHelper.Rollback();
}
}
}
}
catch (Exception e)
{
SQLHelper.Rollback();
ServerHelper.Error(e);
msg = "暂时无法处理此购买,请稍后再试。";
}
}
else
{
msg = "目标物品不存在。";
}
}
resultData.Add("result", result);
resultData.Add("msg", msg);
}
///
/// 更新库存
///
///
///
private void UpdateInventory(Dictionary requestData, Dictionary resultData)
{
string msg = "无法更新库存数据,请稍后再试。";
if (SQLHelper != null && requestData.Count > 0)
{
Inventory inventory = DataRequest.GetDictionaryJsonObject(requestData, "inventory") ?? Factory.GetInventory();
bool fullUpdate = DataRequest.GetDictionaryJsonObject(requestData, "fullUpdate");
SQLHelper.UpdateInventory(inventory, fullUpdate);
if (SQLHelper.Success)
{
msg = "";
}
}
resultData.Add("msg", msg);
}
///
/// 使用物品
///
///
///
private void Use(Dictionary requestData, Dictionary resultData)
{
bool result = false;
string msg = "无法使用此物品,请稍后再试。";
if (SQLHelper != null && requestData.Count > 0)
{
Guid itemGuid = DataRequest.GetDictionaryJsonObject(requestData, "itemGuid");
long userid = DataRequest.GetDictionaryJsonObject(requestData, "userid");
Character[] targets = DataRequest.GetDictionaryJsonObject(requestData, "targets") ?? [];
long useCount = DataRequest.GetDictionaryJsonObject(requestData, "useCount");
User? user = SQLHelper.GetUserById(userid, true);
if (user != null && user.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
// 暂定标准实现是传这两个参数,作用目标和使用数量
Dictionary args = new()
{
{ "targets", targets },
{ "useCount", useCount }
};
bool used = item.UseItem(args);
if (used)
{
SQLHelper.UpdateInventory(user.Inventory);
}
}
if (result)
{
msg = "";
}
}
resultData.Add("result", result);
resultData.Add("msg", msg);
}
///
/// 出售物品(商店)
///
///
///
private void StoreSell(Dictionary requestData, Dictionary resultData)
{
bool result = false;
string msg = "无法出售此物品,请稍后再试。";
if (SQLHelper != null && requestData.Count > 0)
{
Guid itemGuid = DataRequest.GetDictionaryJsonObject(requestData, "itemGuid");
long userid = DataRequest.GetDictionaryJsonObject(requestData, "userid");
User? user = SQLHelper.GetUserById(userid, true);
if (user != null && user.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
if (!item.IsSellable)
{
msg = $"此物品无法出售{(item.NextSellableTime != DateTime.MinValue ? $",此物品将在 {item.NextSellableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可出售" : "")}。";
}
else
{
double reward = item.Price;
user.Inventory.Credits += reward;
item.EntityState = EntityState.Deleted;
SQLHelper.UpdateInventory(user.Inventory);
}
}
if (result)
{
msg = "";
}
}
resultData.Add("msg", msg);
}
///
/// 出售物品(市场)
///
///
///
private void MarketSell(Dictionary requestData, Dictionary resultData)
{
string msg = "无法上架此物品,请稍后再试。";
if (requestData.Count > 0)
{
Guid itemGuid = DataRequest.GetDictionaryJsonObject(requestData, "itemGuid");
long userid = DataRequest.GetDictionaryJsonObject(requestData, "userid");
double price = DataRequest.GetDictionaryJsonObject(requestData, "price");
User? user = SQLHelper?.GetUserById(userid, true);
if (user != null && user.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
if (!item.IsSellable)
{
msg = $"此物品无法出售{(item.NextSellableTime != DateTime.MinValue ? $",此物品将在 {item.NextSellableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可出售" : "")}。";
}
else
{
SQLHelper?.AddMarketItem(itemGuid, userid, price);
if (SQLHelper?.Success ?? false)
{
msg = "";
}
}
}
}
resultData.Add("msg", msg);
}
///
/// 下架市场物品
///
///
///
private void MarketDelist(Dictionary requestData, Dictionary resultData)
{
string msg = "无法下架市场物品,请稍后再试。";
if (requestData.Count > 0)
{
long userid = DataRequest.GetDictionaryJsonObject(requestData, "userid");
if (userid != 0)
{
SQLHelper?.DeleteMarketItemByUserId(userid);
}
else
{
Guid itemGuid = DataRequest.GetDictionaryJsonObject(requestData, "itemGuid");
if (itemGuid != Guid.Empty) SQLHelper?.DeleteMarketItem(itemGuid);
}
if (SQLHelper?.Success ?? false)
{
msg = "";
}
}
resultData.Add("msg", msg);
}
///
/// 更新市场价格
///
///
///
private void UpdateMarketPrice(Dictionary requestData, Dictionary resultData)
{
string msg = "无法更新市场价格,请稍后再试。";
if (requestData.Count > 0)
{
Guid itemGuid = DataRequest.GetDictionaryJsonObject(requestData, "itemGuid");
double price = DataRequest.GetDictionaryJsonObject(requestData, "price");
SQLHelper?.UpdateMarketItemPrice(itemGuid, price);
if (SQLHelper?.Success ?? false)
{
msg = "";
}
}
resultData.Add("msg", msg);
}
///
/// 获取交易报价
///
///
///
private void GetOffer(Dictionary requestData, Dictionary resultData)
{
string msg = "无法获取报价,请稍后再试。";
if (SQLHelper != null && requestData.Count >= 1)
{
long offerId = DataRequest.GetDictionaryJsonObject(requestData, "id");
bool apiQuery = DataRequest.GetDictionaryJsonObject(requestData, "apiQuery");
Offer? offer = SQLHelper.GetOffer(offerId);
if (offer != null)
{
// 检查当前用户是否有权限查看(报价创建者或接收者)允许管理员使用 API 查询报价
long userId = Server.User.Id;
if ((apiQuery && Server.User.IsAdmin) || offer.Offeror == userId || offer.Offeree == userId)
{
resultData.Add("offer", offer);
msg = "";
}
else
{
msg = "您无权查看此报价。";
}
}
else
{
msg = "报价不存在。";
}
}
resultData.Add("msg", msg);
}
///
/// 创建交易报价
///
///
///
private void MakeOffer(Dictionary requestData, Dictionary resultData)
{
string msg = "无法创建报价,请稍后再试。";
if (SQLHelper != null && requestData.Count >= 1)
{
long offeree = DataRequest.GetDictionaryJsonObject(requestData, "offeree");
long offeror = Server.User.Id;
if (offeror != 0 && offeree != 0 && offeror != offeree)
{
SQLHelper.AddOffer(offeror, offeree);
if (SQLHelper.Success)
{
long offerId = SQLHelper.LastInsertId;
Offer? offer = SQLHelper.GetOffer(offerId);
if (offer != null)
{
resultData.Add("offer", offer);
msg = "";
}
}
}
else
{
msg = "无效的用户ID。";
}
}
resultData.Add("msg", msg);
}
///
/// 修改交易报价
///
///
///
private void ReviseOffer(Dictionary requestData, Dictionary resultData)
{
string msg = "无法修改报价,请稍后再试。";
if (SQLHelper != null && requestData.Count >= 3)
{
long offerId = DataRequest.GetDictionaryJsonObject(requestData, "id");
OfferActionType action = DataRequest.GetDictionaryJsonObject(requestData, "action");
List offerorItems = DataRequest.GetDictionaryJsonObject>(requestData, "offerorItems") ?? [];
List offereeItems = DataRequest.GetDictionaryJsonObject>(requestData, "offereeItems") ?? [];
long userId = Server.User.Id;
Offer? offer = SQLHelper.GetOffer(offerId);
if (offer != null && (offer.Offeror == userId || offer.Offeree == userId))
{
try
{
SQLHelper.NewTransaction();
bool isOfferor = offer.Offeror == userId;
bool canProceed = false;
// 根据 action 处理状态
switch (action)
{
case OfferActionType.OfferorRevise:
if (isOfferor && (offer.Status == OfferState.Created || offer.Status == OfferState.Negotiating))
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.PendingOfferorConfirmation);
canProceed = true;
}
else msg = "当前状态不允许发起方修改。";
break;
case OfferActionType.OfferorConfirm:
if (isOfferor && offer.Status == OfferState.PendingOfferorConfirmation)
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.OfferorConfirmed);
canProceed = true;
}
else msg = "当前状态不允许发起方确认。";
break;
case OfferActionType.OfferorSend:
if (isOfferor && offer.Status == OfferState.OfferorConfirmed)
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.Sent);
canProceed = true;
}
else msg = "当前状态不允许发起方发送。";
break;
case OfferActionType.OfferorCancel:
if (isOfferor && offer.Status != OfferState.Completed && offer.Status != OfferState.Rejected && offer.Status != OfferState.Cancelled && offer.Status != OfferState.Expired)
{
SQLHelper.DeleteOfferItemsBackupByOfferId(offerId);
SQLHelper.UpdateOfferStatus(offerId, OfferState.Cancelled);
canProceed = true;
}
else msg = "当前状态不允许发起方取消。";
break;
case OfferActionType.OfferorAccept:
if (isOfferor && offer.Status == OfferState.Negotiating)
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.NegotiationAccepted);
canProceed = true;
}
else msg = "当前状态不允许发起方同意。";
break;
case OfferActionType.OffereeRevise:
// 接收方修改报价
if (!isOfferor && offer.NegotiatedTimes >= 3)
{
msg = "当前协商次数已达上限(3次),不允许接收方修改。";
}
else if (!isOfferor && (offer.Status == OfferState.Sent || offer.Status == OfferState.NegotiationAccepted))
{
// 备份
SQLHelper.BackupOfferItem(offer);
SQLHelper.UpdateOfferStatus(offerId, OfferState.PendingOffereeConfirmation);
canProceed = true;
}
else msg = "当前状态不允许接收方修改。";
break;
case OfferActionType.OffereeConfirm:
if (!isOfferor && offer.Status == OfferState.PendingOffereeConfirmation)
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.OffereeConfirmed);
canProceed = true;
}
else msg = "当前状态不允许接收方确认。";
break;
case OfferActionType.OffereeSend:
if (!isOfferor && (offer.Status == OfferState.OffereeConfirmed))
{
if (offer.NegotiatedTimes < 3)
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.Negotiating);
SQLHelper.UpdateOfferNegotiatedTimes(offerId, offer.NegotiatedTimes + 1);
canProceed = true;
}
else msg = "当前协商次数已达上限(3次),不允许接收方发送。";
}
else msg = "当前状态不允许接收方修改。";
break;
default:
msg = "无效的操作类型。";
break;
}
if (canProceed)
{
// 更新物品,同时对物品进行检查
User? offeree = SQLHelper.GetUserById(offer.Offeree, true);
User? offeror = SQLHelper.GetUserById(offer.Offeror, true);
if (offeree != null && offeror != null)
{
SQLHelper.DeleteOfferItemsByOfferId(offerId);
foreach (Guid itemGuid in offerorItems)
{
if (offeror.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
if (!item.IsTradable)
{
msg = $"此物品无法交易{(item.NextTradableTime != DateTime.MinValue ? $",此物品将在 {item.NextTradableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可交易" : "")}。";
break;
}
else
{
SQLHelper.AddOfferItem(offerId, offer.Offeror, item.Guid);
}
}
}
foreach (Guid itemGuid in offereeItems)
{
if (offeree.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
if (!item.IsTradable)
{
msg = $"此物品无法交易{(item.NextTradableTime != DateTime.MinValue ? $",此物品将在 {item.NextTradableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可交易" : "")}。";
break;
}
else
{
SQLHelper.AddOfferItem(offerId, offer.Offeree, item.Guid);
}
}
}
if (msg != "")
{
offer = SQLHelper.GetOffer(offerId);
if (offer != null)
{
SQLHelper.Commit();
resultData.Add("offer", offer);
msg = "";
}
}
}
}
if (msg != "")
{
SQLHelper.Rollback();
}
}
catch (Exception e)
{
SQLHelper.Rollback();
ServerHelper.Error(e);
msg = "修改报价时发生错误,请稍后再试。";
}
}
else
{
msg = "报价不存在或您无权修改。";
}
}
resultData.Add("msg", msg);
}
///
/// 回应交易报价
///
///
///
private void RespondOffer(Dictionary requestData, Dictionary resultData)
{
string msg = "无法回应报价,请稍后再试。";
if (SQLHelper != null && requestData.Count >= 2) // 只需要 offerId 和 action
{
long offerId = DataRequest.GetDictionaryJsonObject(requestData, "id");
OfferActionType action = DataRequest.GetDictionaryJsonObject(requestData, "action");
long userId = Server.User.Id;
Offer? offer = SQLHelper.GetOffer(offerId);
if (offer != null && offer.Offeree == userId)
{
bool canProceed = false;
bool isNegotiating = false;
try
{
SQLHelper.NewTransaction();
// 根据 action 处理状态
switch (action)
{
case OfferActionType.OffereeAccept:
if (offer.Status == OfferState.Sent || offer.Status == OfferState.Negotiating || offer.Status == OfferState.NegotiationAccepted)
{
if (offer.Status == OfferState.Negotiating)
{
isNegotiating = true;
}
SQLHelper.UpdateOfferStatus(offerId, OfferState.Completed);
SQLHelper.UpdateOfferFinishTime(offerId, DateTime.Now);
canProceed = true;
}
else msg = "当前状态不允许接受。";
break;
case OfferActionType.OffereeReject:
if (offer.Status == OfferState.Sent || offer.Status == OfferState.Negotiating || offer.Status == OfferState.NegotiationAccepted)
{
SQLHelper.UpdateOfferStatus(offerId, OfferState.Rejected);
SQLHelper.UpdateOfferFinishTime(offerId, DateTime.Now);
canProceed = true;
}
else msg = "当前状态不允许拒绝。";
break;
default:
msg = "无效的操作类型。";
break;
}
if (canProceed)
{
offer = SQLHelper.GetOffer(offerId, isNegotiating);
if (offer != null)
{
if (offer.Status == OfferState.Completed)
{
User? offeree = SQLHelper.GetUserById(offer.Offeree, true);
User? offeror = SQLHelper.GetUserById(offer.Offeror, true);
if (offeree != null && offeror != null)
{
foreach (Guid itemGuid in offer.OffereeItems)
{
if (offeree.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
item.EntityState = EntityState.Deleted;
Item newItem = item.Copy();
newItem.User = offeror;
newItem.IsSellable = false;
newItem.IsTradable = false;
newItem.NextSellableTime = DateTimeUtility.GetTradableTime();
newItem.NextTradableTime = DateTimeUtility.GetTradableTime();
newItem.EntityState = EntityState.Added;
offeror.Inventory.Items.Add(newItem);
}
}
foreach (Guid itemGuid in offer.OfferorItems)
{
if (offeror.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
{
item.EntityState = EntityState.Deleted;
Item newItem = item.Copy();
newItem.User = offeree;
newItem.IsSellable = false;
newItem.IsTradable = false;
newItem.NextSellableTime = DateTimeUtility.GetTradableTime();
newItem.NextTradableTime = DateTimeUtility.GetTradableTime();
newItem.EntityState = EntityState.Added;
offeree.Inventory.Items.Add(newItem);
}
}
SQLHelper.UpdateInventory(offeror.Inventory);
SQLHelper.UpdateInventory(offeree.Inventory);
SQLHelper.Commit();
resultData.Add("offer", offer);
msg = "";
}
}
}
}
if (msg != "")
{
SQLHelper.Rollback();
}
}
catch (Exception e)
{
SQLHelper.Rollback();
ServerHelper.Error(e);
msg = "回应报价时发生错误,请稍后再试。";
}
}
else
{
msg = "报价不存在或您无权回应。";
}
}
resultData.Add("msg", msg);
}
#endregion
}
}