Initial commit — Krunker Civilian Client
Cross-platform Krunker.io game client forked from Krunker Police Client with all KPD/moderator features stripped: no KPD auth, OBS recording, evidence uploads, yt-dlp, bytenode, or code obfuscation. Retained: unlimited FPS (custom Electron 42), ad blocking, resource swapper, matchmaker, userscripts, chat translator, Discord RPC, alt account manager, configurable keybinds, and advanced Chromium flags. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
// ── Shared preload utilities ──
|
||||
// Common types, helpers, and constants used across preload modules.
|
||||
|
||||
// ── Shared interfaces ──
|
||||
|
||||
export interface SavedConsole {
|
||||
log: (...args: unknown[]) => void;
|
||||
warn: (...args: unknown[]) => void;
|
||||
error: (...args: unknown[]) => void;
|
||||
}
|
||||
|
||||
export interface KeybindDef {
|
||||
key: string;
|
||||
ctrl: boolean;
|
||||
shift: boolean;
|
||||
alt: boolean;
|
||||
}
|
||||
|
||||
// ── HTML escaping ──
|
||||
|
||||
const HTML_ESCAPE_MAP: Record<string, string> = {
|
||||
'&': '&', '<': '<', '>': '>', '"': '"', "'": ''',
|
||||
};
|
||||
|
||||
export function escapeHtml(s: string): string {
|
||||
return s.replace(/[&<>"']/g, c => HTML_ESCAPE_MAP[c]);
|
||||
}
|
||||
|
||||
// ── Chat message injection ──
|
||||
// Creates messages in #chatHolder inside a persistent #kpcMessageHolder div.
|
||||
// timeout=0 means the message is persistent (not auto-removed).
|
||||
|
||||
export function genChatMsg(text: string, timeout = 2.25): HTMLElement | null {
|
||||
const chatHolder = document.getElementById('chatHolder');
|
||||
if (!chatHolder) return null;
|
||||
if (!document.getElementById('kpcMessageHolder')) {
|
||||
chatHolder.insertAdjacentHTML('afterbegin', '<div id="kpcMessageHolder"></div>');
|
||||
}
|
||||
const holder = document.getElementById('kpcMessageHolder')!;
|
||||
holder.insertAdjacentHTML('beforeend',
|
||||
'<div class="chatHolder_kpc"><div class="chatItem_kpc"><span class="chatMsg_kpc">' +
|
||||
escapeHtml(text) + '</span></div></div>');
|
||||
const elem = holder.lastElementChild as HTMLElement;
|
||||
if (timeout !== 0) {
|
||||
setTimeout(() => { elem.remove(); }, timeout * 1000);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
// ── Filename sanitisation ──
|
||||
|
||||
export function sanitizeFilename(name: string): string {
|
||||
return name.replace(/[^a-zA-Z0-9_-]/g, '_');
|
||||
}
|
||||
|
||||
// ── Shared CSS constants ──
|
||||
|
||||
export const DEATH_ANIM_BLOCK_ID = 'kpc-animationBlock';
|
||||
export const DEATH_ANIM_BLOCK_CSS =
|
||||
'.death-ui-bottom, .death-ui-bottom-empty { animation: none !important; transition: none !important; }';
|
||||
|
||||
/** Inject or remove the death screen animation block style element. */
|
||||
export function setDeathAnimBlock(enabled: boolean): void {
|
||||
let el = document.getElementById(DEATH_ANIM_BLOCK_ID);
|
||||
if (enabled) {
|
||||
if (!el) {
|
||||
el = document.createElement('style');
|
||||
el.id = DEATH_ANIM_BLOCK_ID;
|
||||
el.textContent = DEATH_ANIM_BLOCK_CSS;
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
} else if (el) {
|
||||
el.remove();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user