diff --git a/examples/unity-simple/.gitignore b/examples/unity-simple/.gitignore
index 2d79b8d5b9..8a3b351951 100644
--- a/examples/unity-simple/.gitignore
+++ b/examples/unity-simple/.gitignore
@@ -34,3 +34,7 @@ sysinfo.txt
# Builds
*.apk
*.unitypackage
+
+# Rider plugins
+/Assets/Plugins/
+/Assets/Plugins.meta
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model.meta b/examples/unity-simple/Assets/Scripts/Agones/model.meta
new file mode 100644
index 0000000000..a2894af8bb
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 500ddd914aef4fcca9861f610b7cd17b
+timeCreated: 1572467888
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServer.cs b/examples/unity-simple/Assets/Scripts/Agones/model/GameServer.cs
new file mode 120000
index 0000000000..6f7e7070ab
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServer.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/model/GameServer.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServer.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/model/GameServer.cs.meta
new file mode 100644
index 0000000000..3d26aeeeef
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServer.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 03a76250b0ac46ecaeb135236a8b0878
+timeCreated: 1572467889
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServerObjectMeta.cs b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerObjectMeta.cs
new file mode 120000
index 0000000000..0f8b989169
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerObjectMeta.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/model/GameServerObjectMeta.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServerObjectMeta.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerObjectMeta.cs.meta
new file mode 100644
index 0000000000..3adec1b84d
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerObjectMeta.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 5622544a94a94bb58fcaf4db56ad613b
+timeCreated: 1572467889
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServerSpec.cs b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerSpec.cs
new file mode 120000
index 0000000000..8a2f554fd8
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerSpec.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/model/GameServerSpec.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServerSpec.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerSpec.cs.meta
new file mode 100644
index 0000000000..64c669efa2
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerSpec.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: daf87a9144b54399be072876a7e2118d
+timeCreated: 1572467889
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServerStatus.cs b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerStatus.cs
new file mode 120000
index 0000000000..5deed14070
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerStatus.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/model/GameServerStatus.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/GameServerStatus.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerStatus.cs.meta
new file mode 100644
index 0000000000..c80208975c
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/GameServerStatus.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: e106e257a123459d899c55216e51c6c3
+timeCreated: 1572467889
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/SpecHealth.cs b/examples/unity-simple/Assets/Scripts/Agones/model/SpecHealth.cs
new file mode 120000
index 0000000000..189733c72f
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/SpecHealth.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/model/SpecHealth.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/SpecHealth.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/model/SpecHealth.cs.meta
new file mode 100644
index 0000000000..e02b01daf9
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/SpecHealth.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 521f3915c1264dcdaeeb065f893f4d31
+timeCreated: 1572467889
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/StatusPort.cs b/examples/unity-simple/Assets/Scripts/Agones/model/StatusPort.cs
new file mode 120000
index 0000000000..52fd0bad98
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/StatusPort.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/model/StatusPort.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/model/StatusPort.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/model/StatusPort.cs.meta
new file mode 100644
index 0000000000..f99676aa9e
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/model/StatusPort.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: d4d22e0c916347dfadb56c4991cd8488
+timeCreated: 1572467889
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/third_party.meta b/examples/unity-simple/Assets/Scripts/Agones/third_party.meta
new file mode 100644
index 0000000000..b34ccfb0d8
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/third_party.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 1425b63e14e44a15b9d375e5a8878d87
+timeCreated: 1572465524
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/third_party/MiniJSON.cs b/examples/unity-simple/Assets/Scripts/Agones/third_party/MiniJSON.cs
new file mode 120000
index 0000000000..e8089d153b
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/third_party/MiniJSON.cs
@@ -0,0 +1 @@
+../../../../../../sdks/unity/third_party/MiniJSON.cs
\ No newline at end of file
diff --git a/examples/unity-simple/Assets/Scripts/Agones/third_party/MiniJSON.cs.meta b/examples/unity-simple/Assets/Scripts/Agones/third_party/MiniJSON.cs.meta
new file mode 100644
index 0000000000..3ff1563cc7
--- /dev/null
+++ b/examples/unity-simple/Assets/Scripts/Agones/third_party/MiniJSON.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d76460015a67079e081b30be61e1b287
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/examples/unity-simple/Assets/Scripts/UdpEchoServer.cs b/examples/unity-simple/Assets/Scripts/UdpEchoServer.cs
index 933a8ddaa9..65e27037ed 100644
--- a/examples/unity-simple/Assets/Scripts/UdpEchoServer.cs
+++ b/examples/unity-simple/Assets/Scripts/UdpEchoServer.cs
@@ -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)
diff --git a/examples/unity-simple/Packages/manifest.json b/examples/unity-simple/Packages/manifest.json
index 73c0efb557..215430d3e6 100644
--- a/examples/unity-simple/Packages/manifest.json
+++ b/examples/unity-simple/Packages/manifest.json
@@ -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",
diff --git a/examples/unity-simple/ProjectSettings/EditorSettings.asset b/examples/unity-simple/ProjectSettings/EditorSettings.asset
index 78c18acce6..de17694cb9 100644
--- a/examples/unity-simple/ProjectSettings/EditorSettings.asset
+++ b/examples/unity-simple/ProjectSettings/EditorSettings.asset
@@ -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
diff --git a/examples/unity-simple/ProjectSettings/ProjectVersion.txt b/examples/unity-simple/ProjectSettings/ProjectVersion.txt
index f20e53672c..12efb654fa 100644
--- a/examples/unity-simple/ProjectSettings/ProjectVersion.txt
+++ b/examples/unity-simple/ProjectSettings/ProjectVersion.txt
@@ -1 +1 @@
-m_EditorVersion: 2018.4.2f1
+m_EditorVersion: 2018.4.12f1
diff --git a/examples/unity-simple/README.md b/examples/unity-simple/README.md
index 25f7629651..f435edfdf9 100644
--- a/examples/unity-simple/README.md
+++ b/examples/unity-simple/README.md
@@ -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() |
\ No newline at end of file
diff --git a/pkg/sdk/sdk.pb.go b/pkg/sdk/sdk.pb.go
index c05497dd43..adda6f400d 100644
--- a/pkg/sdk/sdk.pb.go
+++ b/pkg/sdk/sdk.pb.go
@@ -19,10 +19,10 @@
package sdk
import (
- fmt "fmt"
- math "math"
+ "fmt"
+ "math"
- proto "github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/proto"
context "golang.org/x/net/context"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
diff --git a/sdks/unity/AgonesSdk.cs b/sdks/unity/AgonesSdk.cs
index 8f0df9b36c..4a64ac9360 100644
--- a/sdks/unity/AgonesSdk.cs
+++ b/sdks/unity/AgonesSdk.cs
@@ -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;
@@ -31,8 +35,7 @@ public class AgonesSdk : MonoBehaviour
///
/// Interval of the server sending a health ping to the Agones sidecar.
///
- [Range(0.01f, 5)]
- public float healthIntervalSecond = 5.0f;
+ [Range(0.01f, 5)] public float healthIntervalSecond = 5.0f;
///
/// Whether the server sends a health ping to the Agones sidecar.
@@ -78,7 +81,23 @@ private void OnApplicationQuit()
///
public async Task Ready()
{
- return await SendRequestAsync("/ready", "{}");
+ return await SendRequestAsync("/ready", "{}").ContinueWith(task => task.Result.ok);
+ }
+
+ ///
+ /// Retrieve the GameServer details
+ ///
+ /// The current GameServer configuration
+ public async Task GameServer()
+ {
+ var result = await SendRequestAsync("/gameserver", "{}", UnityWebRequest.kHttpVerbGET);
+ if (!result.ok)
+ {
+ return null;
+ }
+
+ var data = Json.Deserialize(result.json) as Dictionary;
+ return new GameServer(data);
}
///
@@ -89,7 +108,7 @@ public async Task Ready()
///
public async Task Shutdown()
{
- return await SendRequestAsync("/shutdown", "{}");
+ return await SendRequestAsync("/shutdown", "{}").ContinueWith(task => task.Result.ok);
}
///
@@ -100,7 +119,7 @@ public async Task Shutdown()
///
public async Task Allocate()
{
- return await SendRequestAsync("/allocate", "{}");
+ return await SendRequestAsync("/allocate", "{}").ContinueWith(task => task.Result.ok);
}
///
@@ -114,7 +133,8 @@ public async Task Allocate()
public async Task 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);
}
///
@@ -128,7 +148,8 @@ public async Task SetLabel(string key, string value)
public async Task 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
@@ -150,7 +171,17 @@ private async void HealthCheckAsync()
}
}
- private async Task SendRequestAsync(string api, string json, string method = UnityWebRequest.kHttpVerbPOST)
+ ///
+ /// Result of a Async HTTP request
+ ///
+ private struct AsyncResult
+ {
+ public bool ok;
+ public string json;
+ }
+
+ private async Task SendRequestAsync(string api, string json,
+ string method = UnityWebRequest.kHttpVerbPOST)
{
// To prevent that an async method leaks after destroying this gameObject.
cancellationTokenSource.Token.ThrowIfCancellationRequested();
@@ -164,10 +195,13 @@ private async Task 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
@@ -175,7 +209,7 @@ private async Task SendRequestAsync(string api, string json, string method
Log($"Agones SendRequest failed: {api} {req.error}");
}
- return ok;
+ return result;
}
private void Log(object message)
diff --git a/sdks/unity/model/GameServer.cs b/sdks/unity/model/GameServer.cs
new file mode 100644
index 0000000000..f424d5cb49
--- /dev/null
+++ b/sdks/unity/model/GameServer.cs
@@ -0,0 +1,128 @@
+// Copyright 2019 Google LLC
+// All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Agones.Model
+{
+ ///
+ /// A GameServer Custom Resource Definition object We will only export those resources that make the most sense. Can always expand to more as needed.
+ ///
+ public class GameServer : IEquatable
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GameServer(IReadOnlyDictionary data)
+ {
+ if (data == null) return;
+
+ this.ObjectMeta = new GameServerObjectMeta((Dictionary) data["object_meta"]);
+ this.Spec = new GameServerSpec((Dictionary) data["spec"]);
+ // Seems possible that the status field could be null, especially for local SDK tooling,
+ // so don't know an exception here if the conversion fails.
+ this.Status = new GameServerStatus(data["status"] as Dictionary);
+ }
+
+ ///
+ /// Gets or Sets ObjectMeta
+ ///
+ public GameServerObjectMeta ObjectMeta { get; set; }
+
+ ///
+ /// Gets or Sets Spec
+ ///
+ public GameServerSpec Spec { get; set; }
+
+ ///
+ /// Gets or Sets Status
+ ///
+ public GameServerStatus Status { get; set; }
+
+ ///
+ /// Returns the string presentation of the object
+ ///
+ /// String presentation of the object
+ public override string ToString()
+ {
+ var sb = new StringBuilder();
+ sb.Append("class GameServer {\n");
+ sb.Append(" ObjectMeta: ").Append(ObjectMeta).Append("\n");
+ sb.Append(" Spec: ").Append(Spec).Append("\n");
+ sb.Append(" Status: ").Append(Status).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object input)
+ {
+ return this.Equals(input as GameServer);
+ }
+
+ ///
+ /// Returns true if GameServer instances are equal
+ ///
+ /// Instance of GameServer to be compared
+ /// Boolean
+ public bool Equals(GameServer input)
+ {
+ if (input == null)
+ return false;
+
+ return
+ (
+ this.ObjectMeta == input.ObjectMeta ||
+ (this.ObjectMeta != null &&
+ this.ObjectMeta.Equals(input.ObjectMeta))
+ ) &&
+ (
+ this.Spec == input.Spec ||
+ (this.Spec != null &&
+ this.Spec.Equals(input.Spec))
+ ) &&
+ (
+ this.Status == input.Status ||
+ (this.Status != null &&
+ this.Status.Equals(input.Status))
+ );
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hashCode = 41;
+ if (this.ObjectMeta != null)
+ hashCode = hashCode * 59 + this.ObjectMeta.GetHashCode();
+ if (this.Spec != null)
+ hashCode = hashCode * 59 + this.Spec.GetHashCode();
+ if (this.Status != null)
+ hashCode = hashCode * 59 + this.Status.GetHashCode();
+ return hashCode;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdks/unity/model/GameServerObjectMeta.cs b/sdks/unity/model/GameServerObjectMeta.cs
new file mode 100644
index 0000000000..d3e0b8b2f8
--- /dev/null
+++ b/sdks/unity/model/GameServerObjectMeta.cs
@@ -0,0 +1,194 @@
+// Copyright 2019 Google LLC
+// All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Agones.Model
+{
+ ///
+ /// GameServerObjectMeta
+ ///
+ public class GameServerObjectMeta : IEquatable
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GameServerObjectMeta(IReadOnlyDictionary data)
+ {
+ this.Name = (string) data["name"];
+ this.Namespace = (string) data["namespace"];
+ this.Uid = (string) data["uid"];
+ this.ResourceVersion = (string) data["resource_version"];
+ this.Generation = Int32.Parse((string) data["generation"]);
+ this.CreationTimestamp =
+ DateTimeOffset.FromUnixTimeSeconds(long.Parse((string) data["creation_timestamp"])).DateTime;
+
+ if (data.TryGetValue("deletion_timestamp", out var timestamp))
+ {
+ this.DeletionTimestamp =
+ DateTimeOffset.FromUnixTimeSeconds(long.Parse((string) timestamp)).DateTime;
+ }
+
+ if (data.TryGetValue("annotations", out var annotations))
+ {
+ this.Annotations = new Dictionary();
+ var values = (Dictionary) annotations;
+ foreach (var item in values)
+ {
+ this.Annotations.Add(item.Key, item.Value.ToString());
+ }
+ }
+
+ if (data.TryGetValue("labels", out var labels))
+ {
+ this.Labels = new Dictionary();
+ var values = (Dictionary) labels;
+ foreach (var item in values)
+ {
+ this.Labels.Add(item.Key, item.Value.ToString());
+ }
+ }
+ }
+
+ public string Name { get; }
+ public string Namespace { get; }
+ public string Uid { get; }
+ public string ResourceVersion { get; }
+ public int Generation { get; }
+ public DateTime CreationTimestamp { get; }
+ public DateTime? DeletionTimestamp { get; }
+ public Dictionary Annotations { get; }
+ public Dictionary Labels { get; }
+
+ ///
+ /// Returns the string presentation of the object
+ ///
+ /// String presentation of the object
+ public override string ToString()
+ {
+ var sb = new StringBuilder();
+ sb.Append("class GameServerObjectMeta {\n");
+ sb.Append(" Name: ").Append(Name).Append("\n");
+ sb.Append(" Namespace: ").Append(Namespace).Append("\n");
+ sb.Append(" Uid: ").Append(Uid).Append("\n");
+ sb.Append(" ResourceVersion: ").Append(ResourceVersion).Append("\n");
+ sb.Append(" Generation: ").Append(Generation).Append("\n");
+ sb.Append(" CreationTimestamp: ").Append(CreationTimestamp).Append("\n");
+ sb.Append(" DeletionTimestamp: ").Append(DeletionTimestamp).Append("\n");
+ sb.Append(" Annotations: ").Append(string.Join(";", Annotations)).Append("\n");
+ sb.Append(" Labels: ").Append(string.Join(";", Labels)).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object input)
+ {
+ return this.Equals(input as GameServerObjectMeta);
+ }
+
+ ///
+ /// Returns true if GameServerObjectMeta instances are equal
+ ///
+ /// Instance of GameServerObjectMeta to be compared
+ /// Boolean
+ public bool Equals(GameServerObjectMeta input)
+ {
+ if (input == null)
+ return false;
+
+ return
+ (
+ this.Name == input.Name ||
+ (this.Name != null &&
+ this.Name.Equals(input.Name))
+ ) &&
+ (
+ this.Namespace == input.Namespace ||
+ (this.Namespace != null &&
+ this.Namespace.Equals(input.Namespace))
+ ) &&
+ (
+ this.Uid == input.Uid ||
+ (this.Uid != null &&
+ this.Uid.Equals(input.Uid))
+ ) &&
+ (
+ this.ResourceVersion == input.ResourceVersion ||
+ (this.ResourceVersion != null &&
+ this.ResourceVersion.Equals(input.ResourceVersion))
+ ) &&
+ (
+ this.Generation == input.Generation ||
+ (this.Generation.Equals(input.Generation))
+ ) &&
+ (
+ this.CreationTimestamp == input.CreationTimestamp ||
+ (this.CreationTimestamp.Equals(input.CreationTimestamp))
+ ) &&
+ (
+ this.DeletionTimestamp == input.DeletionTimestamp ||
+ (this.DeletionTimestamp != null &&
+ this.DeletionTimestamp.Equals(input.DeletionTimestamp))
+ ) &&
+ (
+ this.Annotations == input.Annotations ||
+ this.Annotations != null &&
+ this.Annotations.SequenceEqual(input.Annotations)
+ ) &&
+ (
+ this.Labels == input.Labels ||
+ this.Labels != null &&
+ this.Labels.SequenceEqual(input.Labels)
+ );
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hashCode = 41;
+ if (this.Name != null)
+ hashCode = hashCode * 59 + this.Name.GetHashCode();
+ if (this.Namespace != null)
+ hashCode = hashCode * 59 + this.Namespace.GetHashCode();
+ if (this.Uid != null)
+ hashCode = hashCode * 59 + this.Uid.GetHashCode();
+ if (this.ResourceVersion != null)
+ hashCode = hashCode * 59 + this.ResourceVersion.GetHashCode();
+ hashCode = hashCode * 59 + this.Generation.GetHashCode();
+ hashCode = hashCode * 59 + this.CreationTimestamp.GetHashCode();
+ if (this.DeletionTimestamp != null)
+ hashCode = hashCode * 59 + this.DeletionTimestamp.GetHashCode();
+ if (this.Annotations != null)
+ hashCode = hashCode * 59 + this.Annotations.GetHashCode();
+ if (this.Labels != null)
+ hashCode = hashCode * 59 + this.Labels.GetHashCode();
+ return hashCode;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdks/unity/model/GameServerSpec.cs b/sdks/unity/model/GameServerSpec.cs
new file mode 100644
index 0000000000..b47665a273
--- /dev/null
+++ b/sdks/unity/model/GameServerSpec.cs
@@ -0,0 +1,93 @@
+// Copyright 2019 Google LLC
+// All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Agones.Model
+{
+ ///
+ /// GameServerSpec
+ ///
+ public class GameServerSpec : IEquatable
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GameServerSpec(IReadOnlyDictionary data)
+ {
+ this.Health = new SpecHealth((Dictionary) data["health"]);
+ }
+
+ public SpecHealth Health { get; set; }
+
+ ///
+ /// Returns the string presentation of the object
+ ///
+ /// String presentation of the object
+ public override string ToString()
+ {
+ var sb = new StringBuilder();
+ sb.Append("class GameServerSpec {\n");
+ sb.Append(" Health: ").Append(Health).Append("\n");
+ sb.Append("}\n");
+ return sb.ToString();
+ }
+
+ ///
+ /// Returns true if objects are equal
+ ///
+ /// Object to be compared
+ /// Boolean
+ public override bool Equals(object input)
+ {
+ return this.Equals(input as GameServerSpec);
+ }
+
+ ///
+ /// Returns true if GameServerSpec instances are equal
+ ///
+ /// Instance of GameServerSpec to be compared
+ /// Boolean
+ public bool Equals(GameServerSpec input)
+ {
+ if (input == null)
+ return false;
+
+ return
+ (
+ this.Health == input.Health ||
+ (this.Health != null &&
+ this.Health.Equals(input.Health))
+ );
+ }
+
+ ///
+ /// Gets the hash code
+ ///
+ /// Hash code
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hashCode = 41;
+ if (this.Health != null)
+ hashCode = hashCode * 59 + this.Health.GetHashCode();
+ return hashCode;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdks/unity/model/GameServerStatus.cs b/sdks/unity/model/GameServerStatus.cs
new file mode 100644
index 0000000000..f8adcf3b86
--- /dev/null
+++ b/sdks/unity/model/GameServerStatus.cs
@@ -0,0 +1,123 @@
+// Copyright 2019 Google LLC
+// All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Agones.Model
+{
+ ///
+ /// GameServerStatus
+ ///
+ public class GameServerStatus : IEquatable
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GameServerStatus(IReadOnlyDictionary data)
+ {
+ if (data == null) return;
+
+ this.State = (string) data["state"];
+ this.Address = (string) data["address"];
+
+ this.Ports = new List();
+ var items = (IReadOnlyList