MC / templates /console.html
smodusermc's picture
Create console.html
bc8ca28 verified
Raw History Blame Contribute Delete
8.13 kB
{% extends "base.html" %}
{% block page_title %}Console{% endblock %}
{% block header_actions %}
<div class="btn-group">
<button class="btn btn-secondary" onclick="clearConsole()">Clear Display</button>
<button class="btn btn-secondary" onclick="scrollToBottom()">Scroll to Bottom</button>
</div>
{% endblock %}
{% block content %}
<div class="console-container">
<!-- Console Output -->
<div class="console-window">
<div class="console-header">
<span class="console-title">Server Console</span>
<div class="console-filters">
<select id="log-filter" onchange="filterLogs()">
<option value="all">All Messages</option>
<option value="info">Info</option>
<option value="warn">Warnings</option>
<option value="error">Errors</option>
<option value="chat">Chat</option>
<option value="player">Player Events</option>
</select>
<input type="text" id="log-search" placeholder="Search..." onkeyup="filterLogs()">
</div>
</div>
<div class="console-output" id="console-output">
{% for entry in history %}
<div class="console-line {{ entry.type }}">
<span class="console-time">[{{ entry.timestamp }}]</span>
<span class="console-message">{{ entry.message }}</span>
</div>
{% endfor %}
</div>
</div>
<!-- Command Input -->
<div class="console-input-container">
<form id="command-form" onsubmit="sendCommand(event)">
<div class="input-wrapper">
<span class="input-prefix">&gt;</span>
<input type="text" id="command-input" placeholder="Enter command..." autocomplete="off">
<button type="submit" class="btn btn-primary">Send</button>
</div>
</form>
<div class="command-history-hint">Press ↑/↓ for command history</div>
</div>
<!-- Quick Commands Panel -->
<div class="quick-commands-panel">
<h4>Quick Commands</h4>
<div class="quick-commands-grid">
<div class="quick-cmd-group">
<h5>Server</h5>
<button onclick="sendQuickCmd('save-all')">Save All</button>
<button onclick="sendQuickCmd('list')">List Players</button>
<button onclick="sendQuickCmd('seed')">Show Seed</button>
<button onclick="sendQuickCmd('difficulty')">Difficulty</button>
</div>
<div class="quick-cmd-group">
<h5>Time</h5>
<button onclick="sendQuickCmd('time set day')">Day</button>
<button onclick="sendQuickCmd('time set night')">Night</button>
<button onclick="sendQuickCmd('time set noon')">Noon</button>
<button onclick="sendQuickCmd('time set midnight')">Midnight</button>
</div>
<div class="quick-cmd-group">
<h5>Weather</h5>
<button onclick="sendQuickCmd('weather clear')">Clear</button>
<button onclick="sendQuickCmd('weather rain')">Rain</button>
<button onclick="sendQuickCmd('weather thunder')">Thunder</button>
</div>
<div class="quick-cmd-group">
<h5>Gamemode</h5>
<button onclick="sendQuickCmd('gamemode survival @a')">Survival All</button>
<button onclick="sendQuickCmd('gamemode creative @a')">Creative All</button>
<button onclick="sendQuickCmd('gamemode spectator @a')">Spectator All</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
const socket = io();
const consoleOutput = document.getElementById('console-output');
const commandInput = document.getElementById('command-input');
let commandHistory = [];
let historyIndex = -1;
let allLogs = [];
socket.on('connect', () => {
console.log('Console connected');
});
socket.on('console_output', (data) => {
addConsoleLine(data);
});
socket.on('console_history', (data) => {
data.forEach(entry => addConsoleLine(entry, false));
scrollToBottom();
});
function addConsoleLine(data, scroll = true) {
allLogs.push(data);
const line = document.createElement('div');
line.className = `console-line ${data.type || ''}`;
line.innerHTML = `
<span class="console-time">[${data.timestamp}]</span>
<span class="console-message">${escapeHtml(data.message)}</span>
`;
line.dataset.type = data.type || 'info';
line.dataset.message = data.message.toLowerCase();
consoleOutput.appendChild(line);
// Limit displayed lines
while (consoleOutput.children.length > 1000) {
consoleOutput.removeChild(consoleOutput.firstChild);
}
if (scroll) {
scrollToBottom();
}
filterLogs();
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function sendCommand(e) {
e.preventDefault();
const command = commandInput.value.trim();
if (!command) return;
// Add to history
commandHistory.unshift(command);
if (commandHistory.length > 50) {
commandHistory.pop();
}
historyIndex = -1;
socket.emit('send_command', {command: command});
commandInput.value = '';
}
function sendQuickCmd(cmd) {
socket.emit('send_command', {command: cmd});
}
function clearConsole() {
consoleOutput.innerHTML = '';
allLogs = [];
}
function scrollToBottom() {
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
function filterLogs() {
const filter = document.getElementById('log-filter').value;
const search = document.getElementById('log-search').value.toLowerCase();
const lines = consoleOutput.querySelectorAll('.console-line');
lines.forEach(line => {
let show = true;
// Type filter
if (filter !== 'all') {
const type = line.dataset.type || 'info';
if (filter === 'player') {
show = type.includes('player') || type.includes('join') || type.includes('leave');
} else if (filter === 'chat') {
show = type === 'chat';
} else if (filter === 'warn') {
show = type === 'warning' || type === 'warn';
} else if (filter === 'error') {
show = type === 'error';
} else {
show = type === filter;
}
}
// Search filter
if (show && search) {
show = line.dataset.message.includes(search);
}
line.style.display = show ? '' : 'none';
});
}
// Command history navigation
commandInput.addEventListener('keydown', (e) => {
if (e.key === 'ArrowUp') {
e.preventDefault();
if (historyIndex < commandHistory.length - 1) {
historyIndex++;
commandInput.value = commandHistory[historyIndex];
}
} else if (e.key === 'ArrowDown') {
e.preventDefault();
if (historyIndex > 0) {
historyIndex--;
commandInput.value = commandHistory[historyIndex];
} else if (historyIndex === 0) {
historyIndex = -1;
commandInput.value = '';
}
}
});
// Auto-scroll to bottom on load
scrollToBottom();
</script>
{% endblock %}