new file: .gitignore

new file:   README.md
	new file:   database/schema.sql
	new file:   paper-plugin/pom.xml
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/PaperLoggerPlugin.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/commands/MCLoggerCommand.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/database/DatabaseManager.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/BlockListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/EntityListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/InventoryListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/LuckPermsListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerChatCommandListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerDeathListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerMiscListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerSessionListener.java
	new file:   paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/WorldListener.java
	new file:   paper-plugin/src/main/resources/config.yml
	new file:   paper-plugin/src/main/resources/plugin.yml
	new file:   paper-plugin/target/classes/config.yml
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/PaperLoggerPlugin.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/commands/MCLoggerCommand$RsConsumer.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/commands/MCLoggerCommand.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/database/DatabaseManager$ThrowingRunnable.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/database/DatabaseManager.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/BlockListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/EntityListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/InventoryListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/LuckPermsListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerChatCommandListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerDeathListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerMiscListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerSessionListener.class
	new file:   paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/WorldListener.class
	new file:   paper-plugin/target/classes/plugin.yml
	new file:   paper-plugin/target/maven-archiver/pom.properties
	new file:   paper-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
	new file:   paper-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
	new file:   paper-plugin/target/mclogger-paper-1.0.0.jar
	new file:   paper-plugin/target/original-mclogger-paper-1.0.0.jar
	new file:   velocity-plugin/pom.xml
	new file:   velocity-plugin/src/main/java/de/simolzimol/mclogger/velocity/VelocityLoggerPlugin.java
	new file:   velocity-plugin/src/main/java/de/simolzimol/mclogger/velocity/database/VelocityDatabaseManager.java
	new file:   velocity-plugin/src/main/java/de/simolzimol/mclogger/velocity/listeners/VelocityEventListener.java
	new file:   velocity-plugin/src/main/resources/velocity-config.yml
	new file:   velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/VelocityLoggerPlugin.class
	new file:   velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/database/VelocityDatabaseManager$ThrowingRunnable.class
	new file:   velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/database/VelocityDatabaseManager.class
	new file:   velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/listeners/VelocityEventListener.class
	new file:   velocity-plugin/target/classes/velocity-config.yml
	new file:   velocity-plugin/target/classes/velocity-plugin.json
	new file:   velocity-plugin/target/maven-archiver/pom.properties
	new file:   velocity-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
	new file:   velocity-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
	new file:   velocity-plugin/target/mclogger-velocity-1.0.0.jar
	new file:   velocity-plugin/target/original-mclogger-velocity-1.0.0.jar
	new file:   web/Dockerfile
	new file:   web/app.py
	new file:   web/blueprints/__init__.py
	new file:   web/blueprints/auth.py
	new file:   web/blueprints/group_admin.py
	new file:   web/blueprints/panel.py
	new file:   web/blueprints/site_admin.py
	new file:   web/config.py
	new file:   web/crypto.py
	new file:   web/docker-compose.yml
	new file:   web/panel_db.py
	new file:   web/requirements.txt
	new file:   web/static/css/style.css
	new file:   web/static/js/main.js
	new file:   web/templates/_pagination.html
	new file:   web/templates/admin/base.html
	new file:   web/templates/admin/dashboard.html
	new file:   web/templates/admin/group_edit.html
	new file:   web/templates/admin/group_members.html
	new file:   web/templates/admin/groups.html
	new file:   web/templates/admin/user_edit.html
	new file:   web/templates/admin/users.html
	new file:   web/templates/auth/admin_login.html
	new file:   web/templates/auth/login.html
	new file:   web/templates/base.html
	new file:   web/templates/blocks.html
	new file:   web/templates/chat.html
	new file:   web/templates/commands.html
	new file:   web/templates/dashboard.html
	new file:   web/templates/deaths.html
	new file:   web/templates/group_admin/base.html
	new file:   web/templates/group_admin/dashboard.html
	new file:   web/templates/group_admin/database.html
	new file:   web/templates/group_admin/member_edit.html
	new file:   web/templates/group_admin/members.html
	new file:   web/templates/login.html
	new file:   web/templates/panel/blocks.html
	new file:   web/templates/panel/chat.html
	new file:   web/templates/panel/commands.html
	new file:   web/templates/panel/dashboard.html
	new file:   web/templates/panel/deaths.html
	new file:   web/templates/panel/no_db.html
	new file:   web/templates/panel/perms.html
	new file:   web/templates/panel/player_detail.html
	new file:   web/templates/panel/players.html
	new file:   web/templates/panel/proxy.html
	new file:   web/templates/panel/server_events.html
	new file:   web/templates/panel/sessions.html
	new file:   web/templates/perms.html
	new file:   web/templates/player_detail.html
	new file:   web/templates/players.html
	new file:   web/templates/proxy.html
	new file:   web/templates/server_events.html
	new file:   web/templates/sessions.html
This commit is contained in:
SimolZimol
2026-04-01 01:36:01 +02:00
commit b918dadb0c
109 changed files with 9196 additions and 0 deletions

230
web/static/css/style.css Normal file
View File

@@ -0,0 +1,230 @@
/* ============================================================
MCLogger Admin Interface CSS
Author: SimolZimol
============================================================ */
:root {
--sidebar-width: 230px;
--sidebar-bg: #0f1117;
--sidebar-border: #1e2230;
--topbar-bg: #13161f;
--content-bg: #181c27;
--card-bg: #1e2230;
--card-border: #2a2f42;
--text-muted-custom: #6b7280;
--accent-green: #1db954;
}
/* ── Layout ─────────────────────────────────────────────── */
html, body {
height: 100%;
overflow: hidden;
background: var(--content-bg);
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
font-size: 14px;
}
#wrapper {
height: 100vh;
overflow: hidden;
}
/* ── Sidebar ─────────────────────────────────────────────── */
#sidebar {
width: var(--sidebar-width);
min-width: var(--sidebar-width);
background: var(--sidebar-bg);
border-right: 1px solid var(--sidebar-border);
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
transition: width .25s ease, min-width .25s ease;
}
#sidebar.collapsed {
width: 64px;
min-width: 64px;
}
#sidebar.collapsed .sidebar-brand div,
#sidebar.collapsed .sidebar-brand small,
#sidebar.collapsed .nav-link span {
display: none;
}
.sidebar-brand {
padding: .25rem 0;
}
#sidebar .nav-link {
color: #9ca3af;
border-radius: 6px;
padding: .45rem .75rem;
font-size: .875rem;
display: flex;
align-items: center;
gap: .6rem;
transition: background .15s, color .15s;
white-space: nowrap;
}
#sidebar .nav-link i {
font-size: 1rem;
flex-shrink: 0;
}
#sidebar .nav-link:hover { background: rgba(255,255,255,.05); color: #e5e7eb; }
#sidebar .nav-link.active { background: rgba(29,185,84,.15); color: var(--accent-green); }
/* ── Topbar ──────────────────────────────────────────────── */
.topbar {
background: var(--topbar-bg);
border-bottom: 1px solid var(--sidebar-border);
height: 52px;
flex-shrink: 0;
}
/* ── Content ─────────────────────────────────────────────── */
#page-content {
display: flex;
flex-direction: column;
background: var(--content-bg);
height: 100vh;
}
main {
flex: 1;
overflow-y: auto;
}
/* ── Cards ───────────────────────────────────────────────── */
.card {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 10px;
}
.card-header {
background: rgba(0,0,0,.2);
border-bottom: 1px solid var(--card-border);
font-size: .85rem;
font-weight: 600;
color: #d1d5db;
}
/* ── Statistik-Karten ────────────────────────────────────── */
.stat-card { transition: transform .15s; cursor: default; }
.stat-card:hover { transform: translateY(-2px); }
.stat-icon {
width: 44px;
height: 44px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 1.3rem;
}
.stat-value {
font-size: 1.5rem;
font-weight: 700;
line-height: 1;
color: #f3f4f6;
}
.stat-label {
font-size: .72rem;
color: var(--text-muted-custom);
margin-top: 2px;
}
/* ── Tabellen ────────────────────────────────────────────── */
.table {
color: #d1d5db;
font-size: .8rem;
}
.table > thead {
font-size: .75rem;
letter-spacing: .03em;
color: #9ca3af;
}
.table-hover > tbody > tr:hover > td {
background: rgba(255,255,255,.04);
}
.table-dark {
--bs-table-bg: rgba(0,0,0,.3);
}
/* ── Badges ──────────────────────────────────────────────── */
.badge { font-size: .7rem; font-weight: 500; }
/* ── Inputs ──────────────────────────────────────────────── */
.form-control, .form-select {
background-color: #111827;
border-color: var(--card-border);
color: #e5e7eb;
font-size: .8rem;
}
.form-control:focus, .form-select:focus {
border-color: var(--accent-green);
box-shadow: 0 0 0 2px rgba(29,185,84,.25);
background-color: #111827;
color: #f9fafb;
}
.form-control::placeholder { color: #6b7280; }
/* ── Buttons ─────────────────────────────────────────────── */
.btn-success { background-color: var(--accent-green); border-color: var(--accent-green); }
.btn-success:hover { background-color: #17a34a; border-color: #17a34a; }
/* ── Pagination ──────────────────────────────────────────── */
.page-link {
background-color: var(--card-bg);
border-color: var(--card-border);
color: #9ca3af;
font-size: .8rem;
}
.page-link:hover { background-color: rgba(255,255,255,.07); color: #f3f4f6; }
.page-item.active .page-link { background-color: var(--accent-green); border-color: var(--accent-green); color: #000; }
.page-item.disabled .page-link { background-color: transparent; }
/* ── Login-Seite ─────────────────────────────────────────── */
body .card.shadow-lg {
background: #1e2230;
border: 1px solid #2a2f42;
}
/* ── Scrollbars ──────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #374151; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #4b5563; }
/* ── Diverse ─────────────────────────────────────────────── */
.blink {
animation: blink-anim 1.5s infinite;
}
@keyframes blink-anim {
0%, 100% { opacity: 1; }
50% { opacity: .2; }
}
.font-monospace { font-family: 'Consolas', 'Cascadia Code', monospace !important; }
.text-truncate { max-width: 250px; }
/* Chart.js Canvas */
canvas { max-height: 250px; }
/* Alert */
.alert { font-size: .85rem; }
/* sticky-top in dark scrollable containers */
.sticky-top { z-index: 1; }

97
web/static/js/main.js Normal file
View File

@@ -0,0 +1,97 @@
/* ============================================================
MCLogger main.js
Author: SimolZimol
============================================================ */
// ── Sidebar Toggle ────────────────────────────────────────
document.addEventListener('DOMContentLoaded', () => {
const btn = document.getElementById('sidebarToggle');
const sidebar = document.getElementById('sidebar');
if (btn && sidebar) {
btn.addEventListener('click', () => {
sidebar.classList.toggle('collapsed');
localStorage.setItem('sidebar-collapsed', sidebar.classList.contains('collapsed'));
});
// Zustand beim Laden wiederherstellen
if (localStorage.getItem('sidebar-collapsed') === 'true') {
sidebar.classList.add('collapsed');
}
}
// Online-Count aktualisieren
updateOnlineCount();
setInterval(updateOnlineCount, 30_000);
// Tooltips initialisieren
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
new bootstrap.Tooltip(el);
});
// Automatisch Tabellen sortieren ermöglichen
initTableSort();
});
// ── Online-Count API ──────────────────────────────────────
function updateOnlineCount() {
fetch('/api/online')
.then(r => r.json())
.then(data => {
const el = document.getElementById('online-count');
if (el) el.textContent = data.length;
})
.catch(() => {/* Ignorieren wenn nicht eingeloggt */});
}
// ── Einfache Tabellen-Sortierung ──────────────────────────
function initTableSort() {
document.querySelectorAll('th[data-sort]').forEach(th => {
th.style.cursor = 'pointer';
th.addEventListener('click', () => {
const table = th.closest('table');
const idx = Array.from(th.parentNode.children).indexOf(th);
const asc = th.dataset.order !== 'asc';
th.dataset.order = asc ? 'asc' : 'desc';
const rows = Array.from(table.querySelectorAll('tbody tr'));
rows.sort((a, b) => {
const av = a.cells[idx]?.textContent.trim() ?? '';
const bv = b.cells[idx]?.textContent.trim() ?? '';
return asc ? av.localeCompare(bv, 'de', {numeric: true}) : bv.localeCompare(av, 'de', {numeric: true});
});
const tbody = table.querySelector('tbody');
rows.forEach(r => tbody.appendChild(r));
});
});
}
// ── Formatierung ──────────────────────────────────────────
function fmtDuration(sec) {
sec = parseInt(sec) || 0;
const h = Math.floor(sec / 3600);
const m = Math.floor((sec % 3600) / 60);
const s = sec % 60;
if (h) return `${h}h ${m}m`;
if (m) return `${m}m ${s}s`;
return `${s}s`;
}
// ── Live-Chat-Reload (optional) ───────────────────────────
if (window.location.pathname === '/chat') {
// Kein automatisches Reload im Chat (würde Filter zurücksetzen)
}
// ── Kopieren in Zwischenablage ────────────────────────────
document.querySelectorAll('.copy-btn').forEach(btn => {
btn.addEventListener('click', () => {
const target = document.querySelector(btn.dataset.target);
if (target) {
navigator.clipboard.writeText(target.textContent.trim())
.then(() => {
btn.innerHTML = '<i class="bi bi-check2"></i>';
setTimeout(() => btn.innerHTML = '<i class="bi bi-clipboard"></i>', 1500);
});
}
});
});