Test-Harness aus dem Repo nehmen und ignorieren
Die Datei stubbt die API, damit das Panel ohne laufenden Bot rendert. Sie wird beim Entwickeln erzeugt und ist mir beim letzten Commit mit reingerutscht. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,149 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Harness</title>
|
||||
<link rel="stylesheet" crossorigin href="/src/style.css">
|
||||
<script>
|
||||
// Nur zum Ansehen: liefert Beispieldaten statt echter API.
|
||||
history.replaceState(null, '', sessionStorage.getItem('harnessPfad') || '/');
|
||||
const jetzt = new Date().toISOString();
|
||||
// Panel-Modus: eingeloggt als Owner, damit /settings rendert
|
||||
const alsOwner = sessionStorage.getItem('harnessOwner') === '1';
|
||||
const MODULE = [
|
||||
['devlogs','Devlogs','inhalte',true,[]], ['commit_feed','Commit-Feed','inhalte',true,[]],
|
||||
['releases','Release-Ankuendigungen','inhalte',true,[]], ['weekly_recap','Wochen-Rueckblick','inhalte',true,[]],
|
||||
['devlog_threads','Devlog-Threads','inhalte',true,[]], ['social','Twitch & YouTube','inhalte',true,[]],
|
||||
['levels','Level-System','community',true,[]], ['starboard','Starboard','community',false,[]],
|
||||
['gallery','Galerie','community',true,[]], ['voting','Feature-Wuensche','community',true,[]],
|
||||
['giveaways','Verlosungen','community',true,[]], ['birthdays','Geburtstage','community',true,[]],
|
||||
['events','Events','community',true,[]], ['playtester','Playtester','community',false,[]],
|
||||
['alpha_keys','Alpha-Keys','community',true,[]], ['role_menus','Rollen-Menues','community',true,[]],
|
||||
['applications','Bewerbungen','community',true,[]],
|
||||
['moderation','Moderation','moderation',true,[]], ['modlog','Protokoll','moderation',true,[{label:'Mod-Log-Kanal'}]],
|
||||
['modmail','Modmail','moderation',true,[]], ['tickets','Tickets','moderation',true,[]],
|
||||
['welcome','Willkommens-Karten','moderation',true,[]], ['autorole','Auto-Rolle','moderation',false,[]],
|
||||
['sticky_roles','Rollen merken','moderation',true,[]], ['bug_reports','Fehlermeldungen','moderation',true,[{label:'Gitea-Token'}]],
|
||||
['server_monitor','Server-Monitor','server',true,[]], ['watchdog','Waechter','server',true,[]],
|
||||
['temp_voice','Temp-Voice','server',false,[]], ['triggers','Auto-Antworten','server',true,[]],
|
||||
['reminders','Erinnerungen','server',true,[]], ['scheduled_posts','Geplante Beitraege','server',true,[]],
|
||||
['tags','Textbausteine','server',true,[]], ['backups','DB-Sicherung','server',true,[]],
|
||||
['repo_backups','Repo-Sicherung','server',false,[]], ['member_gate','Member-Gate','server',true,[]],
|
||||
].map(([id, name, group, enabled, missing]) => ({ id, name, group, enabled, missing, desc: '', tab: 'system' }));
|
||||
|
||||
const TAGE = Array.from({ length: 30 }, (_, i) => ({
|
||||
day: new Date(Date.now() - (29 - i) * 86400000).toISOString().slice(0, 10),
|
||||
messages: Math.round(120 + Math.sin(i / 2.2) * 70 + (i % 7 === 0 ? 90 : 0)),
|
||||
joins: 2 + (i % 3), leaves: i % 4 === 0 ? 2 : 1,
|
||||
}));
|
||||
|
||||
const DATEN = {
|
||||
'/api/me': alsOwner
|
||||
? { user: { id: '1', username: 'D4rkst3r', avatar: null }, admin: true, scopes: [] }
|
||||
: { user: null, admin: false, scopes: [] },
|
||||
'/api/serverstats': { members: 1234, days: TAGE },
|
||||
'/api/modules': {
|
||||
modules: MODULE, favorites: ['devlogs', 'welcome'], maxFavorites: 8,
|
||||
groups: [
|
||||
{ id: 'inhalte', label: 'Inhalte & Feeds' }, { id: 'community', label: 'Community' },
|
||||
{ id: 'moderation', label: 'Moderation & Support' }, { id: 'server', label: 'Server & Technik' },
|
||||
],
|
||||
},
|
||||
'/api/auditlog': { entries: [] },
|
||||
'/api/alphakeys': { keys: [], free: 0, playtestersWithout: [] },
|
||||
'/api/texts': { templates: [], groups: [] },
|
||||
'/api/tuning': { values: [], groups: [] },
|
||||
'/api/webadmins': { admins: [], scopes: [], owner: { user_id: '1', name: 'D4rkst3r', avatar: null } },
|
||||
'/api/pages': { pages: [] },
|
||||
'/api/settings': {
|
||||
settings: {}, channels: [], roles: [], categories: [],
|
||||
status: {
|
||||
botTag: 'd4rkbot#4021', botName: 'd4rkbot', botAvatar: null, botDescription: '',
|
||||
uptimeSeconds: 1051980, guilds: 1, giteaTokenConfigured: true,
|
||||
// Volles ISO mit Z — genau so schreibt es toISOString() in der
|
||||
// echten Datenbank, und genau daran ist die Anzeige gescheitert.
|
||||
lastBackup: new Date(Date.now() - 6 * 3600000).toISOString(),
|
||||
devlogs: 142, commits: 3184, dbSizeBytes: 50331648,
|
||||
lastDevlog: new Date(Date.now() - 2 * 86400000).toISOString(),
|
||||
lastCommit: new Date(Date.now() - 3600000).toISOString(),
|
||||
},
|
||||
},
|
||||
'/api/invite': { invite: 'https://discord.gg/example' },
|
||||
'/api/legal': { split: true, hubUrl: 'https://d4rkst3r.de' },
|
||||
// Stundeneimer wie uptimeBuckets() sie liefert: meist voll erreichbar,
|
||||
// ein harter Ausfall, eine teilweise Stunde, und eine Messluecke.
|
||||
'/api/servers': (() => {
|
||||
const eimer = [];
|
||||
const jetzt = new Date(); jetzt.setMinutes(0, 0, 0);
|
||||
for (let i = 167; i >= 0; i--) {
|
||||
if (i > 40 && i < 52) continue; // Luecke: Bot war aus
|
||||
const d = new Date(jetzt.getTime() - i * 3600000);
|
||||
let an = 30;
|
||||
if (i >= 92 && i <= 97) an = 0; // Ausfall
|
||||
else if (i === 91 || i === 98 || i === 20) an = 17; // teilweise
|
||||
eimer.push({ stunde: d.toISOString().slice(0, 13), proben: 30, an });
|
||||
}
|
||||
return { servers: [
|
||||
{ id: 1, name: 'EcoGame RP', icon: '\ud83c\udfae', online: true, players: 64, max: 128, ping: 23, map: 'Los Santos',
|
||||
address: 'play.d4rkst3r.de:30120', connect_url: 'fivem://connect/play.d4rkst3r.de', checkedAt: jetzt,
|
||||
history: Array.from({length: 24}, (_, i) => ({ online: i !== 5, players: 20 + i })), uptime: eimer },
|
||||
{ id: 2, name: 'Testserver', icon: '\ud83e\uddea', online: false, players: 0, max: 32, history: [], uptime: [], checkedAt: jetzt },
|
||||
]}; })(),
|
||||
'/api/services': { services: [] },
|
||||
'/api/devlogs': { total: 2, pageSize: 10, items: [
|
||||
{ message_id: '1', posted_at: jetzt, content: 'Devlog \u2014 EcoGame\n\nHeute am Fahrzeug-Handling gearbeitet.\n\n*3 Commits heute*', images: [] },
|
||||
{ message_id: '2', posted_at: new Date(Date.now() - 86400000 * 40).toISOString(), content: 'Devlog \u2014 Bot\n\nAltes Update.', images: [] },
|
||||
]},
|
||||
'/api/devlog-projects': { projects: [{ name: 'EcoGame', n: 1 }, { name: 'Bot', n: 1 }] },
|
||||
'/api/roadmap': { milestones: [
|
||||
{ title: 'Alpha 1', state: 'open', open: 3, closed: 7, due_on: jetzt, description: 'Erste spielbare Fassung.' },
|
||||
{ title: 'Grundger\u00fcst', state: 'closed', open: 0, closed: 12 },
|
||||
]},
|
||||
'/api/wishes': { canVote: false, wishes: [{ message_id: '9', idea: 'Mehr Fahrzeuge', author: 'Lisa', score: 5, voted: false }] },
|
||||
'/api/heatmap': { days: [{ day: jetzt.slice(0,10), n: 3 }] },
|
||||
'/api/gallery': { total: 1, pageSize: 12, items: [
|
||||
{ author_name: 'Nova', posted_at: jetzt, images: ['https://cdn.discordapp.com/embed/avatars/2.png'] },
|
||||
]},
|
||||
'/api/levels': { levels: [
|
||||
{ user_id: '1', display_name: 'Lisa', username: 'lisa', avatar: null, level: 12, xp: 45231 },
|
||||
{ user_id: '2', display_name: 'Nova', username: 'nova', avatar: null, level: 8, xp: 18400 },
|
||||
]},
|
||||
'/api/events': { events: [
|
||||
{ url: 'https://discord.com/x', name: 'Playtest #4', start: jetzt, interested: 12, description: 'Kommt vorbei.' },
|
||||
]},
|
||||
'/api/releases': { total: 1, pageSize: 10, items: [
|
||||
{ repo: 'D4rkst3r/d4rkbot', tag: 'v1.2.0', prerelease: true, published_at: jetzt, name: 'Team & Sprachen', body: '- Team-Seite\n- Englisch', url: 'https://git.d4rkst3r.de' },
|
||||
]},
|
||||
'/api/features': { groups: [
|
||||
{ id: 'inhalte', label: 'Inhalte & Feeds' }, { id: 'community', label: 'Community' },
|
||||
], features: [
|
||||
{ id: 'devlogs', group: 'inhalte', name: 'Devlogs', desc: 'Entwicklungs-Berichte als gebrandetes Embed posten.' },
|
||||
{ id: 'levels', group: 'community', name: 'Level-System', desc: 'XP f\u00fcrs Mitreden.' },
|
||||
{ id: 'gibtsnicht', group: 'community', name: 'Modul ohne \u00dcbersetzung', desc: 'F\u00e4llt bewusst auf Deutsch zur\u00fcck.' },
|
||||
]},
|
||||
};
|
||||
const echt = window.fetch;
|
||||
window.fetch = (url, opts) => {
|
||||
const pfad = String(url).split('?')[0];
|
||||
if (pfad.startsWith('/api/')) {
|
||||
// Alles Unbekannte: gaengige Listen-Schluessel als leeres Array, damit
|
||||
// .filter/.map nicht auf undefined laufen
|
||||
const leer = {};
|
||||
for (const k of ['keys', 'playtesters', 'menus', 'tags', 'posts', 'forms', 'triggers',
|
||||
'servers', 'apps', 'services', 'pages', 'modules', 'groups', 'templates',
|
||||
'values', 'entries', 'admins', 'items', 'levels', 'events', 'wishes',
|
||||
'milestones', 'days', 'projects', 'scopes']) leer[k] = [];
|
||||
return Promise.resolve(new Response(JSON.stringify(DATEN[pfad] ?? leer), {
|
||||
status: 200, headers: { 'Content-Type': 'application/json' },
|
||||
}));
|
||||
}
|
||||
return echt(url, opts);
|
||||
};
|
||||
</script>
|
||||
<script type="module" crossorigin src="/src/main.jsx"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user