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

Feature: Auth token usage + Region Lock #121

Merged
merged 7 commits into from
Oct 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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