457 lines
14 KiB
C#
457 lines
14 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using Newtonsoft.Json;
|
|
using SocketIOClient;
|
|
using UnityEngine;
|
|
|
|
public class CreateRoomData
|
|
{
|
|
[JsonProperty("roomId")]
|
|
public string roomId { get; set; }
|
|
}
|
|
|
|
public class JoinRoomData
|
|
{
|
|
[JsonProperty("roomId")]
|
|
public string roomId { get; set; }
|
|
[JsonProperty("opponentRating")]
|
|
public int opponentRating { get; set; }
|
|
[JsonProperty("opponentNickname")]
|
|
public string opponentNickname { get; set; }
|
|
[JsonProperty("opponentImageIndex")]
|
|
public int opponentImageIndex { get; set; }
|
|
[JsonProperty("isBlack")]
|
|
public Boolean isBlack { get; set; }
|
|
}
|
|
|
|
public class StartGameData
|
|
{
|
|
[JsonProperty("opponentId")]
|
|
public string opponentId { get; set; }
|
|
[JsonProperty("opponentRating")]
|
|
public int opponentRating { get; set; }
|
|
[JsonProperty("opponentNickname")]
|
|
public string opponentNickname { get; set; }
|
|
[JsonProperty("opponentImageIndex")]
|
|
public int opponentImageIndex { get; set; }
|
|
[JsonProperty("isBlack")]
|
|
public Boolean isBlack { get; set; }
|
|
}
|
|
|
|
|
|
public class PositionData
|
|
{
|
|
[JsonProperty("x")]
|
|
public int x { get; set; }
|
|
|
|
[JsonProperty("y")]
|
|
public int y { get; set; }
|
|
}
|
|
|
|
public class MoveData
|
|
{
|
|
[JsonProperty("position")]
|
|
public PositionData position { get; set; }
|
|
}
|
|
|
|
|
|
public class MessageData
|
|
{
|
|
[JsonProperty("message")]
|
|
public string message { get; set; }
|
|
}
|
|
|
|
public class RevengeData
|
|
{
|
|
[JsonProperty("message")]
|
|
public string message { get; set; }
|
|
[JsonProperty("isBlack")]
|
|
public Boolean isBlack { get; set; }
|
|
}
|
|
|
|
public class MultiplayManager : IDisposable
|
|
{
|
|
private SocketIOUnity _socket;
|
|
private event Action<Constants.MultiplayManagerState, object> _onMultiplayStateChanged;
|
|
public Action<MoveData> OnOpponentMove;
|
|
|
|
private string _roomId;
|
|
|
|
public MultiplayManager(Action<Constants.MultiplayManagerState, object> onMultiplayStateChanged)
|
|
{
|
|
_onMultiplayStateChanged = onMultiplayStateChanged;
|
|
try
|
|
{
|
|
var serverUrl = new Uri(Constants.GameServerURL);
|
|
|
|
_socket = new SocketIOUnity(serverUrl, new SocketIOOptions
|
|
{
|
|
Transport = SocketIOClient.Transport.TransportProtocol.WebSocket
|
|
});
|
|
|
|
_socket.On("createRoom", CreateRoom);
|
|
_socket.On("joinRoom", JoinRoom);
|
|
_socket.On("startGame", StartGame);
|
|
_socket.On("switchAI", SwitchAI);
|
|
_socket.On("exitRoom", ExitRoom);
|
|
_socket.On("endGame", EndGame);
|
|
_socket.On("doOpponent", DoOpponent);
|
|
_socket.On("doSurrender", DoSurrender);
|
|
_socket.On("surrenderConfirmed", SurrenderConfirmed);
|
|
_socket.On("receiveTimeout", ReceiveTimeout);
|
|
// 무승부 관련
|
|
_socket.On("receiveDrawRequest", ReceiveDrawRequest);
|
|
_socket.On("drawRequestSent", DrawRequestSent);
|
|
_socket.On("drawAccepted", DrawAccepted);
|
|
_socket.On("drawConfirmed", DrawConfirmed);
|
|
_socket.On("drawRejected", DrawRejected);
|
|
_socket.On("drawRejectionConfirmed", DrawRejectionConfirmed);
|
|
// 재대결 관련
|
|
_socket.On("receiveRevengeRequest", ReceiveRevengeRequest);
|
|
_socket.On("revengeRequestSent", RevengeRequestSent);
|
|
_socket.On("revengeAccepted", RevengeAccepted);
|
|
_socket.On("revengeConfirmed", RevengeConfirmed);
|
|
_socket.On("revengeRejected", RevengeRejected);
|
|
_socket.On("revengeRejectionConfirmed", RevengeRejectionConfirmed);
|
|
// 강제 종료 처리
|
|
_socket.On("opponentDisconnected", OpponentDisconnected);
|
|
|
|
_socket.Connect();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError("MultiplayManager 생성 중 오류 발생: " + e.Message);
|
|
}
|
|
}
|
|
|
|
public async void RegisterPlayer(string nickname, int rating, int imageIndex)
|
|
{
|
|
// 연결될 때까지 대기
|
|
while (!_socket.Connected)
|
|
{
|
|
await Task.Delay(100); // 0.1초 대기 후 다시 확인
|
|
}
|
|
_socket.Emit("registerPlayer", new { nickname, rating, imageIndex });
|
|
}
|
|
|
|
private void CreateRoom(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<CreateRoomData>();
|
|
_roomId = data.roomId;
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.CreateRoom, data.roomId);
|
|
}
|
|
|
|
private void JoinRoom(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<JoinRoomData>();
|
|
_roomId = data.roomId;
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.JoinRoom, data);
|
|
}
|
|
|
|
private void SwitchAI(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.SwitchAI, data.message);
|
|
}
|
|
|
|
private void StartGame(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<StartGameData>();
|
|
|
|
// 필요한 데이터 사용
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.StartGame, data);
|
|
}
|
|
|
|
|
|
// 서버로 부터 상대방의 마커 정보를 받기 위한 메서드
|
|
private void DoOpponent(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MoveData>();
|
|
if (data != null && data.position != null)
|
|
{
|
|
Vector2Int opponentPosition = new Vector2Int(data.position.x, data.position.y);
|
|
OnOpponentMove?.Invoke(new MoveData { position = data.position });
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("DoOpponent: 데이터가 올바르지 않습니다.");
|
|
}
|
|
}
|
|
|
|
|
|
// 플레이어의 마커 위치를 서버로 전달하기 위한 메서드
|
|
public void SendPlayerMove(string roomId, Vector2Int position)
|
|
{
|
|
_socket.Emit("doPlayer", new
|
|
{
|
|
roomId,
|
|
position = new { x = position.x, y = position.y }
|
|
});
|
|
}
|
|
|
|
|
|
private void ExitRoom(SocketIOResponse response)
|
|
{
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.ExitRoom, null);
|
|
}
|
|
|
|
private void EndGame(SocketIOResponse response)
|
|
{
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.EndGame, null);
|
|
}
|
|
|
|
public void LeaveRoom() // MultiplayManager에 있는 _roomId 사용, 매개변수 필요 X
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("LeaveRoom 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
|
|
_socket.Emit("leaveRoom", new { roomId = _roomId });
|
|
_roomId = null; // 방 나가면 roomId 초기화
|
|
}
|
|
|
|
public void ForceQuit()
|
|
{
|
|
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))
|
|
{
|
|
Debug.LogError("RequestSurrender 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("requestSurrender",new { roomId = _roomId });
|
|
}
|
|
|
|
private void DoSurrender(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DoSurrender, data.message);
|
|
}
|
|
|
|
private void SurrenderConfirmed(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.SurrenderConfirmed, data.message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 타임 아웃 요청
|
|
/// </summary>
|
|
public void SendTimeout()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("SendTimeout 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("sendTimeout",new { roomId = _roomId });
|
|
}
|
|
|
|
/// <summary>
|
|
/// 타임 아웃 수신
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
private void ReceiveTimeout(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.ReceiveTimeout, data.message);
|
|
}
|
|
|
|
#region 무승부
|
|
|
|
public void RequestDraw()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("requestDraw 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("requestDraw",new { roomId = _roomId });
|
|
}
|
|
|
|
private void ReceiveDrawRequest(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.ReceiveDrawRequest, data.message);
|
|
}
|
|
|
|
private void DrawRequestSent(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRequestSent, data.message);
|
|
}
|
|
|
|
public void AcceptDraw()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("acceptDraw 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("acceptDraw", new { roomId = _roomId });
|
|
}
|
|
|
|
private void DrawAccepted(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawAccepted, data.message);
|
|
}
|
|
|
|
private void DrawConfirmed(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawConfirmed, data.message);
|
|
}
|
|
|
|
public void RejectDraw()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("rejectDraw 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("rejectDraw", new { roomId = _roomId });
|
|
}
|
|
|
|
private void DrawRejected(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejected, data.message);
|
|
}
|
|
|
|
private void DrawRejectionConfirmed(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejectionConfirmed, data.message);
|
|
}
|
|
|
|
private void DerawRejectionConfirmed(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejectionConfirmed, data.message);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 재대결
|
|
|
|
public void RequestRevengeRequest()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("RequestRevengeRequest 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("requestRevenge",new { roomId = _roomId });
|
|
}
|
|
|
|
private void ReceiveRevengeRequest(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.ReceiveRevengeRequest, data.message);
|
|
}
|
|
|
|
private void RevengeRequestSent(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeRequestSent, data.message);
|
|
}
|
|
|
|
public void AcceptRevenge()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("acceptRevenge 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("acceptRevenge", new { roomId = _roomId });
|
|
}
|
|
|
|
private void RevengeAccepted(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<RevengeData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeAccepted, data);
|
|
}
|
|
|
|
private void RevengeConfirmed(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<RevengeData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeConfirmed, data);
|
|
}
|
|
|
|
public void RejectRevenge()
|
|
{
|
|
if (string.IsNullOrEmpty(_roomId))
|
|
{
|
|
Debug.LogError("rejectRevenge 호출 실패: _roomId가 설정되지 않음");
|
|
return;
|
|
}
|
|
_socket.Emit("rejectRevenge", new { roomId = _roomId });
|
|
}
|
|
|
|
private void RevengeRejected(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeRejected, data.message);
|
|
}
|
|
|
|
private void RevengeRejectionConfirmed(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeRejectionConfirmed, data.message);
|
|
}
|
|
|
|
private void OpponentDisconnected(SocketIOResponse response)
|
|
{
|
|
var data = response.GetValue<MessageData>();
|
|
|
|
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.OpponentDisconnected, data.message);
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_socket != null)
|
|
{
|
|
_socket.Disconnect();
|
|
_socket.Dispose();
|
|
_socket = null;
|
|
_roomId = null;
|
|
}
|
|
}
|
|
|
|
public string GetRoomId()
|
|
{
|
|
return _roomId;
|
|
}
|
|
}
|