| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- <!DOCTYPE html>
- <html lang="es">
- <head>
- <meta charset="UTF-8">
- <title>Player Simulator</title>
- <!-- Bootstrap 5 -->
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
-
- <style>
- body {
- background-color: #f5f6fa;
- }
- .log {
- background: #1e1e1e;
- color: #00ff9c;
- height: 220px;
- overflow-y: auto;
- font-family: monospace;
- padding: 10px;
- border-radius: 5px;
- font-size: 0.85rem;
- }
- </style>
- </head>
- <body>
- <div class="container my-4">
- <h1 class="mb-4 text-center">🌍 - Player Simulator</h1>
- <div class="row g-4">
- <div class="col-md-12">
- <div class="alert alert-primary">
- 🧑 Jugador actual: <strong id="playerId"></strong>
- </div>
- </div>
- <!-- Acciones manuales -->
- <div class="col-md-6">
- <div class="card shadow-sm">
- <div class="card-header bg-primary text-white">
- 🎮 Acciones manuales
- </div>
- <div class="card-body d-flex flex-wrap gap-2">
- <button class="btn btn-outline-primary" onclick="sendAction('EXPLORE')">🧭 Explorar</button>
- <button class="btn btn-outline-success" onclick="sendAction('GATHER')">🌿 Recolectar</button>
- <button class="btn btn-outline-danger" onclick="sendAction('FIGHT')">⚔ Combatir</button>
- <button class="btn btn-outline-secondary" onclick="sendAction('REST')">💤 Descansar</button>
- </div>
- </div>
- </div>
- <!-- Acciones automáticas fijas -->
- <div class="col-md-6">
- <div class="card shadow-sm">
- <div class="card-header bg-warning">
- ⏱ Acciones automáticas
- </div>
- <div class="card-body">
- <div class="row g-2">
- <div class="col-md-6">
- <label class="form-label">Acción</label>
- <select id="autoAction" class="form-select">
- <option value="EXPLORE">Explorar</option>
- <option value="GATHER">Recolectar</option>
- <option value="FIGHT">Combatir</option>
- <option value="REST">Descansar</option>
- </select>
- </div>
- <div class="col-md-6">
- <label class="form-label">Cada (ms)</label>
- <input type="number" id="interval" class="form-control" value="2000">
- </div>
- </div>
- <div class="mt-3 d-flex gap-2">
- <button class="btn btn-success" onclick="startAuto()">▶ Iniciar</button>
- <button class="btn btn-danger" onclick="stopAuto()">⏹ Detener</button>
- <span class="badge bg-secondary align-self-center" id="autoStatus">Detenido</span>
- </div>
- </div>
- </div>
- </div>
- <!-- Simulación aleatoria -->
- <div class="col-md-6">
- <div class="card shadow-sm">
- <div class="card-header bg-dark text-white">
- 🎲 Simulación aleatoria
- </div>
- <div class="card-body">
- <label class="form-label">Intervalo (ms)</label>
- <input type="number" id="randomInterval" class="form-control mb-3" value="1000">
- <div class="d-flex gap-2">
- <button class="btn btn-success" onclick="startRandomSimulation()">🎲 Iniciar</button>
- <button class="btn btn-danger" onclick="stopRandomSimulation()">⏹ Detener</button>
- <span class="badge bg-secondary align-self-center" id="randomStatus">Detenida</span>
- </div>
- </div>
- </div>
- </div>
- <!-- Consultas -->
- <div class="col-md-6">
- <div class="card shadow-sm">
- <div class="card-header bg-info text-white">
- 📊 Consultas
- </div>
- <div class="card-body d-flex flex-wrap gap-2">
- <button class="btn btn-outline-info" onclick="fetchState()">🌍 Estado del mundo</button>
- <button class="btn btn-outline-info" onclick="fetchStats()">👤 Stats del jugador</button>
- </div>
- </div>
- </div>
- <!-- Log -->
- <div class="col-12">
- <div class="card shadow-sm">
- <div class="card-header bg-secondary text-white">
- 🧾 Log de eventos
- </div>
- <div class="card-body">
- <div class="log" id="log"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <script>
- const WORLD_API = "http://localhost:8020/world";
- const ACTIONS = ["EXPLORE", "GATHER", "FIGHT", "REST"];
- let autoTimer = null;
- let randomTimer = null;
- function generatePlayerId() {
- return "player-" + crypto.randomUUID();
- }
- let playerId = localStorage.getItem("playerId");
- if (!playerId) {
- playerId = generatePlayerId();
- localStorage.setItem("playerId", playerId);
- }
- document.addEventListener("DOMContentLoaded", () => {
- document.getElementById("playerId").innerText = playerId;
- log(`Jugador registrado con id: ${playerId}`);
- });
-
- function log(message) {
- const logDiv = document.getElementById("log");
- let output;
- if (typeof message === "object") {
- output = JSON.stringify(message, null, 2);
- }
- else if (typeof message === "string") {
- try {
- const parsed = JSON.parse(message);
- output = JSON.stringify(parsed, null, 2);
- } catch {
- output = message;
- }
- }
- else {
- output = String(message);
- }
- const entry = document.createElement("pre");
- entry.textContent = output;
- logDiv.appendChild(entry);
- logDiv.scrollTop = logDiv.scrollHeight;
- }
- function sendAction(action) {
- console.log('sending action '+action);
- fetch(`${WORLD_API}/action`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- playerId: playerId,
- action: action
- })
- })
- .then(res => res.json())
- .then(data => {
- log(`➡ Acción (${action}): `);
- log(data);
- })
- .catch(err => { log(`❌ Error (${action}): ${err}`); });
- }
- function fetchState() {
- fetch(`${WORLD_API}/state`)
- .then(res => res.json())
- .then(data => {
- log(`🌍 Estado mundo: `);
- log(data);
- })
- .catch(err => log("❌ Error al obtener el estado del mundo"));
- }
- function fetchStats() {
- fetch(`${WORLD_API}/players/${playerId}/stats`)
- .then(res => res.json())
- .then(data => {
- log(`📊 Stats jugador:`);
- log(data);
- })
- .catch(err => log("❌ Error al obtener estadísticas"));
- }
- function startAuto() {
- if (autoTimer) return;
- const action = document.getElementById("autoAction").value;
- const interval = parseInt(document.getElementById("interval").value);
- autoTimer = setInterval(() => sendAction(action), interval);
- document.getElementById("autoStatus").className = "badge bg-success";
- document.getElementById("autoStatus").innerText = "En ejecución";
- log(`▶ Acción automática: ${action} cada ${interval} ms`);
- }
- function stopAuto() {
- clearInterval(autoTimer);
- autoTimer = null;
- document.getElementById("autoStatus").className = "badge bg-secondary";
- document.getElementById("autoStatus").innerText = "Detenido";
- log(`⏹ Acción automática detenida`);
- }
- function startRandomSimulation() {
- if (randomTimer) return;
- const interval = parseInt(document.getElementById("randomInterval").value);
- randomTimer = setInterval(() => {
- const action = ACTIONS[Math.floor(Math.random() * ACTIONS.length)];
- sendAction(action);
- }, interval);
- document.getElementById("randomStatus").className = "badge bg-success";
- document.getElementById("randomStatus").innerText = "En ejecución";
- log(`🎲 Simulación aleatoria cada ${interval} ms`);
- }
- function stopRandomSimulation() {
- clearInterval(randomTimer);
- randomTimer = null;
- document.getElementById("randomStatus").className = "badge bg-secondary";
- document.getElementById("randomStatus").innerText = "⛔ Detenida";
- log(`⏹ Simulación aleatoria detenida`);
- }
- </script>
- </body>
- </html>
|