Greasy Fork is available in English.
Headless TankTrouble max performance optimizer with effect and server selection tweaks
// ==UserScript==
// @name TT Performance Optimizer
// @namespace http://tanktrouble.com/
// @version 3.0.0
// @description Headless TankTrouble max performance optimizer with effect and server selection tweaks
// @author Aurelion-X9
// @match *://tanktrouble.com/*
// @match *://*.tanktrouble.com/*
// @grant unsafeWindow
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
const win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
const ROOT_TRIM_CLASS = 'tt-po-trim';
const APPLY_INTERVAL_MS = 1000;
const SERVER_REFRESH_INTERVAL_MS = 12000;
const AUTO_SWITCH_COOLDOWN_MS = 30000;
const COOKIE_DAYS = 365;
const PROFILE_CONFIGS = {
balanced: {
label: 'Balanced',
desiredFps: 120,
disableSystemMessages: false,
effectMode: 'reduced',
quality: {
tankExplosionSmokeCount: 1,
tankExplosionFragmentCount: 1,
missileLaunchSmokeCount: 0,
missileSmokeFrequency: 9999,
mineExplosionSmokeCount: 1,
crateLandDustCount: 0,
aimerMinSegmentLength: 2,
aimerOffMaxSegmentLength: 12,
aimerOnMaxSegmentLength: 6,
bulletPuffCount: 0,
shieldInverseBoltProbability: 1,
shieldSparkParticlesPerEmit: 0,
spawnZoneInverseUnstableParticleProbability: 1,
spawnZoneNumCollapseParticles: 0
},
ui: {
MAX_CAMERA_SHAKE: 0,
MINE_EXPLOSION_CAMERA_SHAKE: 0,
TANK_EXPLOSION_CAMERA_SHAKE: 0,
TANK_FEATHER_COUNT: 0,
TANK_FEATHER_POOL_SIZE: 0,
MAX_SCORE_FRAGMENTS_PER_EXPLOSION: 0,
MIN_SCORE_FRAGMENTS_PER_LETTER: 0,
GOLD_SPARKLE_MAX_INTERVAL_TIME: 6000,
GOLD_SPARKLE_MIN_INTERVAL_TIME: 4000,
DIAMOND_SPARKLE_MAX_INTERVAL_TIME: 6000,
DIAMOND_SPARKLE_MIN_INTERVAL_TIME: 4000,
RUBBLE_FRAGMENT_POOL_SIZE: 0,
SHIELD_NUM_BOLTS: 0,
SHIELD_SPARK_BOLT_POOL_SIZE: 0,
BULLET_PUFF_POOL_SIZE: 0,
GAME_ICON_COUNT: 4,
DISABLE_TANK_BADGES: true
}
},
aggressive: {
label: 'Aggressive',
desiredFps: 165,
disableSystemMessages: true,
effectMode: 'off',
quality: {
tankExplosionSmokeCount: 0,
tankExplosionFragmentCount: 0,
missileLaunchSmokeCount: 0,
missileSmokeFrequency: 999999,
mineExplosionSmokeCount: 0,
crateLandDustCount: 0,
aimerMinSegmentLength: 0,
aimerOffMaxSegmentLength: 10,
aimerOnMaxSegmentLength: 5,
bulletPuffCount: 0,
shieldInverseBoltProbability: 1,
shieldSparkParticlesPerEmit: 0,
spawnZoneInverseUnstableParticleProbability: 1,
spawnZoneNumCollapseParticles: 0
},
ui: {
MAX_CAMERA_SHAKE: 0,
MINE_EXPLOSION_CAMERA_SHAKE: 0,
TANK_EXPLOSION_CAMERA_SHAKE: 0,
TANK_FEATHER_COUNT: 0,
TANK_FEATHER_POOL_SIZE: 0,
MAX_SCORE_FRAGMENTS_PER_EXPLOSION: 0,
MIN_SCORE_FRAGMENTS_PER_LETTER: 0,
GOLD_SPARKLE_MAX_INTERVAL_TIME: 999999,
GOLD_SPARKLE_MIN_INTERVAL_TIME: 999999,
DIAMOND_SPARKLE_MAX_INTERVAL_TIME: 999999,
DIAMOND_SPARKLE_MIN_INTERVAL_TIME: 999999,
RUBBLE_FRAGMENT_POOL_SIZE: 0,
RUBBLE_FRAGMENT_MAX_LIFETIME: 0,
RUBBLE_FRAGMENT_MIN_LIFETIME: 0,
RUBBLE_FRAGMENT_MAX_ROTATION_SPEED: 0,
RUBBLE_FRAGMENT_SPEED_SCALE: 0,
RUBBLE_FRAGMENT_RANDOM_SPEED: 0,
RUBBLE_SMOKE_SPEED_SCALE: 0,
RUBBLE_SMOKE_RANDOM_SPEED: 0,
INVERSE_RUBBLE_SPAWN_PROBABILITY_IN_COLLISION: 999999,
INVERSE_RUBBLE_SPAWN_PROBABILITY_IN_THE_OPEN: 999999,
SHIELD_NUM_BOLTS: 0,
SHIELD_SPARK_BOLT_POOL_SIZE: 0,
BULLET_PUFF_POOL_SIZE: 0,
MUZZLE_FLASH_DURATION: 0,
BULLET_TRAIL_LENGTH: 0,
BULLET_TRAIL_OPACITY: 0,
GAME_ICON_COUNT: 4,
DISABLE_TANK_BADGES: true
}
},
max: {
label: 'Max',
desiredFps: 240,
disableSystemMessages: true,
effectMode: 'off',
quality: {
tankExplosionSmokeCount: 0,
tankExplosionFragmentCount: 0,
missileLaunchSmokeCount: 0,
missileSmokeFrequency: 999999,
mineExplosionSmokeCount: 0,
crateLandDustCount: 0,
aimerMinSegmentLength: 0,
aimerOffMaxSegmentLength: 8,
aimerOnMaxSegmentLength: 4,
bulletPuffCount: 0,
shieldInverseBoltProbability: 1,
shieldSparkParticlesPerEmit: 0,
spawnZoneInverseUnstableParticleProbability: 1,
spawnZoneNumCollapseParticles: 0
},
ui: {
MAX_CAMERA_SHAKE: 0,
MINE_EXPLOSION_CAMERA_SHAKE: 0,
TANK_EXPLOSION_CAMERA_SHAKE: 0,
TANK_FEATHER_COUNT: 0,
TANK_FEATHER_POOL_SIZE: 0,
MAX_SCORE_FRAGMENTS_PER_EXPLOSION: 0,
MIN_SCORE_FRAGMENTS_PER_LETTER: 0,
GOLD_SPARKLE_MAX_INTERVAL_TIME: 999999,
GOLD_SPARKLE_MIN_INTERVAL_TIME: 999999,
DIAMOND_SPARKLE_MAX_INTERVAL_TIME: 999999,
DIAMOND_SPARKLE_MIN_INTERVAL_TIME: 999999,
RUBBLE_FRAGMENT_POOL_SIZE: 0,
RUBBLE_FRAGMENT_MAX_LIFETIME: 0,
RUBBLE_FRAGMENT_MIN_LIFETIME: 0,
RUBBLE_FRAGMENT_MAX_ROTATION_SPEED: 0,
RUBBLE_FRAGMENT_SPEED_SCALE: 0,
RUBBLE_FRAGMENT_RANDOM_SPEED: 0,
RUBBLE_SMOKE_SPEED_SCALE: 0,
RUBBLE_SMOKE_RANDOM_SPEED: 0,
INVERSE_RUBBLE_SPAWN_PROBABILITY_IN_COLLISION: 999999,
INVERSE_RUBBLE_SPAWN_PROBABILITY_IN_THE_OPEN: 999999,
SHIELD_NUM_BOLTS: 0,
SHIELD_SPARK_BOLT_POOL_SIZE: 0,
BULLET_PUFF_POOL_SIZE: 0,
MUZZLE_FLASH_DURATION: 0,
BULLET_TRAIL_LENGTH: 0,
BULLET_TRAIL_OPACITY: 0,
GAME_ICON_COUNT: 4,
DISABLE_TANK_BADGES: true
}
}
};
const state = {
enabled: true,
profile: 'max',
trimPage: true,
autoBestServer: true
};
const runtime = {
originalCookies: null,
originalUiConstants: new Map(),
originalQualityValues: new Map(),
originalGameValues: new WeakMap(),
originalChatSystemMessage: null,
currentStatus: 'Waiting for TankTrouble runtime...',
bestServer: null,
currentServerLatency: null,
serverRefreshBusy: false,
lastAutoSwitchAt: 0,
rafSamples: [],
patchedEmitters: new Set()
};
function getProfile() {
return PROFILE_CONFIGS[state.profile] || PROFILE_CONFIGS.max;
}
function setStatus(message) {
runtime.currentStatus = String(message || '');
try {
console.debug('[TT Optimizer]', runtime.currentStatus);
} catch (error) {}
}
function setCookie(name, value) {
const expires = new Date(Date.now() + COOKIE_DAYS * 24 * 60 * 60 * 1000).toUTCString();
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; SameSite=Lax`;
}
function removeCookie(name) {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; SameSite=Lax`;
}
function getCookie(name) {
const parts = (`; ${document.cookie}`).split(`; ${name}=`);
if (parts.length < 2) {
return null;
}
return decodeURIComponent(parts.pop().split(';').shift());
}
function snapshotOriginalCookies() {
if (runtime.originalCookies) {
return;
}
runtime.originalCookies = {
quality: getCookie('quality'),
cameraShake: getCookie('cameraShake'),
tankBadges: getCookie('tankBadges'),
systemMessages: getCookie('systemMessages'),
displayAllGames: getCookie('displayAllGames')
};
}
function restoreOriginalCookies() {
if (!runtime.originalCookies) {
return;
}
for (const [key, value] of Object.entries(runtime.originalCookies)) {
if (value === null || value === undefined || value === '') {
removeCookie(key);
} else {
setCookie(key, value);
}
}
}
function getGame() {
try {
return typeof win.GameManager !== 'undefined' && typeof win.GameManager.getGame === 'function'
? win.GameManager.getGame()
: null;
} catch (error) {
return null;
}
}
function getGameController() {
try {
return typeof win.GameManager !== 'undefined' && typeof win.GameManager.getGameController === 'function'
? win.GameManager.getGameController()
: null;
} catch (error) {
return null;
}
}
function getLocalPlayerId() {
try {
if (typeof win.ClientManager !== 'undefined' && typeof win.ClientManager.getClient === 'function') {
const client = win.ClientManager.getClient();
if (client) {
const playerId = typeof client.getPlayerId === 'function' ? client.getPlayerId() : client.playerId;
if (playerId !== undefined && playerId !== null) {
return String(playerId);
}
}
}
} catch (error) {}
return '';
}
function isActiveMatchLikely() {
try {
const controller = getGameController();
const playerId = getLocalPlayerId();
if (!controller || !playerId || typeof controller.getTank !== 'function') {
return false;
}
return Boolean(controller.getTank(playerId));
} catch (error) {
return false;
}
}
function getCurrentServerId() {
try {
if (typeof win.Cookies !== 'undefined' && typeof win.Cookies.get === 'function') {
const cookieServer = win.Cookies.get('multiplayerserverid');
if (cookieServer) {
return String(cookieServer);
}
}
} catch (error) {}
try {
if (typeof win.ClientManager !== 'undefined' && typeof win.ClientManager.getSelectedServer === 'function') {
const selected = win.ClientManager.getSelectedServer();
if (selected !== undefined && selected !== null) {
return String(selected);
}
}
} catch (error) {}
return getCookie('multiplayerserverid');
}
function getServerName(serverId) {
try {
if (typeof win.ClientManager !== 'undefined' && typeof win.ClientManager.getAvailableServers === 'function') {
const servers = win.ClientManager.getAvailableServers();
const match = servers && serverId !== null && serverId !== undefined ? servers[serverId] : null;
if (match && match.name) {
return String(match.name);
}
}
} catch (error) {}
return serverId ? String(serverId) : 'Unknown';
}
function rememberOriginalUiConstant(key) {
if (runtime.originalUiConstants.has(key)) {
return;
}
if (typeof win.UIConstants === 'undefined' || !(key in win.UIConstants)) {
return;
}
runtime.originalUiConstants.set(key, win.UIConstants[key]);
}
function applyUiConstants(profile) {
if (typeof win.UIConstants === 'undefined') {
return false;
}
for (const [key, value] of Object.entries(profile.ui)) {
if (!(key in win.UIConstants)) {
continue;
}
rememberOriginalUiConstant(key);
try {
win.UIConstants[key] = value;
} catch (error) {}
}
return true;
}
function restoreUiConstants() {
if (typeof win.UIConstants === 'undefined') {
return;
}
for (const [key, value] of runtime.originalUiConstants.entries()) {
try {
win.UIConstants[key] = value;
} catch (error) {}
}
}
function rememberOriginalQualityValue(level, key, value) {
const mapKey = `${level}:${key}`;
if (!runtime.originalQualityValues.has(mapKey)) {
runtime.originalQualityValues.set(mapKey, value);
}
}
function applyQualityValues(profile) {
if (typeof win.QualityManager === 'undefined' || !win.QualityManager.QUALITY_VALUES) {
return false;
}
for (const [level, values] of Object.entries(win.QualityManager.QUALITY_VALUES)) {
if (!values || typeof values !== 'object') {
continue;
}
for (const [key, value] of Object.entries(profile.quality)) {
if (!(key in values)) {
continue;
}
rememberOriginalQualityValue(level, key, values[key]);
try {
values[key] = value;
} catch (error) {}
}
}
if (typeof win.QualityManager.setQuality === 'function') {
try {
win.QualityManager.setQuality('low');
} catch (error) {}
}
return true;
}
function restoreQualityValues() {
if (typeof win.QualityManager === 'undefined' || !win.QualityManager.QUALITY_VALUES) {
return;
}
for (const [mapKey, value] of runtime.originalQualityValues.entries()) {
const [level, key] = mapKey.split(':');
if (!win.QualityManager.QUALITY_VALUES[level]) {
continue;
}
try {
win.QualityManager.QUALITY_VALUES[level][key] = value;
} catch (error) {}
}
}
function rememberOriginalGameValues(game) {
if (!game || runtime.originalGameValues.has(game)) {
return;
}
runtime.originalGameValues.set(game, {
antialias: game.antialias,
clearBeforeRender: game.clearBeforeRender,
stageSmoothed: game.stage ? game.stage.smoothed : undefined,
rendererClearBeforeRender: game.renderer ? game.renderer.clearBeforeRender : undefined,
rendererRoundPixels: game.renderer ? game.renderer.roundPixels : undefined,
renderSessionRoundPixels: game.renderer && game.renderer.renderSession ? game.renderer.renderSession.roundPixels : undefined,
desiredFps: game.time ? game.time.desiredFps : undefined,
advancedTiming: game.time ? game.time.advancedTiming : undefined,
slowMotion: game.time ? game.time.slowMotion : undefined,
imageRendering: game.canvas && game.canvas.style ? game.canvas.style.imageRendering : ''
});
}
function applyGameFlags(profile) {
const game = getGame();
if (!game) {
return false;
}
rememberOriginalGameValues(game);
try {
game.antialias = false;
game.clearBeforeRender = true;
if (game.stage) {
game.stage.smoothed = false;
}
if (game.renderer) {
if ('clearBeforeRender' in game.renderer) {
game.renderer.clearBeforeRender = true;
}
}
if (game.time) {
game.time.advancedTiming = true;
game.time.desiredFps = Math.max(Number(game.time.desiredFps) || 0, profile.desiredFps);
if (typeof game.time.slowMotion === 'number') {
game.time.slowMotion = 1;
}
}
if (game.canvas && game.canvas.style) {
game.canvas.style.imageRendering = 'auto';
}
} catch (error) {}
return true;
}
function restoreGameFlags() {
const game = getGame();
if (!game) {
return;
}
const original = runtime.originalGameValues.get(game);
if (!original) {
return;
}
try {
game.antialias = original.antialias;
game.clearBeforeRender = original.clearBeforeRender;
if (game.stage && original.stageSmoothed !== undefined) {
game.stage.smoothed = original.stageSmoothed;
}
if (game.renderer) {
if ('clearBeforeRender' in game.renderer && original.rendererClearBeforeRender !== undefined) {
game.renderer.clearBeforeRender = original.rendererClearBeforeRender;
}
if ('roundPixels' in game.renderer && original.rendererRoundPixels !== undefined) {
game.renderer.roundPixels = original.rendererRoundPixels;
}
if (game.renderer.renderSession && original.renderSessionRoundPixels !== undefined) {
game.renderer.renderSession.roundPixels = original.renderSessionRoundPixels;
}
}
if (game.time) {
if (original.desiredFps !== undefined) {
game.time.desiredFps = original.desiredFps;
}
if (original.advancedTiming !== undefined) {
game.time.advancedTiming = original.advancedTiming;
}
if (original.slowMotion !== undefined) {
game.time.slowMotion = original.slowMotion;
}
}
if (game.canvas && game.canvas.style) {
game.canvas.style.imageRendering = original.imageRendering || '';
}
} catch (error) {}
}
function applySystemMessageMode(profile) {
if (!win.TankTrouble || !win.TankTrouble.ChatBox) {
return;
}
if (!runtime.originalChatSystemMessage && typeof win.TankTrouble.ChatBox.addSystemMessage === 'function') {
runtime.originalChatSystemMessage = win.TankTrouble.ChatBox.addSystemMessage;
}
if (profile.disableSystemMessages) {
win.TankTrouble.ChatBox.addSystemMessage = function() {};
} else if (runtime.originalChatSystemMessage) {
win.TankTrouble.ChatBox.addSystemMessage = runtime.originalChatSystemMessage;
}
}
function restoreSystemMessages() {
if (win.TankTrouble && win.TankTrouble.ChatBox && runtime.originalChatSystemMessage) {
win.TankTrouble.ChatBox.addSystemMessage = runtime.originalChatSystemMessage;
}
}
function applyCookiesForProfile(profile) {
snapshotOriginalCookies();
setCookie('quality', 'low');
if (profile.disableSystemMessages) {
setCookie('systemMessages', 'true');
} else {
removeCookie('systemMessages');
}
}
function hideEmitterInstance(instance) {
if (!instance) {
return;
}
try {
instance.on = false;
} catch (error) {}
try {
instance.exists = false;
} catch (error) {}
try {
instance.visible = false;
} catch (error) {}
try {
if (typeof instance.kill === 'function') {
instance.kill();
}
} catch (error) {}
try {
if (typeof instance.remove === 'function') {
instance.remove();
}
} catch (error) {}
try {
if (typeof instance.retire === 'function') {
instance.retire();
}
} catch (error) {}
}
function patchPrototypeMethodOnce(className, methodName, factory) {
const patchKey = `${className}.${methodName}`;
if (runtime.patchedEmitters.has(patchKey)) {
return false;
}
const Ctor = win[className];
if (!Ctor || !Ctor.prototype || typeof Ctor.prototype[methodName] !== 'function') {
return false;
}
const original = Ctor.prototype[methodName];
Ctor.prototype[methodName] = factory(original);
runtime.patchedEmitters.add(patchKey);
return true;
}
function patchEmitters() {
patchPrototypeMethodOnce('UISmokeEmitter', 'spawn', originalSpawn => function(x, y) {
const mode = state.enabled ? getProfile().effectMode : 'normal';
if (mode === 'normal') {
return originalSpawn.apply(this, arguments);
}
if (mode === 'reduced') {
this.revive();
this.visible = true;
this.x = x;
this.y = y;
this.setAlpha(0.65, 0.65);
if (typeof this.explode === 'function') {
this.explode(600, 1);
}
if (typeof this.start === 'function') {
this.start(false, 750, 250, 1);
}
return;
}
hideEmitterInstance(this);
});
patchPrototypeMethodOnce('UIExplosionEmitter', 'spawn', originalSpawn => function(x, y, smokeCount) {
const mode = state.enabled ? getProfile().effectMode : 'normal';
if (mode === 'normal') {
return originalSpawn.apply(this, arguments);
}
if (mode === 'reduced') {
return originalSpawn.call(this, x, y, Math.min(1, Math.max(0, Number(smokeCount) || 0)));
}
hideEmitterInstance(this);
});
[
'UIDustEmitter',
'UIMissileLaunchEmitter',
'UIRubbleEmitter',
'UIShieldSparkEmitter',
'UISpawnZoneSparkEmitter',
'UIConfettiEmitter',
'UITrophyExplosionEmitter'
].forEach(className => {
patchPrototypeMethodOnce(className, 'spawn', originalSpawn => function() {
const mode = state.enabled ? getProfile().effectMode : 'normal';
if (mode === 'normal') {
return originalSpawn.apply(this, arguments);
}
if (mode === 'reduced') {
return originalSpawn.apply(this, arguments);
}
hideEmitterInstance(this);
});
});
}
function updateRootClasses() {
const root = document.documentElement;
if (!root) {
return;
}
root.classList.toggle(ROOT_TRIM_CLASS, state.enabled && state.trimPage);
}
function applyProfile() {
updateRootClasses();
if (!state.enabled) {
restoreUiConstants();
restoreQualityValues();
restoreGameFlags();
restoreSystemMessages();
restoreOriginalCookies();
setStatus('Optimizer disabled.');
return;
}
const profile = getProfile();
applyCookiesForProfile(profile);
applyUiConstants(profile);
applyQualityValues(profile);
applyGameFlags(profile);
applySystemMessageMode(profile);
setStatus(`${profile.label} profile active.`);
}
function startRafSampler() {
let lastTime = performance.now();
function frame(now) {
const delta = now - lastTime;
lastTime = now;
if (delta > 0 && delta < 1000) {
runtime.rafSamples.push(1000 / delta);
if (runtime.rafSamples.length > 40) {
runtime.rafSamples.shift();
}
}
win.requestAnimationFrame(frame);
}
win.requestAnimationFrame(frame);
}
function ensureStyle() {
if (document.getElementById('tt-performance-optimizer-style')) {
return;
}
const style = document.createElement('style');
style.id = 'tt-performance-optimizer-style';
style.textContent = `
html.${ROOT_TRIM_CLASS} #leftBanner,
html.${ROOT_TRIM_CLASS} #rightBanner,
html.${ROOT_TRIM_CLASS} #topBanner,
html.${ROOT_TRIM_CLASS} #secondaryContent,
html.${ROOT_TRIM_CLASS} #tertiaryContent,
html.${ROOT_TRIM_CLASS} #messagesSnippet,
html.${ROOT_TRIM_CLASS} #wallOfFameSnippet,
html.${ROOT_TRIM_CLASS} #scrapyardSnippet,
html.${ROOT_TRIM_CLASS} .teaser,
html.${ROOT_TRIM_CLASS} .snippet {
display: none !important;
}
html.${ROOT_TRIM_CLASS} #contentWrapper,
html.${ROOT_TRIM_CLASS} #content,
html.${ROOT_TRIM_CLASS} #mainContent {
width: 100% !important;
max-width: none !important;
}
html.${ROOT_TRIM_CLASS} * {
text-shadow: none !important;
box-shadow: none !important;
}
html.${ROOT_TRIM_CLASS} #game canvas,
html.${ROOT_TRIM_CLASS} #playerPanel canvas,
html.${ROOT_TRIM_CLASS} #gameCanvas {
image-rendering: auto !important;
}
`;
(document.head || document.documentElement).appendChild(style);
}
function reloadGameCanvas() {
try {
const game = getGame();
if (!game || typeof win.GameManager === 'undefined' || typeof win.GameManager.insertGame !== 'function' || typeof win.$ === 'undefined') {
setStatus('Game reload is not available yet.');
return;
}
const controller = getGameController();
if (controller && typeof controller.endGame === 'function') {
controller.endGame();
}
if (game.load && typeof game.load.reset === 'function') {
game.load.reset(true, true);
}
game.destroy();
win.GameManager.phaserInstance = null;
win.GameManager.insertGame(win.$('#game'));
setStatus('Game canvas reloaded.');
} catch (error) {
setStatus('Game reload failed.');
}
}
async function refreshServerStats() {
if (runtime.serverRefreshBusy || typeof win.ClientManager === 'undefined' || typeof win.ClientManager.getAvailableServerStats !== 'function') {
return runtime.bestServer;
}
runtime.serverRefreshBusy = true;
const stats = new Map();
const currentServerId = getCurrentServerId();
const bestServer = await new Promise(resolve => {
let settled = false;
const finish = () => {
if (settled) {
return;
}
settled = true;
const values = Array.from(stats.values()).sort((a, b) => a.latency - b.latency);
resolve(values[0] || null);
};
try {
win.ClientManager.getAvailableServerStats(function(success, serverId, latency, gameCount, playerCount) {
if (!success || !Number.isFinite(Number(latency))) {
return;
}
const id = String(serverId);
const entry = {
id,
latency: Number(latency),
name: getServerName(id),
gameCount: Number(gameCount) || 0,
playerCount: Number(playerCount) || 0
};
stats.set(id, entry);
if (currentServerId && id === String(currentServerId)) {
runtime.currentServerLatency = entry.latency;
}
});
} catch (error) {
finish();
return;
}
setTimeout(finish, 1000);
});
runtime.serverRefreshBusy = false;
runtime.bestServer = bestServer;
return bestServer;
}
async function switchToBestServer(force) {
const bestServer = await refreshServerStats();
if (!bestServer) {
setStatus('No server stats available yet.');
return false;
}
if (!force && isActiveMatchLikely()) {
setStatus('Skipped server switch during active match.');
return false;
}
const currentServerId = getCurrentServerId();
if (currentServerId && String(currentServerId) === String(bestServer.id)) {
setStatus(`Already on ${bestServer.name} (${bestServer.latency} ms).`);
return true;
}
if (typeof win.ClientManager === 'undefined' || typeof win.ClientManager.selectMultiplayerServer !== 'function') {
setStatus('Server switching is unavailable here.');
return false;
}
try {
win.ClientManager.selectMultiplayerServer(bestServer.id);
runtime.lastAutoSwitchAt = Date.now();
setStatus(`Switched to ${bestServer.name} (${bestServer.latency} ms).`);
return true;
} catch (error) {
setStatus('Server switch failed.');
return false;
}
}
async function runAutoServerSelection() {
if (!state.enabled || !state.autoBestServer) {
return;
}
if (Date.now() - runtime.lastAutoSwitchAt < AUTO_SWITCH_COOLDOWN_MS) {
return;
}
if (isActiveMatchLikely()) {
return;
}
const bestServer = await refreshServerStats();
if (!bestServer) {
return;
}
const currentServerId = getCurrentServerId();
if (currentServerId && String(currentServerId) === String(bestServer.id)) {
return;
}
await switchToBestServer(false);
}
function startLoops() {
win.setInterval(() => {
patchEmitters();
applyProfile();
}, APPLY_INTERVAL_MS);
win.setInterval(async () => {
await refreshServerStats();
await runAutoServerSelection();
}, SERVER_REFRESH_INTERVAL_MS);
}
function init() {
ensureStyle();
patchEmitters();
applyProfile();
refreshServerStats();
}
startRafSampler();
startLoops();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init, { once: true });
} else {
init();
}
})();