匹配房间功能 (#19)

* 匹配房间 第一部分

* 修复开始匹配后按钮可用状态异常问题

* 优化匹配结果弹窗

* 优化匹配结束的UI变化

* 匹配成功后进入房间

* 需要再次检查匹配状态

---------

Co-authored-by: yeziuku <yezi@wrss.org>
This commit is contained in:
milimoe 2023-10-25 00:12:08 +08:00 committed by GitHub
parent 83276adba7
commit 0882e526e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 187 additions and 120 deletions

1
.gitignore vendored
View File

@ -363,5 +363,6 @@ MigrationBackup/
FodyWeavers.xsd FodyWeavers.xsd
# FunGame Implement # FunGame Implement
/FunGame.Implement/*.cs
FunGame.Implement/Implement/*.cs FunGame.Implement/Implement/*.cs
FunGame.Implement/Implement/Implement/*.cs FunGame.Implement/Implement/Implement/*.cs

View File

@ -15,6 +15,7 @@ namespace Milimoe.FunGame.Desktop.Controller
private readonly Session Usercfg = RunTime.Session; private readonly Session Usercfg = RunTime.Session;
private readonly DataRequest ChatRequest; private readonly DataRequest ChatRequest;
private readonly DataRequest CreateRoomRequest; private readonly DataRequest CreateRoomRequest;
private readonly DataRequest MatchRoomRequest;
private readonly DataRequest GetRoomPlayerCountRequest; private readonly DataRequest GetRoomPlayerCountRequest;
private readonly DataRequest UpdateRoomRequest; private readonly DataRequest UpdateRoomRequest;
private readonly DataRequest IntoRoomRequest; private readonly DataRequest IntoRoomRequest;
@ -25,6 +26,7 @@ namespace Milimoe.FunGame.Desktop.Controller
Main = main; Main = main;
ChatRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_Chat); ChatRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_Chat);
CreateRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_CreateRoom); CreateRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_CreateRoom);
MatchRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_MatchRoom);
GetRoomPlayerCountRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Room_GetRoomPlayerCount); GetRoomPlayerCountRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Room_GetRoomPlayerCount);
UpdateRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_UpdateRoom); UpdateRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_UpdateRoom);
IntoRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_IntoRoom); IntoRoomRequest = RunTime.NewLongRunningDataRequest(DataRequestType.Main_IntoRoom);
@ -184,6 +186,29 @@ namespace Milimoe.FunGame.Desktop.Controller
return room; return room;
} }
public async Task<bool> MatchRoomAsync(string RoomType, bool isCancel = false)
{
bool result = false;
try
{
MatchRoomRequest.AddRequestData("roomtype", RoomType);
MatchRoomRequest.AddRequestData("matcher", Usercfg.LoginUser);
MatchRoomRequest.AddRequestData("iscancel", isCancel);
await MatchRoomRequest.SendRequestAsync();
if (MatchRoomRequest.Result == RequestResult.Success)
{
result = MatchRoomRequest.GetResult<bool>("result");
}
}
catch (Exception e)
{
Main.GetMessage(e.GetErrorInfo(), TimeType.None);
}
return result;
}
public async Task<bool> ChatAsync(string msg) public async Task<bool> ChatAsync(string msg)
{ {
try try

View File

@ -147,6 +147,16 @@ namespace Milimoe.FunGame.Desktop.Controller
Close(); Close();
} }
protected override void SocketHandler_System(SocketObject ServerMessage)
{
// 收到系统消息,直接发送弹窗
string msg = "";
ShowMessageType type = ShowMessageType.General;
if (ServerMessage.Parameters.Length > 0) msg = ServerMessage.GetParam<string>(0) ?? "";
if (ServerMessage.Parameters.Length > 1) type = ServerMessage.GetParam<ShowMessageType>(1);
Main.ShowMessage(type, msg, "系统消息", 60);
}
protected override void SocketHandler_HeartBeat(SocketObject ServerMessage) protected override void SocketHandler_HeartBeat(SocketObject ServerMessage)
{ {
// 收到心跳包时更新与服务器的连接延迟 // 收到心跳包时更新与服务器的连接延迟
@ -184,5 +194,23 @@ namespace Milimoe.FunGame.Desktop.Controller
if (ServerMessage.Length > 0) room = ServerMessage.GetParam<Room>(0) ?? General.HallInstance; if (ServerMessage.Length > 0) room = ServerMessage.GetParam<Room>(0) ?? General.HallInstance;
if (room.Roomid != "-1" && room.Roomid == Usercfg.InRoom.Roomid) Main.UpdateUI(MainInvokeType.UpdateRoomMaster, room); if (room.Roomid != "-1" && room.Roomid == Usercfg.InRoom.Roomid) Main.UpdateUI(MainInvokeType.UpdateRoomMaster, room);
} }
protected override void SocketHandler_MatchRoom(SocketObject ServerMessage)
{
// 匹配成功,询问是否加入房间
Config.FunGame_isMatching = false;
Room room = General.HallInstance;
if (ServerMessage.Length > 0) room = ServerMessage.GetParam<Room>(0) ?? General.HallInstance;
if (room.Roomid == "-1")
{
Main.ShowMessage(ShowMessageType.General, "暂时无法找到符合条件的房间。", "匹配房间");
Main.UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Success, room);
Main.UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Cancel);
}
else if (Main.ShowMessage(ShowMessageType.YesNo, "已找到符合条件的房间,是否加入?", "匹配房间", 10) == MessageResult.Yes)
{
Main.UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Success, room);
}
}
} }
} }

View File

@ -555,6 +555,8 @@ namespace Milimoe.FunGame.Desktop.UI
StopMatch.UseVisualStyleBackColor = true; StopMatch.UseVisualStyleBackColor = true;
StopMatch.Visible = false; StopMatch.Visible = false;
StopMatch.Click += StopMatch_Click; StopMatch.Click += StopMatch_Click;
StopMatch.MouseHover += StopMatch_MouseHover;
StopMatch.MouseLeave += StopMatch_MouseLeave;
// //
// Main // Main
// //

View File

@ -26,15 +26,10 @@ namespace Milimoe.FunGame.Desktop.UI
/** /**
* *
*/ */
private Task? MatchFunGame = null; // 匹配线程(即将删除)
private MainController? MainController = null; private MainController? MainController = null;
private readonly Core.Model.RoomList Rooms = RunTime.RoomList; private readonly Core.Model.RoomList Rooms = RunTime.RoomList;
private readonly Core.Model.Session Usercfg = RunTime.Session; private readonly Core.Model.Session Usercfg = RunTime.Session;
private int _MatchSeconds = 0; // 记录匹配房间的秒数
/**
*
*/
Action<int, object[]?>? StartMatch_Action = null;
public Main() public Main()
{ {
@ -239,6 +234,13 @@ namespace Milimoe.FunGame.Desktop.UI
} }
break; break;
case MainInvokeType.MatchRoom:
if (objs != null && objs.Length > 0)
{
StartMatch_Method((StartMatchState)objs[0], objs[1..]);
}
break;
default: default:
break; break;
} }
@ -409,6 +411,7 @@ namespace Milimoe.FunGame.Desktop.UI
SetRoomid(Usercfg.InRoom); SetRoomid(Usercfg.InRoom);
QuitRoom.Visible = false; QuitRoom.Visible = false;
StartMatch.Visible = true; StartMatch.Visible = true;
StopMatch.Visible = false;
RoomSetting.Visible = false; RoomSetting.Visible = false;
CreateRoom.Visible = true; CreateRoom.Visible = true;
NowRoomID.Visible = false; NowRoomID.Visible = false;
@ -422,6 +425,7 @@ namespace Milimoe.FunGame.Desktop.UI
{ {
// 显示:退出房间、房间设置、当前房间号、复制房间号 // 显示:退出房间、房间设置、当前房间号、复制房间号
// 隐藏:停止匹配、创建房间 // 隐藏:停止匹配、创建房间
StartMatch.Visible = false;
StopMatch.Visible = false; StopMatch.Visible = false;
QuitRoom.Visible = true; QuitRoom.Visible = true;
CreateRoom.Visible = false; CreateRoom.Visible = false;
@ -458,12 +462,16 @@ namespace Milimoe.FunGame.Desktop.UI
CheckTeam.Enabled = isLogon; CheckTeam.Enabled = isLogon;
CheckHasPass.Enabled = isLogon; CheckHasPass.Enabled = isLogon;
StartMatch.Enabled = isLogon; StartMatch.Enabled = isLogon;
CreateRoom.Enabled = isLogon;
RoomBox.Enabled = isLogon;
AccountSetting.Enabled = isLogon; AccountSetting.Enabled = isLogon;
Stock.Enabled = isLogon; Stock.Enabled = isLogon;
Store.Enabled = isLogon; Store.Enabled = isLogon;
RefreshRoomList.Enabled = isLogon; if (!Config.FunGame_isMatching)
{
// 匹配中时不修改部分按钮状态
RoomBox.Enabled = isLogon;
CreateRoom.Enabled = isLogon;
RefreshRoomList.Enabled = isLogon;
}
} }
/// <summary> /// <summary>
@ -539,110 +547,113 @@ namespace Milimoe.FunGame.Desktop.UI
/// </summary> /// </summary>
/// <param name="i">主要参数:触发方法的哪一个分支</param> /// <param name="i">主要参数:触发方法的哪一个分支</param>
/// <param name="objs">可传多个参数</param> /// <param name="objs">可传多个参数</param>
private void StartMatch_Method(int i, object[]? objs = null) private void StartMatch_Method(StartMatchState status, params object[] objs)
{ {
switch (i) switch (status)
{ {
case (int)StartMatchState.Matching: case StartMatchState.Matching:
// 开始匹配 // 开始匹配
Config.FunGame_isMatching = true; if (MainController != null)
int loop = 0;
string roomid = Convert.ToString(new Random().Next(1, 10000));
// 匹配中 匹配成功返回房间号
Task.Factory.StartNew(() =>
{ {
// 创建新线程,防止主界面阻塞 TaskUtility.NewTask(async () =>
Thread.Sleep(3000);
while (loop < 10000 && Config.FunGame_isMatching)
{ {
loop++; Config.FunGame_isMatching = true;
if (loop == Convert.ToInt32(roomid)) if (await MainController.MatchRoomAsync(Config.FunGame_GameMode))
{ {
// 创建委托,操作主界面 // 开始匹配
StartMatch_Action = (int i, object[]? objs) => while (Config.FunGame_isMatching)
{ {
StartMatch_Method(i, objs); if (_MatchSeconds < 60)
}; {
if (InvokeRequired) await Task.Delay(1000);
{ _MatchSeconds++;
Invoke(StartMatch_Action, (int)StartMatchState.Success, new object[] { roomid }); SetMatchSecondsText();
continue;
}
// 达到60秒时
if (Config.FunGame_isMatching && await MainController.MatchRoomAsync(Config.FunGame_GameMode, true))
{
// 取消匹配
UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Success, General.HallInstance);
UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Cancel);
break;
}
} }
else
{
StartMatch_Action((int)StartMatchState.Success, new object[] { roomid });
}
break;
} }
} else Config.FunGame_isMatching = false;
}); });
break;
case (int)StartMatchState.Success:
Config.FunGame_isMatching = false;
// 匹配成功返回房间号
roomid = "-1";
if (objs != null) roomid = (string)objs[0];
if (!roomid.Equals(-1))
{
WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 匹配成功");
WritelnGameInfo(">> 房间号: " + roomid);
SetRoomid(GetRoom(roomid));
} }
else else
{ {
WritelnGameInfo("ERROR匹配失败"); WritelnGameInfo("ERROR匹配失败");
break;
} }
// 设置按钮可见性
InRoom();
// 创建委托,操作主界面
StartMatch_Action = (i, objs) =>
{
StartMatch_Method(i, objs);
};
if (InvokeRequired)
{
Invoke(StartMatch_Action, (int)StartMatchState.Enable, new object[] { true });
}
else
{
StartMatch_Action((int)StartMatchState.Enable, new object[] { true });
}
MatchFunGame = null;
break; break;
case (int)StartMatchState.Enable: case StartMatchState.Success:
// 匹配成功返回房间号
TaskUtility.NewTask(async () =>
{
Room room = General.HallInstance;
if (objs != null) room = (Room)objs[0];
if (room.Roomid != "-1")
{
GetMessage("匹配成功 -> 房间号: " + room.Roomid);
if (MainController != null) await MainController.UpdateRoomAsync();
if (Rooms.IsExist(room.Roomid))
{
Room target = Rooms[room.Roomid];
await InvokeController_IntoRoom(target);
}
else
{
GetMessage("加入房间失败!原因:房间号不存在或已被解散。");
}
}
else
{
GetMessage("匹配失败!暂时无法找到符合条件的房间。");
}
// 更新按钮图标和文字
UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Enable, true);
StopMatch.Visible = false;
StartMatch.Visible = true;
});
break;
case StartMatchState.Enable:
// 设置匹配过程中的各种按钮是否可用 // 设置匹配过程中的各种按钮是否可用
bool isPause = false; bool isEnabel = false;
if (objs != null) isPause = (bool)objs[0]; if (objs != null) isEnabel = (bool)objs[0];
CheckMix.Enabled = isPause; CheckMix.Enabled = isEnabel;
CheckTeam.Enabled = isPause; CheckTeam.Enabled = isEnabel;
CheckHasPass.Enabled = isPause; CheckHasPass.Enabled = isEnabel;
CreateRoom.Enabled = isPause; CreateRoom.Enabled = isEnabel;
RoomBox.Enabled = isPause; RoomBox.Enabled = isEnabel;
Login.Enabled = isPause; RefreshRoomList.Enabled = isEnabel;
Logout.Enabled = isEnabel;
break; break;
case (int)StartMatchState.Cancel: case StartMatchState.Cancel:
Config.FunGame_isMatching = false;
WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 终止匹配"); WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 终止匹配");
WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 已终止匹配。"); WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 已终止匹配。");
Config.FunGame_isMatching = false; UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Enable, true);
StartMatch_Action = (i, objs) =>
{
StartMatch_Method(i, objs);
};
if (InvokeRequired)
{
Invoke(StartMatch_Action, (int)StartMatchState.Enable, new object[] { true });
}
else
{
StartMatch_Action((int)StartMatchState.Enable, new object[] { true });
}
MatchFunGame = null;
StopMatch.Visible = false; StopMatch.Visible = false;
StartMatch.Visible = true; StartMatch.Visible = true;
break; break;
} }
} }
/// <summary>
/// 更新当前匹配时间
/// </summary>
private void SetMatchSecondsText()
{
if (_MatchSeconds <= 0) StopMatch.Text = "停止匹配";
if (_MatchSeconds < 60)
{
StopMatch.Text = _MatchSeconds + " 秒";
}
else StopMatch.Text = "1 分 " + (_MatchSeconds - 60) + " 秒";
}
/// <summary> /// <summary>
/// 登录账号,显示登出按钮 /// 登录账号,显示登出按钮
/// </summary> /// </summary>
@ -685,18 +696,13 @@ namespace Milimoe.FunGame.Desktop.UI
/// </summary> /// </summary>
private void StopMatch_Click() private void StopMatch_Click()
{ {
StartMatch_Action = (i, objs) => TaskUtility.NewTask(async () =>
{ {
StartMatch_Method(i, objs); if (MainController != null && await MainController.MatchRoomAsync(Config.FunGame_GameMode, true))
}; {
if (InvokeRequired) UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Cancel);
{ }
Invoke(StartMatch_Action, (int)StartMatchState.Cancel, new object[] { true }); });
}
else
{
StartMatch_Action((int)StartMatchState.Cancel, new object[] { true });
}
} }
/// <summary> /// <summary>
@ -881,6 +887,25 @@ namespace Milimoe.FunGame.Desktop.UI
}); });
} }
/// <summary>
/// 鼠标离开停止匹配按钮时,恢复按钮文本为匹配时长
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void StopMatch_MouseLeave(object? sender, EventArgs e) => SetMatchSecondsText();
/// <summary>
/// 鼠标轻触停止匹配按钮时,将文本从匹配时长转为停止匹配
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void StopMatch_MouseHover(object? sender, EventArgs e)
{
StopMatch.Text = "停止匹配";
}
#endregion #endregion
#region #region
@ -903,6 +928,8 @@ namespace Milimoe.FunGame.Desktop.UI
private void StartMatch_Click(object sender, EventArgs e) private void StartMatch_Click(object sender, EventArgs e)
{ {
// 开始匹配 // 开始匹配
_MatchSeconds = 0;
SetMatchSecondsText();
WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 开始匹配"); WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 开始匹配");
WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 开始匹配"); WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 开始匹配");
WriteGameInfo(">> 匹配参数:"); WriteGameInfo(">> 匹配参数:");
@ -911,25 +938,9 @@ namespace Milimoe.FunGame.Desktop.UI
StartMatch.Visible = false; StartMatch.Visible = false;
StopMatch.Visible = true; StopMatch.Visible = true;
// 暂停其他按钮 // 暂停其他按钮
StartMatch_Method((int)StartMatchState.Enable, new object[] { false }); UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Enable, false);
// 创建委托,开始匹配 // 开始匹配
StartMatch_Action = (i, objs) => UpdateUI(MainInvokeType.MatchRoom, StartMatchState.Matching);
{
StartMatch_Method(i, objs);
};
// 创建新线程匹配
MatchFunGame = Task.Factory.StartNew(() =>
{
if (InvokeRequired)
{
Invoke(StartMatch_Action, (int)StartMatchState.Matching, null);
}
else
{
StartMatch_Action((int)StartMatchState.Matching, null);
}
});
} }
/// <summary> /// <summary>
@ -1407,7 +1418,7 @@ namespace Milimoe.FunGame.Desktop.UI
} }
break; break;
case Constant.FunGame_Disconnect: case Constant.FunGame_Disconnect:
if (Config.FunGame_isConnected && MainController != null) if (Config.FunGame_isConnected && !Config.FunGame_isMatching && MainController != null)
{ {
// 先退出登录再断开连接 // 先退出登录再断开连接
bool SuccessLogOut = false; bool SuccessLogOut = false;