Skip to content

Commit

Permalink
Adds Unity Project
Browse files Browse the repository at this point in the history
Uses Unity 2019.1.3f1
  • Loading branch information
mfitzer committed May 31, 2019
1 parent 3d8097d commit 8b0ffb5
Show file tree
Hide file tree
Showing 225 changed files with 19,553 additions and 0 deletions.
34 changes: 34 additions & 0 deletions Assets/CommandLine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.ComponentModel;
using UnityEngine;

public class CommandLine
{
public static bool TryGetCommandLineArgValue<T>(string argName, out T value)
{
value = default(T);
try
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (!converter.CanConvertFrom(typeof(string)))
return false;

string[] args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++)
{
if (string.Compare(args[i], argName, StringComparison.InvariantCultureIgnoreCase) != 0 ||
args.Length <= i + 1)
continue;

value = (T) converter.ConvertFromString(args[i + 1]);
return true;
}

return false;
}
catch
{
return false;
}
}
}
11 changes: 11 additions & 0 deletions Assets/CommandLine.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/Matchmaking.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

131 changes: 131 additions & 0 deletions Assets/Matchmaking/Matchmaker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System;
using System.Net;

namespace UnityEngine.Ucg.Matchmaking
{
public class Matchmaker
{
/// <summary>
/// The hostname[:port]/{projectid} of your matchmaking server
/// </summary>
public string Endpoint;

MatchmakingRequest MatchmakingRequest;

MatchmakingController matchmakingController;

public delegate void SuccessCallback(Assignment assignment);

public delegate void ErrorCallback(string error);

SuccessCallback m_Success;
ErrorCallback m_Error;

public enum MatchmakingState
{
None,
Requesting,
Searching,
Found,
Error
};

/// <summary>
/// The matchmaking state machine's current state
/// </summary>
public MatchmakingState State = MatchmakingState.None;

public Matchmaker(string endpoint)
{
Endpoint = endpoint;
}

/// <summary>
/// Matchmaking state-machine driver
/// </summary>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public void Update()
{
switch (State)
{
case MatchmakingState.Requesting:
matchmakingController.UpdateRequestMatch();
break;
case MatchmakingState.Searching:
matchmakingController.UpdateGetAssignment();
break;
case MatchmakingState.Found:
case MatchmakingState.Error:
break; // User hasn't stopped the state machine yet.
default:
throw new ArgumentOutOfRangeException();
}
}

/// <summary>
/// Generates a matchmaking request from the custom player and group properties provided.
/// </summary>
/// <param name="playerId">The id of the player</param>
/// <param name="playerProps">Custom player properties relevant to the matchmaking function</param>
/// <param name="groupProps">Custom group properties relevant to the matchmaking function</param>
/// <returns></returns>
public static MatchmakingRequest CreateMatchmakingRequest(string playerId, MatchmakingPlayerProperties playerProps, MatchmakingGroupProperties groupProps)
{
MatchmakingPlayer thisPlayer = new MatchmakingPlayer(playerId)
{
Properties = JsonUtility.ToJson(playerProps)
};

MatchmakingRequest request = new MatchmakingRequest()
{
Properties = JsonUtility.ToJson(groupProps)
};


request.Players.Add(thisPlayer);

return request;
}

/// <summary>
/// Start matchmaking
/// </summary>
/// <param name="request">The matchmaking request</param>
/// <param name="successCallback">If a match is found, this callback will provide the connection information</param>
/// <param name="errorCallback">If matchmaking fails, this callback will provided some failure information</param>
public void RequestMatch(MatchmakingRequest request, SuccessCallback successCallback,
ErrorCallback errorCallback)
{
m_Success = successCallback;
m_Error = errorCallback;
MatchmakingRequest = request;

matchmakingController = new MatchmakingController(Endpoint);

matchmakingController.StartRequestMatch(request, GetAssignment, OnError);
State = MatchmakingState.Requesting;
Debug.Log(State);
}

void GetAssignment()
{
matchmakingController.StartGetAssignment(MatchmakingRequest.Players[0].Id, OnSuccess, OnError);
State = MatchmakingState.Searching;
Debug.Log(State);
}

void OnSuccess(Assignment assignment)
{
State = MatchmakingState.Found;
Debug.Log(State);
m_Success.Invoke(assignment);
}

void OnError(string error)
{
State = MatchmakingState.Error;
Debug.Log(State);
m_Error.Invoke(error);
}
}
}
11 changes: 11 additions & 0 deletions Assets/Matchmaking/Matchmaker.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions Assets/Matchmaking/MatchmakingClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

namespace UnityEngine.Ucg.Matchmaking
{
class MatchmakingClient
{
internal string Url { get; }

const string k_CreateRequestEndpoint = "/request";

const string k_GetAssignmentEndpoint = "/assignment";

const string k_ApiVersion = "1";

internal MatchmakingClient(string endpoint)
{
Url = "https://" + endpoint + "/api/v" + k_ApiVersion + "/matchmaking";
}

/// <summary>
/// Start matchmaking for a provided request. This tells your matchmaking endpoint to add
/// the players and group data in the request to the matchmaking pool for consideration
/// </summary>
/// <param name="request">The matchmaking request</param>
/// <returns>An asynchronous operation that can be used in various async flow patterns.
/// The webrequest inside will contain a json success object</returns>
/// TODO: Strongly type expect contract return from successful call
internal UnityWebRequestAsyncOperation RequestMatchAsync(MatchmakingRequest request)
{
string url = Url + k_CreateRequestEndpoint;
UnityWebRequest webRequest = new UnityWebRequest(url, "POST");
webRequest.SetRequestHeader("Content-Type", "application/json");
string txtRec = JsonUtility.ToJson(request);
byte[] jsonToSend = new UTF8Encoding().GetBytes(txtRec);
webRequest.uploadHandler = new UploadHandlerRaw(jsonToSend);
webRequest.downloadHandler = new DownloadHandlerBuffer();
Debug.Log("Calling... " + url + " " + txtRec);
return webRequest.SendWebRequest();
}

/// <summary>
/// Retrieve the assignment for a given player. This call will perform a long GET while listening for
/// matchmaking results
/// </summary>
/// <param name="id">The id of a player</param>
/// <returns>An asynchronous operation that can be used in various async flow patterns.
/// The webrequest inside will contain a json connection string object</returns>
/// TODO: Strongly type expect contract return from successful call
internal UnityWebRequestAsyncOperation GetAssignmentAsync(string id)
{
string url = Url + k_GetAssignmentEndpoint + "?id=" + id;
UnityWebRequest webRequest = new UnityWebRequest(url, "GET");
webRequest.SetRequestHeader("Content-Type", "application/json");
webRequest.downloadHandler = new DownloadHandlerBuffer();
Debug.Log("Calling... " + url);
return webRequest.SendWebRequest();
}
}
}
3 changes: 3 additions & 0 deletions Assets/Matchmaking/MatchmakingClient.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 115 additions & 0 deletions Assets/Matchmaking/MatchmakingController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System;
using UnityEngine;
using UnityEngine.Networking;

namespace UnityEngine.Ucg.Matchmaking
{
class MatchmakingController
{
public delegate void RequestMatchSuccess();
public delegate void RequestMatchError(string error);
public delegate void GetAssignmentSuccess(Assignment assignment);
public delegate void GetAssignmentError(string error);

RequestMatchSuccess m_RequestMatchSuccess;
RequestMatchError m_RequestMatchError;
GetAssignmentSuccess m_GetAssignmentSuccess;
GetAssignmentError m_GetAssignmentError;

MatchmakingClient m_Client;

UnityWebRequestAsyncOperation m_RequestMatchOperation;

UnityWebRequestAsyncOperation m_GetAssignmentOperation;

internal MatchmakingController(string endpoint)
{
m_Client = new MatchmakingClient(endpoint);
}

/// <summary>
/// Start a matchmaking request call on the controller
/// </summary>
internal void StartRequestMatch(MatchmakingRequest request, RequestMatchSuccess successCallback, RequestMatchError errorCallback)
{
m_RequestMatchOperation = m_Client.RequestMatchAsync(request);
m_RequestMatchSuccess = successCallback;
m_RequestMatchError = errorCallback;
}

/// <summary>
/// Update the state of the request. If it is complete, this will invoke the correct registered callback
/// </summary>
internal void UpdateRequestMatch()
{
if (m_RequestMatchOperation == null)
{
Debug.Log("You must call StartRequestMatch first");
return;
}
else if (!m_RequestMatchOperation.isDone)
{
return;
}

if (m_RequestMatchOperation.webRequest.isNetworkError || m_RequestMatchOperation.webRequest.isHttpError)
{
Debug.LogError("There was an error calling matchmaking RequestMatch. Error: " + m_RequestMatchOperation.webRequest.error);
m_RequestMatchError.Invoke(m_RequestMatchOperation.webRequest.error);
return;
}

MatchmakingResult result = JsonUtility.FromJson<MatchmakingResult>(m_RequestMatchOperation.webRequest.downloadHandler.text);
if (!result.success)
{
m_RequestMatchError.Invoke(result.error);
return;
}

m_RequestMatchSuccess.Invoke();
}

/// <summary>
/// Start a matchmaking request to get the provided player's assigned connection information
/// </summary>
internal void StartGetAssignment(string id, GetAssignmentSuccess successCallback, GetAssignmentError errorCallback)
{
m_GetAssignmentOperation = m_Client.GetAssignmentAsync(id);
m_GetAssignmentSuccess = successCallback;
m_GetAssignmentError = errorCallback;
}

/// <summary>
/// Update the state of the request. If it is complete, this will invoke the correct registered callback
/// </summary>
internal void UpdateGetAssignment()
{
if (m_GetAssignmentOperation == null)
{
Debug.Log("You must call StartGetAssignment first");
return;
}
else if (!m_GetAssignmentOperation.isDone)
{
return;
}

if (m_GetAssignmentOperation.webRequest.isNetworkError || m_GetAssignmentOperation.webRequest.isHttpError)
{
Debug.LogError("There was an error calling matchmaking getAssignment. Error: " + m_GetAssignmentOperation.webRequest.error);
m_GetAssignmentError.Invoke(m_GetAssignmentOperation.webRequest.error);
return;
}

Assignment result = JsonUtility.FromJson<Assignment>(m_GetAssignmentOperation.webRequest.downloadHandler.text);

if(!string.IsNullOrEmpty(result.AssignmentError))
{
m_GetAssignmentError.Invoke(result.AssignmentError);
return;
}

m_GetAssignmentSuccess.Invoke(result);
}
}
}
3 changes: 3 additions & 0 deletions Assets/Matchmaking/MatchmakingController.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8b0ffb5

Please sign in to comment.