feat: extended map popup

This commit is contained in:
Dawid Wysokiński 2023-02-03 14:09:43 +01:00
parent 23fe731ced
commit fafbf587da
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
5 changed files with 156 additions and 17 deletions

View File

@ -1,7 +1,7 @@
const preambles = {
'extended-player-profile': `// ==UserScript==
// @name Extended player profile
// @version 1.1.0
// @version 1.1.1
// @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*

View File

@ -1,9 +1,32 @@
import differenceInSeconds from 'date-fns/differenceInSeconds';
import { TWHelpClient } from './lib/twhelp';
import addSeconds from 'date-fns/addSeconds';
import { ServerConfig, TWHelpClient, UnitInfo } from './lib/twhelp';
declare global {
interface Window {
TWMap: {
popup: {
loadVillage: (villageId: string) => void;
_loadVillage: (villageId: string) => void;
displayForVillage: (
village: { id: string },
x: number,
y: number
) => void;
_displayForVillage: (
village: { id: string },
x: number,
y: number
) => void;
};
};
}
}
class TWHelpConnector {
private static readonly SERVER_CONFIG_LOCAL_STORAGE_KEY =
'kichiyaki_server_config';
private static readonly SERVER_CONFIG_CACHE_KEY =
'extended_map_popup_server_config';
private static readonly UNIT_INFO_CACHE_KEY = 'extended_map_popup_unit_info';
constructor(
private readonly client: TWHelpClient,
@ -12,13 +35,15 @@ class TWHelpConnector {
) {}
serverConfig() {
return this.withCache(
TWHelpConnector.SERVER_CONFIG_LOCAL_STORAGE_KEY,
3600,
() => {
return this.client.serverConfig(this.version, this.server);
}
);
return this.withCache(TWHelpConnector.SERVER_CONFIG_CACHE_KEY, 3600, () => {
return this.client.serverConfig(this.version, this.server);
});
}
unitInfo() {
return this.withCache(TWHelpConnector.UNIT_INFO_CACHE_KEY, 3600, () => {
return this.client.unitInfo(this.version, this.server);
});
}
private async withCache<T>(
@ -51,6 +76,80 @@ class TWHelpConnector {
}
}
class Popup {
constructor(
private readonly config: ServerConfig,
private readonly unitInfo: UnitInfo,
private readonly currentVillage: Window['game_data']['village'],
private readonly connector: TWHelpConnector
) {}
addHandlers() {
window.TWMap.popup._loadVillage = window.TWMap.popup.loadVillage;
window.TWMap.popup.loadVillage = this.loadVillage.bind(this);
window.TWMap.popup._displayForVillage =
window.TWMap.popup.displayForVillage;
window.TWMap.popup.displayForVillage = this.display.bind(this);
}
private loadVillage(villageId: string) {
window.TWMap.popup._loadVillage(villageId);
console.log(villageId);
}
private display(village: { id: string }, x: number, y: number) {
window.TWMap.popup._displayForVillage(village, x, y);
this.displayArrivalTimes(x, y);
}
private displayArrivalTimes(x: number, y: number) {
const dist = Math.hypot(
x - this.currentVillage.x,
y - this.currentVillage.y
);
const imgs = document.querySelectorAll(
'#map_popup #info_content tbody img[src*="unit/unit_"]'
);
if (imgs.length === 0) {
return;
}
const tbody = imgs[0].closest('tbody');
if (!(tbody instanceof HTMLTableSectionElement)) {
return;
}
const tr = document.createElement('tr');
tr.classList.add('center');
imgs.forEach((img, idx) => {
if (!(img instanceof HTMLImageElement)) {
return;
}
for (const [unit, config] of Object.entries(this.unitInfo)) {
if (!img.src.includes(unit)) {
continue;
}
const td = document.createElement('td');
td.style.padding = '2px';
td.style.backgroundColor = idx % 2 === 0 ? '#F8F4E8' : '#DED3B9';
td.style.maxWidth = '70px';
td.innerText = addSeconds(
window.Timing.getCurrentServerTime(),
Math.round(dist * config.speed * 60)
).toLocaleString();
tr.appendChild(td);
break;
}
});
tbody.appendChild(tr);
}
}
class ExtendedMapPopup {
connector: TWHelpConnector;
constructor(client: TWHelpClient) {
@ -63,7 +162,15 @@ class ExtendedMapPopup {
async run() {
const config = await this.connector.serverConfig();
console.log(config);
const unitInfo = await this.connector.unitInfo();
console.log(config, unitInfo);
new Popup(
config,
unitInfo,
window.game_data.village,
this.connector
).addHandlers();
}
}

View File

@ -119,11 +119,11 @@ 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',
HISTORY = 'kichiyaki_history',
OTHER_SERVERS = 'extended_player_profile_other_servers',
IN_A_DAY_RANKS = 'extended_player_profile_in_a_day_ranks',
TRIBE_CHANGES = 'extended_player_profile_tribe_changes',
ENNOBLEMENTS = 'extended_player_profile_ennoblements',
HISTORY = 'extended_player_profile_history',
}
class UI {

5
src/global.d.ts vendored
View File

@ -10,6 +10,8 @@ declare global {
};
village: {
id: number;
x: number;
y: number;
};
market: string;
locale: string;
@ -33,5 +35,8 @@ declare global {
show: (id: string, html: string) => void;
close: () => void;
};
Timing: {
getCurrentServerTime: () => number;
};
}
}

View File

@ -108,6 +108,26 @@ export type ServerConfig = {
};
};
export type Unit = {
speed: number;
};
export type UnitInfo = {
archer: Unit;
axe: Unit;
catapult: Unit;
heavy: Unit;
knight: Unit;
light: Unit;
marcher: Unit;
militia: Unit;
ram: Unit;
snob: Unit;
spear: Unit;
spy: Unit;
sword: Unit;
};
export type ListResult<T> = {
data: T[];
total: number;
@ -164,6 +184,13 @@ export class TWHelpClient {
return resp.data.data;
}
public async unitInfo(version: string, server: string): Promise<UnitInfo> {
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/unit-info`
);
return resp.data.data;
}
public async player(
version: string,
server: string,