mirror of
https://github.com/project-redbud/FunGame-Server.git
synced 2025-04-22 03:59:36 +08:00
优雅的关闭服务器;补全了所有数据请求实现;API Token 加密方式修改;添加了服务器初始化时创建管理员账号的必要步骤
This commit is contained in:
parent
a412929a10
commit
db474673fb
@ -174,6 +174,10 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
MarketSell(data, result);
|
||||
break;
|
||||
|
||||
case DataRequestType.Inventory_MarketDelist:
|
||||
MarketDelist(data, result);
|
||||
break;
|
||||
|
||||
case DataRequestType.Inventory_UpdateMarketPrice:
|
||||
UpdateMarketPrice(data, result);
|
||||
break;
|
||||
@ -250,12 +254,12 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
Room room = General.HallInstance;
|
||||
if (requestData.Count >= 3)
|
||||
{
|
||||
RoomType type = DataRequest.GetDictionaryJsonObject<RoomType>(requestData, "roomtype");
|
||||
string gamemodule = DataRequest.GetDictionaryJsonObject<string>(requestData, "gamemoduleserver") ?? "";
|
||||
string gamemap = DataRequest.GetDictionaryJsonObject<string>(requestData, "gamemap") ?? "";
|
||||
bool isrank = DataRequest.GetDictionaryJsonObject<bool>(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))
|
||||
RoomType type = DataRequest.GetDictionaryJsonObject<RoomType>(requestData, "roomType");
|
||||
string gameModule = DataRequest.GetDictionaryJsonObject<string>(requestData, "moduleServer") ?? "";
|
||||
string gameMap = DataRequest.GetDictionaryJsonObject<string>(requestData, "map") ?? "";
|
||||
bool isRank = DataRequest.GetDictionaryJsonObject<bool>(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);
|
||||
@ -263,7 +267,7 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
}
|
||||
User user = DataRequest.GetDictionaryJsonObject<User>(requestData, "master") ?? Factory.GetUser();
|
||||
string password = DataRequest.GetDictionaryJsonObject<string>(requestData, "password") ?? "";
|
||||
int maxusers = DataRequest.GetDictionaryJsonObject<int>(requestData, "maxusers");
|
||||
int maxusers = DataRequest.GetDictionaryJsonObject<int>(requestData, "maxUsers");
|
||||
|
||||
if (user.Id != 0)
|
||||
{
|
||||
@ -279,7 +283,7 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
}
|
||||
if (roomid != "-1" && SQLHelper != null)
|
||||
{
|
||||
SQLHelper.Execute(RoomQuery.Insert_CreateRoom(SQLHelper, roomid, user.Id, type, gamemodule, gamemap, isrank, password, maxusers));
|
||||
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);
|
||||
@ -372,11 +376,11 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
bool result = true;
|
||||
if (requestData.Count >= 1)
|
||||
{
|
||||
bool iscancel = DataRequest.GetDictionaryJsonObject<bool>(requestData, "iscancel");
|
||||
bool iscancel = DataRequest.GetDictionaryJsonObject<bool>(requestData, "isCancel");
|
||||
if (!iscancel)
|
||||
{
|
||||
ServerHelper.WriteLine("[MatchRoom] Start", InvokeMessageType.DataRequest);
|
||||
RoomType type = DataRequest.GetDictionaryJsonObject<RoomType>(requestData, "roomtype");
|
||||
RoomType type = DataRequest.GetDictionaryJsonObject<RoomType>(requestData, "roomType");
|
||||
User user = DataRequest.GetDictionaryJsonObject<User>(requestData, "matcher") ?? Factory.GetUser();
|
||||
StartMatching(type, user);
|
||||
}
|
||||
@ -669,9 +673,9 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
string msg = "无法找回您的密码,请稍后再试。"; // 返回的验证信息
|
||||
if (requestData.Count >= 3)
|
||||
{
|
||||
string username = DataRequest.GetDictionaryJsonObject<string>(requestData, ForgetVerifyCodes.Column_Username) ?? "";
|
||||
string email = DataRequest.GetDictionaryJsonObject<string>(requestData, ForgetVerifyCodes.Column_Email) ?? "";
|
||||
string verifycode = DataRequest.GetDictionaryJsonObject<string>(requestData, ForgetVerifyCodes.Column_ForgetVerifyCode) ?? "";
|
||||
string username = DataRequest.GetDictionaryJsonObject<string>(requestData, "username") ?? "";
|
||||
string email = DataRequest.GetDictionaryJsonObject<string>(requestData, "email") ?? "";
|
||||
string verifycode = DataRequest.GetDictionaryJsonObject<string>(requestData, "forgetVerifyCode") ?? "";
|
||||
|
||||
// 客户端发来了验证码就进行验证,没有发就生成
|
||||
if (verifycode.Trim() != "")
|
||||
@ -1013,7 +1017,17 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void UpdateUser(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
string msg = "无法更新用户数据,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count > 0)
|
||||
{
|
||||
User user = DataRequest.GetDictionaryJsonObject<User>(requestData, "user") ?? Factory.GetUser();
|
||||
SQLHelper.UpdateUser(user);
|
||||
if (SQLHelper.Success)
|
||||
{
|
||||
msg = "";
|
||||
}
|
||||
}
|
||||
resultData.Add("msg", msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1026,8 +1040,8 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
string msg = "无法更新您的密码,请稍后再试。";
|
||||
if (requestData.Count >= 2)
|
||||
{
|
||||
string username = DataRequest.GetDictionaryJsonObject<string>(requestData, UserQuery.Column_Username) ?? "";
|
||||
string password = DataRequest.GetDictionaryJsonObject<string>(requestData, UserQuery.Column_Password) ?? "";
|
||||
string username = DataRequest.GetDictionaryJsonObject<string>(requestData, "username") ?? "";
|
||||
string password = DataRequest.GetDictionaryJsonObject<string>(requestData, "password") ?? "";
|
||||
if (username.Trim() != "" && password.Trim() != "")
|
||||
{
|
||||
FunGameSystem.UpdateUserKey(username);
|
||||
@ -1094,7 +1108,16 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void GetStore(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
List<Store> stores = [];
|
||||
|
||||
if (requestData.Count > 0)
|
||||
{
|
||||
long[] ids = DataRequest.GetDictionaryJsonObject<long[]>(requestData, "ids") ?? [];
|
||||
stores = SQLHelper?.GetStoresWithGoods(ids) ?? [];
|
||||
}
|
||||
|
||||
resultData.Add("result", stores.Count > 0);
|
||||
resultData.Add("stores", stores);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1104,7 +1127,34 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void GetMarket(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
List<MarketItem> markets = [];
|
||||
|
||||
if (requestData.Count > 0)
|
||||
{
|
||||
long[] users = DataRequest.GetDictionaryJsonObject<long[]>(requestData, "users") ?? [];
|
||||
MarketItemState state = DataRequest.GetDictionaryJsonObject<MarketItemState>(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<long[]>(requestData, "items") ?? [];
|
||||
if (items.Length > 0)
|
||||
{
|
||||
markets = [.. markets.Where(i => items.Contains(i.Id))];
|
||||
}
|
||||
}
|
||||
|
||||
resultData.Add("result", markets.Count > 0);
|
||||
resultData.Add("markets", markets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1114,7 +1164,122 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void StoreBuy(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
bool result = true;
|
||||
double totalCost = 0;
|
||||
List<string> buyResult = [];
|
||||
if (SQLHelper != null && requestData.Count > 0)
|
||||
{
|
||||
long storeid = DataRequest.GetDictionaryJsonObject<long>(requestData, "storeid");
|
||||
long userid = DataRequest.GetDictionaryJsonObject<long>(requestData, "userid");
|
||||
string currency = DataRequest.GetDictionaryJsonObject<string>(requestData, "currency") ?? "";
|
||||
Dictionary<long, int> counts = DataRequest.GetDictionaryJsonObject<Dictionary<long, int>>(requestData, "counts") ?? [];
|
||||
bool ignore = DataRequest.GetDictionaryJsonObject<bool>(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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理商店购买
|
||||
/// </summary>
|
||||
/// <param name="goods"></param>
|
||||
/// <param name="useCredits"></param>
|
||||
/// <param name="price"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <param name="user"></param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1124,7 +1289,86 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void MarketBuy(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
bool result = false;
|
||||
string msg = "无法购买此物品,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count > 0)
|
||||
{
|
||||
Guid itemGuid = DataRequest.GetDictionaryJsonObject<Guid>(requestData, "itemGuid");
|
||||
|
||||
MarketItem? marketItem = SQLHelper.GetMarketItem(itemGuid);
|
||||
if (marketItem != null)
|
||||
{
|
||||
long userid = DataRequest.GetDictionaryJsonObject<long>(requestData, "userid");
|
||||
double price = DataRequest.GetDictionaryJsonObject<double>(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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1134,7 +1378,18 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void UpdateInventory(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
string msg = "无法更新库存数据,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count > 0)
|
||||
{
|
||||
Inventory inventory = DataRequest.GetDictionaryJsonObject<Inventory>(requestData, "inventory") ?? Factory.GetInventory();
|
||||
bool fullUpdate = DataRequest.GetDictionaryJsonObject<bool>(requestData, "fullUpdate");
|
||||
SQLHelper.UpdateInventory(inventory, fullUpdate);
|
||||
if (SQLHelper.Success)
|
||||
{
|
||||
msg = "";
|
||||
}
|
||||
}
|
||||
resultData.Add("msg", msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1144,7 +1399,36 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void Use(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
bool result = false;
|
||||
string msg = "无法使用此物品,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count > 0)
|
||||
{
|
||||
Guid itemGuid = DataRequest.GetDictionaryJsonObject<Guid>(requestData, "itemGuid");
|
||||
long userid = DataRequest.GetDictionaryJsonObject<long>(requestData, "userid");
|
||||
Character[] targets = DataRequest.GetDictionaryJsonObject<Character[]>(requestData, "targets") ?? [];
|
||||
long useCount = DataRequest.GetDictionaryJsonObject<long>(requestData, "useCount");
|
||||
User? user = SQLHelper.GetUserById(userid, true);
|
||||
if (user != null && user.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
|
||||
{
|
||||
// 暂定标准实现是传这两个参数,作用目标和使用数量
|
||||
Dictionary<string, object> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1154,7 +1438,33 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void StoreSell(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
bool result = false;
|
||||
string msg = "无法出售此物品,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count > 0)
|
||||
{
|
||||
Guid itemGuid = DataRequest.GetDictionaryJsonObject<Guid>(requestData, "itemGuid");
|
||||
long userid = DataRequest.GetDictionaryJsonObject<long>(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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1164,7 +1474,58 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void MarketSell(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
string msg = "无法上架此物品,请稍后再试。";
|
||||
if (requestData.Count > 0)
|
||||
{
|
||||
Guid itemGuid = DataRequest.GetDictionaryJsonObject<Guid>(requestData, "itemGuid");
|
||||
long userid = DataRequest.GetDictionaryJsonObject<long>(requestData, "userid");
|
||||
double price = DataRequest.GetDictionaryJsonObject<double>(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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下架市场物品
|
||||
/// </summary>
|
||||
/// <param name="requestData"></param>
|
||||
/// <param name="resultData"></param>
|
||||
private void MarketDelist(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
string msg = "无法下架市场物品,请稍后再试。";
|
||||
if (requestData.Count > 0)
|
||||
{
|
||||
long userid = DataRequest.GetDictionaryJsonObject<long>(requestData, "userid");
|
||||
if (userid != 0)
|
||||
{
|
||||
SQLHelper?.DeleteMarketItemByUserId(userid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Guid itemGuid = DataRequest.GetDictionaryJsonObject<Guid>(requestData, "itemGuid");
|
||||
if (itemGuid != Guid.Empty) SQLHelper?.DeleteMarketItem(itemGuid);
|
||||
}
|
||||
if (SQLHelper?.Success ?? false)
|
||||
{
|
||||
msg = "";
|
||||
}
|
||||
}
|
||||
resultData.Add("msg", msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1174,7 +1535,18 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
/// <param name="resultData"></param>
|
||||
private void UpdateMarketPrice(Dictionary<string, object> requestData, Dictionary<string, object> resultData)
|
||||
{
|
||||
// TODO
|
||||
string msg = "无法更新市场价格,请稍后再试。";
|
||||
if (requestData.Count > 0)
|
||||
{
|
||||
Guid itemGuid = DataRequest.GetDictionaryJsonObject<Guid>(requestData, "itemGuid");
|
||||
double price = DataRequest.GetDictionaryJsonObject<double>(requestData, "price");
|
||||
SQLHelper?.UpdateMarketItemPrice(itemGuid, price);
|
||||
if (SQLHelper?.Success ?? false)
|
||||
{
|
||||
msg = "";
|
||||
}
|
||||
}
|
||||
resultData.Add("msg", msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1187,7 +1559,7 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
string msg = "无法获取报价,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count >= 1)
|
||||
{
|
||||
long offerId = DataRequest.GetDictionaryJsonObject<long>(requestData, OffersQuery.Column_Id);
|
||||
long offerId = DataRequest.GetDictionaryJsonObject<long>(requestData, "id");
|
||||
bool apiQuery = DataRequest.GetDictionaryJsonObject<bool>(requestData, "apiQuery");
|
||||
Offer? offer = SQLHelper.GetOffer(offerId);
|
||||
if (offer != null)
|
||||
@ -1222,7 +1594,7 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
string msg = "无法创建报价,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count >= 1)
|
||||
{
|
||||
long offeree = DataRequest.GetDictionaryJsonObject<long>(requestData, OffersQuery.Column_Offeree);
|
||||
long offeree = DataRequest.GetDictionaryJsonObject<long>(requestData, "offeree");
|
||||
long offeror = Server.User.Id;
|
||||
if (offeror != 0 && offeree != 0 && offeror != offeree)
|
||||
{
|
||||
@ -1256,7 +1628,7 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
string msg = "无法修改报价,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count >= 3)
|
||||
{
|
||||
long offerId = DataRequest.GetDictionaryJsonObject<long>(requestData, OffersQuery.Column_Id);
|
||||
long offerId = DataRequest.GetDictionaryJsonObject<long>(requestData, "id");
|
||||
OfferActionType action = DataRequest.GetDictionaryJsonObject<OfferActionType>(requestData, "action");
|
||||
List<Guid> offerorItems = DataRequest.GetDictionaryJsonObject<List<Guid>>(requestData, "offerorItems") ?? [];
|
||||
List<Guid> offereeItems = DataRequest.GetDictionaryJsonObject<List<Guid>>(requestData, "offereeItems") ?? [];
|
||||
@ -1367,17 +1739,45 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
|
||||
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)
|
||||
{
|
||||
SQLHelper.AddOfferItem(offerId, offer.Offeror, itemGuid);
|
||||
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)
|
||||
{
|
||||
SQLHelper.AddOfferItem(offerId, offer.Offeree, itemGuid );
|
||||
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)
|
||||
{
|
||||
@ -1386,6 +1786,8 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
msg = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msg != "")
|
||||
{
|
||||
@ -1417,7 +1819,7 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
string msg = "无法回应报价,请稍后再试。";
|
||||
if (SQLHelper != null && requestData.Count >= 2) // 只需要 offerId 和 action
|
||||
{
|
||||
long offerId = DataRequest.GetDictionaryJsonObject<long>(requestData, OffersQuery.Column_Id);
|
||||
long offerId = DataRequest.GetDictionaryJsonObject<long>(requestData, "id");
|
||||
OfferActionType action = DataRequest.GetDictionaryJsonObject<OfferActionType>(requestData, "action");
|
||||
long userId = Server.User.Id;
|
||||
|
||||
@ -1470,15 +1872,14 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
{
|
||||
if (offer.Status == OfferState.Completed)
|
||||
{
|
||||
User offeree = Server.User;
|
||||
User? offeree = SQLHelper.GetUserById(offer.Offeree, true);
|
||||
User? offeror = SQLHelper.GetUserById(offer.Offeror, true);
|
||||
if (offeror != null)
|
||||
if (offeree != null && offeror != null)
|
||||
{
|
||||
foreach (Guid itemGuid in offer.OffereeItems)
|
||||
{
|
||||
if (offeree.Inventory.Items.FirstOrDefault(i => i.Guid == itemGuid) is Item item)
|
||||
{
|
||||
offeree.Inventory.Items.Remove(item);
|
||||
item.EntityState = EntityState.Deleted;
|
||||
|
||||
Item newItem = item.Copy();
|
||||
@ -1487,15 +1888,14 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
newItem.IsTradable = false;
|
||||
newItem.NextSellableTime = DateTimeUtility.GetTradableTime();
|
||||
newItem.NextTradableTime = DateTimeUtility.GetTradableTime();
|
||||
offeror.Inventory.Items.Add(newItem);
|
||||
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)
|
||||
{
|
||||
offeror.Inventory.Items.Remove(item);
|
||||
item.EntityState = EntityState.Deleted;
|
||||
|
||||
Item newItem = item.Copy();
|
||||
@ -1504,8 +1904,8 @@ namespace Milimoe.FunGame.Server.Controller
|
||||
newItem.IsTradable = false;
|
||||
newItem.NextSellableTime = DateTimeUtility.GetTradableTime();
|
||||
newItem.NextTradableTime = DateTimeUtility.GetTradableTime();
|
||||
offeree.Inventory.Items.Add(newItem);
|
||||
newItem.EntityState = EntityState.Added;
|
||||
offeree.Inventory.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
SQLHelper.UpdateInventory(offeror.Inventory);
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Milimoe.FunGame;
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Library.Common.Network;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
using Milimoe.FunGame.Server.Controller;
|
||||
@ -23,6 +22,28 @@ Console.CancelKeyPress += (sender, e) =>
|
||||
Environment.Exit(0); // 退出程序
|
||||
};
|
||||
|
||||
FunGameSystem.CloseListener += async () =>
|
||||
{
|
||||
if (SocketListener != null)
|
||||
{
|
||||
foreach (ServerModel<ServerSocket> model in SocketListener.ClientList.Cast<ServerModel<ServerSocket>>())
|
||||
{
|
||||
await model.Kick("服务器正在关闭。");
|
||||
}
|
||||
SocketListener.Close();
|
||||
SocketListener = null;
|
||||
}
|
||||
if (WebSocketListener != null)
|
||||
{
|
||||
foreach (ServerModel<ServerWebSocket> model in WebSocketListener.ClientList.Cast<ServerModel<ServerWebSocket>>())
|
||||
{
|
||||
await model.Kick("服务器正在关闭。");
|
||||
}
|
||||
WebSocketListener.Close();
|
||||
WebSocketListener = null;
|
||||
}
|
||||
};
|
||||
|
||||
while (Running)
|
||||
{
|
||||
string order = Console.ReadLine() ?? "";
|
||||
@ -30,21 +51,23 @@ while (Running)
|
||||
if (order != "" && Running)
|
||||
{
|
||||
order = order.ToLower();
|
||||
if (FunGameSystem.OrderList.TryGetValue(order, out Action<string>? action) && action != null)
|
||||
{
|
||||
action(order);
|
||||
}
|
||||
switch (order)
|
||||
{
|
||||
case OrderDictionary.Quit:
|
||||
case OrderDictionary.Exit:
|
||||
case OrderDictionary.Close:
|
||||
Running = false;
|
||||
CloseServer();
|
||||
break;
|
||||
case OrderDictionary.Restart:
|
||||
if (SocketListener is null || WebSocketListener is null)
|
||||
{
|
||||
ServerHelper.WriteLine("重启服务器");
|
||||
StartServer();
|
||||
}
|
||||
else ServerHelper.WriteLine("服务器正在运行,拒绝重启!");
|
||||
else ServerHelper.WriteLine("服务器正在运行,请手动结束服务器进程再启动!");
|
||||
break;
|
||||
default:
|
||||
if (SocketListener != null)
|
||||
@ -60,9 +83,6 @@ while (Running)
|
||||
}
|
||||
}
|
||||
|
||||
ServerHelper.WriteLine("服务器已关闭,按任意键退出程序。");
|
||||
Console.ReadKey();
|
||||
|
||||
void StartServer()
|
||||
{
|
||||
TaskUtility.NewTask(async () =>
|
||||
@ -246,38 +266,18 @@ void StartServer()
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e.Message.Equals(new ServerErrorException().Message))
|
||||
{
|
||||
if (SocketListener != null)
|
||||
{
|
||||
SocketListener.Close();
|
||||
SocketListener = null;
|
||||
}
|
||||
if (WebSocketListener != null)
|
||||
{
|
||||
WebSocketListener.Close();
|
||||
WebSocketListener = null;
|
||||
}
|
||||
}
|
||||
ServerHelper.Error(e);
|
||||
CloseServer();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (SocketListener != null)
|
||||
{
|
||||
SocketListener.Close();
|
||||
SocketListener = null;
|
||||
}
|
||||
if (WebSocketListener != null)
|
||||
{
|
||||
WebSocketListener.Close();
|
||||
WebSocketListener = null;
|
||||
}
|
||||
CloseServer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CloseServer()
|
||||
{
|
||||
Running = false;
|
||||
FunGameSystem.CloseServer();
|
||||
}
|
||||
|
@ -1,7 +1,13 @@
|
||||
using Milimoe.FunGame.Core.Interface.Base;
|
||||
using System.Text;
|
||||
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.Server.Others;
|
||||
using Milimoe.FunGame.Server.Services;
|
||||
using ProjectRedbud.FunGame.SQLQueryExtension;
|
||||
|
||||
namespace Milimoe.FunGame.Server.Model
|
||||
{
|
||||
@ -45,9 +51,6 @@ namespace Milimoe.FunGame.Server.Model
|
||||
case OrderDictionary.ShowUsers2:
|
||||
ShowUsers(server);
|
||||
break;
|
||||
case OrderDictionary.Help:
|
||||
ShowHelp();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -109,9 +112,90 @@ namespace Milimoe.FunGame.Server.Model
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowHelp()
|
||||
public static void FirstRunRegAdmin()
|
||||
{
|
||||
ServerHelper.WriteLine("Milimoe -> 帮助");
|
||||
using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper() ?? throw new SQLServiceException();
|
||||
ServerHelper.WriteLine("首次启动需要注册管理员账号,请按提示输入信息!", InvokeMessageType.Core);
|
||||
string username, password, email;
|
||||
ServerHelper.Write("请输入管理员用户名:", InvokeMessageType.Core);
|
||||
while (true)
|
||||
{
|
||||
username = Console.ReadLine() ?? "";
|
||||
int usernameLength = NetworkUtility.GetUserNameLength(username);
|
||||
if (usernameLength < 3 || usernameLength > 12)
|
||||
{
|
||||
ServerHelper.WriteLine("账号名长度不符合要求:3~12个字符数(一个中文2个字符)", InvokeMessageType.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ServerHelper.Write("请输入管理员邮箱:", InvokeMessageType.Core);
|
||||
while (true)
|
||||
{
|
||||
email = Console.ReadLine() ?? "";
|
||||
if (!NetworkUtility.IsEmail(email))
|
||||
{
|
||||
ServerHelper.WriteLine("这不是一个邮箱地址!", InvokeMessageType.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ServerHelper.Write("请输入管理员密码:", InvokeMessageType.Core);
|
||||
while (true)
|
||||
{
|
||||
StringBuilder passwordBuilder = new();
|
||||
ConsoleKeyInfo key;
|
||||
|
||||
do
|
||||
{
|
||||
key = Console.ReadKey(true);
|
||||
|
||||
if (key.Key == ConsoleKey.Enter)
|
||||
{
|
||||
Console.WriteLine();
|
||||
break;
|
||||
}
|
||||
else if (key.Key == ConsoleKey.Backspace)
|
||||
{
|
||||
if (passwordBuilder.Length > 0)
|
||||
{
|
||||
passwordBuilder.Remove(passwordBuilder.Length - 1, 1);
|
||||
Console.Write("\b \b");
|
||||
}
|
||||
}
|
||||
else if (!char.IsControl(key.KeyChar))
|
||||
{
|
||||
passwordBuilder.Append(key.KeyChar);
|
||||
Console.Write("*");
|
||||
}
|
||||
} while (true);
|
||||
|
||||
password = passwordBuilder.ToString();
|
||||
|
||||
if (password.Length < 6 || password.Length > 15)
|
||||
{
|
||||
ServerHelper.WriteLine("密码长度不符合要求:6~15个字符数", InvokeMessageType.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
(string msg, RegInvokeType type, bool success) = DataRequestService.RegisterUser(sql, username, password, email, "localhost");
|
||||
ServerHelper.WriteLine(msg, InvokeMessageType.Core);
|
||||
if (success)
|
||||
{
|
||||
User? user = sql.GetUserByUsernameAndEmail(username, email);
|
||||
if (user != null)
|
||||
{
|
||||
user.IsAdmin = true;
|
||||
sql.UpdateUser(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ namespace Milimoe.FunGame.Server.Model
|
||||
Room Room = FunGameSystem.RoomList[roomid] ?? General.HallInstance;
|
||||
User.OnlineState = OnlineState.Online;
|
||||
// 是否是房主
|
||||
if (isMaster)
|
||||
if (isMaster && Room.Roomid != "-1")
|
||||
{
|
||||
List<User> users = [.. FunGameSystem.RoomList[roomid].UserAndIsReady.Keys];
|
||||
User? newRoomMaster = null;
|
||||
|
@ -12,9 +12,19 @@ namespace Milimoe.FunGame.Server.Services
|
||||
{
|
||||
public class DataRequestService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取插件取消请求的原因
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetPluginCancelString(DataRequestType type, GeneralEventArgs e) => $"{DataRequestSet.GetTypeString(type)} 请求已取消。{(e.EventMsg != "" ? $"原因:{e.EventMsg}" : "")}";
|
||||
|
||||
#region Register
|
||||
|
||||
public static (string Msg, RegInvokeType RegInvokeType, bool Success) Reg(object sender, string username, string password, string email, string verifyCode, string clientIP = "")
|
||||
{
|
||||
string msg = "";
|
||||
string msg;
|
||||
RegInvokeType type = RegInvokeType.None;
|
||||
bool success = false;
|
||||
string clientName = ServerHelper.MakeClientName(clientIP);
|
||||
@ -31,49 +41,77 @@ namespace Milimoe.FunGame.Server.Services
|
||||
|
||||
using SQLHelper? sqlHelper = Factory.OpenFactory.GetSQLHelper();
|
||||
using MailSender? mailSender = Factory.OpenFactory.GetMailSender();
|
||||
|
||||
if (sqlHelper != null)
|
||||
{
|
||||
// 如果没发验证码,就生成验证码
|
||||
if (verifyCode.Trim() == "")
|
||||
(msg, type, success) = ProcessRegistration(sqlHelper, mailSender, username, password, email, verifyCode, clientIP, clientName);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = "服务器无法处理您的注册,注册失败!";
|
||||
}
|
||||
|
||||
eventArgs.Success = success;
|
||||
FunGameSystem.ServerPluginLoader?.OnAfterRegEvent(sender, eventArgs);
|
||||
FunGameSystem.WebAPIPluginLoader?.OnAfterRegEvent(sender, eventArgs);
|
||||
|
||||
return (msg, type, success);
|
||||
}
|
||||
|
||||
internal static (string Msg, RegInvokeType Type, bool Success) ProcessRegistration(SQLHelper sqlHelper, MailSender? mailSender, string username, string password, string email, string verifyCode, string clientIP, string clientName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(verifyCode))
|
||||
{
|
||||
return HandleNoVerifyCode(sqlHelper, mailSender, username, email, clientName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandleWithVerifyCode(sqlHelper, username, password, email, verifyCode, clientIP, clientName);
|
||||
}
|
||||
}
|
||||
|
||||
internal static (string Msg, RegInvokeType Type, bool Success) HandleNoVerifyCode(SQLHelper sqlHelper, MailSender? mailSender, string username, string email, string clientName)
|
||||
{
|
||||
// 先检查账号是否重复
|
||||
sqlHelper.ExecuteDataSet(UserQuery.Select_IsExistUsername(sqlHelper, username));
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
ServerHelper.WriteLine(clientName + " 账号已被注册");
|
||||
msg = "此账号名已被使用!";
|
||||
type = RegInvokeType.DuplicateUserName;
|
||||
return ("此账号名已被使用!", RegInvokeType.DuplicateUserName, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// 检查邮箱是否重复
|
||||
sqlHelper.ExecuteDataSet(UserQuery.Select_IsExistEmail(sqlHelper, email));
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
ServerHelper.WriteLine(clientName + " 邮箱已被注册");
|
||||
msg = "此邮箱已被注册!";
|
||||
type = RegInvokeType.DuplicateEmail;
|
||||
return ("此邮箱已被注册!", RegInvokeType.DuplicateEmail, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// 检查验证码是否发送过
|
||||
sqlHelper.ExecuteDataSet(RegVerifyCodes.Select_HasSentRegVerifyCode(sqlHelper, username, email));
|
||||
if (sqlHelper.Result == SQLResult.Success && DateTime.TryParse(sqlHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegTime].ToString(), out DateTime RegTime) && (DateTime.Now - RegTime).TotalMinutes < 10)
|
||||
{
|
||||
string RegVerifyCode = sqlHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegVerifyCode].ToString() ?? "";
|
||||
ServerHelper.WriteLine(clientName + $" 十分钟内已向{email}发送过验证码:{RegVerifyCode}");
|
||||
type = RegInvokeType.InputVerifyCode;
|
||||
return ("", RegInvokeType.InputVerifyCode, false);
|
||||
}
|
||||
else
|
||||
|
||||
// 发送验证码
|
||||
return SendVerificationCode(sqlHelper, mailSender, username, email, clientName);
|
||||
}
|
||||
|
||||
internal static (string Msg, RegInvokeType Type, bool Success) SendVerificationCode(SQLHelper sqlHelper, MailSender? mailSender, string username, string email, string clientName)
|
||||
{
|
||||
// 发送验证码,需要先删除之前过期的验证码
|
||||
sqlHelper.NewTransaction();
|
||||
sqlHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(sqlHelper, username, email));
|
||||
string regVerify = Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 6);
|
||||
sqlHelper.Execute(RegVerifyCodes.Insert_RegVerifyCode(sqlHelper, username, email, regVerify));
|
||||
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
sqlHelper.Commit();
|
||||
|
||||
if (mailSender != null)
|
||||
{
|
||||
// 发送验证码
|
||||
@ -95,14 +133,16 @@ namespace Milimoe.FunGame.Server.Services
|
||||
{
|
||||
ServerHelper.WriteLine(clientName + $" 验证码为:{regVerify},请服务器管理员告知此用户");
|
||||
}
|
||||
type = RegInvokeType.InputVerifyCode;
|
||||
}
|
||||
else sqlHelper.Rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ("", RegInvokeType.InputVerifyCode, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlHelper.Rollback();
|
||||
return ("发送验证码失败!", RegInvokeType.None, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static (string Msg, RegInvokeType Type, bool Success) HandleWithVerifyCode(SQLHelper sqlHelper, string username, string password, string email, string verifyCode, string clientIP, string clientName)
|
||||
{
|
||||
// 先检查验证码
|
||||
sqlHelper.ExecuteDataSet(RegVerifyCodes.Select_RegVerifyCode(sqlHelper, username, email, verifyCode));
|
||||
@ -112,57 +152,58 @@ namespace Milimoe.FunGame.Server.Services
|
||||
{
|
||||
RegTime = General.DefaultTime;
|
||||
}
|
||||
|
||||
// 检查验证码是否过期
|
||||
if ((DateTime.Now - RegTime).TotalMinutes >= 10)
|
||||
{
|
||||
ServerHelper.WriteLine(clientName + " 验证码已过期");
|
||||
msg = "此验证码已过期,请重新注册。";
|
||||
sqlHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(sqlHelper, username, email));
|
||||
type = RegInvokeType.None;
|
||||
return ("此验证码已过期,请重新注册。", RegInvokeType.None, false);
|
||||
}
|
||||
|
||||
// 注册
|
||||
return RegisterUser(sqlHelper, username, password, email, clientIP);
|
||||
}
|
||||
else if (sqlHelper.Result == SQLResult.NotFound)
|
||||
{
|
||||
return ("验证码不正确,请重新输入!", RegInvokeType.None, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 注册
|
||||
if (verifyCode.Equals(sqlHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegVerifyCode]))
|
||||
return ("服务器无法处理您的注册,注册失败!", RegInvokeType.None, false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static (string Msg, RegInvokeType Type, bool Success) RegisterUser(SQLHelper sqlHelper, string username, string password, string email, string clientIP)
|
||||
{
|
||||
sqlHelper.NewTransaction();
|
||||
ServerHelper.WriteLine("[Reg] Username: " + username + " Email: " + email);
|
||||
FunGameSystem.UpdateUserKey(username);
|
||||
password = password.Encrypt(FunGameSystem.GetUserKey(username));
|
||||
sqlHelper.RegisterUser(username, password, email, clientIP);
|
||||
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
success = true;
|
||||
msg = "注册成功!请牢记您的账号与密码!";
|
||||
sqlHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(sqlHelper, username, email));
|
||||
sqlHelper.Commit();
|
||||
return ("注册成功!请牢记您的账号与密码!", RegInvokeType.None, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlHelper.Rollback();
|
||||
msg = "服务器无法处理您的注册,注册失败!";
|
||||
}
|
||||
}
|
||||
else msg = "验证码不正确,请重新输入!";
|
||||
}
|
||||
}
|
||||
else if (sqlHelper.Result == SQLResult.NotFound) msg = "验证码不正确,请重新输入!";
|
||||
else msg = "服务器无法处理您的注册,注册失败!";
|
||||
return ("服务器无法处理您的注册,注册失败!", RegInvokeType.None, false);
|
||||
}
|
||||
}
|
||||
|
||||
eventArgs.Success = success;
|
||||
FunGameSystem.ServerPluginLoader?.OnAfterRegEvent(sender, eventArgs);
|
||||
FunGameSystem.WebAPIPluginLoader?.OnAfterRegEvent(sender, eventArgs);
|
||||
#endregion
|
||||
|
||||
return (msg, type, success);
|
||||
}
|
||||
#region Login
|
||||
|
||||
public static (bool Success, DataSet DataSet, string Msg, Guid Key) PreLogin(object sender, string username, string password, string autokey = "")
|
||||
{
|
||||
bool success = false;
|
||||
DataSet dsUser = new();
|
||||
string msg = "用户名或密码不正确。";
|
||||
string msg;
|
||||
Guid key = Guid.Empty;
|
||||
|
||||
LoginEventArgs eventArgs = new(username, password, autokey);
|
||||
@ -175,38 +216,7 @@ namespace Milimoe.FunGame.Server.Services
|
||||
return (success, dsUser, eventArgs.EventMsg, key);
|
||||
}
|
||||
|
||||
// 验证登录
|
||||
if (username != "" && password != "")
|
||||
{
|
||||
password = password.Encrypt(FunGameSystem.GetUserKey(username));
|
||||
ServerHelper.WriteLine("[" + DataRequestSet.GetTypeString(DataRequestType.Login_Login) + "] Username: " + username);
|
||||
using SQLHelper? sqlHelper = Factory.OpenFactory.GetSQLHelper();
|
||||
if (sqlHelper != null)
|
||||
{
|
||||
sqlHelper.ExecuteDataSet(UserQuery.Select_Users_LoginQuery(sqlHelper, username, password));
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
dsUser = sqlHelper.DataSet;
|
||||
key = Guid.NewGuid();
|
||||
success = true;
|
||||
msg = "";
|
||||
if (autokey.Trim() != "")
|
||||
{
|
||||
sqlHelper.ExecuteDataSet(UserQuery.Select_CheckAutoKey(sqlHelper, username, autokey));
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
ServerHelper.WriteLine("[" + DataRequestSet.GetTypeString(DataRequestType.Login_Login) + "] AutoKey: 已确认");
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
msg = "AutoKey 不正确,拒绝自动登录!";
|
||||
ServerHelper.WriteLine("[" + DataRequestSet.GetTypeString(DataRequestType.Login_Login) + "] " + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(success, dsUser, msg, key) = ProcessLogin(username, password, autokey);
|
||||
|
||||
eventArgs.Success = success;
|
||||
FunGameSystem.ServerPluginLoader?.OnAfterLoginEvent(sender, eventArgs);
|
||||
@ -216,6 +226,71 @@ namespace Milimoe.FunGame.Server.Services
|
||||
return (success, dsUser, msg, key);
|
||||
}
|
||||
|
||||
private static string GetPluginCancelString(DataRequestType type, GeneralEventArgs e) => $"{DataRequestSet.GetTypeString(type)} 请求已取消。{(e.EventMsg != "" ? $"原因:{e.EventMsg}" : "")}";
|
||||
internal static (bool Success, DataSet DataSet, string Msg, Guid Key) ProcessLogin(string username, string password, string autokey)
|
||||
{
|
||||
bool success = false;
|
||||
DataSet dsUser = new();
|
||||
string msg = "用户名或密码不正确。";
|
||||
Guid key = Guid.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
|
||||
{
|
||||
password = password.Encrypt(FunGameSystem.GetUserKey(username));
|
||||
ServerHelper.WriteLine("[" + DataRequestSet.GetTypeString(DataRequestType.Login_Login) + "] Username: " + username);
|
||||
|
||||
using SQLHelper? sqlHelper = Factory.OpenFactory.GetSQLHelper();
|
||||
if (sqlHelper != null)
|
||||
{
|
||||
(success, dsUser, msg, key) = ValidateLogin(sqlHelper, username, password, autokey);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = "无法连接到数据库,登录失败!";
|
||||
}
|
||||
}
|
||||
|
||||
return (success, dsUser, msg, key);
|
||||
}
|
||||
|
||||
internal static (bool Success, DataSet DataSet, string Msg, Guid Key) ValidateLogin(SQLHelper sqlHelper, string username, string password, string autokey)
|
||||
{
|
||||
bool success = false;
|
||||
DataSet dsUser = new();
|
||||
string msg = "用户名或密码不正确。";
|
||||
Guid key = Guid.NewGuid();
|
||||
|
||||
sqlHelper.ExecuteDataSet(UserQuery.Select_Users_LoginQuery(sqlHelper, username, password));
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
dsUser = sqlHelper.DataSet;
|
||||
success = true;
|
||||
msg = "";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(autokey))
|
||||
{
|
||||
(success, msg) = CheckAutoKey(sqlHelper, username, autokey);
|
||||
}
|
||||
}
|
||||
|
||||
return (success, dsUser, msg, key);
|
||||
}
|
||||
|
||||
internal static (bool Success, string Msg) CheckAutoKey(SQLHelper sqlHelper, string username, string autokey)
|
||||
{
|
||||
sqlHelper.ExecuteDataSet(UserQuery.Select_CheckAutoKey(sqlHelper, username, autokey));
|
||||
if (sqlHelper.Result == SQLResult.Success)
|
||||
{
|
||||
ServerHelper.WriteLine("[" + DataRequestSet.GetTypeString(DataRequestType.Login_Login) + "] AutoKey: 已确认");
|
||||
return (true, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = "AutoKey 不正确,拒绝自动登录!";
|
||||
ServerHelper.WriteLine("[" + DataRequestSet.GetTypeString(DataRequestType.Login_Login) + "] " + msg);
|
||||
return (false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
using System.Collections;
|
||||
using Milimoe.FunGame.Core.Api.Transmittal;
|
||||
using Milimoe.FunGame.Core.Api.Transmittal;
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
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.Core.Model;
|
||||
using Milimoe.FunGame.Server.Model;
|
||||
using Milimoe.FunGame.Server.Others;
|
||||
using Milimoe.FunGame.Server.Services.DataUtility;
|
||||
|
||||
@ -13,10 +13,13 @@ namespace Milimoe.FunGame.Server.Services
|
||||
{
|
||||
public class FunGameSystem
|
||||
{
|
||||
public delegate Task CloseListenerHandler();
|
||||
public static event CloseListenerHandler? CloseListener;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器指令列表
|
||||
/// </summary>
|
||||
public static Hashtable OrderList { get; } = [];
|
||||
public static Dictionary<string, Action<string>> OrderList { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 在线房间列表
|
||||
@ -59,9 +62,9 @@ namespace Milimoe.FunGame.Server.Services
|
||||
public const string FunGameWebAPITokenID = "fungame_web_api";
|
||||
|
||||
/// <summary>
|
||||
/// API Secret 字段名
|
||||
/// API Secret 文件名
|
||||
/// </summary>
|
||||
public const string APISecretField = "api_secret";
|
||||
public const string APISecretFileName = ".apisecret";
|
||||
|
||||
/// <summary>
|
||||
/// 初始化数据库连接器
|
||||
@ -286,12 +289,12 @@ namespace Milimoe.FunGame.Server.Services
|
||||
/// 检查是否存在 API Secret Key
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public static bool IsAPISecretKeyExist(string key)
|
||||
public static bool APISecretKeyExists(string key)
|
||||
{
|
||||
using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper();
|
||||
if (sql != null)
|
||||
{
|
||||
key = Encryption.HmacSha256(key, LocalConfig.Get<string>(APISecretField) ?? "");
|
||||
key = Encryption.HmacSha256(key, Encryption.FileSha256(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, APISecretFileName)));
|
||||
sql.ExecuteDataSet(ApiTokens.Select_GetAPISecretKey(sql, key));
|
||||
if (sql.Result == SQLResult.Success)
|
||||
{
|
||||
@ -302,18 +305,18 @@ namespace Milimoe.FunGame.Server.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 API Secret Key
|
||||
/// 创建 API Secret Key
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="reference1"></param>
|
||||
/// <param name="reference2"></param>
|
||||
public static string SetAPISecretKey(string token, string reference1 = "", string reference2 = "", SQLHelper? sqlHelper = null)
|
||||
public static string CreateAPISecretKey(string token, string reference1 = "", string reference2 = "", SQLHelper? sqlHelper = null)
|
||||
{
|
||||
bool useSQLHelper = sqlHelper != null;
|
||||
sqlHelper ??= Factory.OpenFactory.GetSQLHelper();
|
||||
string key = Encryption.GenerateRandomString();
|
||||
string enKey = Encryption.HmacSha256(key, LocalConfig.Get<string>(APISecretField) ?? "");
|
||||
if (sqlHelper != null)
|
||||
string enKey = Encryption.HmacSha256(key, Encryption.FileSha256(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, APISecretFileName)));
|
||||
if (sqlHelper != null && enKey != "")
|
||||
{
|
||||
sqlHelper.ExecuteDataSet(ApiTokens.Select_GetAPIToken(sqlHelper, token));
|
||||
if (sqlHelper.Success)
|
||||
@ -325,6 +328,10 @@ namespace Milimoe.FunGame.Server.Services
|
||||
sqlHelper.Execute(ApiTokens.Insert_APIToken(sqlHelper, token, enKey, reference1, reference2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerHelper.WriteLine($"API Secret Key '{token}' 创建失败,未连接到数据库或者找不到加密秘钥。", InvokeMessageType.Error);
|
||||
}
|
||||
if (!useSQLHelper)
|
||||
{
|
||||
sqlHelper?.Dispose();
|
||||
@ -333,7 +340,7 @@ namespace Milimoe.FunGame.Server.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 SQL 服务后需要做的事
|
||||
/// 创建 SQL 服务后需要做的事,包括数据库初始化,API 初始化,首次建立管理员账户等等
|
||||
/// </summary>
|
||||
/// <param name="sqlHelper"></param>
|
||||
public static void AfterCreateSQLService(SQLHelper sqlHelper)
|
||||
@ -351,8 +358,12 @@ namespace Milimoe.FunGame.Server.Services
|
||||
{
|
||||
mysqlHelper.ExecuteSqlFile(AppDomain.CurrentDomain.BaseDirectory + "fungame.sql");
|
||||
}
|
||||
LocalConfig.Add(APISecretField, Encryption.GenerateRandomString());
|
||||
SetAPISecretKey(FunGameWebAPITokenID, sqlHelper: sqlHelper);
|
||||
ConsoleModel.FirstRunRegAdmin();
|
||||
using StreamWriter sw = File.CreateText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, APISecretFileName));
|
||||
sw.WriteLine(Encryption.GenerateRandomString());
|
||||
sw.Flush();
|
||||
sw.Close();
|
||||
ServerHelper.WriteLine($"已生成一个默认的 API Token,Token ID: {FunGameWebAPITokenID}, Secret Key: 【{CreateAPISecretKey(FunGameWebAPITokenID, sqlHelper: sqlHelper)}】,请妥善保管方括号内的内容,仅显示一次。如遗忘需要使用管理员账号重置。");
|
||||
sqlHelper.Execute(Configs.Insert_Config(sqlHelper, "Initialization", FunGameInfo.FunGame_Version, "SQL Service Installed."));
|
||||
SQLConfig.Clear();
|
||||
SQLConfig.Add("Initialized", true);
|
||||
@ -365,6 +376,10 @@ namespace Milimoe.FunGame.Server.Services
|
||||
sqlHelper.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据库是否存在
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool DatabaseExists()
|
||||
{
|
||||
SQLConfig.LoadConfig();
|
||||
@ -401,6 +416,8 @@ namespace Milimoe.FunGame.Server.Services
|
||||
plugin.Controller.Close();
|
||||
}
|
||||
}
|
||||
// 停止所有正在运行的监听
|
||||
CloseListener?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +234,11 @@ namespace Milimoe.FunGame.Server.Services
|
||||
public static void InitOrderList()
|
||||
{
|
||||
FunGameSystem.OrderList.Clear();
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Help, "Milimoe -> 帮助");
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Quit, "关闭服务器");
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Exit, "关闭服务器");
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Close, "关闭服务器");
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Restart, "重启服务器");
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Help, s => WriteLine("Milimoe -> 帮助"));
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Quit, s => WriteLine("关闭服务器"));
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Exit, s => WriteLine("关闭服务器"));
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Close, s => WriteLine("关闭服务器"));
|
||||
FunGameSystem.OrderList.Add(OrderDictionary.Restart, s => WriteLine("重启服务器"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,6 +247,16 @@ try
|
||||
// 开始监听连接
|
||||
listener.BannedList.AddRange(Config.ServerBannedList);
|
||||
|
||||
FunGameSystem.CloseListener += async () =>
|
||||
{
|
||||
foreach (ServerModel<ServerWebSocket> model in listener.ClientList.Cast<ServerModel<ServerWebSocket>>())
|
||||
{
|
||||
await model.Kick("服务器正在关闭。");
|
||||
}
|
||||
listener.Close();
|
||||
await app.StopAsync();
|
||||
};
|
||||
|
||||
Task order = Task.Factory.StartNew(GetConsoleOrder);
|
||||
|
||||
app.Run();
|
||||
@ -265,8 +275,20 @@ async Task GetConsoleOrder()
|
||||
if (order != "")
|
||||
{
|
||||
order = order.ToLower();
|
||||
if (FunGameSystem.OrderList.TryGetValue(order, out Action<string>? action) && action != null)
|
||||
{
|
||||
action(order);
|
||||
}
|
||||
switch (order)
|
||||
{
|
||||
case OrderDictionary.Quit:
|
||||
case OrderDictionary.Exit:
|
||||
case OrderDictionary.Close:
|
||||
CloseServer();
|
||||
break;
|
||||
case OrderDictionary.Restart:
|
||||
ServerHelper.WriteLine("服务器正在运行,请手动结束服务器进程再启动!");
|
||||
break;
|
||||
default:
|
||||
await ConsoleModel.Order(listener, order);
|
||||
break;
|
||||
|
@ -25,7 +25,7 @@ namespace Milimoe.FunGame.WebAPI.Services
|
||||
string key = authorizationHeader["Bearer ".Length..].Trim();
|
||||
|
||||
// 验证 API Bearer Token
|
||||
if (key == "" || !FunGameSystem.IsAPISecretKeyExist(key))
|
||||
if (key == "" || !FunGameSystem.APISecretKeyExists(key))
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return AuthenticateResult.Fail("Invalid Token.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user