Commit c7d0c79b authored by hex's avatar hex

refactor(mycard): harden request flow and connection resilience

parent d6536a39
using UnityEngine; using UnityEngine;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading; using System.Threading;
public class MyCard : WindowServantSP public class MyCard : WindowServantSP
{ {
public bool isMatching = false; public bool isMatching = false;
public bool isRequesting = false; public bool isRequesting = false;
//const string mycardTiramisuAddress = "tiramisu.mycard.moe";
//const string mycardTiramisuAthleticPort = "8911";
//const string mycardTiramisuEntertainPort = "7911";
private Coroutine requestCoroutine = null; private Coroutine requestCoroutine = null;
private Thread joinThread = null;
MyCardHelper mycardHelper; MyCardHelper mycardHelper;
UIInput inputUsername; UIInput inputUsername;
UIInput inputPsw; UIInput inputPsw;
...@@ -48,10 +43,19 @@ public class MyCard : WindowServantSP ...@@ -48,10 +43,19 @@ public class MyCard : WindowServantSP
public void TerminateRequest() public void TerminateRequest()
{ {
if (mycardHelper != null)
{
mycardHelper.CancelCurrentRequest();
}
if (requestCoroutine != null) if (requestCoroutine != null)
{ {
Program.I().StopCoroutine(requestCoroutine); Program.I().StopCoroutine(requestCoroutine);
requestCoroutine = null; requestCoroutine = null;
}
if (isRequesting)
{
isRequesting = false; isRequesting = false;
Program.PrintToChat(InterString.Get("匹配已中断。")); Program.PrintToChat(InterString.Get("匹配已中断。"));
} }
...@@ -80,56 +84,102 @@ public class MyCard : WindowServantSP ...@@ -80,56 +84,102 @@ public class MyCard : WindowServantSP
Application.OpenURL("https://ygobbs.com/"); Application.OpenURL("https://ygobbs.com/");
} }
IEnumerator MatchCoroutine(string username, string password, string matchType) { bool TryStartJoinThread(MatchResultObject matchResultObject)
isRequesting = true; {
Program.PrintToChat(InterString.Get("正在登录至 MyCard。")); if (matchResultObject == null)
bool loginSuccess = false; {
string failReason = ""; return false;
// 启动并等待登录协程完成
yield return Program.I().StartCoroutine(mycardHelper.Login(username, password, (success, reason) => {
loginSuccess = success;
failReason = reason;
}));
if (!loginSuccess) {
Program.PrintToChat(InterString.Get("MyCard 登录失败。原因: ") + failReason);
isRequesting = false;
yield break; // 结束协程
} }
Program.PrintToChat(InterString.Get("MyCard 登录成功,用户名: ") + mycardHelper.username);
// Program.PrintToChat(InterString.Get("正在获取匹配秘钥。")); if (joinThread != null && joinThread.IsAlive)
yield return Program.I().StartCoroutine(mycardHelper.GetUserU16Secret((success, reason) =>
{ {
loginSuccess = success; return false;
failReason = reason; }
}));
if (!loginSuccess) string address = matchResultObject.address;
string userName = mycardHelper.username;
string port = matchResultObject.port.ToString();
string roomPassword = matchResultObject.password;
string version = "0x" + string.Format("{0:X}", Config.ClientVersion);
joinThread = new Thread(() =>
{ {
Program.PrintToChat(InterString.Get("获取用户密钥失败。请重新登录。原因: ") + failReason); TcpHelper.join(address, userName, port, roomPassword, version);
isRequesting = false; });
yield break; // 结束协程 joinThread.Name = "MyCardJoinThread";
joinThread.IsBackground = true;
joinThread.Start();
return true;
}
IEnumerator MatchCoroutine(string username, string password, string matchType)
{
isRequesting = true;
try
{
Program.PrintToChat(InterString.Get("正在登录至 MyCard。"));
bool loginSuccess = false;
string failReason = "";
yield return Program.I().StartCoroutine(mycardHelper.Login(username, password, (success, reason) =>
{
loginSuccess = success;
failReason = reason;
}));
if (!loginSuccess)
{
Program.PrintToChat(InterString.Get("MyCard 登录失败。原因: ") + failReason);
yield break;
}
Program.PrintToChat(InterString.Get("MyCard 登录成功,用户名: ") + mycardHelper.username);
yield return Program.I().StartCoroutine(mycardHelper.GetUserU16Secret((success, reason) =>
{
loginSuccess = success;
failReason = reason;
}));
if (!loginSuccess)
{
Program.PrintToChat(InterString.Get("获取用户密钥失败。请重新登录。原因: ") + failReason);
yield break;
}
Program.PrintToChat(InterString.Get("正在请求匹配。匹配类型: ") + matchType);
MatchResultObject matchResultObject = null;
yield return Program.I().StartCoroutine(mycardHelper.RequestMatch(matchType, (result, reason) =>
{
matchResultObject = result;
failReason = reason;
}));
if (matchResultObject == null)
{
Program.PrintToChat(InterString.Get("匹配请求失败。原因: ") + failReason);
yield break;
}
if (!TryStartJoinThread(matchResultObject))
{
Program.PrintToChat(InterString.Get("连接任务已存在,请稍后再试。"));
yield break;
}
Program.PrintToChat(InterString.Get("匹配成功。正在进入房间。"));
isMatching = true;
} }
// Program.PrintToChat(InterString.Get("获取匹配秘钥成功。")); finally
Program.PrintToChat(InterString.Get("正在请求匹配。匹配类型: ") + matchType); {
MatchResultObject matchResultObject = null;
// 启动并等待匹配协程完成
yield return Program.I().StartCoroutine(mycardHelper.RequestMatch(matchType, (result, reason) => {
matchResultObject = result;
failReason = reason;
}));
if (matchResultObject == null) {
Program.PrintToChat(InterString.Get("匹配请求失败。原因: ") + failReason);
isRequesting = false; isRequesting = false;
yield break; requestCoroutine = null;
} }
Program.PrintToChat(InterString.Get("匹配成功。正在进入房间。"));
this.isMatching = true;
// TcpHelper.join 内部自己创建并管理线程,这里直接调用是安全的
// 只要 TcpHelper.join 本身及其后续操作不调用 Unity API
(new Thread(() => { TcpHelper.join(matchResultObject.address, mycardHelper.username, matchResultObject.port.ToString(), matchResultObject.password, "0x" + String.Format("{0:X}", Config.ClientVersion)); })).Start();
isRequesting = false;
requestCoroutine = null;
} }
void StartMatch(string matchType) void StartMatch(string matchType)
{ {
string username = inputUsername.value; string username = inputUsername.value;
...@@ -143,16 +193,20 @@ public class MyCard : WindowServantSP ...@@ -143,16 +193,20 @@ public class MyCard : WindowServantSP
{ {
TerminateRequest(); TerminateRequest();
} }
SaveUser(); SaveUser();
Program.PrintToChat(InterString.Get("已开始匹配。")); Program.PrintToChat(InterString.Get("已开始匹配。"));
// 启动协程,而不是线程 mycardHelper.ResetCancellation();
requestCoroutine = Program.I().StartCoroutine(MatchCoroutine(username, password, matchType)); requestCoroutine = Program.I().StartCoroutine(MatchCoroutine(username, password, matchType));
} }
void onClickJoinAthletic() { void onClickJoinAthletic()
{
StartMatch("athletic"); StartMatch("athletic");
} }
void onClickJoinEntertain() {
void onClickJoinEntertain()
{
StartMatch("entertain"); StartMatch("entertain");
} }
} }
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment