feat: extended map popup
This commit is contained in:
parent
23fe731ced
commit
fafbf587da
|
@ -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*
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue