From 9abc67f9c68a82de4f7269c2f9737f8243b7f9c6 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 28 Mar 2025 13:21:52 +0900 Subject: [PATCH 1/4] =?UTF-8?q?DO-79=20[Feat]=20=EA=B0=95=EC=A0=9C=20?= =?UTF-8?q?=EC=A2=85=EB=A3=8C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Script/Common/Constants.cs | 3 ++- Assets/Script/Game/GameLogic.cs | 17 ++++++++++++++--- Assets/Script/Game/GameManager.cs | 6 ++++++ Assets/Script/Game/MultiplayManager.cs | 19 ++++++++++++++++++- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Assets/Script/Common/Constants.cs b/Assets/Script/Common/Constants.cs index 83d9046..eb717cc 100644 --- a/Assets/Script/Common/Constants.cs +++ b/Assets/Script/Common/Constants.cs @@ -31,6 +31,7 @@ RevengeConfirmed, // 재대결 수락 전송 확인 RevengeRejected, // 재대결 거절 수신 RevengeRejectionConfirmed, // 재대결 거절 전송 확인 - ReceiveTimeout // 상대방이 타임 아웃일 때 + ReceiveTimeout, // 상대방이 타임 아웃일 때 + OpponentDisconnected }; } \ No newline at end of file diff --git a/Assets/Script/Game/GameLogic.cs b/Assets/Script/Game/GameLogic.cs index 07b35ff..9e80963 100644 --- a/Assets/Script/Game/GameLogic.cs +++ b/Assets/Script/Game/GameLogic.cs @@ -113,12 +113,19 @@ public partial class GameLogic : IDisposable StartGameOnMainThread(); break; case Constants.MultiplayManagerState.ExitRoom: - Debug.Log("## Exit Room"); + Debug.Log("## Exit Room"); // TODO: Exit Room 처리 break; case Constants.MultiplayManagerState.EndGame: Debug.Log("## End Game"); - // TODO: End Room 처리 + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenConfirmPanel("상대방의 연결이 끊어졌습니다.", () => + { + GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Win); + EndGame(Enums.GameResult.Win); + }); + }); break; case Constants.MultiplayManagerState.DoSurrender: Debug.Log("상대방의 항복 요청 들어옴"); @@ -264,7 +271,11 @@ public partial class GameLogic : IDisposable }); }); break; - } + case Constants.MultiplayManagerState.OpponentDisconnected: + Debug.Log("상대방 강제 종료"); + // 실제로 실행되지 않음. 상대방 강제 종료 시에는 EndGame으로 처리됨 + break; + } ReplayManager.Instance.InitReplayData(UserManager.Instance.Nickname,"nicknameB"); }); diff --git a/Assets/Script/Game/GameManager.cs b/Assets/Script/Game/GameManager.cs index d8d7d77..559d58f 100644 --- a/Assets/Script/Game/GameManager.cs +++ b/Assets/Script/Game/GameManager.cs @@ -131,4 +131,10 @@ public class GameManager : Singleton if (_gameLogic == null) return; _gameLogic.RequestDrawChance = false; } + + private void OnApplicationQuit() + { + Debug.Log("앱 종료 감지: 소켓 연결 정리 중..."); + _gameLogic?.Dispose(); + } } \ No newline at end of file diff --git a/Assets/Script/Game/MultiplayManager.cs b/Assets/Script/Game/MultiplayManager.cs index 62a1a29..dec1b84 100644 --- a/Assets/Script/Game/MultiplayManager.cs +++ b/Assets/Script/Game/MultiplayManager.cs @@ -113,7 +113,9 @@ public class MultiplayManager : IDisposable _socket.On("revengeConfirmed", RevengeConfirmed); _socket.On("revengeRejected", RevengeRejected); _socket.On("revengeRejectionConfirmed", RevengeRejectionConfirmed); - + // 강제 종료 처리 + _socket.On("opponentDisconnected", OpponentDisconnected); + _socket.Connect(); } catch (Exception e) @@ -212,6 +214,7 @@ public class MultiplayManager : IDisposable return; } + Debug.Log("방 나감"); _socket.Emit("leaveRoom", new { roomId = _roomId }); _roomId = null; // 방 나가면 roomId 초기화 } @@ -337,6 +340,13 @@ public class MultiplayManager : IDisposable _onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejectionConfirmed, data.message); } + + private void DerawRejectionConfirmed(SocketIOResponse response) + { + var data = response.GetValue(); + + _onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejectionConfirmed, data.message); + } #endregion @@ -414,6 +424,13 @@ public class MultiplayManager : IDisposable _onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeRejectionConfirmed, data.message); } + private void OpponentDisconnected(SocketIOResponse response) + { + var data = response.GetValue(); + + _onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.OpponentDisconnected, data.message); + } + #endregion public void Dispose() From 0c881a2d1ac5f10a0bd688b431c2ff8653624611 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 28 Mar 2025 13:30:43 +0900 Subject: [PATCH 2/4] =?UTF-8?q?DO-79=20[Style]=20=EC=95=88=EC=93=B0?= =?UTF-8?q?=EB=8A=94=20Debug.Log=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Script/Game/MultiplayManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Assets/Script/Game/MultiplayManager.cs b/Assets/Script/Game/MultiplayManager.cs index dec1b84..1c69ac6 100644 --- a/Assets/Script/Game/MultiplayManager.cs +++ b/Assets/Script/Game/MultiplayManager.cs @@ -214,7 +214,6 @@ public class MultiplayManager : IDisposable return; } - Debug.Log("방 나감"); _socket.Emit("leaveRoom", new { roomId = _roomId }); _roomId = null; // 방 나가면 roomId 초기화 } From 3051232991aaf550bf528e0e721ea5b69e198665 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 28 Mar 2025 13:33:43 +0900 Subject: [PATCH 3/4] =?UTF-8?q?DO-79=20[Style]=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EB=81=8A=EA=B9=80=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Script/Game/GameLogic.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Script/Game/GameLogic.cs b/Assets/Script/Game/GameLogic.cs index 16efe1c..8d21ec4 100644 --- a/Assets/Script/Game/GameLogic.cs +++ b/Assets/Script/Game/GameLogic.cs @@ -120,7 +120,7 @@ public partial class GameLogic : IDisposable Debug.Log("## End Game"); ExecuteOnMainThread(() => { - GameManager.Instance.panelManager.OpenConfirmPanel("상대방의 연결이 끊어졌습니다.", () => + GameManager.Instance.panelManager.OpenConfirmPanel("연결이 끊어졌습니다.", () => { GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Win); EndGame(Enums.GameResult.Win); From e52ec962ab12355baddbcd8a063b17ccff3dbd5a Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 28 Mar 2025 15:21:50 +0900 Subject: [PATCH 4/4] =?UTF-8?q?DO-79=20[Fix]=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EA=B0=95=EC=A2=85/=EC=A2=85=EB=A3=8C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Script/Game/GameLogic.cs | 33 ++++++++++++++++--- Assets/Script/Game/GameManager.cs | 7 +++- Assets/Script/Game/GameUtility/GameRoutine.cs | 6 +++- Assets/Script/Game/MultiplayManager.cs | 12 +++++++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/Assets/Script/Game/GameLogic.cs b/Assets/Script/Game/GameLogic.cs index 8d21ec4..7b9f8f2 100644 --- a/Assets/Script/Game/GameLogic.cs +++ b/Assets/Script/Game/GameLogic.cs @@ -34,6 +34,7 @@ public partial class GameLogic : IDisposable public int SelectedRow { get; private set; } public int SelectedCol { get; private set; } public FioTimer FioTimer { get; private set; } + public bool GameInProgress { get; private set; } // 게임 진행 중인지 확인 #endregion @@ -120,10 +121,9 @@ public partial class GameLogic : IDisposable Debug.Log("## End Game"); ExecuteOnMainThread(() => { - GameManager.Instance.panelManager.OpenConfirmPanel("연결이 끊어졌습니다.", () => + GameManager.Instance.panelManager.OpenConfirmPanel("상대방이 방을 나갔습니다.", () => { - GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Win); - EndGame(Enums.GameResult.Win); + // TODO: 무승부/항복 등 버튼 동작 안하도록 처리 }); }); break; @@ -199,6 +199,7 @@ public partial class GameLogic : IDisposable break; case Constants.MultiplayManagerState.ReceiveRevengeRequest: Debug.Log("상대방의 재대결 요청이 들어옴"); + ChangeGameInProgress(true); ExecuteOnMainThread(() => { GameManager.Instance.panelManager.OpenDrawConfirmPanel("상대방의 재대결 요청을\n승낙하시겠습니까?", () => @@ -276,7 +277,14 @@ public partial class GameLogic : IDisposable break; case Constants.MultiplayManagerState.OpponentDisconnected: Debug.Log("상대방 강제 종료"); - // 실제로 실행되지 않음. 상대방 강제 종료 시에는 EndGame으로 처리됨 + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenConfirmPanel("연결이 끊어졌습니다.", () => + { + GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Win); + EndGame(Enums.GameResult.Win); + }); + }); break; } ReplayManager.Instance.InitReplayData(UserManager.Instance.Nickname,"nicknameB"); @@ -339,6 +347,9 @@ public partial class GameLogic : IDisposable // 메인스레드에서 게임 시작 private void StartGameOnMainThread() { + ChangeGameInProgress(true); + Debug.Log("GameInProgress 변경 true"); + ExecuteOnMainThread(() => { // 로딩 패널 열려있으면 닫기 @@ -551,10 +562,24 @@ public partial class GameLogic : IDisposable private void TimerUnpause() => FioTimer.StartTimer(); #endregion + + public void ChangeGameInProgress(bool inProgress) + { + if (GameInProgress == inProgress) + return; + + GameInProgress = inProgress; + } public void Dispose() { MultiPlayManager?.LeaveRoom(_roomId); MultiPlayManager?.Dispose(); } + + public void ForceQuit() + { + MultiPlayManager?.ForceQuit(_roomId); + MultiPlayManager?.Dispose(); + } } diff --git a/Assets/Script/Game/GameManager.cs b/Assets/Script/Game/GameManager.cs index 0507fbe..10bc6fc 100644 --- a/Assets/Script/Game/GameManager.cs +++ b/Assets/Script/Game/GameManager.cs @@ -156,6 +156,11 @@ public class GameManager : Singleton private void OnApplicationQuit() { Debug.Log("앱 종료 감지: 소켓 연결 정리 중..."); - _gameLogic?.Dispose(); + + if(_gameLogic.GameInProgress) + _gameLogic?.ForceQuit(); + else + _gameLogic?.Dispose(); + } } \ No newline at end of file diff --git a/Assets/Script/Game/GameUtility/GameRoutine.cs b/Assets/Script/Game/GameUtility/GameRoutine.cs index 18c131f..a6b26cb 100644 --- a/Assets/Script/Game/GameUtility/GameRoutine.cs +++ b/Assets/Script/Game/GameUtility/GameRoutine.cs @@ -1,4 +1,6 @@ -public partial class GameLogic +using UnityEngine; + +public partial class GameLogic { // 돌 카운터 증가 함수 public void CountStoneCounter() => _totalStoneCounter++; @@ -85,5 +87,7 @@ SetState(null); ReplayManager.Instance.SaveReplayDataResult(result); //TODO: 게임 종료 후 행동 구현 + ChangeGameInProgress(false); + Debug.Log("GameInProgress 변경 false"); } } \ No newline at end of file diff --git a/Assets/Script/Game/MultiplayManager.cs b/Assets/Script/Game/MultiplayManager.cs index 1c69ac6..1e8c232 100644 --- a/Assets/Script/Game/MultiplayManager.cs +++ b/Assets/Script/Game/MultiplayManager.cs @@ -218,6 +218,18 @@ public class MultiplayManager : IDisposable _roomId = null; // 방 나가면 roomId 초기화 } + public void ForceQuit(string roomId) + { + if (string.IsNullOrEmpty(_roomId)) + { + Debug.LogError("Disconnect 호출 실패: _roomId가 설정되지 않음"); + return; + } + + _socket.Emit("disconnect", new { roomId = _roomId }); + _roomId = null; // 방 나가면 roomId 초기화 + } + public void RequestSurrender() { if (string.IsNullOrEmpty(_roomId))