Skip to content

Commit

Permalink
Implementation of GameServer() for Unity (#1169)
Browse files Browse the repository at this point in the history
- Refactored `SendRequestAsync` to return a `AsyncResult` which contains
  both a success bool, and the returned body text from the http call.
- Used the swagger.json to generate the basic structure of the
  `GameServer` object, and then hand modified as needed.
- Had to include third_party/MiniJSON because Unity doesn't natively
  support `Dictionary`, which means we can't get Label or Annotation
  data. Then had to manually import the MiniJSON data into GameServer
  and related model objects.
- Used a set of symlinks to share the Agones Unity SDK code with the
  unity-simple example. Couldn't think of a better way.
- Minor version update on the example project as that is the earliest
  version I could get in 2018.4.x
- Added `GameServer` command to the simple-unity example as well.

Work on #927
  • Loading branch information
markmandel authored Nov 7, 2019
1 parent 72523e2 commit 7c50719
Show file tree
Hide file tree
Showing 33 changed files with 1,442 additions and 37 deletions.
4 changes: 4 additions & 0 deletions examples/unity-simple/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ sysinfo.txt
# Builds
*.apk
*.unitypackage

# Rider plugins
/Assets/Plugins/
/Assets/Plugins.meta
3 changes: 3 additions & 0 deletions examples/unity-simple/Assets/Scripts/Agones/model.meta

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

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

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

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

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

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

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

3 changes: 3 additions & 0 deletions examples/unity-simple/Assets/Scripts/Agones/third_party.meta

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

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

8 changes: 8 additions & 0 deletions examples/unity-simple/Assets/Scripts/UdpEchoServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ async void Update()

echoBytes = Encoding.UTF8.GetBytes($"Allocate {ok}");
break;

case "GameServer":
var gameserver = await agones.GameServer();
Debug.Log($"Server - GameServer {gameserver}");

ok = gameserver != null;
echoBytes = Encoding.UTF8.GetBytes(ok ? $"GameServer() Name: {gameserver.ObjectMeta.Name} {ok}" : $"GameServer(): {ok}");
break;

case "Label":
if (recvTexts.Length == 3)
Expand Down
2 changes: 1 addition & 1 deletion examples/unity-simple/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"com.unity.ads": "2.0.8",
"com.unity.analytics": "3.2.2",
"com.unity.collab-proxy": "1.2.15",
"com.unity.package-manager-ui": "2.0.7",
"com.unity.package-manager-ui": "2.0.8",
"com.unity.purchasing": "2.0.3",
"com.unity.textmeshpro": "1.4.1",
"com.unity.modules.ai": "1.0.0",
Expand Down
44 changes: 23 additions & 21 deletions examples/unity-simple/ProjectSettings/EditorSettings.asset
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 7
m_ExternalVersionControlSupport: Visible Meta Files
m_SerializationMode: 2
m_LineEndingsForNewScripts: 2
m_DefaultBehaviorMode: 0
m_SpritePackerMode: 0
m_SpritePackerPaddingPower: 1
m_EtcTextureCompressorBehavior: 1
m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd
m_ProjectGenerationRootNamespace:
m_UserGeneratedProjectSuffix:
m_CollabEditorSettings:
inProgressEnabled: 1
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 7
m_ExternalVersionControlSupport: Visible Meta Files
m_SerializationMode: 2
m_LineEndingsForNewScripts: 2
m_DefaultBehaviorMode: 0
m_PrefabRegularEnvironment: {fileID: 0}
m_PrefabUIEnvironment: {fileID: 0}
m_SpritePackerMode: 0
m_SpritePackerPaddingPower: 1
m_EtcTextureCompressorBehavior: 1
m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef
m_ProjectGenerationRootNamespace:
m_CollabEditorSettings:
inProgressEnabled: 1
m_EnableTextureStreamingInPlayMode: 1
2 changes: 1 addition & 1 deletion examples/unity-simple/ProjectSettings/ProjectVersion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
m_EditorVersion: 2018.4.2f1
m_EditorVersion: 2018.4.12f1
1 change: 1 addition & 0 deletions examples/unity-simple/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ $ kubectl create -f gameserver.yaml
| Label $1 $2 | SetLabel($1, $2) |
| Annotation $1 $2 | SetAnnotation($1, $2) |
| Shutdown | Shutdown() |
| GaameServer | GameServer() |
6 changes: 3 additions & 3 deletions pkg/sdk/sdk.pb.go

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

56 changes: 45 additions & 11 deletions sdks/unity/AgonesSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Agones.Model;
using MiniJSON;
using UnityEngine;
using UnityEngine.Networking;

Expand All @@ -31,8 +35,7 @@ public class AgonesSdk : MonoBehaviour
/// <summary>
/// Interval of the server sending a health ping to the Agones sidecar.
/// </summary>
[Range(0.01f, 5)]
public float healthIntervalSecond = 5.0f;
[Range(0.01f, 5)] public float healthIntervalSecond = 5.0f;

/// <summary>
/// Whether the server sends a health ping to the Agones sidecar.
Expand Down Expand Up @@ -78,7 +81,23 @@ private void OnApplicationQuit()
/// </returns>
public async Task<bool> Ready()
{
return await SendRequestAsync("/ready", "{}");
return await SendRequestAsync("/ready", "{}").ContinueWith(task => task.Result.ok);
}

/// <summary>
/// Retrieve the GameServer details
/// </summary>
/// <returns>The current GameServer configuration</returns>
public async Task<GameServer> GameServer()
{
var result = await SendRequestAsync("/gameserver", "{}", UnityWebRequest.kHttpVerbGET);
if (!result.ok)
{
return null;
}

var data = Json.Deserialize(result.json) as Dictionary<string, object>;
return new GameServer(data);
}

/// <summary>
Expand All @@ -89,7 +108,7 @@ public async Task<bool> Ready()
/// </returns>
public async Task<bool> Shutdown()
{
return await SendRequestAsync("/shutdown", "{}");
return await SendRequestAsync("/shutdown", "{}").ContinueWith(task => task.Result.ok);
}

/// <summary>
Expand All @@ -100,7 +119,7 @@ public async Task<bool> Shutdown()
/// </returns>
public async Task<bool> Allocate()
{
return await SendRequestAsync("/allocate", "{}");
return await SendRequestAsync("/allocate", "{}").ContinueWith(task => task.Result.ok);
}

/// <summary>
Expand All @@ -114,7 +133,8 @@ public async Task<bool> Allocate()
public async Task<bool> SetLabel(string key, string value)
{
string json = JsonUtility.ToJson(new KeyValueMessage(key, value));
return await SendRequestAsync("/metadata/label", json, UnityWebRequest.kHttpVerbPUT);
return await SendRequestAsync("/metadata/label", json, UnityWebRequest.kHttpVerbPUT)
.ContinueWith(task => task.Result.ok);
}

/// <summary>
Expand All @@ -128,7 +148,8 @@ public async Task<bool> SetLabel(string key, string value)
public async Task<bool> SetAnnotation(string key, string value)
{
string json = JsonUtility.ToJson(new KeyValueMessage(key, value));
return await SendRequestAsync("/metadata/annotation", json, UnityWebRequest.kHttpVerbPUT);
return await SendRequestAsync("/metadata/annotation", json, UnityWebRequest.kHttpVerbPUT)
.ContinueWith(task => task.Result.ok);
}
#endregion

Expand All @@ -150,7 +171,17 @@ private async void HealthCheckAsync()
}
}

private async Task<bool> SendRequestAsync(string api, string json, string method = UnityWebRequest.kHttpVerbPOST)
/// <summary>
/// Result of a Async HTTP request
/// </summary>
private struct AsyncResult
{
public bool ok;
public string json;
}

private async Task<AsyncResult> SendRequestAsync(string api, string json,
string method = UnityWebRequest.kHttpVerbPOST)
{
// To prevent that an async method leaks after destroying this gameObject.
cancellationTokenSource.Token.ThrowIfCancellationRequested();
Expand All @@ -164,18 +195,21 @@ private async Task<bool> SendRequestAsync(string api, string json, string method

await new AgonesAsyncOperationWrapper(req.SendWebRequest());

bool ok = req.responseCode == (long)System.Net.HttpStatusCode.OK;
var result = new AsyncResult();

result.ok = req.responseCode == (long) HttpStatusCode.OK;

if (ok)
if (result.ok)
{
result.json = req.downloadHandler.text;
Log($"Agones SendRequest ok: {api} {req.downloadHandler.text}");
}
else
{
Log($"Agones SendRequest failed: {api} {req.error}");
}

return ok;
return result;
}

private void Log(object message)
Expand Down
Loading

0 comments on commit 7c50719

Please sign in to comment.