2025-07-30 23:24:37 +08:00

382 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Models;
using Oshima.FunGame.OshimaServers.Model;
namespace Oshima.FunGame.OshimaServers.Service
{
public class OnlineService
{
public static SemaphoreSlim RoomSemaphoreSlim { get; } = new(1, 1);
public static SemaphoreSlim HorseRacingSettleSemaphoreSlim { get; } = new(1, 1);
public static Dictionary<string, bool> GroupsHasHorseRacing { get; } = [];
public static void GetRoomSemaphoreSlim()
{
RoomSemaphoreSlim.Wait(FunGameConstant.SemaphoreSlimTimeout);
}
public static void ReleaseRoomSemaphoreSlim()
{
if (RoomSemaphoreSlim.CurrentCount == 0)
{
RoomSemaphoreSlim.Release();
}
}
public static void GetHorseRacingSettleSemaphoreSlim()
{
HorseRacingSettleSemaphoreSlim.Wait(FunGameConstant.SemaphoreSlimTimeout);
}
public static void ReleaseHorseRacingSettleSemaphoreSlim()
{
if (HorseRacingSettleSemaphoreSlim.CurrentCount == 0)
{
HorseRacingSettleSemaphoreSlim.Release();
}
}
public static Room CreateRoom(User user, string roomType, string password, string groupId, out string msg)
{
try
{
GetRoomSemaphoreSlim();
long id = FunGameConstant.Rooms.Count > 0 ? FunGameConstant.Rooms.Values.Max(r => r.Id) + 1 : 1;
Room room = Factory.GetRoom(id, password: password);
msg = "";
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? room2) && room2 != null)
{
msg = $"你已经在{room2.Name} [ {room2.Roomid} ] 中了,请先离开房间后再创建房间。";
}
else
{
switch (roomType)
{
case "horseracing":
if (GroupsHasHorseRacing.TryGetValue(groupId, out bool has) && has)
{
msg = "本群已经存在一个赛马房间!空闲房间会在 6 分钟后自动解散,请先等待该房间完成比赛或自动解散。";
}
else
{
room.RoomType = RoomType.Custom;
room.Name = "赛马房间";
room.GameMap = groupId;
room.MaxUsers = 8;
}
break;
case "mix":
room.RoomType = RoomType.Mix;
room.Name = "混战房间";
room.MaxUsers = 10;
break;
case "team":
room.RoomType = RoomType.Team;
room.Name = "团队死斗房间";
room.MaxUsers = 8;
break;
case "cooperative":
room.RoomType = RoomType.Custom;
room.Name = "共斗房间";
room.MaxUsers = 4;
break;
default:
msg = "不支持的房间类型。";
break;
}
}
if (msg == "")
{
room.Roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7);
while (true)
{
if (!FunGameConstant.Rooms.ContainsKey(room.Roomid))
{
break;
}
room.Roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7);
}
msg = $"房间创建成功,房间号为:{room.Roomid}\r\n注意房间若在 6 分钟后仍处于空闲状态,将自动解散。";
room.RoomMaster = user;
room.CreateTime = DateTime.Now;
}
if (room.Roomid != "-1")
{
FunGameConstant.Rooms[room.Roomid] = room;
if (room.Name == "赛马房间")
{
GroupsHasHorseRacing[room.GameMap] = true;
}
}
return room;
}
catch (Exception e)
{
msg = $"创建房间失败,错误信息:{e.Message}";
return Factory.GetRoom();
}
finally
{
ReleaseRoomSemaphoreSlim();
}
}
public static bool IntoRoom(User user, string roomid, string password, out string msg)
{
try
{
GetRoomSemaphoreSlim();
msg = "";
if (FunGameConstant.Rooms.TryGetValue(roomid, out Room? room) && room != null)
{
if (password == room.Password)
{
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? room2) && room2 != null)
{
msg = $"你已经在{room2.Name} [ {room2.Roomid} ] 中了,请先退出房间后再加入房间。";
return false;
}
if (room.UserAndIsReady.Count >= room.MaxUsers)
{
msg = "房间人数已满,无法加入。";
return false;
}
if (room.RoomState != RoomState.Created)
{
msg = "房间状态异常,无法加入。";
return false;
}
FunGameConstant.UsersInRoom[user.Id] = room;
room.UserAndIsReady[user] = true;
user.OnlineState = OnlineState.InRoom;
msg = $"成功加入{room.Name}{room.Roomid}\r\n房间人数{room.UserAndIsReady.Count} / {room.MaxUsers}";
return true;
}
else
{
msg = "密码错误,无法加入房间。";
return false;
}
}
else
{
msg = "房间不存在,无法加入。";
return false;
}
}
catch (Exception e)
{
msg = $"加入房间失败,错误信息:{e.Message}";
return false;
}
finally
{
ReleaseRoomSemaphoreSlim();
}
}
public static bool QuitRoom(User user, out string msg)
{
try
{
GetRoomSemaphoreSlim();
msg = "";
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? room) && room != null)
{
if (room.RoomState != RoomState.Created)
{
msg = "房间状态异常,无法退出。";
return false;
}
else
{
FunGameConstant.UsersInRoom.Remove(user.Id);
msg = $"成功退出{room.Name}{room.Roomid}";
User[] users = [.. room.UserAndIsReady.Keys.Where(u => u.Id == user.Id)];
foreach (User userTemp in users)
{
room.UserAndIsReady.Remove(userTemp);
}
if (room.UserAndIsReady.Count == 0)
{
FunGameConstant.Rooms.Remove(room.Roomid);
msg += ",该房间人数为零,已解散该房间。";
if (room.Name == "赛马房间")
{
GroupsHasHorseRacing[room.GameMap] = false;
}
}
else if (room.RoomMaster.Id == user.Id)
{
User newRoomMaster = room.UserAndIsReady.Keys.First();
room.RoomMaster = newRoomMaster;
string newRoomMasterName = newRoomMaster.Username;
if (FunGameConstant.UserIdAndUsername.TryGetValue(newRoomMaster.Id, out User? temp) && temp != null)
{
newRoomMasterName = temp.Username;
}
msg += $",新房主为:{newRoomMasterName}。";
}
return true;
}
}
else
{
msg = "你当前不在任何房间中。";
return false;
}
}
catch (Exception e)
{
msg = $"退出房间失败,错误信息:{e.Message}";
return false;
}
finally
{
ReleaseRoomSemaphoreSlim();
}
}
public static void RoomsAutoDisband()
{
try
{
GetRoomSemaphoreSlim();
Room[] rooms = [.. FunGameConstant.Rooms.Values];
foreach (Room room in rooms)
{
if (room.RoomState == RoomState.Created && room.CreateTime.AddMinutes(6) < DateTime.Now)
{
foreach (User user in room.UserAndIsReady.Keys)
{
FunGameConstant.UsersInRoom.Remove(user.Id);
}
FunGameConstant.Rooms.Remove(room.Roomid);
if (room.Name == "赛马房间")
{
GroupsHasHorseRacing[room.GameMap] = false;
}
}
}
}
catch { }
finally
{
ReleaseRoomSemaphoreSlim();
}
}
public static void ReSetRoomState(string roomid)
{
try
{
GetRoomSemaphoreSlim();
if (FunGameConstant.Rooms.TryGetValue(roomid, out Room? room) && room != null)
{
room.CreateTime = DateTime.Now;
room.RoomState = RoomState.Created;
}
}
catch { }
finally
{
ReleaseRoomSemaphoreSlim();
}
}
public static async Task<(Room, List<string>)> RunGameAsync(User user)
{
Room room = General.HallInstance;
try
{
GetRoomSemaphoreSlim();
List<string> msgs = [];
if (FunGameConstant.UsersInRoom.TryGetValue(user.Id, out Room? value) && value != null)
{
room = value;
if (room.RoomMaster.Id != user.Id)
{
msgs.Add("你不是房主,无法开始游戏。");
}
else if (room.RoomState != RoomState.Created)
{
msgs.Add("房间状态异常,无法开始游戏,已自动解散该房间。");
foreach (User userTemp in room.UserAndIsReady.Keys)
{
FunGameConstant.UsersInRoom.Remove(userTemp.Id);
}
FunGameConstant.Rooms.Remove(room.Roomid);
if (room.Name == "赛马房间")
{
GroupsHasHorseRacing[room.GameMap] = false;
}
}
else if (room.UserAndIsReady.Count < 2)
{
msgs.Add("房间人数不足,无法开始游戏。");
}
else
{
room.RoomState = RoomState.Gaming;
switch (room.Name)
{
case "赛马房间":
try
{
GetHorseRacingSettleSemaphoreSlim();
Dictionary<long, int> userPoints = HorseRacing.RunHorseRacing(msgs, room);
PluginConfig pc = new("horseracing", room.GameMap);
pc.LoadConfig();
Dictionary<long, int> waitforsettle = pc.Get<Dictionary<long, int>>("points") ?? [];
foreach (long uid in waitforsettle.Keys)
{
int points = waitforsettle[uid];
if (userPoints.ContainsKey(uid))
{
userPoints[uid] += points;
}
else
{
userPoints[uid] = points;
}
}
pc.Add("points", userPoints);
pc.SaveConfig();
}
catch (Exception e2)
{
msgs.Add("Error: " + e2.Message);
}
finally
{
ReleaseHorseRacingSettleSemaphoreSlim();
}
break;
default:
msgs.Add("游戏已开始!");
await Task.Delay(5000);
msgs.Add("游戏已结束!");
break;
}
}
}
else
{
msgs.Add("你当前不在任何房间中。");
}
return (room, msgs);
}
catch (Exception e)
{
return (room, [$"游戏遇到错误,错误信息:{e.Message}"]);
}
finally
{
ReleaseRoomSemaphoreSlim();
}
}
}
}