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  }