refactor: remove matchmaker accept hotkey and always auto-join

This commit is contained in:
2026-04-15 08:44:20 -07:00
parent db89352ed8
commit ae359497be
4 changed files with 26 additions and 128 deletions
-4
View File
@@ -54,7 +54,6 @@ export interface AppConfig {
maxPlayers: number; maxPlayers: number;
minRemainingTime: number; minRemainingTime: number;
openServerBrowser: boolean; openServerBrowser: boolean;
autoJoin: boolean;
sortByPlayers: boolean; sortByPlayers: boolean;
}; };
keybinds: { keybinds: {
@@ -64,7 +63,6 @@ export interface AppConfig {
joinFromClipboard: Keybind; joinFromClipboard: Keybind;
devTools: Keybind; devTools: Keybind;
matchmaker: Keybind; matchmaker: Keybind;
matchmakerAccept: Keybind;
matchmakerCancel: Keybind; matchmakerCancel: Keybind;
fullscreenToggle: Keybind; fullscreenToggle: Keybind;
}; };
@@ -120,7 +118,6 @@ export const DEFAULT_KEYBINDS: AppConfig['keybinds'] = {
joinFromClipboard: { key: 'j', ctrl: true, shift: false, alt: false }, joinFromClipboard: { key: 'j', ctrl: true, shift: false, alt: false },
devTools: { key: 'F12', ctrl: false, shift: false, alt: false }, devTools: { key: 'F12', ctrl: false, shift: false, alt: false },
matchmaker: { key: 'F6', ctrl: false, shift: false, alt: false }, matchmaker: { key: 'F6', ctrl: false, shift: false, alt: false },
matchmakerAccept: { key: 'Enter', ctrl: false, shift: false, alt: false },
matchmakerCancel: { key: 'Escape', ctrl: false, shift: false, alt: false }, matchmakerCancel: { key: 'Escape', ctrl: false, shift: false, alt: false },
fullscreenToggle: { key: 'F11', ctrl: false, shift: false, alt: false }, fullscreenToggle: { key: 'F11', ctrl: false, shift: false, alt: false },
}; };
@@ -169,7 +166,6 @@ export const config = new Store<AppConfig>({
maxPlayers: 6, maxPlayers: 6,
minRemainingTime: 120, minRemainingTime: 120,
openServerBrowser: true, openServerBrowser: true,
autoJoin: false,
sortByPlayers: false, sortByPlayers: false,
}, },
keybinds: DEFAULT_KEYBINDS, keybinds: DEFAULT_KEYBINDS,
-2
View File
@@ -389,7 +389,6 @@ async function launchApp(): Promise<void> {
if (mm.enabled) { if (mm.enabled) {
win.webContents.send('matchmaker-find', { win.webContents.send('matchmaker-find', {
...mm, ...mm,
acceptKey: binds.matchmakerAccept,
cancelKey: binds.matchmakerCancel, cancelKey: binds.matchmakerCancel,
}); });
} else { } else {
@@ -411,7 +410,6 @@ async function launchApp(): Promise<void> {
if (mm.enabled) { if (mm.enabled) {
win.webContents.send('matchmaker-find', { win.webContents.send('matchmaker-find', {
...mm, ...mm,
acceptKey: binds.matchmakerAccept,
cancelKey: binds.matchmakerCancel, cancelKey: binds.matchmakerCancel,
}); });
} else { } else {
+1 -13
View File
@@ -853,7 +853,7 @@ function buildAppearanceSection(body: HTMLElement, uiConfRaw: any): void {
} }
function buildMatchmakerSection(body: HTMLElement, mmConf: any, bag: SettingsBag): void { function buildMatchmakerSection(body: HTMLElement, mmConf: any, bag: SettingsBag): void {
const mm = mmConf || { enabled: true, regions: [], gamemodes: [], minPlayers: 1, maxPlayers: 6, minRemainingTime: 120, openServerBrowser: true, autoJoin: false }; const mm = mmConf || { enabled: true, regions: [], gamemodes: [], minPlayers: 1, maxPlayers: 6, minRemainingTime: 120, openServerBrowser: true, sortByPlayers: false };
function saveMM(): void { function saveMM(): void {
ipcRenderer.invoke('set-config', 'matchmaker', mm); ipcRenderer.invoke('set-config', 'matchmaker', mm);
@@ -873,13 +873,6 @@ function buildMatchmakerSection(body: HTMLElement, mmConf: any, bag: SettingsBag
onChange: (v) => { mm.openServerBrowser = v; saveMM(); }, onChange: (v) => { mm.openServerBrowser = v; saveMM(); },
})); }));
body.appendChild(createToggleRow({
label: 'Auto-Join',
desc: 'Automatically join the best match without showing the popup',
checked: mm.autoJoin ?? false, instant: true,
onChange: (v) => { mm.autoJoin = v; saveMM(); },
}));
body.appendChild(createToggleRow({ body.appendChild(createToggleRow({
label: 'Prioritize Player Count', label: 'Prioritize Player Count',
desc: 'Sort results by most players first, then by ping (default is ping first)', desc: 'Sort results by most players first, then by ping (default is ping first)',
@@ -891,10 +884,6 @@ function buildMatchmakerSection(body: HTMLElement, mmConf: any, bag: SettingsBag
bag.binds.matchmaker = b; bag.binds.matchmaker = b;
bag.saveBinds(); bag.saveBinds();
}, undefined, true)); }, undefined, true));
body.appendChild(createKeybindRow('Matchmaker Accept', 'Key to accept a found game', bag.binds.matchmakerAccept, (b) => {
bag.binds.matchmakerAccept = b;
bag.saveBinds();
}, undefined, true));
body.appendChild(createKeybindRow('Matchmaker Cancel', 'Key to dismiss the matchmaker popup', bag.binds.matchmakerCancel, (b) => { body.appendChild(createKeybindRow('Matchmaker Cancel', 'Key to dismiss the matchmaker popup', bag.binds.matchmakerCancel, (b) => {
bag.binds.matchmakerCancel = b; bag.binds.matchmakerCancel = b;
bag.saveBinds(); bag.saveBinds();
@@ -1363,7 +1352,6 @@ function renderSettings(searchQuery?: string): void {
const translatorConf = allConf.translator; const translatorConf = allConf.translator;
const defaultBinds = { const defaultBinds = {
matchmaker: { key: 'F6', ctrl: false, shift: false, alt: false }, matchmaker: { key: 'F6', ctrl: false, shift: false, alt: false },
matchmakerAccept: { key: 'Enter', ctrl: false, shift: false, alt: false },
matchmakerCancel: { key: 'Escape', ctrl: false, shift: false, alt: false }, matchmakerCancel: { key: 'Escape', ctrl: false, shift: false, alt: false },
fullscreenToggle: { key: 'F11', ctrl: false, shift: false, alt: false }, fullscreenToggle: { key: 'F11', ctrl: false, shift: false, alt: false },
}; };
+8 -92
View File
@@ -65,19 +65,10 @@ export interface MatchmakerConfig {
maxPlayers: number; maxPlayers: number;
minRemainingTime: number; minRemainingTime: number;
openServerBrowser: boolean; openServerBrowser: boolean;
autoJoin: boolean;
sortByPlayers: boolean; sortByPlayers: boolean;
acceptKey: Keybind;
cancelKey: Keybind; cancelKey: Keybind;
} }
function secondsToTimestring(num: number): string {
const minutes = Math.floor(num / 60);
const seconds = num % 60;
if (minutes < 1) return `${num}s`;
return `${minutes}m ${seconds}s`;
}
function matchesKey(bind: Keybind, event: KeyboardEvent): boolean { function matchesKey(bind: Keybind, event: KeyboardEvent): boolean {
if ((document.activeElement as HTMLElement)?.tagName === 'INPUT') return false; if ((document.activeElement as HTMLElement)?.tagName === 'INPUT') return false;
return event.key === bind.key return event.key === bind.key
@@ -103,21 +94,17 @@ popupElement.appendChild(popupDescription);
const popupOptions = document.createElement('div'); const popupOptions = document.createElement('div');
popupOptions.id = 'matchmakerPopupOptions'; popupOptions.id = 'matchmakerPopupOptions';
const popupConfirmBtn = document.createElement('div');
popupConfirmBtn.id = 'matchmakerConfirmButton';
popupConfirmBtn.className = 'matchmakerPopupButton bigShadowT';
popupConfirmBtn.textContent = 'Join';
popupConfirmBtn.setAttribute('onmouseenter', 'playTick()');
popupConfirmBtn.addEventListener('click', () => decideMatchmakerDecision(true));
const popupCancelBtn = document.createElement('div'); const popupCancelBtn = document.createElement('div');
popupCancelBtn.id = 'matchmakerCancelButton'; popupCancelBtn.id = 'matchmakerCancelButton';
popupCancelBtn.className = 'matchmakerPopupButton bigShadowT'; popupCancelBtn.className = 'matchmakerPopupButton bigShadowT';
popupCancelBtn.textContent = 'Cancel'; popupCancelBtn.textContent = 'Cancel';
popupCancelBtn.setAttribute('onmouseenter', 'playTick()'); popupCancelBtn.setAttribute('onmouseenter', 'playTick()');
popupCancelBtn.addEventListener('click', () => decideMatchmakerDecision(false)); popupCancelBtn.addEventListener('click', () => {
const w = window as any;
if (typeof w.playSelect === 'function') w.playSelect();
dismissPopup();
});
popupOptions.appendChild(popupConfirmBtn);
popupOptions.appendChild(popupCancelBtn); popupOptions.appendChild(popupCancelBtn);
popupElement.appendChild(popupOptions); popupElement.appendChild(popupOptions);
@@ -147,10 +134,8 @@ searchContainer.appendChild(searchCancelBtn);
popupElement.appendChild(searchContainer); popupElement.appendChild(searchContainer);
// ── State ── // ── State ──
let popupGameID = '';
let popupCandidates: MatchmakerGame[] = []; let popupCandidates: MatchmakerGame[] = [];
let openServerBrowser = true; let openServerBrowser = true;
let confirmKey: Keybind = { key: 'Enter', ctrl: false, shift: false, alt: false };
let cancelKey: Keybind = { key: 'Escape', ctrl: false, shift: false, alt: false }; let cancelKey: Keybind = { key: 'Escape', ctrl: false, shift: false, alt: false };
let searchAborted = false; let searchAborted = false;
@@ -192,25 +177,11 @@ async function verifyAndJoin(gameID: string): Promise<void> {
function dismissPopup(): void { function dismissPopup(): void {
document.removeEventListener('keydown', handleSearchBind, true); document.removeEventListener('keydown', handleSearchBind, true);
document.removeEventListener('keydown', handleMatchmakerBind, true);
if (popupElement.parentNode) popupElement.remove(); if (popupElement.parentNode) popupElement.remove();
popupElement.classList.remove('searching'); popupElement.classList.remove('searching');
} }
function decideMatchmakerDecision(accept: boolean): void {
const w = window as any;
if (typeof w.playSelect === 'function') w.playSelect();
if (accept && popupGameID !== 'none') {
verifyAndJoin(popupGameID);
} else {
dismissPopup();
if (popupGameID === 'none' && openServerBrowser && typeof w.openServerWindow === 'function') {
w.openServerWindow(0);
}
}
}
function handleSearchBind(event: KeyboardEvent): void { function handleSearchBind(event: KeyboardEvent): void {
if (document.pointerLockElement) return; if (document.pointerLockElement) return;
if (matchesKey(cancelKey, event)) { if (matchesKey(cancelKey, event)) {
@@ -220,42 +191,6 @@ function handleSearchBind(event: KeyboardEvent): void {
} }
} }
function handleMatchmakerBind(event: KeyboardEvent): void {
if (document.pointerLockElement) return;
const isAccept = matchesKey(confirmKey, event);
const isCancel = matchesKey(cancelKey, event);
if (isAccept || isCancel) {
document.removeEventListener('keydown', handleMatchmakerBind, true);
decideMatchmakerDecision(isAccept);
}
}
function showResultPopup(game: MatchmakerGame): void {
popupElement.classList.remove('searching');
const mapIdx = MAP_ICON_INDICES.indexOf(game.map);
popupElement.style.backgroundImage = `url(https://assets.krunker.io/img/maps/map_${mapIdx >= 0 ? mapIdx : 0}.png)`;
popupGameID = game.gameID;
if (game.gameID === 'none') {
popupTitle.innerText = 'No Games Found...';
popupDescription.innerHTML = 'Check the server browser to see other lobbies.';
popupConfirmBtn.style.display = 'none';
} else {
popupTitle.innerText = 'Game Found!';
const regionName = MATCHMAKER_REGION_NAMES[game.region] ?? 'Unknown Region';
popupDescription.innerHTML = `${escapeHtml(game.gamemode)} on ${escapeHtml(game.map)} (${escapeHtml(regionName)})<br/>${game.playerCount}/${game.playerLimit} Players, ${secondsToTimestring(game.remainingTime)} Left`;
popupConfirmBtn.style.display = 'block';
}
// Re-trigger slide animation
popupElement.style.animation = 'none';
void popupElement.offsetWidth;
popupElement.style.animation = '';
document.removeEventListener('keydown', handleSearchBind, true);
document.addEventListener('keydown', handleMatchmakerBind, true);
}
function showSearchPopup(): void { function showSearchPopup(): void {
searchAborted = false; searchAborted = false;
popupElement.classList.add('searching'); popupElement.classList.add('searching');
@@ -264,7 +199,7 @@ function showSearchPopup(): void {
searchFeed.innerHTML = ''; searchFeed.innerHTML = '';
searchCounter.textContent = ''; searchCounter.textContent = '';
document.removeEventListener('keydown', handleMatchmakerBind, true);
document.addEventListener('keydown', handleSearchBind, true); document.addEventListener('keydown', handleSearchBind, true);
const uiBase = document.getElementById('uiBase'); const uiBase = document.getElementById('uiBase');
@@ -374,7 +309,6 @@ function sortGames(games: MatchmakerGame[], pings: Record<string, number>, sortB
export async function fetchGame(mmConfig: MatchmakerConfig, _con?: SavedConsole): Promise<void> { export async function fetchGame(mmConfig: MatchmakerConfig, _con?: SavedConsole): Promise<void> {
openServerBrowser = mmConfig.openServerBrowser; openServerBrowser = mmConfig.openServerBrowser;
confirmKey = mmConfig.acceptKey;
cancelKey = mmConfig.cancelKey; cancelKey = mmConfig.cancelKey;
// Dismiss existing popup if active (also aborts in-flight search) // Dismiss existing popup if active (also aborts in-flight search)
@@ -434,8 +368,7 @@ export async function fetchGame(mmConfig: MatchmakerConfig, _con?: SavedConsole)
const best = pool[Math.floor(Math.random() * pool.length)]; const best = pool[Math.floor(Math.random() * pool.length)];
_con?.log('[KCC-MM] Best match:', best.gameID, best.region, best.map, `(${pings[best.region] ?? '?'}ms, pool: ${pool.length})`); _con?.log('[KCC-MM] Best match:', best.gameID, best.region, best.map, `(${pings[best.region] ?? '?'}ms, pool: ${pool.length})`);
if (mmConfig.autoJoin) { // Brief "Lobby Found!" flash before auto-joining
// Brief "Lobby Found!" flash before joining
const regionName = MATCHMAKER_REGION_NAMES[best.region] ?? best.region; const regionName = MATCHMAKER_REGION_NAMES[best.region] ?? best.region;
searchStatus.textContent = 'Lobby Found!'; searchStatus.textContent = 'Lobby Found!';
searchFeed.innerHTML = ''; searchFeed.innerHTML = '';
@@ -450,29 +383,12 @@ export async function fetchGame(mmConfig: MatchmakerConfig, _con?: SavedConsole)
searchCounter.textContent = `${best.gamemode} \u00B7 ${regionName} \u00B7 ${pings[best.region] ?? '?'}ms`; searchCounter.textContent = `${best.gamemode} \u00B7 ${regionName} \u00B7 ${pings[best.region] ?? '?'}ms`;
await new Promise(r => setTimeout(r, 1200)); await new Promise(r => setTimeout(r, 1200));
await verifyAndJoin(best.gameID); await verifyAndJoin(best.gameID);
return;
}
showResultPopup(best);
} else { } else {
_con?.log('[KCC-MM] No matching games found'); _con?.log('[KCC-MM] No matching games found');
if (mmConfig.autoJoin) {
dismissPopup(); dismissPopup();
if (openServerBrowser && typeof (window as any).openServerWindow === 'function') { if (openServerBrowser && typeof (window as any).openServerWindow === 'function') {
(window as any).openServerWindow(0); (window as any).openServerWindow(0);
} }
return;
}
showResultPopup({
gameID: 'none',
region: 'none',
playerCount: 0,
playerLimit: 0,
map: MAP_ICON_INDICES[0],
gamemode: MATCHMAKER_GAMEMODES[0],
remainingTime: 0,
});
} }
} }