colores asignados al azar y simulador de jugadores en el dashboard

This commit is contained in:
2025-08-15 19:09:49 -06:00
parent 310fb3455a
commit 5e42eb7d54
5 changed files with 131 additions and 11 deletions

View File

@@ -331,6 +331,17 @@ class ColyseusService {
return room;
}
async fetchAllowedUuids(): Promise<string[]> {
try {
const res = await fetch(`${this.apiBase}/admin/uuids`);
const data = await res.json();
return Array.isArray(data?.uuids) ? data.uuids : [];
} catch (e) {
console.error('Failed to fetch allowed UUIDs', e);
return [];
}
}
private getUuidFromPath(): string {
if (typeof window === 'undefined') return '';
const path = window.location.pathname.replace(/^\/+/, '');

View File

@@ -25,6 +25,29 @@
</div>
<div class="dashboard-content">
<!-- Open Tabs Section -->
<div class="open-tabs-section">
<div class="section-header">
<h2>🧪 Abrir Pestañas de Jugadores</h2>
</div>
<div class="open-tabs-controls">
<label>Cantidad:</label>
<select v-model="openCount" class="select">
<option :value="1">1 (específico)</option>
<option :value="2">2</option>
<option :value="6">6</option>
<option :value="10">10</option>
</select>
<template v-if="openCount === 1">
<label>UUID:</label>
<select v-model="selectedUuid" class="select">
<option v-for="u in allowedUuids" :key="u" :value="u">{{ u }}</option>
</select>
</template>
<button class="btn btn-open" @click="openTabs">Abrir pestañas</button>
<span class="hint">Abre /{uuid} en nuevas pestañas.</span>
</div>
</div>
<!-- Global Controls Section -->
<div class="global-controls-section">
<div class="section-header">
@@ -213,13 +236,26 @@ const maxReconnectAttempts = 5;
const selectedGlobalVariant = ref('');
const isLoadingGlobal = ref(false);
// Open tabs UI state
const allowedUuids = ref<string[]>([]);
const openCount = ref<1|2|6|10>(1);
const selectedUuid = ref('');
const gameRooms = computed(() => rooms.value.filter(r => r.name === 'game'));
const lobbyRooms = computed(() => rooms.value.filter(r => r.name === 'lobby'));
const totalPlayers = computed(() => rooms.value.reduce((sum, room) => sum + room.clients, 0));
onMounted(() => {
onMounted(async () => {
// Try SSE first, fallback to polling if it fails
initSSE();
// Load allowed UUIDs
try {
const list = await colyseusService.fetchAllowedUuids();
allowedUuids.value = list || [];
if (!selectedUuid.value && allowedUuids.value.length > 0) {
selectedUuid.value = allowedUuids.value[0];
}
} catch {}
});
onUnmounted(() => {
@@ -302,6 +338,31 @@ function goToLobby() {
router.push('/');
}
function openTabs() {
const base = window.location.origin;
const openOne = (uuid: string) => {
const url = `${base}/${uuid}`;
window.open(url, '_blank');
};
if (openCount.value === 1) {
if (!selectedUuid.value) return;
openOne(selectedUuid.value);
return;
}
// Randomly select N distinct UUIDs
const N = openCount.value as number;
const pool = [...allowedUuids.value];
if (pool.length === 0) return;
for (let i = pool.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[pool[i], pool[j]] = [pool[j], pool[i]];
}
const pick = pool.slice(0, Math.min(N, pool.length));
pick.forEach(u => openOne(u));
}
// Global control functions
async function pauseAllGames() {
if (!confirm('Are you sure you want to pause ALL active games?')) return;
@@ -649,6 +710,13 @@ const selectedRoom = computed(() => {
margin: 0 auto;
}
.open-tabs-section { margin: 16px 0 24px; padding: 12px; background:#f8f9fa; border-radius: 10px; color:#333; }
.open-tabs-controls { display:flex; flex-wrap:wrap; gap:10px; align-items:center; }
.open-tabs-controls .select { padding:6px 10px; border-radius:6px; border:1px solid #ddd; }
.btn-open { background:#2196f3; color:white; padding: 8px 12px; border:none; border-radius:8px; cursor:pointer; }
.btn-open:hover { background:#1976d2; }
.hint { color:#666; font-size:12px; }
.global-controls-section {
margin-bottom: 40px;
}
@@ -860,4 +928,4 @@ const selectedRoom = computed(() => {
.btn-lobby:hover {
background: rgba(255, 255, 255, 0.3);
}
</style>
</style>