297 lines
8.2 KiB
C#
297 lines
8.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Oculus.Platform.Models;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Oculus.Platform.Samples.VrBoardGame
|
|
{
|
|
public class MatchmakingManager : MonoBehaviour
|
|
{
|
|
private enum MatchRoomState
|
|
{
|
|
None = 0,
|
|
Queued = 1,
|
|
Configuring = 2,
|
|
MyTurn = 3,
|
|
RemoteTurn = 4
|
|
}
|
|
|
|
[SerializeField]
|
|
private GameController m_gameController;
|
|
|
|
[SerializeField]
|
|
private Text m_matchButtonText;
|
|
|
|
[SerializeField]
|
|
private Text m_infoText;
|
|
|
|
private const string POOL = "VR_BOARD_GAME_POOL";
|
|
|
|
private ulong m_matchRoom;
|
|
|
|
private User m_remotePlayer;
|
|
|
|
private float m_lastUpdateTime;
|
|
|
|
private const float POLL_FREQUENCY = 30f;
|
|
|
|
private MatchRoomState m_state;
|
|
|
|
private void Start()
|
|
{
|
|
Matchmaking.SetMatchFoundNotificationCallback(MatchFoundCallback);
|
|
Rooms.SetUpdateNotificationCallback(MatchmakingRoomUpdateCallback);
|
|
TransitionToState(MatchRoomState.None);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
MatchRoomState state = m_state;
|
|
if ((state == MatchRoomState.Configuring || state == MatchRoomState.MyTurn || state == MatchRoomState.RemoteTurn) && 30f < Time.time - m_lastUpdateTime)
|
|
{
|
|
Debug.Log("Polling Room");
|
|
m_lastUpdateTime = Time.time;
|
|
Rooms.Get(m_matchRoom).OnComplete(MatchmakingRoomUpdateCallback);
|
|
}
|
|
}
|
|
|
|
public void MatchButtonPressed()
|
|
{
|
|
if (m_state == MatchRoomState.None)
|
|
{
|
|
TransitionToState(MatchRoomState.Queued);
|
|
}
|
|
else
|
|
{
|
|
TransitionToState(MatchRoomState.None);
|
|
}
|
|
}
|
|
|
|
public void EndMatch(int localScore, int remoteScore)
|
|
{
|
|
MatchRoomState state = m_state;
|
|
if (state == MatchRoomState.MyTurn || state == MatchRoomState.RemoteTurn)
|
|
{
|
|
string key = PlatformManager.MyID.ToString();
|
|
string key2 = m_remotePlayer.ID.ToString();
|
|
Dictionary<string, int> dictionary = new Dictionary<string, int>();
|
|
if (localScore > remoteScore)
|
|
{
|
|
dictionary[key] = 1;
|
|
dictionary[key2] = 2;
|
|
}
|
|
else if (localScore < remoteScore)
|
|
{
|
|
dictionary[key] = 2;
|
|
dictionary[key2] = 1;
|
|
}
|
|
else
|
|
{
|
|
dictionary[key] = 1;
|
|
dictionary[key2] = 1;
|
|
}
|
|
Matchmaking.ReportResultsInsecure(m_matchRoom, dictionary).OnComplete(GenericErrorCheckCallback);
|
|
}
|
|
TransitionToState(MatchRoomState.None);
|
|
}
|
|
|
|
private void OnApplicationQuit()
|
|
{
|
|
Matchmaking.Cancel();
|
|
if (m_matchRoom != 0)
|
|
{
|
|
Rooms.Leave(m_matchRoom);
|
|
}
|
|
}
|
|
|
|
private void TransitionToState(MatchRoomState state)
|
|
{
|
|
MatchRoomState state2 = m_state;
|
|
m_state = state;
|
|
switch (m_state)
|
|
{
|
|
case MatchRoomState.None:
|
|
m_matchButtonText.text = "Find Match";
|
|
m_remotePlayer = null;
|
|
Matchmaking.Cancel();
|
|
if (m_matchRoom != 0)
|
|
{
|
|
Rooms.Leave(m_matchRoom);
|
|
m_matchRoom = 0uL;
|
|
}
|
|
break;
|
|
case MatchRoomState.Queued:
|
|
m_matchButtonText.text = "Leave Queue";
|
|
Matchmaking.Enqueue2("VR_BOARD_GAME_POOL").OnComplete(MatchmakingEnqueueCallback);
|
|
break;
|
|
case MatchRoomState.Configuring:
|
|
m_matchButtonText.text = "Cancel Match";
|
|
break;
|
|
case MatchRoomState.MyTurn:
|
|
case MatchRoomState.RemoteTurn:
|
|
m_matchButtonText.text = "Cancel Match";
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void MatchmakingEnqueueCallback(Message untyped_msg)
|
|
{
|
|
if (untyped_msg.IsError)
|
|
{
|
|
Debug.Log(untyped_msg.GetError().Message);
|
|
TransitionToState(MatchRoomState.None);
|
|
return;
|
|
}
|
|
Message<MatchmakingEnqueueResult> message = (Message<MatchmakingEnqueueResult>)untyped_msg;
|
|
MatchmakingEnqueueResult data = message.Data;
|
|
m_infoText.text = string.Format("Avg Wait Time: {0}s\nMax Expected Wait: {1}s\nIn Last Hour: {2}\nRecent Percentage: {3}%", data.AverageWait, data.MaxExpectedWait, data.MatchesInLastHourCount, data.RecentMatchPercentage);
|
|
}
|
|
|
|
private void MatchFoundCallback(Message<Oculus.Platform.Models.Room> msg)
|
|
{
|
|
if (msg.IsError)
|
|
{
|
|
Debug.Log(msg.GetError().Message);
|
|
TransitionToState(MatchRoomState.None);
|
|
}
|
|
else if (m_state == MatchRoomState.Queued)
|
|
{
|
|
Matchmaking.JoinRoom(msg.Data.ID, true).OnComplete(MatchmakingJoinRoomCallback);
|
|
m_matchRoom = msg.Data.ID;
|
|
}
|
|
}
|
|
|
|
private void MatchmakingJoinRoomCallback(Message<Oculus.Platform.Models.Room> msg)
|
|
{
|
|
if (msg.IsError)
|
|
{
|
|
Debug.Log(msg.GetError().Message);
|
|
TransitionToState(MatchRoomState.None);
|
|
}
|
|
else if (m_state == MatchRoomState.Queued)
|
|
{
|
|
int num = ((msg.Data.UsersOptional != null) ? msg.Data.UsersOptional.Count : 0);
|
|
Debug.Log("Match room joined: " + m_matchRoom + " count: " + num);
|
|
TransitionToState(MatchRoomState.Configuring);
|
|
if (msg.Data.UsersOptional != null && msg.Data.UsersOptional.Count == 2)
|
|
{
|
|
ProcessRoomData(msg.Data);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MatchmakingRoomUpdateCallback(Message<Oculus.Platform.Models.Room> msg)
|
|
{
|
|
if (msg.IsError)
|
|
{
|
|
Debug.Log(msg.GetError().Message);
|
|
TransitionToState(MatchRoomState.None);
|
|
return;
|
|
}
|
|
string text = ((msg.Data.OwnerOptional == null) ? string.Empty : msg.Data.OwnerOptional.OculusID);
|
|
int num = ((msg.Data.UsersOptional != null) ? msg.Data.UsersOptional.Count : 0);
|
|
Debug.LogFormat("Room Update {0}\n Owner {1}\n User Count {2}\n Datastore Count {3}\n", msg.Data.ID, text, num, msg.Data.DataStore.Count);
|
|
if (msg.Data.ID != m_matchRoom)
|
|
{
|
|
Debug.Log("Unexpected room update from: " + msg.Data.ID);
|
|
}
|
|
else
|
|
{
|
|
ProcessRoomData(msg.Data);
|
|
}
|
|
}
|
|
|
|
private void ProcessRoomData(Oculus.Platform.Models.Room room)
|
|
{
|
|
m_lastUpdateTime = Time.time;
|
|
if (m_state == MatchRoomState.Configuring)
|
|
{
|
|
if (room.UsersOptional != null)
|
|
{
|
|
foreach (User item in room.UsersOptional)
|
|
{
|
|
if (PlatformManager.MyID != item.ID)
|
|
{
|
|
Debug.Log("Found remote user: " + item.OculusID);
|
|
m_remotePlayer = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (m_remotePlayer == null)
|
|
{
|
|
return;
|
|
}
|
|
bool flag = DoesLocalUserGoFirst();
|
|
TransitionToState((!flag) ? MatchRoomState.RemoteTurn : MatchRoomState.MyTurn);
|
|
Matchmaking.StartMatch(m_matchRoom).OnComplete(GenericErrorCheckCallback);
|
|
m_gameController.StartOnlineMatch(m_remotePlayer.OculusID, flag);
|
|
}
|
|
if (m_state == MatchRoomState.RemoteTurn && room.DataStore.ContainsKey(m_remotePlayer.OculusID) && room.DataStore[m_remotePlayer.OculusID] != string.Empty)
|
|
{
|
|
ProcessRemoteMove(room.DataStore[m_remotePlayer.OculusID]);
|
|
TransitionToState(MatchRoomState.MyTurn);
|
|
}
|
|
if (m_state == MatchRoomState.MyTurn && room.OwnerOptional != null && room.OwnerOptional.ID == PlatformManager.MyID)
|
|
{
|
|
m_gameController.MarkRemoteTurnComplete();
|
|
}
|
|
if (room.UsersOptional == null || (room.UsersOptional != null && room.UsersOptional.Count != 2))
|
|
{
|
|
Debug.Log("Other user quit the room");
|
|
m_gameController.RemoteMatchEnded();
|
|
}
|
|
}
|
|
|
|
private void ProcessRemoteMove(string moveString)
|
|
{
|
|
Debug.Log("Processing remote move string: " + moveString);
|
|
string[] array = moveString.Split(':');
|
|
GamePiece.Piece piece = (GamePiece.Piece)Enum.Parse(typeof(GamePiece.Piece), array[0]);
|
|
int num = int.Parse(array[1]);
|
|
int num2 = int.Parse(array[2]);
|
|
num = 2 - num;
|
|
num2 = 2 - num2;
|
|
m_gameController.MakeRemoteMove(piece, num, num2);
|
|
}
|
|
|
|
public void SendLocalMove(GamePiece.Piece piece, int boardX, int boardY)
|
|
{
|
|
string text = string.Format("{0}:{1}:{2}", piece.ToString(), boardX, boardY);
|
|
Debug.Log("Sending move: " + text);
|
|
Dictionary<string, string> dictionary = new Dictionary<string, string>();
|
|
dictionary[PlatformManager.MyOculusID] = text;
|
|
dictionary[m_remotePlayer.OculusID] = string.Empty;
|
|
Rooms.UpdateDataStore(m_matchRoom, dictionary).OnComplete(UpdateDataStoreCallback);
|
|
TransitionToState(MatchRoomState.RemoteTurn);
|
|
}
|
|
|
|
private void UpdateDataStoreCallback(Message<Oculus.Platform.Models.Room> msg)
|
|
{
|
|
if (m_state == MatchRoomState.RemoteTurn)
|
|
{
|
|
Rooms.UpdateOwner(m_matchRoom, m_remotePlayer.ID);
|
|
}
|
|
}
|
|
|
|
private bool DoesLocalUserGoFirst()
|
|
{
|
|
if (m_matchRoom % 2 == 0)
|
|
{
|
|
return PlatformManager.MyID < m_remotePlayer.ID;
|
|
}
|
|
return PlatformManager.MyID > m_remotePlayer.ID;
|
|
}
|
|
|
|
private void GenericErrorCheckCallback(Message msg)
|
|
{
|
|
if (msg.IsError)
|
|
{
|
|
Debug.Log(msg.GetError().Message);
|
|
TransitionToState(MatchRoomState.None);
|
|
}
|
|
}
|
|
}
|
|
}
|