Commit 9e5a0496 authored by hex's avatar hex

refactor tcphelper

parent eea918a9
Pipeline #38649 failed
......@@ -97,7 +97,7 @@ public class Book : WindowServant2D
{
deckString = "";
master = new MultiStringMaster();
foreach (var item in TcpHelper.deckStrings)
foreach (var item in TcpHelperAsync.DeckStrings)
{
master.Add(item);
}
......
......@@ -97,7 +97,7 @@ public class Menu : WindowServantSP
{
Program.I().quit();
Program.Running = false;
TcpHelper.SaveRecord();
GameRecordManager.SaveRecord();
#if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IPHONE) // IL2CPP 使用此方法才能退出
Application.Quit();
#else
......
using System;
using System.Collections.Concurrent;
using UnityEngine;
using YGOSharp.Network.Enums;
public class GameMessage
{
public CtosMessage MessageType { get; set; }
public object Data { get; set; }
public Action<bool> OnComplete { get; set; }
public GameMessage(CtosMessage messageType, object data = null, Action<bool> onComplete = null)
{
MessageType = messageType;
Data = data;
OnComplete = onComplete;
}
}
public static class GameMessageQueue
{
private static readonly ConcurrentQueue<GameMessage> _messageQueue = new ConcurrentQueue<GameMessage>();
public static void Enqueue(GameMessage message)
{
_messageQueue.Enqueue(message);
Debug.Log($"[GameMessageQueue] Enqueued message: {message.MessageType}");
}
public static bool TryDequeue(out GameMessage message)
{
return _messageQueue.TryDequeue(out message);
}
// 便捷方法
public static void SendResponse(byte[] response)
{
Enqueue(new GameMessage(CtosMessage.Response, response));
}
public static void SendChat(string text)
{
Enqueue(new GameMessage(CtosMessage.Chat, text));
}
public static void SendSurrender()
{
Enqueue(new GameMessage(CtosMessage.Surrender));
}
public static void SendHandResult(int result)
{
Enqueue(new GameMessage(CtosMessage.HandResult, result));
}
public static void SendTpResult(bool tp)
{
Enqueue(new GameMessage(CtosMessage.TpResult, tp));
}
public static void SendUpdateDeck(YGOSharp.Deck deck)
{
Enqueue(new GameMessage(CtosMessage.UpdateDeck, deck));
}
public static void SendLeaveGame()
{
Enqueue(new GameMessage(CtosMessage.LeaveGame));
}
public static void SendTimeConfirm()
{
Enqueue(new GameMessage(CtosMessage.TimeConfirm));
}
public static void SendHsToDuelist()
{
Enqueue(new GameMessage(CtosMessage.HsToDuelist));
}
public static void SendHsToObserver()
{
Enqueue(new GameMessage(CtosMessage.HsToObserver));
}
public static void SendHsReady()
{
Enqueue(new GameMessage(CtosMessage.HsReady));
}
public static void SendHsNotReady()
{
Enqueue(new GameMessage(CtosMessage.HsNotReady));
}
public static void SendHsKick(int position)
{
Enqueue(new GameMessage(CtosMessage.HsKick, position));
}
public static void SendHsStart()
{
Enqueue(new GameMessage(CtosMessage.HsStart));
}
public static void SendExternalAddress(string hostname)
{
Enqueue(new GameMessage(CtosMessage.ExternalAddress, hostname));
}
public static void SendPlayerInfo(string name)
{
Enqueue(new GameMessage(CtosMessage.PlayerInfo, name));
}
public static void SendJoinGame(string password, string version = null)
{
Enqueue(new GameMessage(CtosMessage.JoinGame, new { password, version }));
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using YGOSharp.OCGWrapper.Enums;
public static class GameRecordManager
{
private static readonly List<Package> _packagesInRecord = new List<Package>();
public static string LastRecordName { get; private set; } = "";
public static void AddRecordLine(Package package)
{
if (Program.I().ocgcore.condition != Ocgcore.Condition.record)
{
_packagesInRecord.Add(package);
}
}
public static void SaveRecord()
{
try
{
if (_packagesInRecord.Count > 10)
{
bool shouldWrite = false;
int startIndex = 0;
int currentIndex = 0;
foreach (var package in _packagesInRecord)
{
currentIndex++;
try
{
if (package.Fuction == (int)GameMessage.Start ||
package.Fuction == (int)GameMessage.ReloadField)
{
shouldWrite = true;
startIndex = currentIndex;
}
}
catch (Exception e)
{
Debug.LogError($"[GameRecordManager] Error processing package: {e.Message}");
}
}
if (shouldWrite)
{
if (startIndex > _packagesInRecord.Count)
{
startIndex = _packagesInRecord.Count;
}
_packagesInRecord.Insert(startIndex, Program.I().ocgcore.getNamePacket());
LastRecordName = UIHelper.getTimeString();
string replayPath = "replay/" + LastRecordName + ".yrp3d";
using (var stream = File.Create(replayPath))
using (var writer = new BinaryWriter(stream))
{
foreach (var package in _packagesInRecord)
{
writer.Write((byte)package.Fuction);
writer.Write((uint)package.Data.getLength());
writer.Write(package.Data.get());
}
stream.Flush();
}
Debug.Log($"[GameRecordManager] Record saved: {replayPath}");
}
}
_packagesInRecord.Clear();
}
catch (Exception e)
{
Debug.LogError($"[GameRecordManager] Error saving record: {e.Message}");
}
}
public static void ClearRecord()
{
_packagesInRecord.Clear();
Debug.Log("[GameRecordManager] Record cleared");
}
public static List<Package> ReadPackagesFromRecord(string path)
{
Debug.Log($"[GameRecordManager] Reading record from: {path}");
List<Package> packages = new List<Package>();
try
{
byte[] data = File.ReadAllBytes(path);
packages = ParsePackages(data);
}
catch (Exception e)
{
Debug.LogError($"[GameRecordManager] Error reading record: {e.Message}");
}
return packages;
}
public static List<Package> ParsePackages(byte[] buffer)
{
List<Package> packages = new List<Package>();
try
{
using (var reader = new BinaryReader(new MemoryStream(buffer)))
{
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
Package package = new Package();
package.Fuction = reader.ReadByte();
uint dataLength = reader.ReadUInt32();
package.Data = new BinaryMaster(reader.ReadBytes((int)dataLength));
packages.Add(package);
}
}
}
catch (Exception e)
{
Debug.LogError($"[GameRecordManager] Error parsing packages: {e.Message}");
}
return packages;
}
}
\ No newline at end of file
This diff is collapsed.
using UnityEngine;
public class TcpHelperTest : MonoBehaviour
{
void Start()
{
// 测试连接状态
Debug.Log($"[Test] Initial state: {TcpHelperAsync.CurrentState}");
Debug.Log($"[Test] Is connected: {TcpHelperAsync.IsConnected}");
// 测试消息队列
GameMessageQueue.SendChat("Test message from queue");
Debug.Log("[Test] Message queued successfully");
// 测试事件订阅
TcpHelperAsync.OnStateChanged += OnConnectionStateChanged;
TcpHelperAsync.OnConnected += OnConnected;
TcpHelperAsync.OnDisconnected += OnDisconnected;
TcpHelperAsync.OnError += OnError;
Debug.Log("[Test] Event handlers registered");
}
void Update()
{
// 在主线程处理消息
TcpHelperAsync.ProcessMessages();
}
void OnDestroy()
{
// 清理事件订阅
TcpHelperAsync.OnStateChanged -= OnConnectionStateChanged;
TcpHelperAsync.OnConnected -= OnConnected;
TcpHelperAsync.OnDisconnected -= OnDisconnected;
TcpHelperAsync.OnError -= OnError;
}
private void OnConnectionStateChanged(ConnectionState newState)
{
Debug.Log($"[Test] Connection state changed to: {newState}");
}
private void OnConnected()
{
Debug.Log("[Test] Connected successfully!");
}
private void OnDisconnected()
{
Debug.Log("[Test] Disconnected");
}
private void OnError(System.Exception error)
{
Debug.LogError($"[Test] Connection error: {error.Message}");
}
// 测试连接方法
[ContextMenu("Test Connection")]
public async void TestConnection()
{
bool success = await TcpHelperAsync.ConnectAsync("127.0.0.1", "TestUser", "7911", "TestRoom", "0x1340");
Debug.Log($"[Test] Connection result: {success}");
}
[ContextMenu("Test Disconnect")]
public void TestDisconnect()
{
TcpHelperAsync.Disconnect();
Debug.Log("[Test] Disconnect called");
}
}
\ No newline at end of file
......@@ -54,15 +54,12 @@ public class MyCard : WindowServantSP
void onClickExit()
{
Program.I().shiftToServant(Program.I().menu);
if (TcpHelper.tcpClient != null)
if (TcpHelperAsync.IsConnected)
{
if (isRequesting) {
terminateThread();
}
if (TcpHelper.tcpClient.Connected)
{
TcpHelper.tcpClient.Close();
}
TcpHelperAsync.Disconnect();
}
}
......@@ -95,7 +92,7 @@ public class MyCard : WindowServantSP
Program.PrintToChat(InterString.Get("匹配成功。正在进入房间。"));
this.isMatching = true;
(new Thread(() => { TcpHelper.join(matchResultObject.address, mycardHelper.username, matchResultObject.port.ToString(), matchResultObject.password, "0x" + String.Format("{0:X}", Config.ClientVersion)); })).Start();
_ = TcpHelperAsync.ConnectAsync(matchResultObject.address, mycardHelper.username, matchResultObject.port.ToString(), matchResultObject.password, "0x" + String.Format("{0:X}", Config.ClientVersion));
isRequesting = false;
} catch (Exception e) {
if (e.GetType() != typeof(ThreadAbortException)) {
......
......@@ -794,7 +794,7 @@ public class Ocgcore : ServantWithCardDescription
public void returnTo()
{
TcpHelper.SaveRecord();
GameRecordManager.SaveRecord();
if (returnServant != null)
{
Program.I().shiftToServant(returnServant);
......@@ -815,30 +815,19 @@ public class Ocgcore : ServantWithCardDescription
public void onExit()
{
if (TcpHelper.tcpClient != null)
if (TcpHelperAsync.IsConnected)
{
if (TcpHelper.tcpClient.Connected)
{
setDefaultReturnServant();
TcpHelper.tcpClient.Client.Shutdown(0);
TcpHelper.tcpClient.Close();
}
TcpHelper.tcpClient = null;
setDefaultReturnServant();
TcpHelperAsync.Disconnect();
}
returnTo();
}
public void onEmergencyExit()
{
if (TcpHelper.tcpClient != null)
if (TcpHelperAsync.IsConnected)
{
/*if (TcpHelper.tcpClient.Connected)
{
setDefaultReturnServant();
TcpHelper.tcpClient.Client.Shutdown(0);
TcpHelper.tcpClient.Close();
} */
TcpHelper.tcpClient = null;
TcpHelperAsync.Disconnect();
}
returnTo();
}
......@@ -876,7 +865,7 @@ public class Ocgcore : ServantWithCardDescription
public void addPackage(Package p)
{
TcpHelper.AddRecordLine(p);
GameRecordManager.AddRecordLine(p);
Packages.Enqueue(p);
Packages_ALL.Add(p);
}
......@@ -2908,9 +2897,9 @@ public class Ocgcore : ServantWithCardDescription
{
try
{
if (File.Exists("replay/" + TcpHelper.lastRecordName + ".yrp3d"))
if (File.Exists("replay/" + GameRecordManager.LastRecordName + ".yrp3d"))
{
if (TcpHelper.lastRecordName != winCaculator.input.value)
if (GameRecordManager.LastRecordName != winCaculator.input.value)
{
if (File.Exists("replay/" + winCaculator.input.value + ".yrp3d"))
{
......@@ -2918,7 +2907,7 @@ public class Ocgcore : ServantWithCardDescription
}
}
File.Move(
"replay/" + TcpHelper.lastRecordName + ".yrp3d",
"replay/" + GameRecordManager.LastRecordName + ".yrp3d",
"replay/" + winCaculator.input.value + ".yrp3d"
);
}
......@@ -2937,14 +2926,14 @@ public class Ocgcore : ServantWithCardDescription
{
try
{
if (File.Exists("replay/" + TcpHelper.lastRecordName + ".yrp3d"))
if (File.Exists("replay/" + GameRecordManager.LastRecordName + ".yrp3d"))
{
if (File.Exists("replay/" + "-lastReplay" + ".yrp3d"))
{
File.Delete("replay/" + "-lastReplay" + ".yrp3d");
}
File.Move(
"replay/" + TcpHelper.lastRecordName + ".yrp3d",
"replay/" + GameRecordManager.LastRecordName + ".yrp3d",
"replay/-lastReplay.yrp3d"
);
}
......@@ -7146,7 +7135,7 @@ public class Ocgcore : ServantWithCardDescription
flagForCancleChain = false;
//Package p = new Package();
//p.Fuction = (int)GameMessage.sibyl_clear;
//TcpHelper.AddRecordLine(p);
//GameRecordManager.AddRecordLine(p);
if (clearTimeFlag)
{
clearTimeFlag = false;
......@@ -7270,7 +7259,7 @@ public class Ocgcore : ServantWithCardDescription
int player = r.ReadByte();
r.ReadByte();
int time_limit = r.ReadInt16();
TcpHelper.CtosMessage_TimeConfirm();
GameMessageQueue.SendTimeConfirm();
gameInfo.setTime(unSwapPlayer(localPlayer(player)), time_limit);
if (unSwapPlayer(localPlayer(player)) == 0)
{
......@@ -9079,7 +9068,7 @@ public class Ocgcore : ServantWithCardDescription
void returnFromDeckEdit()
{
TcpHelper.CtosMessage_UpdateDeck(((DeckManager)Program.I().deckManager).getRealDeck());
GameMessageQueue.SendUpdateDeck(((DeckManager)Program.I().deckManager).getRealDeck());
}
public GameField gameField;
......@@ -9941,13 +9930,13 @@ public class Ocgcore : ServantWithCardDescription
if (result.value == "yes")
{
surrended = true;
if (TcpHelper.tcpClient != null && TcpHelper.tcpClient.Connected)
if (TcpHelperAsync.IsConnected)
{
if (paused)
{
EventDelegate.Execute(UIHelper.getByName<UIButton>(toolBar, "go_").onClick);
}
TcpHelper.CtosMessage_Surrender();
GameMessageQueue.SendSurrender();
}
else
{
......@@ -9965,8 +9954,7 @@ public class Ocgcore : ServantWithCardDescription
if (
Program.I().room.duelEnded == true
|| surrended
|| TcpHelper.tcpClient == null
|| TcpHelper.tcpClient.Connected == false
|| !TcpHelperAsync.IsConnected
)
{
surrended = false;
......@@ -9983,7 +9971,7 @@ public class Ocgcore : ServantWithCardDescription
RMSshow_none(InterString.Get("右侧为您准备了对手上一局使用的卡。"));
((DeckManager)Program.I().deckManager).shiftCondition(DeckManager.Condition.changeSide);
returnTo();
((DeckManager)Program.I().deckManager).deck = TcpHelper.deck;
((DeckManager)Program.I().deckManager).deck = TcpHelperAsync.CurrentDeck;
((DeckManager)Program.I().deckManager).FormCodedDeckToObjectDeck();
((CardDescription)Program.I().cardDescription).setTitle(
Config.Get("deckInUse", "miaowu")
......@@ -10013,8 +10001,7 @@ public class Ocgcore : ServantWithCardDescription
if (
Program.I().room.duelEnded == true
|| surrended
|| TcpHelper.tcpClient == null
|| TcpHelper.tcpClient.Connected == false
|| !TcpHelperAsync.IsConnected
|| Program.I().room.needSide == true
|| condition != Condition.duel
)
......
......@@ -1234,7 +1234,7 @@ public class Program : MonoBehaviour
{
servants[i].Update();
}
TcpHelper.preFrameFunction();
TcpHelperAsync.ProcessMessages();
delayedTask remove = null;
while (true)
{
......@@ -1321,7 +1321,7 @@ public class Program : MonoBehaviour
void OnApplicationQuit()
{
TcpHelper.SaveRecord();
GameRecordManager.SaveRecord();
SaveConfig();
for (int i = 0; i < servants.Count; i++)
{
......@@ -1330,7 +1330,7 @@ public class Program : MonoBehaviour
Running = false;
try
{
TcpHelper.tcpClient.Close();
TcpHelperAsync.Disconnect();
}
catch (System.Exception e)
{
......
......@@ -29,11 +29,11 @@ public class Room : WindowServantSP
&& realPlayers[selftype].getIfPreped()
)
{
TcpHelper.CtosMessage_HsNotReady();
TcpHelper.CtosMessage_UpdateDeck(
GameMessageQueue.SendHsNotReady();
GameMessageQueue.SendUpdateDeck(
new YGOSharp.Deck("deck/" + superScrollView.selectedString + ".ydk")
);
TcpHelper.CtosMessage_HsReady();
GameMessageQueue.SendHsReady();
}
}
......@@ -99,7 +99,7 @@ public class Room : WindowServantSP
{
if (val != "")
{
TcpHelper.CtosMessage_Chat(val);
GameMessageQueue.SendChat(val);
//AddChatMsg(val, -1);
}
}
......@@ -112,7 +112,7 @@ public class Room : WindowServantSP
void handler(byte[] buffer)
{
TcpHelper.CtosMessage_Response(buffer);
GameMessageQueue.SendResponse(buffer);
}
#region STOC
......@@ -288,7 +288,7 @@ public class Room : WindowServantSP
p.Fuction = (int)YGOSharp.OCGWrapper.Enums.GameMessage.sibyl_chat;
p.Data = new BinaryMaster();
p.Data.writer.WriteUnicode(res, res.Length + 1);
TcpHelper.AddRecordLine(p);
GameRecordManager.AddRecordLine(p);
switch ((PlayerType)player)
{
case PlayerType.Red:
......@@ -537,8 +537,8 @@ public class Room : WindowServantSP
p.Fuction = (int)YGOSharp.OCGWrapper.Enums.GameMessage.sibyl_replay;
p.Data = new BinaryMaster();
p.Data.writer.Write(data);
TcpHelper.AddRecordLine(p);
TcpHelper.SaveRecord();
GameRecordManager.AddRecordLine(p);
GameRecordManager.SaveRecord();
}
public bool duelEnded = false;
......@@ -739,26 +739,26 @@ public class Room : WindowServantSP
{
if (result[0].value == "first")
{
TcpHelper.CtosMessage_TpResult(true);
GameMessageQueue.SendTpResult(true);
}
if (result[0].value == "second")
{
TcpHelper.CtosMessage_TpResult(false);
GameMessageQueue.SendTpResult(false);
}
}
if (hashCode == "StocMessage_SelectHand")
{
if (result[0].value == "jiandao")
{
TcpHelper.CtosMessage_HandResult(1);
GameMessageQueue.SendHandResult(1);
}
if (result[0].value == "shitou")
{
TcpHelper.CtosMessage_HandResult(2);
GameMessageQueue.SendHandResult(2);
}
if (result[0].value == "bu")
{
TcpHelper.CtosMessage_HandResult(3);
GameMessageQueue.SendHandResult(3);
}
}
}
......@@ -1236,20 +1236,20 @@ public class Room : WindowServantSP
}
if (arg2)
{
TcpHelper.CtosMessage_UpdateDeck(
GameMessageQueue.SendUpdateDeck(
new YGOSharp.Deck("deck/" + Config.Get("deckInUse", "miaouwu") + ".ydk")
);
TcpHelper.CtosMessage_HsReady();
GameMessageQueue.SendHsReady();
}
else
{
TcpHelper.CtosMessage_HsNotReady();
GameMessageQueue.SendHsNotReady();
}
}
private void OnKick(int pos)
{
TcpHelper.CtosMessage_HsKick(pos);
GameMessageQueue.SendHsKick(pos);
}
private UIButton startButton()
......@@ -1289,28 +1289,28 @@ public class Room : WindowServantSP
{
if (realPlayers[selftype].getIfPreped())
{
TcpHelper.CtosMessage_HsNotReady();
GameMessageQueue.SendHsNotReady();
}
else
{
TcpHelper.CtosMessage_UpdateDeck(
GameMessageQueue.SendUpdateDeck(
new YGOSharp.Deck("deck/" + Config.Get("deckInUse", "wizard") + ".ydk")
);
TcpHelper.CtosMessage_HsReady();
GameMessageQueue.SendHsReady();
}
}
}
if (gameObjectListened.name == "duelist_")
{
TcpHelper.CtosMessage_HsToDuelist();
GameMessageQueue.SendHsToDuelist();
}
if (gameObjectListened.name == "observer_")
{
TcpHelper.CtosMessage_HsToObserver();
GameMessageQueue.SendHsToObserver();
}
if (gameObjectListened.name == "start_")
{
TcpHelper.CtosMessage_HsStart();
GameMessageQueue.SendHsStart();
}
}
......
......@@ -33,7 +33,7 @@ public class PrecyOcg
byte[] bufferR = new byte[buffer.Length + 1];
bufferR[0] = 1;
buffer.CopyTo(bufferR,1);
TcpHelper.addDateJumoLine(bufferR);
TcpHelperAsync.AddReceivedData(bufferR);
}
public void startPuzzle(System.String path)
......
......@@ -141,7 +141,7 @@ public class selectReplay : WindowServantSP
byte[] returnValue = null;
try
{
var collection = TcpHelper.readPackagesInRecord(path);
var collection = GameRecordManager.ReadPackagesFromRecord(path);
foreach (var item in collection)
{
Debug.Log(item.Fuction);
......@@ -467,7 +467,7 @@ public class selectReplay : WindowServantSP
if (precy != null)
precy.dispose();
precy = new PrecyOcg();
var collections = TcpHelper.getPackages(
var collections = GameRecordManager.ParsePackages(
precy.ygopro.getYRP3dBuffer(
getYRP(getYRPbuffer("replay/" + name + ".yrp3d"))
)
......@@ -476,7 +476,7 @@ public class selectReplay : WindowServantSP
}
else
{
var collection = TcpHelper.readPackagesInRecord("replay/" + name + ".yrp3d");
var collection = GameRecordManager.ReadPackagesFromRecord("replay/" + name + ".yrp3d");
pushCollection(collection);
}
}
......@@ -492,7 +492,7 @@ public class selectReplay : WindowServantSP
if (precy != null)
precy.dispose();
precy = new PrecyOcg();
var collections = TcpHelper.getPackages(
var collections = GameRecordManager.ParsePackages(
precy.ygopro.getYRP3dBuffer(getYRP(File.ReadAllBytes("replay/" + name)))
);
pushCollection(collections);
......
......@@ -300,12 +300,9 @@ public class SelectServer : WindowServantSP
void onClickExit()
{
Program.I().shiftToServant(Program.I().menu);
if (TcpHelper.tcpClient != null)
if (TcpHelperAsync.IsConnected)
{
if (TcpHelper.tcpClient.Connected)
{
TcpHelper.tcpClient.Close();
}
TcpHelperAsync.Disconnect();
}
}
......@@ -383,12 +380,7 @@ public class SelectServer : WindowServantSP
File.WriteAllText("config/passwords.conf", all);
printFile(false);
Program.I().mycard.isMatching = false;
(
new Thread(() =>
{
TcpHelper.join(ipString, name, portString, pswString, versionString);
})
).Start();
_ = TcpHelperAsync.ConnectAsync(ipString, name, portString, pswString, versionString);
}
else
{
......
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