From f98e983c2c4cf4709c80d431fd1ac8f6d7ab2944 Mon Sep 17 00:00:00 2001 From: VladimirKhil Date: Sat, 24 Feb 2024 13:59:55 +0100 Subject: [PATCH] Switch to new RunGameAsync API --- .../SI.GameServer.Client/GameServerClient.cs | 161 +----------------- .../SI.GameServer.Client/IGameServerClient.cs | 78 ++------- .../ViewModel/SIOnlineViewModel.cs | 145 +++------------- 3 files changed, 40 insertions(+), 344 deletions(-) diff --git a/src/Common/SI.GameServer.Client/GameServerClient.cs b/src/Common/SI.GameServer.Client/GameServerClient.cs index f86d548e..8a8bddcb 100644 --- a/src/Common/SI.GameServer.Client/GameServerClient.cs +++ b/src/Common/SI.GameServer.Client/GameServerClient.cs @@ -22,8 +22,6 @@ namespace SI.GameServer.Client; /// public sealed class GameServerClient : IGameServerClient { - private const int _BufferSize = 80 * 1024; - private bool _isOpened; private readonly GameServerClientOptions _options; @@ -31,7 +29,6 @@ public sealed class GameServerClient : IGameServerClient private readonly CookieContainer _cookieContainer; private readonly HttpClientHandler _httpClientHandler; private readonly HttpClient _client; - private readonly ProgressMessageHandler _progressMessageHandler; private HubConnection? _connection; @@ -56,7 +53,6 @@ private HubConnection Connection public event Action? Joined; public event Action? Leaved; public event Action? Receieve; - public event Action? UploadProgress; public event Action? IncomingMessage; public event Func? Closed; @@ -73,10 +69,7 @@ public GameServerClient(IOptions options, IUIThreadExec _cookieContainer = new CookieContainer(); _httpClientHandler = new HttpClientHandler { CookieContainer = _cookieContainer }; - _progressMessageHandler = new ProgressMessageHandler(_httpClientHandler); - _progressMessageHandler.HttpSendProgress += MessageHandler_HttpSendProgress; - - _client = new HttpClient(_progressMessageHandler) + _client = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(ServiceUri), Timeout = _options.Timeout, @@ -87,74 +80,6 @@ public GameServerClient(IOptions options, IUIThreadExec public Task RunGameAsync(RunGameRequest runGameRequest, CancellationToken cancellationToken = default) => Connection.InvokeAsync("RunGame", runGameRequest, cancellationToken); - public Task CreateGameAsync( - GameSettingsCore gameSettings, - PackageKey packageKey, - ComputerAccountInfo[] computerAccounts, - CancellationToken cancellationToken = default) - { - gameSettings.AppSettings.Culture = Thread.CurrentThread.CurrentUICulture.Name; - - return _connection.InvokeAsync( - "CreateGame", - gameSettings, - packageKey, - computerAccounts.Select(ca => ca.Account).ToArray(), - cancellationToken); - } - - public Task CreateGame2Async( - GameSettingsCore gameSettings, - PackageInfo packageInfo, - ComputerAccountInfo[] computerAccounts, - CancellationToken cancellationToken = default) - { - gameSettings.AppSettings.Culture = Thread.CurrentThread.CurrentUICulture.Name; - - return Connection.InvokeAsync( - "CreateGame2", - gameSettings, - packageInfo, - computerAccounts.Select(ca => ca.Account).ToArray(), - cancellationToken); - } - - public Task CreateAndJoinGameAsync( - GameSettingsCore gameSettings, - PackageKey packageKey, - ComputerAccountInfo[] computerAccounts, - bool isMale, - CancellationToken cancellationToken = default) - { - gameSettings.AppSettings.Culture = Thread.CurrentThread.CurrentUICulture.Name; - - return _connection.InvokeAsync( - "CreateAndJoinGameNew", - gameSettings, - packageKey, - computerAccounts.Select(ca => ca.Account).ToArray(), - isMale, - cancellationToken); - } - - public Task CreateAndJoinGame2Async( - GameSettingsCore gameSettings, - PackageInfo packageInfo, - ComputerAccountInfo[] computerAccounts, - bool isMale, - CancellationToken cancellationToken = default) - { - gameSettings.AppSettings.Culture = Thread.CurrentThread.CurrentUICulture.Name; - - return Connection.InvokeAsync( - "CreateAndJoinGame2", - gameSettings, - packageInfo, - computerAccounts.Select(ca => ca.Account).ToArray(), - isMale, - cancellationToken); - } - public async ValueTask DisposeAsync() { if (_connection != null) @@ -179,7 +104,7 @@ public Task> GetGamesAsync(int fromId, CancellationToken cancell _connection.InvokeAsync>("GetGamesSlice", fromId, cancellationToken); public Task GetGamesHostInfoAsync(CancellationToken cancellationToken = default) => - _connection.InvokeAsync("GetGamesHostInfo", cancellationToken); + _connection.InvokeAsync("GetGamesHostInfoNew", Thread.CurrentThread.CurrentUICulture.Name, cancellationToken); public Task GetNewsAsync(CancellationToken cancellationToken = default) => _connection.InvokeAsync("GetNews", cancellationToken); @@ -190,12 +115,6 @@ public Task GetLatestChatMessagesAsync(CancellationToken cancella public Task GetUsersAsync(CancellationToken cancellationToken = default) => _connection.InvokeAsync("GetUsers", cancellationToken); - public Task HasPackageAsync(PackageKey packageKey, CancellationToken cancellationToken = default) => - _connection.InvokeAsync("HasPackage", packageKey, cancellationToken); - - public Task HasImageAsync(FileKey imageKey, CancellationToken cancellationToken = default) => - _connection.InvokeAsync("HasPicture", imageKey, cancellationToken); - private async Task AuthenticateUserAsync( string user, string password, @@ -287,80 +206,6 @@ public async Task OpenAsync(string userName, CancellationToken cancellationToken public Task SayAsync(string message) => _connection.InvokeAsync("Say", message); - public async Task UploadPackageAsync(FileKey packageKey, Stream stream, CancellationToken cancellationToken = default) - { - var url = "api/upload/package"; - using var content = new StreamContent(stream, _BufferSize); - - try - { - using var formData = new MultipartFormDataContent - { - { content, "file", packageKey.Name } - }; - - formData.Headers.ContentMD5 = packageKey.Hash; - using var response = await _client.PostAsync(url, formData, cancellationToken); - - if (!response.IsSuccessStatusCode) - { - var errorMessage = await GetErrorMessageAsync(response, cancellationToken); - throw new Exception(errorMessage); - } - } - catch (HttpRequestException exc) - { - throw new Exception(Resources.UploadPackageConnectionError, exc.InnerException ?? exc); - } - catch (TaskCanceledException exc) - { - if (!exc.CancellationToken.IsCancellationRequested) - { - throw new Exception(Resources.UploadPackageTimeout, exc); - } - - throw exc; - } - } - - public async Task UploadImageAsync(FileKey imageKey, Stream data, CancellationToken cancellationToken = default) - { - var uri = "api/upload/image"; - - var bytesContent = new StreamContent(data, _BufferSize); - - using var formData = new MultipartFormDataContent - { - { bytesContent, Convert.ToBase64String(imageKey.Hash), imageKey.Name } - }; - - formData.Headers.ContentMD5 = imageKey.Hash; - - var response = await _client.PostAsync(uri, formData, cancellationToken); - - if (!response.IsSuccessStatusCode) - { - var errorString = await response.Content.ReadAsStringAsync(cancellationToken); - throw new Exception($"{response.StatusCode}: {errorString}"); - } - - return await response.Content.ReadAsStringAsync(cancellationToken); - } - - public Task JoinGameAsync( - int gameId, - GameRole role, - bool isMale, - string password, - CancellationToken cancellationToken = default) => - _connection.InvokeAsync("JoinGameNew", gameId, (int)role, isMale, password, cancellationToken); - - public Task SendMessageAsync(Message message, CancellationToken cancellationToken = default) => - _connection.InvokeAsync("SendMessage", message, cancellationToken); - - public Task LeaveGameAsync(CancellationToken cancellationToken = default) => - _connection.InvokeAsync("LeaveGame", cancellationToken); - private static async Task GetErrorMessageAsync(HttpResponseMessage response, CancellationToken cancellationToken) { var serverError = await response.Content.ReadAsStringAsync(cancellationToken); @@ -392,8 +237,6 @@ private void OnUI(Action action) action(); } - private void MessageHandler_HttpSendProgress(object? sender, HttpProgressEventArgs e) => UploadProgress?.Invoke(e.ProgressPercentage); - private sealed class ReconnectPolicy : IRetryPolicy { public TimeSpan? NextRetryDelay(RetryContext retryContext) => TimeSpan.FromSeconds(5); diff --git a/src/Common/SI.GameServer.Client/IGameServerClient.cs b/src/Common/SI.GameServer.Client/IGameServerClient.cs index 46b00066..fbf24cd6 100644 --- a/src/Common/SI.GameServer.Client/IGameServerClient.cs +++ b/src/Common/SI.GameServer.Client/IGameServerClient.cs @@ -1,7 +1,5 @@ using SI.GameServer.Contract; -using SIData; using System; -using System.IO; using System.Threading; using System.Threading.Tasks; @@ -10,10 +8,25 @@ namespace SI.GameServer.Client; /// /// Provides a client to SIGame server. /// -public interface IGameServerClient : IGameClient +public interface IGameServerClient : IAsyncDisposable { string ServiceUri { get; } + /// + /// Reconnecting event. + /// + event Func Reconnecting; + + /// + /// Reconnected event. + /// + event Func Reconnected; + + /// + /// Connection closed event. + /// + event Func Closed; + event Action GameCreated; event Action GameDeleted; event Action GameChanged; @@ -22,8 +35,6 @@ public interface IGameServerClient : IGameClient event Action Leaved; event Action Receieve; - event Action UploadProgress; - Task OpenAsync(string userName, CancellationToken token = default); /// @@ -50,62 +61,7 @@ public interface IGameServerClient : IGameClient Task> GetGamesAsync(int fromId, CancellationToken cancellationToken = default); - Task HasPackageAsync(PackageKey packageKey, CancellationToken cancellationToken = default); - - Task UploadPackageAsync(FileKey packageHash, Stream stream, CancellationToken cancellationToken = default); - - Task RunGameAsync( - RunGameRequest runGameRequest, - CancellationToken cancellationToken = default); - - Task CreateGameAsync( - GameSettingsCore gameSettings, - PackageKey packageKey, - ComputerAccountInfo[] computerAccounts, - CancellationToken cancellationToken = default); - - Task CreateGame2Async( - GameSettingsCore gameSettings, - PackageInfo packageInfo, - ComputerAccountInfo[] computerAccounts, - CancellationToken cancellationToken = default); - - Task HasImageAsync(FileKey imageKey, CancellationToken cancellationToken = default); - - Task UploadImageAsync(FileKey imageKey, Stream data, CancellationToken cancellationToken = default); + Task RunGameAsync(RunGameRequest runGameRequest, CancellationToken cancellationToken = default); Task SayAsync(string message); - - Task JoinGameAsync( - int gameId, - GameRole role, - bool isMale, - string password, - CancellationToken cancellationToken = default); - - Task SendMessageAsync(Message message, CancellationToken cancellationToken = default); - - Task CreateAndJoinGameAsync( - GameSettingsCore gameSettings, - PackageKey packageKey, - ComputerAccountInfo[] computerAccounts, - bool isMale, - CancellationToken cancellationToken = default); - - /// - /// Creates a new game and joins its. - /// - /// Game settings. - /// Package info. - /// Custom computer accounts info. - /// Male flag. - /// Cancellation token. - Task CreateAndJoinGame2Async( - GameSettingsCore gameSettings, - PackageInfo packageInfo, - ComputerAccountInfo[] computerAccounts, - bool isMale, - CancellationToken cancellationToken = default); - - Task LeaveGameAsync(CancellationToken cancellationToken = default); } diff --git a/src/SIGame/SIGame.ViewModel/ViewModel/SIOnlineViewModel.cs b/src/SIGame/SIGame.ViewModel/ViewModel/SIOnlineViewModel.cs index 06c7e697..a5f56044 100644 --- a/src/SIGame/SIGame.ViewModel/ViewModel/SIOnlineViewModel.cs +++ b/src/SIGame/SIGame.ViewModel/ViewModel/SIOnlineViewModel.cs @@ -370,8 +370,6 @@ public SIOnlineViewModel( _gameServerClient.Reconnected += GameServerClient_Reconnected; _gameServerClient.Closed += GameServerClient_Closed; - _gameServerClient.UploadProgress += GameServerClient_UploadProgress; - ServerAddress = _gameServerClient.ServiceUri; AddEmoji = new CustomCommand(AddEmoji_Executed); @@ -421,8 +419,6 @@ private Task GameServerClient_Reconnected(string? message) private void AddEmoji_Executed(object? arg) => ChatText += arg.ToString(); - private void GameServerClient_UploadProgress(int progress) => UploadProgress = progress; - private Task GameServerClient_Closed(Exception? exception) { PlatformSpecific.PlatformManager.Instance.ShowMessage( @@ -699,8 +695,6 @@ protected override async Task ClearConnectionAsync() _gameServerClient.Reconnecting -= GameServerClient_Reconnecting; _gameServerClient.Reconnected -= GameServerClient_Reconnected; _gameServerClient.Closed -= GameServerClient_Closed; - - _gameServerClient.UploadProgress -= GameServerClient_UploadProgress; } await base.ClearConnectionAsync(); @@ -856,94 +850,42 @@ protected override void Prepare(GameSettingsViewModel gameSettings) GameSettings.Message = Resources.Creating; + settings.AppSettings.Culture = Thread.CurrentThread.CurrentUICulture.Name; - // TODO: enable after server update - //settings.AppSettings.Culture = Thread.CurrentThread.CurrentUICulture.Name; - - //var runGameResponse = await _gameServerClient.RunGameAsync( - // new SI.GameServer.Contract.RunGameRequest(( - // GameSettingsCore)settings, - // packageInfo, - // computerAccounts.Select(ca => ca.Account).ToArray()), - // cancellationToken); - - //if (!runGameResponse.IsSuccess) - //{ - // throw new Exception(GetMessage(runGameResponse.ErrorType)); - //} - - // GameSettings.Message = Resources.GameEntering; - - //var name = Human.Name; - - //_password = settings.NetworkGamePassword; - - //var game = new GameInfo - //{ - // HostUri = runGameResponse.HostUri, - // GameID = runGameResponse.GameId, - // Owner = name - //}; - - //await JoinGameAsync(game, settings.Role, runGameResponse.IsHost, cancellationToken); - - //if (_host == null) - //{ - // return null; - //} - - //_host.Connector?.SetGameID(runGameResponse.GameId); - - //return (_node, _host); - - if (_userSettings.UseSignalRConnection) - { - var gameCreatingResult2 = await _gameServerClient.CreateAndJoinGame2Async( - (GameSettingsCore)settings, + var runGameResponse = await _gameServerClient.RunGameAsync( + new SI.GameServer.Contract.RunGameRequest(( + GameSettingsCore)settings, packageInfo, - computerAccounts.ToArray(), - Human.IsMale, - cancellationToken); - - if (gameCreatingResult2.Code != SI.GameServer.Contract.GameCreationResultCode.Ok) - { - var errorDetail = gameCreatingResult2.ErrorMessage != null ? $": {gameCreatingResult2.ErrorMessage}" : null; - throw new Exception(GetMessage(gameCreatingResult2.Code) + errorDetail); - } - - await InitNodeAndClientNewAsync(_gameServerClient, cancellationToken); - await JoinGameCompletedAsync(settings.Role, true, cancellationToken); - - if (_host == null) - { - return null; - } - - _host.Connector.SetGameID(gameCreatingResult2.GameId); - - return (_node, _host); - } - - var gameCreatingResult = await _gameServerClient.CreateGame2Async( - (GameSettingsCore)settings, - packageInfo, - computerAccounts.ToArray(), + computerAccounts.Select(ca => ca.Account).ToArray()), cancellationToken); - if (gameCreatingResult.Code != SI.GameServer.Contract.GameCreationResultCode.Ok) + if (!runGameResponse.IsSuccess) { - throw new Exception(GetMessage(gameCreatingResult.Code)); + throw new Exception(GetMessage(runGameResponse.ErrorType)); } GameSettings.Message = Resources.GameEntering; - await ConnectToServerAsHostAsync(gameCreatingResult.GameId, settings, cancellationToken); + var name = Human.Name; + + _password = settings.NetworkGamePassword; + + var game = new GameInfo + { + HostUri = runGameResponse.HostUri, + GameID = runGameResponse.GameId, + Owner = name + }; + + await JoinGameAsync(game, settings.Role, runGameResponse.IsHost, cancellationToken); if (_host == null) { return null; } + _host.Connector?.SetGameID(runGameResponse.GameId); + return (_node, _host); } @@ -1017,41 +959,6 @@ private SI.GameServer.Contract.SIContentInfo GetContentInfo() return _gamesHostInfo.ContentInfos[randomIndex]; } - private async Task UploadPackageAsync( - PackageSource packageSource, - PackageKey packageKey, - CancellationToken cancellationToken) - { - var data = await packageSource.GetPackageDataAsync(cancellationToken) ?? throw new Exception(Resources.BadPackage); - - using (data) - { - if (cancellationToken.IsCancellationRequested) - { - return false; - } - - if (data.Length > _gamesHostInfo.MaxPackageSizeMb * 1024 * 1024) - { - throw new Exception($"{Resources.FileTooLarge}. {string.Format(Resources.MaximumFileSize, _gamesHostInfo.MaxPackageSizeMb)}"); - } - - GameSettings.Message = Resources.SendingPackageToServer; - ShowProgress = true; - - try - { - await _gameServerClient.UploadPackageAsync(packageKey, data, cancellationToken); - } - finally - { - ShowProgress = false; - } - } - - return true; - } - private async Task InitNodeAndClientNewAsync(IGameClient gameClient, CancellationToken cancellationToken = default) { _node = new GameServerSlave( @@ -1280,16 +1187,6 @@ public override async Task JoinGameCoreAsync( } } - internal async Task ConnectToServerAsHostAsync(int gameID, GameSettings gameSettings, CancellationToken cancellationToken = default) - { - var name = Human.Name; - - _password = gameSettings.NetworkGamePassword; - var game = new GameInfo { GameID = gameID, Owner = name }; - - await JoinGameAsync(game, gameSettings.Role, true, cancellationToken); - } - public void Say(string message, bool system = false) { if (!system)