Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Commit

Permalink
Feature: Auth token usage + Region Lock (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
Antosik committed Oct 31, 2020
1 parent b6e28d4 commit 8141cc9
Show file tree
Hide file tree
Showing 61 changed files with 1,243 additions and 1,147 deletions.
7 changes: 5 additions & 2 deletions main/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"my-last-games": "My latest games with the guild",
"stage": "Stage",
"season": "Season",
"client-not-launched": "League of Legends client is not launched!",
"auth-required": "Authentication required",
"auth-required-sub": "Please launch the League of Legends client",
"to-season": "To the season",
"to-main-page": "Go home",
"search": "Search"
Expand Down Expand Up @@ -101,7 +102,9 @@
"unexpected": "An unexpected error has occurred!",
"something": "Something went wrong: {message}",
"request": "It was not possible to send a request",
"internal": "Internal application error"
"lcu-required": "A League of Legends client required to be running",
"internal": "Internal application error",
"another-region": "Sorry, but Guilds are an exclusive RU server program"
},
"invite": {
"all": "Invite all",
Expand Down
7 changes: 5 additions & 2 deletions main/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"my-last-games": "袦芯懈 锌芯褋谢械写薪懈械 懈谐褉褘 褋 谐懈谢褜写懈械泄",
"stage": "协褌邪锌",
"season": "小械蟹芯薪",
"client-not-launched": "袣谢懈械薪褌 League of Legends 薪械 蟹邪锌褍褖械薪!",
"auth-required": "孝褉械斜褍械褌褋褟 邪胁褌芯褉懈蟹邪褑懈褟",
"auth-required-sub": "袩芯卸邪谢褍泄褋褌邪, 蟹邪锌褍褋褌懈褌械 泻谢懈械薪褌 League of Legends",
"to-season": "袣 褋械蟹芯薪褍",
"to-main-page": "袩械褉械泄褌懈 薪邪 谐谢邪胁薪褍褞",
"search": "袩芯懈褋泻"
Expand Down Expand Up @@ -101,7 +102,9 @@
"unexpected": "袩褉芯懈蟹芯褕谢邪 褋褌褉邪薪薪邪褟 芯褕懈斜泻邪!",
"something": "效褌芯-褌芯 锌芯褕谢芯 薪械 褌邪泻: {message}",
"request": "袧械 褍写邪谢芯褋褜 芯褌锌褉邪胁懈褌褜 蟹邪锌褉芯褋",
"internal": "袙薪褍褌褉械薪薪褟褟 芯褕懈斜泻邪 锌褉懈谢芯卸械薪懈褟"
"lcu-required": "孝褉械斜褍械褌褋褟 蟹邪锌褍褖械薪薪褘泄 泻谢懈械薪褌 League of Legends",
"internal": "袙薪褍褌褉械薪薪褟褟 芯褕懈斜泻邪 锌褉懈谢芯卸械薪懈褟",
"another-region": "袠蟹胁懈薪懈褌械, 薪芯 袚懈谢褜写懈懈 - 褝泻褋泻谢褞蟹懈胁薪邪褟 锌褉芯谐褉邪屑屑邪 袪校-褋械褉胁械褉邪"
},
"invite": {
"all": "袩褉懈谐谢邪褋懈褌褜 胁褋械褏",
Expand Down
6 changes: 3 additions & 3 deletions main/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ export class LeagueGuildsClient implements IDestroyable {
private async _onLCUConnected(): Promise<void> {

const token = await this.#lcuModule.api.getIdToken();

this.#guildsModule.api.setToken(token);
this.#rpc.send("guilds:connected");
this.#guildsModule.service.connect();

await Promise.all([
this.#discordRPCModule.mount(),
this.#guildGroupModule.mount(),
this.#lobbyInvitationsModule.mount(),
this.#staticGroupsModule.mount(),
]);
}
Expand All @@ -75,7 +75,6 @@ export class LeagueGuildsClient implements IDestroyable {
await Promise.all([
this.#discordRPCModule.unmount(),
this.#guildGroupModule.unmount(),
this.#lobbyInvitationsModule.unmount(),
this.#staticGroupsModule.unmount(),
]);
}
Expand All @@ -87,6 +86,7 @@ export class LeagueGuildsClient implements IDestroyable {

this.#lcuModule.mount();
this.#guildsModule.mount();
this.#lobbyInvitationsModule.mount();
}

public async destroy(): Promise<void> {
Expand Down
11 changes: 8 additions & 3 deletions main/src/core/guilds/connector.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Response } from "node-fetch";

import { EventEmitter } from "events";
import fetch from "node-fetch";
import { stringify as stringifyQuery } from "querystring";

Expand All @@ -9,7 +10,7 @@ import { isExists } from "@guilds-shared/helpers/typeguards";
import { VERSION } from "@guilds-shared/env";


export class GuildsAPI {
export class GuildsAPI extends EventEmitter {

private static RETRY_INTERVAL = 500;
private static RETRY_COUNT = 3;
Expand All @@ -18,6 +19,7 @@ export class GuildsAPI {

public setToken(token: string): void {
this.#token = token;
this.emit("guilds:connected");
}


Expand Down Expand Up @@ -161,8 +163,11 @@ export class GuildsAPI {

logDebug(`[GuildsAPI] (${retryIndex}/${GuildsAPI.RETRY_COUNT}): "${opts.method} /${path}" ${response.status} "${(opts.body && JSON.stringify(opts.body)) ?? ""}"`);

if (response.status === 204) {
return undefined;
if (response.status === 401 || response.status === 403) {
this.emit("guilds:disconnected");
return;
} else if (response.status === 204) {
return;
}

const result = await response.json() as Record<string, unknown> | { detail: string };
Expand Down
79 changes: 77 additions & 2 deletions main/src/core/guilds/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,49 @@
import type { MainRPC } from "@guilds-main/utils/rpc";
import type { GuildsService } from "@guilds-main/core/guilds/service";

import { authStore } from "@guilds-main/store/auth";
import { Controller } from "@guilds-main/utils/abstract/Controller";
import { Result } from "@guilds-shared/helpers/result";
import { isExists } from "@guilds-shared/helpers/typeguards";


export class GuildsController extends Controller {

#guildsService: GuildsService;
#tokenSubscription: TAnyFunc | null;

constructor(rpc: MainRPC, guildsService: GuildsService) {
super(rpc);
this.#guildsService = guildsService;
this.#tokenSubscription = null;
}


// #region Guilds Service Events Handling (Inner)
private _onIdTokenChanged() {
this._onGuildsDisconnected();
this.#guildsService.connect();
}
// #endregion Guilds Service Events Handling (Inner)


// #region Guilds Service Events Handling (Inner)
private _onGuildsConnected() {
this.rpc.send("guilds:connected");
}
private _onGuildsDisconnected() {
this.rpc.send("guilds:disconnected");
}
// #endregion Guilds Service Events Handling (Inner)


// #region RPC Events Handling (Outer)
private _onGuildsConnect() {
this.#guildsService.connect();
}
private _handleClubGetSummoner() {
return Result.resolve(this.#guildsService.getSummoner());
}
private _handleClubGet() {
return Result.resolve(this.#guildsService.getCurrentClub());
}
Expand Down Expand Up @@ -76,12 +104,17 @@ export class GuildsController extends Controller {

// #region IController implementation
_addEventHandlers(): this {
return this._addRPCEventHandlers();
return this
._addRPCEventHandlers()
._addGuildsEventHandlers()
._addStoreEventHandlers();
}

private _addRPCEventHandlers(): this {

this.rpc
.addListener("guilds:connect", this._onGuildsConnect)
.setHandler("guilds:get-summoner", this._handleClubGetSummoner)
.setHandler("guilds:club", this._handleClubGet)
.setHandler("guilds:role", this._handleGuildRole)
.setHandler("guilds:invites:accept", this._handleAcceptInvite)
Expand All @@ -104,13 +137,32 @@ export class GuildsController extends Controller {
return this;
}

private _addGuildsEventHandlers(): this {

this.#guildsService
.addListener("guilds:connected", this._onGuildsConnected)
.addListener("guilds:disconnected", this._onGuildsDisconnected);

return this;
}

private _addStoreEventHandlers(): this {
this.#tokenSubscription = authStore.onDidChange("token", this._onIdTokenChanged);
return this;
}

_removeEventHandlers(): this {
return this._removeRPCEventHandlers();
return this
._removeRPCEventHandlers()
._removeGuildsEventHandlers()
._removeStoreEventHandlers();
}

private _removeRPCEventHandlers(): this {

this.rpc
.removeListener("guilds:connect", this._onGuildsConnect)
.removeHandler("guilds:get-summoner")
.removeHandler("guilds:club")
.removeHandler("guilds:role")
.removeHandler("guilds:invites:accept")
Expand All @@ -133,9 +185,29 @@ export class GuildsController extends Controller {
return this;
}

private _removeGuildsEventHandlers(): this {

this.#guildsService
.removeListener("guilds:connected", this._onGuildsConnected)
.removeListener("guilds:disconnected", this._onGuildsDisconnected);

return this;
}

private _removeStoreEventHandlers(): this {
if (isExists(this.#tokenSubscription)) {
this.#tokenSubscription();
}
return this;
}

_bindMethods(): void {

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
this._onIdTokenChanged = this._onIdTokenChanged.bind(this);

this._onGuildsConnect = this._onGuildsConnect.bind(this);
this._handleClubGetSummoner = this._handleClubGetSummoner.bind(this);
this._handleClubGet = this._handleClubGet.bind(this);
this._handleGamesSeason = this._handleGamesSeason.bind(this);
this._handleGamesStage = this._handleGamesStage.bind(this);
Expand All @@ -154,6 +226,9 @@ export class GuildsController extends Controller {
this._handleGuildRole = this._handleGuildRole.bind(this);
this._handleAcceptInvite = this._handleAcceptInvite.bind(this);
this._handleDeclineInvite = this._handleDeclineInvite.bind(this);

this._onGuildsConnected = this._onGuildsConnected.bind(this);
this._onGuildsDisconnected = this._onGuildsDisconnected.bind(this);
/* eslint-enable @typescript-eslint/no-unsafe-assignment */
}
// #endregion IController implementation
Expand Down
8 changes: 8 additions & 0 deletions main/src/core/guilds/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,12 @@ export class GuildsModule extends Module {
public get controller(): GuildsController {
return this.#controller;
}


// #region IMountable implementation
public mount(): void {
super.mount();
this.#service.connect();
}
// #endregion IMountable implementation
}
29 changes: 29 additions & 0 deletions main/src/core/guilds/service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { GuildsAPI } from "./connector";

import { getGuildSeasonPath, getGuildStagePath } from "./utils/guildPath";
import { AuthStore, authStore } from "@guilds-main/store/auth";
import { i18n } from "@guilds-main/utils/i18n";
import { isExists, isNotExists } from "@guilds-shared/helpers/typeguards";

Expand All @@ -14,6 +15,34 @@ export class GuildsService implements IService {
}


public connect(): void {
const authToken = authStore.getToken();
if (isExists(authToken) && !AuthStore.isTokenExpired(authToken)) {
this.#guildsApi.setToken(authToken.token);
}
}


// #region Events
public addListener(event: string, callback: TAnyFunc): this {
this.#guildsApi.addListener(event, callback);
return this;
}
public removeAllListeners(event: string): this {
this.#guildsApi.removeAllListeners(event);
return this;
}
public removeListener(event: string, callback: TAnyFunc): this {
this.#guildsApi.removeListener(event, callback);
return this;
}
// #endregion Events


public async getSummoner(): Promise<IGuildAPICurrentSummonerResponse> {
return this.#guildsApi.getCurrentSummoner();
}

public async getCurrentClub(): Promise<IGuildAPIClubResponse> {

const { next, prev, club: current } = await this.#guildsApi.getCurrentSummoner();
Expand Down
8 changes: 6 additions & 2 deletions main/src/core/guilds/utils/guildPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { isExists, isNotEmpty, isNotExists } from "@guilds-shared/helpers/typegu
const guildRatingToPoint = (club?: IGuildAPIClubRatingResponse): IInternalGuildPathPoint => ({ rank: club?.rank, points: club?.points ?? 0, absolute: false });
const sortByPoints = (first: IInternalGuildPathPoint, second: IInternalGuildPathPoint): number => first.points - second.points;
const filterEmptyPoints = (point: IInternalGuildPathPoint) => isExists(point.rank) || point.absolute;
const getUniqueTopPoints = (points: IInternalGuildPathPoint[]): IInternalGuildPathPoint[] => {
const rankToPoint = new Map<number, IInternalGuildPathPoint>(points.map(point => [point.rank!, point]));
return Array.from(rankToPoint.values());
};

function constructSegment(guildPoint: IInternalGuildPathPoint, start: IInternalGuildPathPoint, end: IInternalGuildPathPoint): IInternalGuildPathSegment {

Expand Down Expand Up @@ -82,7 +86,7 @@ export async function getGuildSeasonPath(guildsApi: GuildsAPI, season_id: number

return {
current_position: currentPosition,
segments: constructSegments(currentPosition, absolutePoints, topPoints)
segments: constructSegments(currentPosition, absolutePoints, getUniqueTopPoints(topPoints))
};
}

Expand Down Expand Up @@ -117,6 +121,6 @@ export async function getGuildStagePath(guildsApi: GuildsAPI, season_id: number,

return {
current_position: currentPosition,
segments: constructSegments(currentPosition, absolutePoints, topPoints)
segments: constructSegments(currentPosition, absolutePoints, getUniqueTopPoints(topPoints))
};
}
Loading

0 comments on commit 8141cc9

Please sign in to comment.