agones.dev/agones@v1.54.0/sdks/csharp/sdk/Alpha.cs (about) 1 // Copyright 2020 Google LLC All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 using Agones.Dev.Sdk.Alpha; 15 using Grpc.Core; 16 using Microsoft.Extensions.Logging; 17 using System; 18 using System.Collections.Generic; 19 using System.Linq; 20 using System.Threading; 21 using System.Threading.Tasks; 22 using Grpc.Net.Client; 23 using gProto = Google.Protobuf.WellKnownTypes; 24 25 [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Agones.Test")] 26 namespace Agones 27 { 28 public sealed class Alpha : IAgonesAlphaSDK 29 { 30 31 /// <summary> 32 /// The timeout for gRPC calls. 33 /// </summary> 34 public double RequestTimeoutSec { get; set; } 35 36 internal SDK.SDKClient client; 37 internal readonly IClientStreamWriter<Empty> healthStream; 38 internal readonly CancellationTokenSource cts; 39 internal readonly bool ownsCts; 40 internal CancellationToken ctoken; 41 42 private readonly ILogger _logger; 43 private bool _disposed; 44 45 public Alpha( 46 GrpcChannel channel, 47 double requestTimeoutSec = 15, 48 CancellationTokenSource cancellationTokenSource = null, 49 ILogger logger = null) 50 { 51 _logger = logger; 52 RequestTimeoutSec = requestTimeoutSec; 53 54 if (cancellationTokenSource == null) 55 { 56 cts = new CancellationTokenSource(); 57 ownsCts = true; 58 } 59 else 60 { 61 cts = cancellationTokenSource; 62 ownsCts = false; 63 } 64 65 ctoken = cts.Token; 66 client = new SDK.SDKClient(channel); 67 } 68 69 70 /// <summary> 71 /// This returns the last player capacity that was set through the SDK. 72 /// If the player capacity is set from outside the SDK, use SDK.GameServer() instead. 73 /// </summary> 74 /// <returns>Player capacity</returns> 75 public async Task<long> GetPlayerCapacityAsync() 76 { 77 try 78 { 79 var count = await client.GetPlayerCapacityAsync(new Empty(), deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 80 return count.Count_; 81 } 82 catch (RpcException ex) 83 { 84 LogError(ex, "Unable to invoke the GetPlayerCapacity."); 85 throw; 86 } 87 } 88 89 /// <summary> 90 /// This changes the player capacity to a new value. 91 /// </summary> 92 /// <returns>gRPC Status of the request</returns> 93 public async Task<Status> SetPlayerCapacityAsync(long count) 94 { 95 try 96 { 97 await client.SetPlayerCapacityAsync(new Count() 98 { 99 Count_ = count 100 }, deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 101 return new Status(StatusCode.OK, "SetPlayerCapacity request successful."); 102 } 103 catch (RpcException ex) 104 { 105 LogError(ex, "Unable to invoke the SetPlayerCapacity."); 106 return ex.Status; 107 } 108 109 } 110 111 /// <summary> 112 /// This function increases the SDK’s stored player count by one, and appends this playerID to GameServer.Status.Players.IDs. 113 /// Returns true and adds the playerID to the list of playerIDs if the playerIDs was not already in the list of connected playerIDs. 114 /// </summary> 115 /// <returns>True if the playerID was added to the list of playerIDs</returns> 116 public async Task<bool> PlayerConnectAsync(string id) 117 { 118 try 119 { 120 var result = await client.PlayerConnectAsync(new PlayerID() 121 { 122 PlayerID_ = id 123 }, deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 124 return result.Bool_; 125 } 126 catch (RpcException ex) 127 { 128 LogError(ex, "Unable to invoke the PlayerConnect."); 129 throw; 130 } 131 } 132 133 /// <summary> 134 /// This function decreases the SDK’s stored player count by one, and removes the playerID from GameServer.Status.Players.IDs. 135 /// Will return true and remove the supplied playerID from the list of connected playerIDs if the playerID value exists within the list. 136 /// </summary> 137 /// <returns>True if the playerID was removed from the list of playerIDs</returns> 138 public async Task<bool> PlayerDisconnectAsync(string id) 139 { 140 try 141 { 142 var result = await client.PlayerDisconnectAsync(new PlayerID() 143 { 144 PlayerID_ = id 145 }, deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 146 return result.Bool_; 147 } 148 catch (RpcException ex) 149 { 150 LogError(ex, "Unable to invoke the PlayerDisconnect."); 151 throw; 152 } 153 } 154 155 /// <summary> 156 /// Returns the current player count. 157 /// </summary> 158 /// <returns>Player count</returns> 159 public async Task<long> GetPlayerCountAsync() 160 { 161 try 162 { 163 var count = await client.GetPlayerCountAsync(new Empty(), deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 164 return count.Count_; 165 } 166 catch (RpcException ex) 167 { 168 LogError(ex, "Unable to invoke the GetPlayerCount."); 169 throw; 170 } 171 } 172 173 /// <summary> 174 /// This returns if the playerID is currently connected to the GameServer. 175 /// This is always accurate, even if the value hasn’t been updated to the GameServer status yet. 176 /// </summary> 177 /// <returns>True if the playerID is currently connected</returns> 178 public async Task<bool> IsPlayerConnectedAsync(string id) 179 { 180 try 181 { 182 var result = await client.IsPlayerConnectedAsync(new PlayerID() 183 { 184 PlayerID_ = id 185 }, deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 186 return result.Bool_; 187 } 188 catch (RpcException ex) 189 { 190 LogError(ex, "Unable to invoke the IsPlayerConnected."); 191 throw; 192 } 193 } 194 195 /// <summary> 196 /// This returns the list of the currently connected player ids. 197 /// This is always accurate, even if the value has not been updated to the Game Server status yet. 198 /// </summary> 199 /// <returns>The list of the currently connected player ids</returns> 200 public async Task<List<string>> GetConnectedPlayersAsync() 201 { 202 try 203 { 204 var playerIDList = await client.GetConnectedPlayersAsync(new Empty(), deadline: DateTime.UtcNow.AddSeconds(RequestTimeoutSec), cancellationToken: ctoken); 205 return playerIDList.List.ToList(); 206 } 207 catch (RpcException ex) 208 { 209 LogError(ex, "Unable to invoke the GetConnectedPlayers."); 210 throw; 211 } 212 } 213 214 public void Dispose() 215 { 216 if (_disposed) 217 { 218 return; 219 } 220 221 cts.Cancel(); 222 223 if (ownsCts) 224 { 225 cts.Dispose(); 226 } 227 228 _disposed = true; 229 GC.SuppressFinalize(this); 230 } 231 232 private void LogError(Exception ex, string message) 233 { 234 _logger?.LogError(ex, message); 235 } 236 } 237 }