Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create sub library for the LCU #24

Open
RyadaProductions opened this issue Nov 5, 2019 · 15 comments
Open

Create sub library for the LCU #24

RyadaProductions opened this issue Nov 5, 2019 · 15 comments
Milestone

Comments

@RyadaProductions
Copy link
Contributor

Suggestion to create Camille.LCU which will enable people to interface with the league client from C#

@MingweiSamuel
Copy link
Owner

Are you mainly interested in making an user interactive app that hooks into LCU, or just want to collect data?

@RyadaProductions
Copy link
Contributor Author

Mainly in a User interactive app. Although a bit of data collection to support it wouldn't hurt the app.

@MingweiSamuel
Copy link
Owner

MingweiSamuel commented Nov 9, 2019

Which endpoints are you planning on using? We should pick some to support initially and add more as needed

Endpoints to be included (preliminary):

Control

  • GET/POST/DELETE /lol-login/v1/session
  • GET /riotclient/region-locale
  • POST /riotclient/kill-and-restart-ux
  • POST /riotclient/kill-ux
  • POST /riotclient/launch-ux
  • POST /riotclient/unload
  • POST /riotclient/ux-flash
  • POST /riotclient/ux-minimize
  • POST /riotclient/ux-show
  • GET /riotclient/ux-state

Summoner

  • GET /lol-summoner/v1/check-name-availability-new-summoners/{name}
  • GET /lol-summoner/v1/check-name-availability/{name}
  • GET /lol-summoner/v1/current-summoner
  • GET /lol-summoner/v1/current-summoner/autofill
  • PUT /lol-summoner/v1/current-summoner/icon
  • GET /lol-summoner/v1/current-summoner/rerollPoints
  • GET/POST /lol-summoner/v1/current-summoner/summoner-profile
  • GET /lol-summoner/v1/summoner-profile (by puuid)
  • GET /lol-summoner/v1/summoners (by name)
  • TODO

Champion

  • GET /lol-champion/v1/. ??? SummonerID seems to be required to be the logged in user's (so you can't see others' skins)

Ranked

  • GET /lol-ranked/v1/apex-leagues/{queueType}/{tier} -- enums
  • GET /lol-ranked/v1/current-ranked-stats
  • GET /lol-ranked/v1/league-ladders/{puuid}
  • GET /lol-ranked/v1/ranked-stats
  • GET /lol-ranked/v1/ranked-stats/{puuid}
  • GET /lol-ranked/v1/signed-ranked-stats ??
  • TODO

Chat

  • /lol-chat/v1/?

@RyadaProductions
Copy link
Contributor Author

Specifically: Plugin lol-champ-select is what i need.

GET /lol-champ-select/v1/bannable-champions
POST /lol-champ-select/v1/battle-training/launch
GET /lol-champ-select/v1/current-champion
GET /lol-champ-select/v1/disabled-champions
GET /lol-champ-select/v1/pickable-champions
GET /lol-champ-select/v1/pickable-skins
POST /lol-champ-select/v1/retrieve-latest-game-dto
GET /lol-champ-select/v1/session
PATCH /lol-champ-select/v1/session/actions/{id}
POST /lol-champ-select/v1/session/actions/{id}/complete
POST /lol-champ-select/v1/session/bench/swap/{championId}
PATCH /lol-champ-select/v1/session/my-selection
POST /lol-champ-select/v1/session/my-selection/reroll
POST /lol-champ-select/v1/session/simple-inventory
GET /lol-champ-select/v1/session/timer
GET /lol-champ-select/v1/session/trades
GET /lol-champ-select/v1/session/trades/{id}
POST /lol-champ-select/v1/session/trades/{id}/accept
POST /lol-champ-select/v1/session/trades/{id}/cancel
POST /lol-champ-select/v1/session/trades/{id}/decline
POST /lol-champ-select/v1/session/trades/{id}/request
GET /lol-champ-select/v1/team-boost
POST /lol-champ-select/v1/team-boost/purchase

@MingweiSamuel
Copy link
Owner

Alright, I have an initial version that you can test. https://www.nuget.org/packages/Camille.Lcu/

Currently the setup is pretty hidden from the user, just calling var lcu = new Lcu() reads the lockfile in the default install location ("C:\Riot Games\League of Legends"). So as long as the client is open and running it should automatically be able to connect. But in the future we can have it look for the league process and get the install dir from that (code).

Very minimal example usage: https://github.com/MingweiSamuel/Camille/blob/6358c6d/Camille.Lcu.Test/UnitTest1.cs#L27-L39

@RyadaProductions
Copy link
Contributor Author

I will test this somewhere this week. And try to build a nice application that we can use as an example/showcase of the LCU

@RyadaProductions
Copy link
Contributor Author

It seems like the LCU also has support for WebSockets. Which might be a good idea to also implement.
The HTTP approach seems to work, but it will cause a harsher API for programmers to work with without having any event driven notifications etc.

André from the API discord linked: https://gist.github.com/Pupix/eb662b1b784bb704a1390643738a8c15 to me as a showcase of how to use the WebSocket approach

@MingweiSamuel
Copy link
Owner

Will put that down as a TODO, but unfortunately don't have time to work on it this week

@MingweiSamuel
Copy link
Owner

MingweiSamuel commented Nov 20, 2019

Looks like it will be easiest to just support .net core & standard 2.1+ due to the custom cert used by the client
https://docs.microsoft.com/en-us/dotnet/api/system.net.websockets.clientwebsocketoptions.remotecertificatevalidationcallback?view=netcore-3.0#System_Net_WebSockets_ClientWebSocketOptions_RemoteCertificateValidationCallback

Could enable the Riot CA cert globally for earlier versions https://stackoverflow.com/a/2675183/2398020 + https://github.com/MingweiSamuel/Camille/blob/28af5aa/Camille.Lcu/src/LcuConfig.cs#L59-L76
(This changes all cert verification I believe, but would be reasonably secure assuming Riot doesn't leak their private key).
this would be insecure I believe

Also took a look at https://github.com/sta/websocket-sharp as an alternative but looking at the commit history, it's like twilight zone, no idea whats going on with that package (and no nuget updates in 3 years).

@RyadaProductions
Copy link
Contributor Author

Enabling the Cert globally sounds risky in terms of security. My preferred option here would be to bump the version of the LCU library. Then we don't have to rely on updates of other libraries, and we keep it completely in the framework.

@MingweiSamuel
Copy link
Owner

MingweiSamuel commented Nov 21, 2019

Any opinions on what the interface should look like? My philosophy has been for Camille to do as little as possible to get a one-to-one mapping between the methods available and the api methods. In this case a minimum WAMP would essentially be:

event OnConnected
event OnDisconnected
subscribe(string/enum eventtype, event handler)
publish(string/enum eventtype, obj message) // not really needed, probably

(list of events here: https://github.com/MingweiSamuel/lcu-schema/blob/master/help.json#L2-L1433)

But it would be nice to have other features. Automatic reconnects, maybe awaitable events. Not sure what would be useful and how it would interact with the REST portion of the LCU (if at all)

@RyadaProductions
Copy link
Contributor Author

I generally add everything that is public facing to the interface, if an external library/project may have need of it. Since otherwise you will constantly be casting the interface back to the impl or just use the impl flatout.
But that being said, if we add everything here it might be one gigantic interface.

@MingweiSamuel
Copy link
Owner

Ah, I meant "interface" in the more general way of how the API would look like on the outside.

Anyway, I have a first-pass version: https://github.com/MingweiSamuel/Camille/blob/0b45aca/Camille.Lcu.Test/UnitTest1.cs#L18-L48
https://www.nuget.org/packages/Camille.Lcu/3.0.1-nightly-2019-11-30-0b45aca4fa

Essentially there is a new .wamp with OnConnect, OnDisconnect, and also a .Subscribe(string topic, handler fn). List of topics is here: https://github.com/MingweiSamuel/lcu-schema/blob/6d78900/help.json#L2-L309

Currently the subscribe handler just gets a jtoken object, not an actual plain class. But the LCU does actually provide that info so I will add it eventually.

There's not a way to unsubscribe right now. It's a bit clunky but works as a first-pass.

@mikaeldui
Copy link
Contributor

mikaeldui commented Jan 16, 2022

Expanding on the first-pass version, what about lcu.ChampSelect.SubscribeAsync(() => lcu.ChampSelect.GetSession(), (e) => something) or lcu.ChampSelect.SubscribeAsync(nameof(lcu.ChampSelect.GetSession), (e) => something) if the mapping can be easily figured out?

Using Func it could be lcu.ChampSelect.GetSession.Subscribe(() => something).

BTW, I've ported a modified version of lcu-schema/update.ps1 to GitHub Actions so that I can continuously test my LCU integrated app.

@mikaeldui
Copy link
Contributor

mikaeldui commented Feb 18, 2022

if the mapping can be easily figured out?

The mapping seems to be "OnJsonApiEvent_lol-champ-select_v1_session".Replace("OnJsonApiEvent", "").Replace("_", "/") which gives us /lol-champ-select/v1/session. help.json is way less cryptic when sorted 😂.

I've yet to check the other events.


I've opted for using event in my implementation, which does use a similar Subscribe(string, Action<TData>) under the hood:

private event LeagueClientEventHandler<LolChampSelectChampSelectSession> _sessionChanged;
public event LeagueClientEventHandler<LolChampSelectChampSelectSession> SessionChanged
{
    add
    {
        if (_sessionChanged == null)
            EventRouter.Subscribe("OnJsonApiEvent_lol-champ-select_v1_session", (LolChampSelectChampSelectSession args) => _sessionChanged?.Invoke(this, args)); 

        _sessionChanged += value; 
    }

    remove
    {
        _sessionChanged -= value; 
        
        if (_sessionChanged == null) 
            EventRouter.Unsubscribe("OnJsonApiEvent_lol-champ-select_v1_session"); 
    }
}

Note: the code excerpt doesn't have created/updated/deleted implemented.


My implementation of events is now live with version 12.4.1.336 if you want to get a feel for it (e.g. (new LeagueClient()).LeagueOfLegends.ChampSelect.SessionChanged +=). The events would have to be triggered by interactions with the LeagueClientUx, or something else, since I don't do POST/PUT/PATCH/DELETE yet. The main supporting classes are RmsClient and RmsEventRouter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants