This repository has been archived on 2023-01-26. You can view files and clone it, but cannot push or open issues or pull requests.
scripts-old/src/extendedMapPopup.js

325 lines
8.8 KiB
JavaScript

import addMinutes from 'date-fns/addMinutes';
import getTranslations from './i18n/extendedMapPopup';
import requestCreator from './libs/requestCreator';
import { formatDate } from './utils/date';
import getCurrentServer from './utils/getCurrentServer';
import { calcDistanceBetweenTwoPoints } from './utils/math';
import buildUnitImgURL from './utils/buildUnitImgURL';
import { setItem, getItem } from './utils/localStorage';
import { calcAttackDuration } from './utils/tribalwars';
import calcLoyalty from './utils/calcLoyalty';
// ==UserScript==
// @name Extended map popup
// @namespace https://github.com/tribalwarshelp/scripts
// @updateURL https://raw.githubusercontent.com/tribalwarshelp/scripts/master/dist/extendedMapPopup.js
// @downloadURL https://raw.githubusercontent.com/tribalwarshelp/scripts/master/dist/extendedMapPopup.js
// @version 0.6.7
// @description Extended map popup
// @author Kichiyaki https://dwysokinski.me/
// @match *://*/game.php*screen=map*
// @grant none
// ==/UserScript==
const SERVER = getCurrentServer();
const CURR_SERVER_CONFIG = `
query server($key: String!) {
server(key: $key) {
config {
speed
unitSpeed
snob {
maxDist
}
}
unitConfig {
spear {
speed
}
sword {
speed
}
axe {
speed
}
archer {
speed
}
spy {
speed
}
light {
speed
}
marcher {
speed
}
heavy {
speed
}
ram {
speed
}
catapult {
speed
}
knight {
speed
}
snob {
speed
}
}
}
}
`;
const LAST_VILLAGE_CONQUER_QUERY = `
query ennoblements($server: String!, $filter: EnnoblementFilter!, $sort: [String!], $limit: Int) {
ennoblements(server: $server, filter: $filter, sort: $sort, limit: $limit) {
items {
ennobledAt
village {
id
}
}
}
}
`;
const SERVER_CONFIG_LOCAL_STORAGE_KEY =
'kiszkowaty_extended_map_popup_server_cfg';
const translations = getTranslations();
const loadConfigFromLocalStorage = () => {
return getItem(SERVER_CONFIG_LOCAL_STORAGE_KEY);
};
const cacheServerConfig = (data = {}) => {
setItem(SERVER_CONFIG_LOCAL_STORAGE_KEY, data);
};
const isConfigExpired = date => {
return Math.abs(date.getTime() - new Date().getTime()) > 1000 * 60 * 60 * 24;
};
const loadConfig = async () => {
let data = loadConfigFromLocalStorage();
if (
!data ||
!data.server ||
isConfigExpired(new Date(data.loadedAt)) ||
!data.server.config ||
!data.server.config.speed ||
!data.server.config.snob ||
!data.server.config.snob.maxDist ||
!data.server.config.unitSpeed ||
!data.server.unitConfig
) {
data = await requestCreator({
query: CURR_SERVER_CONFIG,
variables: {
key: SERVER,
},
});
data.loadedAt = new Date();
cacheServerConfig(data);
}
return data && data.server && data.server.config
? { config: data.server.config, unitConfig: data.server.unitConfig }
: {};
};
const loadVillageData = async (id, { cacheOnly = false } = {}) => {
if (cacheOnly || TWMap.popup.extendedMapPopupCache[id]) {
return TWMap.popup.extendedMapPopupCache[id];
}
try {
const data = await requestCreator({
query: LAST_VILLAGE_CONQUER_QUERY,
variables: {
server: SERVER,
sort: ['ennobledAt DESC'],
filter: {
villageID: [id],
},
limit: 1,
},
});
TWMap.popup.extendedMapPopupCache[id] = data;
return data;
} catch (error) {
console.log('loadVillageData', error);
}
};
const getAvailableUnits = (unitCfg = {}) => {
const units = [];
for (let unit in unitCfg) {
if (unitCfg[unit].speed !== 0) {
units.push({
...unitCfg[unit],
name: unit,
img: buildUnitImgURL(unit),
});
}
}
return units;
};
const getUnitTdBgColor = index => (index % 2 === 0 ? '#f8f4e8' : '#ded3b9;');
const buildUnitHeader = (unit, index) => {
return `
<td style="padding: 2px; background-color: ${getUnitTdBgColor(index)};">
<img
src="${unit.img}"
title="${unit.name}"
alt="${unit.name}"
/>
</td>
`;
};
const buildUnitArrivalInfo = (t, index) => {
return `
<td style="padding: 2px; background-color: ${getUnitTdBgColor(index)};">
${formatDate(addMinutes(Timing.getCurrentServerTime(), t))}
</td>
`;
};
const renderAdditionalInfo = (id, data, { config, unitConfig }) => {
const coords = TWMap.CoordByXY(TWMap.villageKey[id]);
const distance = calcDistanceBetweenTwoPoints(
coords[0],
coords[1],
window.game_data.village.x,
window.game_data.village.y
);
const ennoblement =
data &&
data.ennoblements &&
data.ennoblements.items &&
data.ennoblements.items.length > 0
? data.ennoblements.items[0]
: undefined;
const parent = document.querySelector('#map_popup #info_content tbody');
let unitsEl = parent.querySelector('#units');
if (!unitsEl) {
unitsEl = document.createElement('tr');
unitsEl.id = 'units';
parent.appendChild(unitsEl);
}
const units = getAvailableUnits(unitConfig);
unitsEl.innerHTML = `
<td colspan="2">
<table style="border: 1px solid #ded3b9; max-width: 450px;"
width="100%"
cellpadding="0"
cellspacing="0">
<tbody>
<tr class="center">
${units.map(buildUnitHeader).join('')}
</tr>
<tr class="center">
${units
.map((unit, index) => {
return buildUnitArrivalInfo(
calcAttackDuration(distance, unit.speed),
index
);
})
.join('')}
</tr>
</tbody>
</table>
</td>
`;
let lastEnnobledAt = parent.querySelector('#lastEnnobledAt');
if (!lastEnnobledAt) {
lastEnnobledAt = document.createElement('tr');
lastEnnobledAt.id = 'lastEnnobledAt';
parent.appendChild(lastEnnobledAt);
}
lastEnnobledAt.innerHTML = `
<td>
${translations.ennobledAt}:
</td>
<td>
${
ennoblement
? formatDate(ennoblement.ennobledAt)
: translations.never
}
</td>
`;
let loyalty = parent.querySelector('#loyalty');
if (!loyalty) {
loyalty = document.createElement('tr');
loyalty.id = 'loyalty';
parent.appendChild(loyalty);
}
loyalty.innerHTML = `
<td>
${translations.possibleLoyalty}:
</td>
<td>
${
ennoblement
? calcLoyalty(new Date(ennoblement.ennobledAt), config.speed)
: 100
}
</td>
`;
let canSendNoble = parent.querySelector('#canSendNoble');
if (!canSendNoble) {
canSendNoble = document.createElement('tr');
canSendNoble.id = 'canSendNoble';
parent.appendChild(canSendNoble);
}
canSendNoble.innerHTML = `
<td>
${translations.canSendNoble}:
</td>
<td>
${
distance < config.snob.maxDist
? translations.yes
: translations.no
}
</td>
`;
};
const createLoadVillageHandler = cfg => async e => {
TWMap.popup._loadVillage(e);
const data = await loadVillageData(parseInt(e));
renderAdditionalInfo(parseInt(e), data, cfg);
};
const createDisplayForVillageHandler = cfg => async (e, a, t) => {
TWMap.popup._displayForVillage(e, a, t);
const data = await loadVillageData(parseInt(e.id), {
cacheOnly: window.game_data.features.Premium.active,
});
renderAdditionalInfo(parseInt(e.id), data, cfg);
};
(async function () {
try {
const configs = await loadConfig();
TWMap.popup.extendedMapPopupCache = {};
TWMap.popup._loadVillage = TWMap.popup.loadVillage;
TWMap.popup.loadVillage = createLoadVillageHandler(configs);
TWMap.popup._displayForVillage = TWMap.popup.displayForVillage;
TWMap.popup.displayForVillage = createDisplayForVillageHandler(configs);
} catch (error) {
console.log('extended map popup', error);
}
})();