diff --git a/dashboard/public/app.js b/dashboard/public/app.js
index e5419d02a9c2e9471cd7656b10d3988a421e1a0a..9f0f53f43f9a5be21e27f29d079a7441fe7babd2 100644
--- a/dashboard/public/app.js
+++ b/dashboard/public/app.js
@@ -32,7 +32,66 @@ const commandForm = document.getElementById('command-form');
const commandInput = document.getElementById('command-input');
const commandHistory = document.getElementById('command-history');
const userEventsList = document.getElementById('user-events-list');
+const adminEventsList = document.getElementById('admin-events-list');
const aiConfigForm = document.getElementById('ai-config-form');
+
+const EVENT_TYPE_LABELS = {
+ 'player_join': '玩家加入',
+ 'player_quit': '玩家离开',
+ 'player_death': '玩家死亡',
+ 'player_chat': 'AI聊天',
+ 'player_message': '公屏消息',
+ 'remote_command': '远程命令',
+ 'server_start': '服务器启动',
+ 'server_stop': '服务器停止'
+};
+
+function formatPlaytime(seconds) {
+ const h = Math.floor(seconds / 3600);
+ const m = Math.floor((seconds % 3600) / 60);
+ const s = seconds % 60;
+ return `${h}小时${m}分${s}秒`;
+}
+
+function formatEventMessage(event) {
+ const time = new Date(event.timestamp).toLocaleTimeString('zh-CN');
+ const type = EVENT_TYPE_LABELS[event.event_type] || event.event_type;
+ const serverName = event.server_name;
+
+ let content = '';
+ switch (event.event_type) {
+ case 'player_join':
+ content = `${event.data.player_name} 加入服务器`;
+ break;
+ case 'player_quit':
+ content = `${event.data.player_name} 离开服务器 (在线 ${formatPlaytime(event.data.playtime)})`;
+ break;
+ case 'player_death':
+ content = event.data.death_message || `${event.data.player_name} 死亡`;
+ if (event.data.killer) {
+ content += ` - 凶手: ${event.data.killer}`;
+ }
+ break;
+ case 'player_chat':
+ case 'player_message':
+ content = `<${event.data.player_name}> ${event.data.message}`;
+ break;
+ case 'remote_command':
+ content = `/ ${event.data.command} (${event.data.sender})`;
+ break;
+ case 'server_start':
+ content = `服务器已启动 (${event.data.version}, ${event.data.max_players} 玩家)`;
+ break;
+ case 'server_stop':
+ content = `服务器已停止`;
+ break;
+ default:
+ content = JSON.stringify(event.data);
+ }
+
+ return `[${time}][${serverName}][${type}]:${content}`;
+}
+
const aiApiUrlInput = document.getElementById('ai-api-url');
const aiModelIdInput = document.getElementById('ai-model-id');
const aiApiKeyInput = document.getElementById('ai-api-key');
@@ -45,6 +104,23 @@ const aiProviderSelect = document.getElementById('ai-provider-select');
const systemLogs = document.getElementById('system-logs');
const clearLogsBtn = document.getElementById('clear-logs-btn');
+function initAdminTabs() {
+ const tabButtons = document.querySelectorAll('.admin-tab-btn');
+ const tabContents = document.querySelectorAll('.admin-tab-content');
+
+ tabButtons.forEach(btn => {
+ btn.addEventListener('click', () => {
+ const tabId = btn.dataset.tab;
+
+ tabButtons.forEach(b => b.classList.remove('active'));
+ tabContents.forEach(c => c.classList.add('hidden'));
+
+ btn.classList.add('active');
+ document.getElementById(`admin-tab-${tabId}`).classList.remove('hidden');
+ });
+ });
+}
+
// AI Providers Configuration
const AI_PROVIDERS = {
openai: {
@@ -184,6 +260,9 @@ function showAdminPanel() {
loadAdminKeys();
loadAIConfig();
+ connectWebSocket();
+
+ initAdminTabs();
}
function showUserPanel() {
@@ -598,22 +677,36 @@ function connectWebSocket() {
}
function addEventToList(event) {
- if (!userEventsList) {
- return;
+ const formattedMessage = formatEventMessage(event);
+
+ if (userEventsList) {
+ const eventItem = document.createElement('div');
+ eventItem.className = 'event-item';
+ eventItem.textContent = formattedMessage;
+ userEventsList.insertBefore(eventItem, userEventsList.firstChild);
+
+ while (userEventsList.children.length > 100) {
+ userEventsList.removeChild(userEventsList.lastChild);
+ }
+
+ if (userEventsList.scrollHeight > userEventsList.clientHeight) {
+ userEventsList.scrollTop = 0;
+ }
}
- const eventItem = document.createElement('div');
- eventItem.className = 'event-item';
- eventItem.innerHTML = `
- ${event.event_type} - ${event.server_name}
- ${new Date(event.timestamp).toLocaleString()}
-
${JSON.stringify(event.data, null, 2)}
- `;
+ if (adminEventsList) {
+ const eventItem = document.createElement('div');
+ eventItem.className = 'event-item';
+ eventItem.textContent = formattedMessage;
+ adminEventsList.insertBefore(eventItem, adminEventsList.firstChild);
- userEventsList.insertBefore(eventItem, userEventsList.firstChild);
+ while (adminEventsList.children.length > 100) {
+ adminEventsList.removeChild(adminEventsList.lastChild);
+ }
- while (userEventsList.children.length > 50) {
- userEventsList.removeChild(userEventsList.lastChild);
+ if (adminEventsList.scrollHeight > adminEventsList.clientHeight) {
+ adminEventsList.scrollTop = 0;
+ }
}
}
diff --git a/dashboard/public/index.html b/dashboard/public/index.html
index 0c9c913ac2f4bd994b917bf5da40315cefbc6a24..dab48a3320922f790fa5bedb859b8a67b88d09f0 100644
--- a/dashboard/public/index.html
+++ b/dashboard/public/index.html
@@ -39,51 +39,68 @@
+ ID: ${regularKey.id}
+Prefix: ${regularKey.keyPrefix}
+ ${regularKey.serverId ? `Server ID: ${regularKey.serverId}
` : ''} +创建时间: ${new Date(regularKey.createdAt).toLocaleString()}
+最后使用: ${regularKey.lastUsed ? new Date(regularKey.lastUsed).toLocaleString() : '从未'}
+