From a8fb50ee645fbb3602edb7d64b14bd22e17ece07 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Sun, 27 Aug 2023 13:11:12 -0700 Subject: [PATCH] Remove LCU API support --- .github/workflows/ci.yml | 8 - src/Camille.Lcu/Camille.Lcu.csproj | 23 --- src/Camille.Lcu/gen/.gitignore | 2 - src/Camille.Lcu/gen/DataClasses.cs.dt | 12 -- src/Camille.Lcu/gen/EndpointExtensions.cs.dt | 8 - src/Camille.Lcu/gen/EndpointMethods.cs.dt | 11 -- src/Camille.Lcu/gen/specTransform.js | 174 ------------------ .../src/AutomaticLockfileProvider.cs | 148 --------------- src/Camille.Lcu/src/Endpoints.cs | 14 -- src/Camille.Lcu/src/ILcuApi.cs | 26 --- src/Camille.Lcu/src/ILockfileProvider.cs | 10 - src/Camille.Lcu/src/LcuApi.cs | 56 ------ src/Camille.Lcu/src/LcuConfig.cs | 38 ---- src/Camille.Lcu/src/LcuRequester.cs | 93 ---------- src/Camille.Lcu/src/Lockfile.cs | 70 ------- src/Camille.Lcu/src/TaskCompletionSource.cs | 8 - .../Camille.Lcu.Test/Camille.Lcu.Test.csproj | 17 -- tests/Camille.Lcu.Test/UnitTest1.cs | 19 -- 18 files changed, 737 deletions(-) delete mode 100644 src/Camille.Lcu/Camille.Lcu.csproj delete mode 100644 src/Camille.Lcu/gen/.gitignore delete mode 100644 src/Camille.Lcu/gen/DataClasses.cs.dt delete mode 100644 src/Camille.Lcu/gen/EndpointExtensions.cs.dt delete mode 100644 src/Camille.Lcu/gen/EndpointMethods.cs.dt delete mode 100644 src/Camille.Lcu/gen/specTransform.js delete mode 100644 src/Camille.Lcu/src/AutomaticLockfileProvider.cs delete mode 100644 src/Camille.Lcu/src/Endpoints.cs delete mode 100644 src/Camille.Lcu/src/ILcuApi.cs delete mode 100644 src/Camille.Lcu/src/ILockfileProvider.cs delete mode 100644 src/Camille.Lcu/src/LcuApi.cs delete mode 100644 src/Camille.Lcu/src/LcuConfig.cs delete mode 100644 src/Camille.Lcu/src/LcuRequester.cs delete mode 100644 src/Camille.Lcu/src/Lockfile.cs delete mode 100644 src/Camille.Lcu/src/TaskCompletionSource.cs delete mode 100644 tests/Camille.Lcu.Test/Camille.Lcu.Test.csproj delete mode 100644 tests/Camille.Lcu.Test/UnitTest1.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed9f5d9e..e8c9d295 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,14 +56,6 @@ jobs: - name: Build run: dotnet build --configuration Release --no-restore -p:version=$env:CAMI_VERSION - - name: Install & Start League Client - id: league-client - uses: magisteriis/setup-league-client@ea5ea0748d459cb8e4bade9d50d2f81b70f009f7 - with: - username: ${{ secrets.LOL_USERNAME }} - password: ${{ secrets.LOL_PASSWORD }} - region: NA - - name: Test if: ${{ github.event_name != 'pull_request' }} env: diff --git a/src/Camille.Lcu/Camille.Lcu.csproj b/src/Camille.Lcu/Camille.Lcu.csproj deleted file mode 100644 index cbff11fc..00000000 --- a/src/Camille.Lcu/Camille.Lcu.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - netstandard2.1;netcoreapp3.1;net5.0;net6.0 - Camille.Lcu - Camille.Lcu - League of Legends Client Update API Library. - - - - - - - - - - - - - - - - diff --git a/src/Camille.Lcu/gen/.gitignore b/src/Camille.Lcu/gen/.gitignore deleted file mode 100644 index dcc0c332..00000000 --- a/src/Camille.Lcu/gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.*.json -*.cs diff --git a/src/Camille.Lcu/gen/DataClasses.cs.dt b/src/Camille.Lcu/gen/DataClasses.cs.dt deleted file mode 100644 index e743510f..00000000 --- a/src/Camille.Lcu/gen/DataClasses.cs.dt +++ /dev/null @@ -1,12 +0,0 @@ -{{ - const { spec, schemasToInclude } = require(it.path + '/specTransform'); - - const header = `// Version ${spec.info.version}`; - const usings = []; /* 'using Camille.RiotGames.Enums;' ]; */ - const useSchema = (schemaKey) - => schemasToInclude.has(schemaKey); - const namespace = 'Lcu'; -}} -{{= it.templates.dataClasses({ - spec, header, usings, useSchema, namespace -}) }} diff --git a/src/Camille.Lcu/gen/EndpointExtensions.cs.dt b/src/Camille.Lcu/gen/EndpointExtensions.cs.dt deleted file mode 100644 index d35fd5f4..00000000 --- a/src/Camille.Lcu/gen/EndpointExtensions.cs.dt +++ /dev/null @@ -1,8 +0,0 @@ -{{ - const { spec } = require(it.path + '/specTransform'); - - const namespace = 'Lcu'; -}} -{{= it.templates.endpointExtensions({ - spec, namespace -}) }} diff --git a/src/Camille.Lcu/gen/EndpointMethods.cs.dt b/src/Camille.Lcu/gen/EndpointMethods.cs.dt deleted file mode 100644 index 31f6c15f..00000000 --- a/src/Camille.Lcu/gen/EndpointMethods.cs.dt +++ /dev/null @@ -1,11 +0,0 @@ -{{ - const { endpoints, spec, schemasToInclude } = require(it.path + '/specTransform'); - - const namespace = 'Lcu'; - const useMethod = ([ route, path ]) => endpoints.includes(route); - const formatSendArgs = operation => 'request, cancellationToken'; - const usings = []; -}} -{{= it.templates.endpointMethods({ - spec, namespace, useMethod, formatSendArgs, usings -}) }} diff --git a/src/Camille.Lcu/gen/specTransform.js b/src/Camille.Lcu/gen/specTransform.js deleted file mode 100644 index 29a99b5c..00000000 --- a/src/Camille.Lcu/gen/specTransform.js +++ /dev/null @@ -1,174 +0,0 @@ -const dotUtils = require('../../../srcgen/dotUtils.js'); // Evil relative path. -const spec = require('./.spec.json'); -const lcuTypeToCamilleEnum = { - "LolRankedLeagueQueueType": { "x-enum": "queueType", "x-type": "int" }, - "LolRankedLeagueTier": { "x-enum": "tier", "x-type": "string" }, - "LolRankedLeagueDivision": { "x-enum": "division", "x-type": "string" } -}; -const endpoints = [ - "/lol-login/v1/account-state", - - "/riotclient/region-locale", - "/riotclient/kill-and-restart-ux", - "/riotclient/kill-ux", - "/riotclient/launch-ux", - "/riotclient/unload", - "/riotclient/ux-flash", - "/riotclient/ux-minimize", - "/riotclient/ux-show", - "/riotclient/ux-state", - "/lol-summoner/v1/check-name-availability-new-summoners/{name}", - "/lol-summoner/v1/check-name-availability/{name}", - "/lol-summoner/v1/current-summoner", - "/lol-summoner/v1/current-summoner/autofill", - "/lol-summoner/v1/current-summoner/icon", - "/lol-summoner/v1/current-summoner/rerollPoints", - "/lol-summoner/v1/current-summoner/summoner-profile", - "/lol-summoner/v1/summoner-profile", - "/lol-summoner/v1/summoners", - "/lol-ranked/v1/apex-leagues/{queueType}/{tier}", - "/lol-ranked/v1/current-ranked-stats", - "/lol-ranked/v1/league-ladders/{puuid}", - "/lol-ranked/v1/ranked-stats", - "/lol-ranked/v1/ranked-stats/{puuid}", - - "/lol-ranked/v2/tiers", - - "/lol-champ-select/v1/bannable-champions", - "/lol-champ-select/v1/battle-training/launch", - "/lol-champ-select/v1/current-champion", - "/lol-champ-select/v1/disabled-champions", - "/lol-champ-select/v1/pickable-champions", - "/lol-champ-select/v1/pickable-skins", - "/lol-champ-select/v1/retrieve-latest-game-dto", - "/lol-champ-select/v1/session", - "/lol-champ-select/v1/session/actions/{id}", - "/lol-champ-select/v1/session/actions/{id}/complete", - "/lol-champ-select/v1/session/bench/swap/{championId}", - "/lol-champ-select/v1/session/my-selection", - "/lol-champ-select/v1/session/my-selection/reroll", - "/lol-champ-select/v1/session/simple-inventory", - "/lol-champ-select/v1/session/timer", - "/lol-champ-select/v1/session/trades", - "/lol-champ-select/v1/session/trades/{id}", - "/lol-champ-select/v1/session/trades/{id}/accept", - "/lol-champ-select/v1/session/trades/{id}/cancel", - "/lol-champ-select/v1/session/trades/{id}/decline", - "/lol-champ-select/v1/session/trades/{id}/request", - "/lol-champ-select/v1/team-boost", - "/lol-champ-select/v1/team-boost/purchase" -]; -const namespaceRenames = { - "RIOTCLIENT": "RiotClient" -}; - -function remapNamespaces(spec, endpoints = null, namespaceRenames = {}, lcuTypeToCamilleEnum = {}) { - const dtoNamespaceMapping = {}; - const dtoNamespaceNewToOldMapping = {}; - - function namespaceRenamed(namespace) { - return namespaceRenames[namespace.toUpperCase()] || namespace; - } - function updateRef(objWithRef) { - const ref = objWithRef['$ref']; - if (!ref || ref.includes('.')) return; // '.' hack to prevent double update. - const path = ref.split('/'); - const type = path.pop(); - - if (lcuTypeToCamilleEnum[type]) { - Object.assign(objWithRef, lcuTypeToCamilleEnum[type]); - delete objWithRef['$ref']; - return; - } - - const namespace = dtoNamespaceMapping[type]; - path.push(`${namespaceRenamed(namespace)}.${dotUtils.removePrefix(type, dtoNamespaceNewToOldMapping[namespace])}`); - objWithRef['$ref'] = path.join('/'); - } - - (endpoints - ? endpoints.map(ep => spec.paths[ep]) - : Object.values(spec.paths)) - .forEach(path => Object.entries(path || {}) - .filter(([ verb, _op ]) => !verb.startsWith('x-')) - .forEach(([ verb, op ]) => { - // TODO. - if (!(op.tags && op.tags.length)) { - console.warn(`Missing tags on ${verb} ${op.operationId}.`); - } - - const oldNamespace = (op.tags && op.tags.length) - ? dotUtils.normalizeEndpointName(op.tags[op.tags.length - 1].split(' ').pop()) - : 'global'; - const oldNamespaceRenamed = namespaceRenamed(oldNamespace); - let namespace = oldNamespace; - - // Shorten method names already containing namespace/endpoint. - let match; - const regex = new RegExp(`${verb}${oldNamespace}(V\\d+)?`, 'i'); - if ((match = regex.exec(op.operationId))) { - const [ prefix, versionOpt ] = match; - namespace = oldNamespaceRenamed; - op.operationId = dotUtils.capitalize(verb) + op.operationId.slice(prefix.length) + (versionOpt || ''); - } - - dtoNamespaceNewToOldMapping[namespace] = oldNamespace; - path['x-endpoint'] = namespace; - - Object.values(op.responses || {}) - .concat(op.requestBody || []) - .map(resp => resp.content).defined() - .map(cont => cont['application/json']).defined() - .map(json => json.schema) - .concat((op.parameters || []).map(param => param.schema || param)) // Add-in parameters. - .flatMap(schem => [ schem, schem.items, schem.additionalProperties ]).defined() - .filter(schem => schem['$ref']) - .forEach(schem => { - const type = schem['$ref'].split('/').pop(); - dtoNamespaceMapping[type] = namespace; - updateRef(schem); - }); - }) - ); - - const stack = Object.entries(dtoNamespaceMapping); - while (stack.length) { - const [ type, namespace ] = stack.pop(); - dtoNamespaceMapping[type] = namespace; - - let schema = spec.components.schemas[type]; - let childRefs = Object.values(schema.properties || {}) - .flatMap(propVal => [ propVal, propVal.items, propVal.additionalProperties ]).defined() - .filter(propVal => propVal['$ref']) - .forEach(propVal => { - const type = propVal['$ref'].split('/').pop(); - if (!dtoNamespaceMapping[type]) { - dtoNamespaceMapping[type] = namespace; - stack.push([ type, namespace ]); - } - updateRef(propVal); - }); - } - - // Remove those enums. - Object.keys(lcuTypeToCamilleEnum).forEach(key => delete dtoNamespaceMapping[key]); - - const schemas = spec.components.schemas; - const schemasToInclude = new Set(); - for (const [ schemaKey, namespace ] of Object.entries(dtoNamespaceMapping)) { - const newNamespace = namespaceRenamed(namespace); - const newSchemaKey = `${newNamespace}.${dotUtils.removePrefix(schemaKey, dtoNamespaceNewToOldMapping[namespace])}`; - if (newSchemaKey === schemaKey) - continue; - (schemas[newSchemaKey] = schemas[schemaKey])['x-endpoint'] = newNamespace; - delete schemas[schemaKey]; - - schemasToInclude.add(newSchemaKey); - } - - return schemasToInclude; -} - -const schemasToInclude = remapNamespaces(spec, endpoints, namespaceRenames, lcuTypeToCamilleEnum); - -module.exports = { endpoints, spec, schemasToInclude }; diff --git a/src/Camille.Lcu/src/AutomaticLockfileProvider.cs b/src/Camille.Lcu/src/AutomaticLockfileProvider.cs deleted file mode 100644 index 0864f33f..00000000 --- a/src/Camille.Lcu/src/AutomaticLockfileProvider.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Camille.Lcu -{ - public class AutomaticLockfileProvider : IDisposable, ILockfileProvider - { - private readonly TimeSpan _processPollingInterval; - - private readonly SemaphoreSlim _lockfilePathLock = new SemaphoreSlim(1); - private string? _lockfilePath = null; - - private FileSystemWatcher? _watcher = null; - - /// - /// This lock must be held to modify _lockfileTaskSource or _lockfileTaskSourceResolved. - /// - private readonly object _lockfileTaskSourceLock = new object(); - private TaskCompletionSource _lockfileTaskSource = new TaskCompletionSource(); - private bool _lockfileTaskSourceResolved = false; - - public AutomaticLockfileProvider() : this(new TimeSpan(0, 0, 1)) - { } - - public AutomaticLockfileProvider(TimeSpan processPollingInterval) - { - _processPollingInterval = processPollingInterval; - } - - public AutomaticLockfileProvider(string lockfilePath) - { - _lockfilePath = lockfilePath; - } - - public async Task GetLockfile(CancellationToken token) - { - await LockfilePathFound(token); - - Task lockfileTask; - Task eitherTask; - lock (_lockfileTaskSourceLock) - { - var cancellationTask = Task.Delay(Timeout.Infinite, token); - - lockfileTask = _lockfileTaskSource.Task; - eitherTask = Task.WhenAny(cancellationTask, lockfileTask); - } - await eitherTask; - - token.ThrowIfCancellationRequested(); - return await lockfileTask; - } - - private async Task LockfilePathFound(CancellationToken token) - { - if (null == _lockfilePath) - { - await _lockfilePathLock.WaitAsync(token); - try - { - // Find the lockfile path if it hasn't been found yet. - while (null == _lockfilePath) - { - try - { - _lockfilePath = Lockfile.GetLockfilePathFromProcess(); - // See if LCU is already running. - CheckUpdatedLockfile(); - - // Set file watchers. - var path = Path.GetDirectoryName(_lockfilePath); - Debug.Assert(null != path); - _watcher = new FileSystemWatcher(path) - { - NotifyFilter = NotifyFilters.LastWrite, - Filter = Path.GetFileName(_lockfilePath) - }; - _watcher.Changed += OnLockfileChanged; - _watcher.Created += OnLockfileChanged; - _watcher.Deleted += OnLockfileChanged; - - _watcher.EnableRaisingEvents = true; // Start the watcher. - - break; - } - catch (InvalidOperationException) - { - await Task.Delay(_processPollingInterval, token); - } - } - } - finally - { - _lockfilePathLock.Release(); - } - } - } - - private void OnLockfileChanged(object sender, FileSystemEventArgs e) - { - CheckUpdatedLockfile(); - } - - private void CheckUpdatedLockfile() - { - lock (_lockfileTaskSourceLock) - { - Debug.Assert(null != _lockfilePath); - - Lockfile lockfile; - try - { - lockfile = Lockfile.ParseFile(_lockfilePath); - } - catch - { - // Lockfile is not there. - if (_lockfileTaskSourceResolved) - { - // ...because it was removed, reset the task. - _lockfileTaskSource = new TaskCompletionSource(); - } - return; - } - - // Lockfile is there. - if (_lockfileTaskSourceResolved) - { - // ...and was updated. - _lockfileTaskSource = new TaskCompletionSource(); - } - _lockfileTaskSource.SetResult(lockfile); - _lockfileTaskSourceResolved = true; - } - } - - public void Dispose() - { - if (null != _watcher) - { - _watcher.Dispose(); - } - } - } -} diff --git a/src/Camille.Lcu/src/Endpoints.cs b/src/Camille.Lcu/src/Endpoints.cs deleted file mode 100644 index 451787e8..00000000 --- a/src/Camille.Lcu/src/Endpoints.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Net.Http; - -namespace Camille.Lcu -{ - public abstract class Endpoints - { - protected readonly ILcuApi @base; - - protected Endpoints(ILcuApi @base) - { - this.@base = @base; - } - } -} diff --git a/src/Camille.Lcu/src/ILcuApi.cs b/src/Camille.Lcu/src/ILcuApi.cs deleted file mode 100644 index 58f3f6e7..00000000 --- a/src/Camille.Lcu/src/ILcuApi.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Camille.Lcu -{ - public interface ILcuApi - { - /// - /// Send a custom request to the LCU, parsing a value as JSON. - /// - /// Type to parse as JSON. - /// Request to send. - /// Cancellation token to cancel the request. - /// The parsed value. May be null if endpoint returned an empty success response. - public Task Send(HttpRequestMessage request, CancellationToken? token = null); - - /// - /// Send a custom request to the LCU, ignoring the return value. - /// - /// Type to parse as JSON. - /// Request to send. - /// Cancellation token to cancel the request. - public Task Send(HttpRequestMessage request, CancellationToken? token = null); - } -} diff --git a/src/Camille.Lcu/src/ILockfileProvider.cs b/src/Camille.Lcu/src/ILockfileProvider.cs deleted file mode 100644 index e4e9ca5a..00000000 --- a/src/Camille.Lcu/src/ILockfileProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; - -namespace Camille.Lcu -{ - public interface ILockfileProvider - { - public Task GetLockfile(CancellationToken token); - } -} diff --git a/src/Camille.Lcu/src/LcuApi.cs b/src/Camille.Lcu/src/LcuApi.cs deleted file mode 100644 index 51a27601..00000000 --- a/src/Camille.Lcu/src/LcuApi.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Camille.Core; - -namespace Camille.Lcu -{ - /// - /// For interacting with the LCU (League Client Update) API. - /// - /// This class is UNSTABLE and subject to change. - /// - public class LcuApi : ILcuApi, IDisposable - { - private readonly LcuRequester _requester; - - public LcuApi() : this(new LcuConfig()) - { } - - public LcuApi(Lockfile lockfile) : this(new LcuConfig - { - LockfileProvider = lockfile, - }) - { } - - public LcuApi(LcuConfig config) - { - _requester = new LcuRequester(config); - } - - /// - public async Task Send(HttpRequestMessage request, CancellationToken? token = null) - { - // Camille's code is context-free. - // This slightly improves performance and helps prevent GUI thread deadlocks. - // https://blogs.msdn.microsoft.com/benwilli/2017/02/09/an-alternative-to-configureawaitfalse-everywhere/ - await new SynchronizationContextRemover(); - var content = await _requester.SendAsync(request, token.GetValueOrDefault()); - if (null == content) return default!; // TODO: throw exception on unexpected null. - return JsonHandler.Deserialize(content); - } - - /// - public async Task Send(HttpRequestMessage request, CancellationToken? token = null) - { - await new SynchronizationContextRemover(); - await _requester.SendAsync(request, token.GetValueOrDefault()); - } - - public void Dispose() - { - _requester.Dispose(); - } - } -} diff --git a/src/Camille.Lcu/src/LcuConfig.cs b/src/Camille.Lcu/src/LcuConfig.cs deleted file mode 100644 index a7684bdc..00000000 --- a/src/Camille.Lcu/src/LcuConfig.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Camille.Core; -using MingweiSamuel.TokenBucket; -using System; -using System.Net.Security; - -namespace Camille.Lcu -{ - public class LcuConfig - { - /// - /// Max concurrent requests (per LCU). - /// - public int MaxConcurrentRequests = 100; - - /// - /// Certification callback used to certify HTTP requests to the LCU. - /// - public RemoteCertificateValidationCallback CertificateValidationCallback = - RiotCertificateUtils.CertificateValidationCallback; - - /// - /// Rate-limiting token bucket used for requests to the LCU. - /// - public Func TokenBucketProvider = - () => new CircularTokenBucket(TimeSpan.FromSeconds(10), 1000, 20, 0.5f, 1.0f); - - /// - /// Hostname (IP address or domain, excluding the port) of the LCU. - /// This should almost certainly be left to the default ("127.0.0.1"). - /// - public string Hostname = "127.0.0.1"; - - /// - /// Strategy for finding the (possibly changing) lockfile. - /// - public ILockfileProvider LockfileProvider = new AutomaticLockfileProvider(); // TODO - } -} diff --git a/src/Camille.Lcu/src/LcuRequester.cs b/src/Camille.Lcu/src/LcuRequester.cs deleted file mode 100644 index 1495663c..00000000 --- a/src/Camille.Lcu/src/LcuRequester.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Text; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; -using MingweiSamuel.TokenBucket; -using Camille.Core; - -namespace Camille.Lcu -{ - public class LcuRequester : IDisposable - { - /// Basic auth username used by the LCU. - private const string USERNAME = "riot"; - - private readonly ITokenBucket? _tokenBucket; - private readonly string _hostname; - - private readonly SemaphoreSlim? _concurrentRequestSemaphore; - private readonly HttpClientHandler _clientHandler; - private readonly HttpClient _client; - private readonly ILockfileProvider _lockfileProvider; - - public LcuRequester(LcuConfig config) - { - _tokenBucket = config.TokenBucketProvider(); - - _concurrentRequestSemaphore = config.MaxConcurrentRequests <= 0 - ? null - : new SemaphoreSlim(config.MaxConcurrentRequests); - - _clientHandler = new HttpClientHandler - { - ClientCertificateOptions = ClientCertificateOption.Manual, - ServerCertificateCustomValidationCallback = (req, cert, chain, polErrs) => - config.CertificateValidationCallback(req, cert, chain, polErrs) - }; - _client = new HttpClient(_clientHandler); - _hostname = config.Hostname; - - _lockfileProvider = config.LockfileProvider; - } - - public async Task SendAsync(HttpRequestMessage request, CancellationToken token) - { - { - var lockfile = await _lockfileProvider.GetLockfile(token); - if (null == lockfile) - throw new InvalidOperationException("Lockfile not available."); - var baseUri = new UriBuilder(lockfile.Protocol, _hostname, lockfile.Port).Uri; - request.RequestUri = new Uri(baseUri, request.RequestUri); - request.Headers.Authorization = new AuthenticationHeaderValue( - "Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{USERNAME}:{lockfile.Password}"))); - } - - if (null != _concurrentRequestSemaphore) - await _concurrentRequestSemaphore.WaitAsync(token); - try - { - if (null != _tokenBucket) - { - long delay; - while (0 <= (delay = TokenBucketUtils.GetAllTokensOrDelay(_tokenBucket))) - { - await Task.Delay(TimeSpan.FromTicks(delay), token); - token.ThrowIfCancellationRequested(); - } - } - - HttpResponseMessage response; - using (request) - response = await _client.SendAsync(request, token); - -#if USE_HTTPCONTENT_READASSTRINGASYNC_CANCELLATIONTOKEN - return await response.Content.ReadAsStringAsync(token); -#else - return await response.Content.ReadAsStringAsync(); -#endif - } - finally - { - _concurrentRequestSemaphore?.Release(); - } - } - - public void Dispose() - { - _client.Dispose(); - _clientHandler.Dispose(); - } - } -} diff --git a/src/Camille.Lcu/src/Lockfile.cs b/src/Camille.Lcu/src/Lockfile.cs deleted file mode 100644 index 01ddaff1..00000000 --- a/src/Camille.Lcu/src/Lockfile.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Camille.Lcu -{ - public class Lockfile : ILockfileProvider - { - public readonly string ProcessName; - public readonly ulong Pid; - public readonly ushort Port; - public readonly string Password; - public readonly string Protocol; - - public Lockfile(string processName, ulong pid, ushort port, string password, string protocol) - { - ProcessName = processName; - Pid = pid; - Port = port; - Password = password; - Protocol = protocol; - } - public Task GetLockfile(CancellationToken token) - { - return Task.FromResult(this); - } - - public static string GetLockfilePathFromProcess(string processName = "LeagueClient") - { - var processes = Process.GetProcessesByName(processName); - if (1 != processes.Length) - throw new InvalidOperationException($"{processes.Length} processes with name \"{processName}\" found, exactly 1 needed."); - - var process = processes[0]; - if (null == process.MainModule) - throw new InvalidOperationException($"MainModule of process with name \"{processName}\" is null."); - - var path = Path.GetDirectoryName(process.MainModule.FileName); - Debug.Assert(null != path); - var lockfilePath = Path.Combine(path, "lockfile"); - return lockfilePath; - } - - public static Lockfile GetFromProcess(string processName = "LeagueClient") - { - return ParseFile(GetLockfilePathFromProcess(processName)); - } - - public static Lockfile ParseFile(string lockfilePath) - { - string text; - using (var stream = File.Open(lockfilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var reader = new StreamReader(stream)) - { - text = reader.ReadToEnd(); - } - var tokens = text.Split(':'); - - var process = tokens[0]; - var pid = ulong.Parse(tokens[1]); - var port = ushort.Parse(tokens[2]); - var password = tokens[3]; - var protocol = tokens[4]; - - return new Lockfile(process, pid, port, password, protocol); - } - } -} diff --git a/src/Camille.Lcu/src/TaskCompletionSource.cs b/src/Camille.Lcu/src/TaskCompletionSource.cs deleted file mode 100644 index 04e288ec..00000000 --- a/src/Camille.Lcu/src/TaskCompletionSource.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Threading.Tasks; - -namespace Camille.Lcu -{ - internal class TaskCompletionSource : TaskCompletionSource - { - } -} \ No newline at end of file diff --git a/tests/Camille.Lcu.Test/Camille.Lcu.Test.csproj b/tests/Camille.Lcu.Test/Camille.Lcu.Test.csproj deleted file mode 100644 index a0ca939f..00000000 --- a/tests/Camille.Lcu.Test/Camille.Lcu.Test.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - netcoreapp3.1;net5.0;net6.0 - false - - - - - - - - - - - - diff --git a/tests/Camille.Lcu.Test/UnitTest1.cs b/tests/Camille.Lcu.Test/UnitTest1.cs deleted file mode 100644 index 31359799..00000000 --- a/tests/Camille.Lcu.Test/UnitTest1.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Threading.Tasks; - -namespace Camille.Lcu.Test -{ - [TestClass] - public class UnitTest1 - { - [TestMethod] - public async Task TestMethod1() - { - using var lcu = new LcuApi(); - - var session = await lcu.LolLogin().GetAccountStateV1Async(); - Console.WriteLine(session); - } - } -}