feat: extended-player-profile - add a new action 'Show other servers'
continuous-integration/drone/tag Build is passing
Details
continuous-integration/drone/tag Build is passing
Details
This commit is contained in:
parent
11c95967d9
commit
8cd531ed8b
|
@ -1,7 +1,7 @@
|
|||
const preambles = {
|
||||
'extended-player-profile': `// ==UserScript==
|
||||
// @name Extended player profile
|
||||
// @version 1.0.2
|
||||
// @version 1.1.0
|
||||
// @description Adds additional info and actions to a player's profile.
|
||||
// @author Dawid Wysokiński - Kichiyaki - contact@dwysokinski.me
|
||||
// @match https://*/game.php?*screen=info_player*
|
||||
|
|
|
@ -4,14 +4,16 @@ import { Player, PlayerSnapshot, TWHelpClient } from './lib/twhelp';
|
|||
import { DialogTable } from './common/dialog-table';
|
||||
import { InADayClient } from './lib/tw';
|
||||
import { createTranslationFunc } from './utils';
|
||||
import { buildURL } from './lib/twstats';
|
||||
|
||||
const t = createTranslationFunc({
|
||||
pl_PL: {
|
||||
'Joined at': 'Dołączył o',
|
||||
'Last activity at': 'Ostatnio aktywny o',
|
||||
'Best rank': 'Najlepszy ranking',
|
||||
'Best rank': 'Najwyższy ranking',
|
||||
'Most points': 'Najwięcej punktów',
|
||||
'Most villages': 'Najwięcej wiosek',
|
||||
'Show other servers': 'Pokaż inne serwery',
|
||||
'Show in a day ranks': 'Pokaż dzienne rankingi',
|
||||
'Show tribe changes': 'Pokaż zmiany plemion',
|
||||
'Show history': 'Pokaż historię',
|
||||
|
@ -51,6 +53,8 @@ const t = createTranslationFunc({
|
|||
'Resources gathered': 'Zebrane surowce',
|
||||
'Villages conquered': 'Przejęte wioski',
|
||||
Changes: 'Zmiany',
|
||||
Open: 'Otwarty',
|
||||
Closed: 'Zamknięty',
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -94,6 +98,13 @@ class TWHelpConnector {
|
|||
sort: ['date:desc'],
|
||||
});
|
||||
}
|
||||
|
||||
playerOtherServers(page: number, limit: number) {
|
||||
return this.client.playerOtherServers(this.version, this.server, this.id, {
|
||||
offset: (page - 1) * limit,
|
||||
limit,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class InADayConnector {
|
||||
|
@ -108,6 +119,7 @@ class InADayConnector {
|
|||
}
|
||||
|
||||
enum DialogId {
|
||||
OTHER_SERVERS = 'kichiyaki_other_servers',
|
||||
IN_A_DAY_RANKS = 'kichiyaki_in_a_day_ranks',
|
||||
TRIBE_CHANGES = 'kichiyaki_tribe_changes',
|
||||
ENNOBLEMENTS = 'kichiyaki_ennoblements',
|
||||
|
@ -276,6 +288,10 @@ class UI {
|
|||
}
|
||||
|
||||
[
|
||||
{
|
||||
name: t('Show other servers'),
|
||||
handler: this.showOtherServers.bind(this),
|
||||
},
|
||||
{
|
||||
name: t('Show in a day ranks'),
|
||||
handler: this.showInADayRanks.bind(this),
|
||||
|
@ -304,6 +320,57 @@ class UI {
|
|||
});
|
||||
}
|
||||
|
||||
private async showOtherServers(e: Event) {
|
||||
e.preventDefault();
|
||||
|
||||
await new DialogTable(
|
||||
DialogId.OTHER_SERVERS,
|
||||
[
|
||||
{
|
||||
header: t('Server'),
|
||||
accessor: (p) =>
|
||||
`<a href="${buildURL({
|
||||
server: p.server.key,
|
||||
id: p.id,
|
||||
entity: 'player',
|
||||
})}">${p.server.key} (${
|
||||
p.server.open ? t('Open') : t('Closed')
|
||||
})</a>`,
|
||||
},
|
||||
{
|
||||
header: t('Tribe'),
|
||||
accessor: (p) => {
|
||||
if (!p.tribe) {
|
||||
return '-';
|
||||
}
|
||||
const url = buildURL({
|
||||
server: p.server.key,
|
||||
id: p.tribe.id,
|
||||
entity: 'tribe',
|
||||
});
|
||||
return `<a href="${url}">${p.tribe.tag}</a>`;
|
||||
},
|
||||
},
|
||||
{
|
||||
header: t('Best rank'),
|
||||
accessor: (p) => p.bestRank.toString(),
|
||||
},
|
||||
{
|
||||
header: t('Most points'),
|
||||
accessor: (p) => p.mostPoints.toLocaleString(),
|
||||
},
|
||||
{
|
||||
header: t('Most villages'),
|
||||
accessor: (p) => p.mostVillages.toLocaleString(),
|
||||
},
|
||||
],
|
||||
30,
|
||||
(page: number, limit: number) => {
|
||||
return this.twhelpConnector.playerOtherServers(page, limit);
|
||||
}
|
||||
).render();
|
||||
}
|
||||
|
||||
private async showInADayRanks(e: Event) {
|
||||
e.preventDefault();
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ import axios, { AxiosInstance } from 'axios';
|
|||
import random from 'lodash/random';
|
||||
import { wait } from '../utils';
|
||||
|
||||
const DEFAULT_TIMEOUT = 10000;
|
||||
|
||||
type InADayScore = {
|
||||
player: {
|
||||
id: number;
|
||||
|
@ -128,9 +126,9 @@ export type InADayPlayer = {
|
|||
|
||||
export class InADayClient {
|
||||
client: AxiosInstance;
|
||||
constructor(timeout?: number) {
|
||||
constructor(timeout: number = 10000) {
|
||||
this.client = axios.create({
|
||||
timeout: timeout ?? DEFAULT_TIMEOUT,
|
||||
timeout,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import axios, { AxiosInstance } from 'axios';
|
||||
|
||||
const DEFAULT_TIMEOUT = 10000;
|
||||
const X_TOTAL_COUNT_HEADER = 'x-total-count';
|
||||
import axios, {
|
||||
AxiosInstance,
|
||||
AxiosResponseHeaders,
|
||||
RawAxiosResponseHeaders,
|
||||
} from 'axios';
|
||||
|
||||
export type Version = {
|
||||
code: string;
|
||||
|
@ -10,6 +11,18 @@ export type Version = {
|
|||
timezone: string;
|
||||
};
|
||||
|
||||
export type ServerMeta = {
|
||||
key: string;
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
export type TribeMeta = {
|
||||
id: number;
|
||||
name: string;
|
||||
tag: string;
|
||||
profileUrl: string;
|
||||
};
|
||||
|
||||
export type Player = {
|
||||
id: number;
|
||||
points: number;
|
||||
|
@ -31,13 +44,11 @@ export type Player = {
|
|||
mostVillagesAt: string;
|
||||
lastActivityAt: string;
|
||||
createdAt: string;
|
||||
tribe: TribeMeta | null;
|
||||
};
|
||||
|
||||
export type TribeMeta = {
|
||||
id: number;
|
||||
name: string;
|
||||
tag: string;
|
||||
profileUrl: string;
|
||||
export type PlayerWithServer = Player & {
|
||||
server: ServerMeta;
|
||||
};
|
||||
|
||||
export type PlayerMeta = {
|
||||
|
@ -112,13 +123,18 @@ export type ListPlayerSnapshotsParams = {
|
|||
sort?: string[];
|
||||
};
|
||||
|
||||
export type ListPlayerOtherServersParams = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
};
|
||||
|
||||
export class TWHelpClient {
|
||||
client: AxiosInstance;
|
||||
|
||||
constructor(url: string, timeout?: number) {
|
||||
constructor(url: string, timeout: number = 10000) {
|
||||
this.client = axios.create({
|
||||
baseURL: url,
|
||||
timeout: timeout ?? DEFAULT_TIMEOUT,
|
||||
timeout,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -126,7 +142,7 @@ export class TWHelpClient {
|
|||
const resp = await this.client.get('/api/v1/versions');
|
||||
return {
|
||||
data: resp.data.data,
|
||||
total: parseInt(resp.headers[X_TOTAL_COUNT_HEADER] ?? '0'),
|
||||
total: this.parseTotal(resp.headers),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -168,7 +184,7 @@ export class TWHelpClient {
|
|||
);
|
||||
return {
|
||||
data: resp.data.data,
|
||||
total: parseInt(resp.headers[X_TOTAL_COUNT_HEADER] ?? '0'),
|
||||
total: this.parseTotal(resp.headers),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -199,7 +215,7 @@ export class TWHelpClient {
|
|||
);
|
||||
return {
|
||||
data: resp.data.data,
|
||||
total: parseInt(resp.headers[X_TOTAL_COUNT_HEADER] ?? '0'),
|
||||
total: this.parseTotal(resp.headers),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -230,7 +246,38 @@ export class TWHelpClient {
|
|||
);
|
||||
return {
|
||||
data: resp.data.data,
|
||||
total: parseInt(resp.headers[X_TOTAL_COUNT_HEADER] ?? '0'),
|
||||
total: this.parseTotal(resp.headers),
|
||||
};
|
||||
}
|
||||
|
||||
public async playerOtherServers(
|
||||
version: string,
|
||||
server: string,
|
||||
id: number,
|
||||
queryParams?: ListPlayerOtherServersParams
|
||||
): Promise<ListResult<PlayerWithServer>> {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (queryParams?.limit) {
|
||||
params.set('limit', queryParams.limit.toString());
|
||||
}
|
||||
|
||||
if (queryParams?.offset) {
|
||||
params.set('offset', queryParams.offset.toString());
|
||||
}
|
||||
|
||||
const resp = await this.client.get(
|
||||
`/api/v1/versions/${version}/servers/${server}/players/${id}/other-servers?${params.toString()}`
|
||||
);
|
||||
return {
|
||||
data: resp.data.data,
|
||||
total: this.parseTotal(resp.headers),
|
||||
};
|
||||
}
|
||||
|
||||
private parseTotal(
|
||||
headers: RawAxiosResponseHeaders | AxiosResponseHeaders
|
||||
): number {
|
||||
return parseInt(headers['x-total-count'] ?? '0');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
const BASE = 'https://www.twstats.com';
|
||||
|
||||
export type BuildURLParams =
|
||||
| {
|
||||
entity: 'player';
|
||||
id: number;
|
||||
server: string;
|
||||
}
|
||||
| {
|
||||
entity: 'tribe';
|
||||
id: number;
|
||||
server: string;
|
||||
};
|
||||
|
||||
export const buildURL = (params: BuildURLParams) => {
|
||||
switch (params.entity) {
|
||||
case 'player':
|
||||
return `${BASE}/in/${params.server}/player/${params.id}`;
|
||||
case 'tribe':
|
||||
return `${BASE}/in/${params.server}/tribe/${params.id}`;
|
||||
default:
|
||||
throw new Error(`Incorrect params.entity`);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue