From d389f9c3d19c688f1ada55714891717db5498fb0 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Thu, 16 Nov 2023 11:15:01 +0100 Subject: [PATCH 01/13] #12439 Added Quiet icon to agent finder --- .../operation/search_agents.getdata.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pandora_console/operation/search_agents.getdata.php b/pandora_console/operation/search_agents.getdata.php index bdeea391a1..f4c1fe0d76 100644 --- a/pandora_console/operation/search_agents.getdata.php +++ b/pandora_console/operation/search_agents.getdata.php @@ -169,12 +169,26 @@ if ($searchAgents) { } foreach ($agents as $key => $agent) { + $agent_quiet = ''; + if ((bool) $agent['quiet'] === true) { + $agent_quiet = html_print_image( + 'images/dot_blue.png', + true, + [ + 'border' => '0', + 'title' => __('Quiet'), + 'alt' => '', + 'class' => 'mrgn_lft_5px', + ] + ); + } + if ($agent['disabled']) { $agents[$key]['agent'] = ''.ucfirst(strtolower($agent['alias'])).''.ui_print_help_tip(__('Disabled'), true).''; + title="'.$agent['id_agente'].'">'.ucfirst(strtolower($agent['alias'])).''.ui_print_help_tip(__('Disabled'), true).''.$agent_quiet; } else { $agents[$key]['agent'] = ''.ucfirst(strtolower($agent['alias'])).''; + title='.$agent['nombre'].'>'.ucfirst(strtolower($agent['alias'])).''.$agent_quiet; } $agents[$key]['os'] = ui_print_os_icon($agent['id_os'], false, true); From b6582b7f7ea10588862856e007b63d81d5373cf2 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Wed, 22 Nov 2023 13:30:44 +0100 Subject: [PATCH 02/13] #12202 added Asteroids game --- pandora_console/include/ajax/events.php | 13 + pandora_console/include/asteroids/LICENSE.txt | 25 + pandora_console/include/asteroids/README.rst | 46 + .../include/asteroids/asteroids.js | 840 ++++++++++++++++++ pandora_console/include/asteroids/index.html | 14 + pandora_console/include/asteroids/style.css | 46 + .../include/javascript/pandora_events.js | 45 + pandora_console/include/styles/asteroids.css | 65 ++ pandora_console/operation/menu.php | 1 + 9 files changed, 1095 insertions(+) create mode 100644 pandora_console/include/asteroids/LICENSE.txt create mode 100644 pandora_console/include/asteroids/README.rst create mode 100644 pandora_console/include/asteroids/asteroids.js create mode 100644 pandora_console/include/asteroids/index.html create mode 100644 pandora_console/include/asteroids/style.css create mode 100644 pandora_console/include/styles/asteroids.css diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 7e8341c4a1..88e063b581 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -95,6 +95,8 @@ $parameters_modal = get_parameter('parameters', 0); // User private filter. $current_filter = get_parameter('current_filter', 0); $private_filter_event = get_parameter('private_filter_event', 0); +// Asteroids. +$playAsteroids = (bool) get_parameter('playAsteroids', false); if ($get_comments === true) { global $config; @@ -2751,3 +2753,14 @@ if ($draw_row_response_info === true) { echo $output; return; } + +// Asteroids. +if ($playAsteroids === true) { + echo ui_require_css_file('asteroids', 'include/styles/', true); + echo ui_require_javascript_file('asteroids', 'include/asteroids/', true); + + $output = '
Asteroids game goes here!
'; + + echo $output; + return; +} diff --git a/pandora_console/include/asteroids/LICENSE.txt b/pandora_console/include/asteroids/LICENSE.txt new file mode 100644 index 0000000000..0dc661d166 --- /dev/null +++ b/pandora_console/include/asteroids/LICENSE.txt @@ -0,0 +1,25 @@ +Copyright (c) 2023, James Socol +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + diff --git a/pandora_console/include/asteroids/README.rst b/pandora_console/include/asteroids/README.rst new file mode 100644 index 0000000000..c7465358c2 --- /dev/null +++ b/pandora_console/include/asteroids/README.rst @@ -0,0 +1,46 @@ +========= +ASTEROIDS +========= + +Last week, at work, we joked about creating an Asteroids clone where every +asteroid had a bug number in it, as a bit of a joke. (Ha ha, every bug you +kill spawns two more!) + +I was bored this afternoon, so here's a port of Asteroids to JS/Canvas. + +Now all I need to do is hook in the bug numbers. + + +Gameplay +======== + +You're the triangle in the middle. You want to destroy the circles. You have +a gun (spacebar), some thrusters to turn (left and right arrow keys) and an +engine (up arrow key). + +Remember, it's kill or be killed out there. + + +Rights +====== + +The name *Asteroids* is, as far as I know, still property of Atari. I mean no +ill-will towards Atari by releasing this code. Frankly, it's a poor +substitute for anything resembling a real game. I just wanted to see if I +could do it. + +If anyone from Atari asks, I will gladly rename and/or remove this code. But +since there are so many *Asteroids* clones as it is, and the original was +released in 1979, and it was kind of a copy of *Spacewar!*, I doubt they'll +mind too much. + + +Strikes me as funny... +====================== + +The original *Spacewar!*, one of the earliest (if not the original) computer +games, took `200 hours to code `_. + +This probably took me 6. + +I am so glad we've moved past the PDP-1. diff --git a/pandora_console/include/asteroids/asteroids.js b/pandora_console/include/asteroids/asteroids.js new file mode 100644 index 0000000000..d6e9a460f4 --- /dev/null +++ b/pandora_console/include/asteroids/asteroids.js @@ -0,0 +1,840 @@ +// Asteroids.js +// Copyright (c) 2010–2023 James Socol +// See LICENSE.txt for license terms. + +// Game settings +GAME_HEIGHT = 480; +GAME_WIDTH = 640; +FRAME_PERIOD = 60; // 1 frame / x frames/sec +LEVEL_TIMEOUT = 2000; // How long to wait after clearing a level. + +// Player settings +ROTATE_SPEED = Math.PI / 10; // How fast do players turn? (radians) +MAX_SPEED = 15; // Maximum player speed +THRUST_ACCEL = 1; +DEATH_TIMEOUT = 2000; // milliseconds +INVINCIBLE_TIMEOUT = 1500; // How long to stay invincible after resurrecting? +PLAYER_LIVES = 3; +POINTS_PER_SHOT = 1; // How many points does a shot cost? (Should be >= 0.) +POINTS_TO_EXTRA_LIFE = 1000; // How many points to get a 1-up? + +// Bullet settings +BULLET_SPEED = 20; +MAX_BULLETS = 3; +MAX_BULLET_AGE = 25; + +// Asteroid settings +ASTEROID_COUNT = 2; // This + current level = number of asteroids. +ASTEROID_GENERATIONS = 3; // How many times to they split before dying? +ASTEROID_CHILDREN = 2; // How many does each death create? +ASTEROID_SPEED = 3; +ASTEROID_SCORE = 10; // How many points is each one worth? + +var Asteroids = function(home) { + // Constructor + // Order matters. + + // Set up logging. + this.log_level = Asteroids.LOG_DEBUG; + this.log = Asteroids.logger(this); + + // Create the info pane, player, and playfield. + home.innerHTML = ""; + this.info = Asteroids.infoPane(this, home); + this.playfield = Asteroids.playfield(this, home); + this.player = Asteroids.player(this); + + // Set up the event listeners. + this.keyState = Asteroids.keyState(this); + this.listen = Asteroids.listen(this); + + // Useful functions. + this.asteroids = Asteroids.asteroids(this); + this.overlays = Asteroids.overlays(this); + this.highScores = Asteroids.highScores(this); + this.level = Asteroids.level(this); + this.gameOver = Asteroids.gameOver(this); + + // Play the game. + Asteroids.play(this); + return this; +}; + +Asteroids.infoPane = function(game, home) { + var pane = document.createElement("div"); + pane.innerHTML = "ASTEROIDS"; + + var lives = document.createElement("span"); + lives.className = "lives"; + lives.innerHTML = "LIVES: " + PLAYER_LIVES; + + var score = document.createElement("span"); + score.className = "score"; + score.innerHTML = "SCORE: 0"; + + var level = document.createElement("span"); + level.className = "level"; + level.innerHTML = "LEVEL: 1"; + + pane.appendChild(lives); + pane.appendChild(score); + pane.appendChild(level); + home.appendChild(pane); + + return { + setLives: function(game, l) { + lives.innerHTML = "LIVES: " + l; + }, + setScore: function(game, s) { + score.innerHTML = "SCORE: " + s; + }, + setLevel: function(game, _level) { + level.innerHTML = "LEVEL: " + _level; + }, + getPane: function() { + return pane; + } + }; +}; + +Asteroids.playfield = function(game, home) { + var canvas = document.createElement("canvas"); + canvas.width = GAME_WIDTH; + canvas.height = GAME_HEIGHT; + home.appendChild(canvas); + return canvas; +}; + +Asteroids.logger = function(game) { + if (typeof console != "undefined" && typeof console.log != "undefined") { + return { + info: function(msg) { + if (game.log_level <= Asteroids.LOG_INFO) console.log(msg); + }, + debug: function(msg) { + if (game.log_level <= Asteroids.LOG_DEBUG) console.log(msg); + }, + warning: function(msg) { + if (game.log_level <= Asteroids.LOG_WARNING) console.log(msg); + }, + error: function(msg) { + if (game.log_level <= Asteroids.LOG_ERROR) console.log(msg); + }, + critical: function(msg) { + if (game.log_level <= Asteroids.LOG_CRITICAL) console.log(msg); + } + }; + } else { + return { + info: function(msg) {}, + debug: function(msg) {}, + warning: function(msg) {}, + error: function(msg) {}, + critical: function(msg) {} + }; + } +}; + +Asteroids.asteroids = function(game) { + var asteroids = []; + + return { + push: function(obj) { + return asteroids.push(obj); + }, + pop: function() { + return asteroids.pop(); + }, + splice: function(i, j) { + return asteroids.splice(i, j); + }, + get length() { + return asteroids.length; + }, + getIterator: function() { + return asteroids; + }, + generationCount: function(_gen) { + var total = 0; + for (var i = 0; i < asteroids.length; i++) { + if (asteroids[i].getGeneration() == _gen) total++; + } + game.log.debug("Found " + total + " asteroids in generation " + _gen); + return total; + } + }; +}; + +/** + * Creates an overlays controller. + */ +Asteroids.overlays = function(game) { + var overlays = []; + + return { + draw: function(ctx) { + for (var i = 0; i < overlays.length; i++) { + overlays[i].draw(ctx); + } + }, + add: function(obj) { + if (-1 == overlays.indexOf(obj) && typeof obj.draw != "undefined") { + overlays.push(obj); + return true; + } + return false; + }, + remove: function(obj) { + var i = overlays.indexOf(obj); + if (-1 != i) { + overlays.splice(i, 1); + return true; + } + return false; + } + }; +}; + +/** + * Creates a player object. + */ +Asteroids.player = function(game) { + // implements IScreenObject + var position = [GAME_WIDTH / 2, GAME_HEIGHT / 2], + velocity = [0, 0], + direction = -Math.PI / 2, + dead = false, + invincible = false, + lastRez = null, + lives = PLAYER_LIVES, + score = 0, + radius = 3, + path = [ + [10, 0], + [-5, 5], + [-5, -5], + [10, 0] + ]; + + return { + getPosition: function() { + return position; + }, + getVelocity: function() { + return velocity; + }, + getSpeed: function() { + return Math.sqrt(Math.pow(velocity[0], 2) + Math.pow(velocity[1], 2)); + }, + getDirection: function() { + return direction; + }, + getRadius: function() { + return radius; + }, + getScore: function() { + return score; + }, + addScore: function(pts) { + score += pts; + }, + lowerScore: function(pts) { + score -= pts; + if (score < 0) { + score = 0; + } + }, + getLives: function() { + return lives; + }, + rotate: function(rad) { + if (!dead) { + direction += rad; + game.log.info(direction); + } + }, + thrust: function(force) { + if (!dead) { + velocity[0] += force * Math.cos(direction); + velocity[1] += force * Math.sin(direction); + + if (this.getSpeed() > MAX_SPEED) { + velocity[0] = MAX_SPEED * Math.cos(direction); + velocity[1] = MAX_SPEED * Math.sin(direction); + } + + game.log.info(velocity); + } + }, + move: function() { + Asteroids.move(position, velocity); + }, + draw: function(ctx) { + let color = "#fff"; + if (invincible) { + const dt = (new Date() - lastRez) / 200; + const c = Math.floor(Math.cos(dt) * 16).toString(16); + color = `#${c}${c}${c}`; + } + Asteroids.drawPath(ctx, position, direction, 1, path, color); + }, + isDead: function() { + return dead; + }, + isInvincible: function() { + return invincible; + }, + extraLife: function(game) { + game.log.debug("Woo, extra life!"); + lives++; + }, + die: function(game) { + if (!dead) { + game.log.info("You died!"); + dead = true; + invincible = true; + lives--; + position = [GAME_WIDTH / 2, GAME_HEIGHT / 2]; + velocity = [0, 0]; + direction = -Math.PI / 2; + if (lives > 0) { + setTimeout( + (function(player, _game) { + return function() { + player.resurrect(_game); + }; + })(this, game), + DEATH_TIMEOUT + ); + } else { + game.gameOver(); + } + } + }, + resurrect: function(game) { + if (dead) { + dead = false; + invincible = true; + lastRez = new Date(); + setTimeout(function() { + invincible = false; + game.log.debug("No longer invincible!"); + }, INVINCIBLE_TIMEOUT); + game.log.debug("You ressurrected!"); + } + }, + fire: function(game) { + if (!dead) { + game.log.debug("You fired!"); + var _pos = [position[0], position[1]], + _dir = direction; + + this.lowerScore(POINTS_PER_SHOT); + + return Asteroids.bullet(game, _pos, _dir); + } + } + }; +}; + +Asteroids.bullet = function(game, _pos, _dir) { + // implements IScreenObject + var position = [_pos[0], _pos[1]], + velocity = [0, 0], + direction = _dir, + age = 0, + radius = 1, + path = [ + [0, 0], + [-4, 0] + ]; + + velocity[0] = BULLET_SPEED * Math.cos(_dir); + velocity[1] = BULLET_SPEED * Math.sin(_dir); + + return { + getPosition: function() { + return position; + }, + getVelocity: function() { + return velocity; + }, + getSpeed: function() { + return Math.sqrt(Math.pow(velocity[0], 2) + Math.pow(velocity[1], 2)); + }, + getRadius: function() { + return radius; + }, + getAge: function() { + return age; + }, + birthday: function() { + age++; + }, + move: function() { + Asteroids.move(position, velocity); + }, + draw: function(ctx) { + Asteroids.drawPath(ctx, position, direction, 1, path); + } + }; +}; + +Asteroids.keyState = function(_) { + var state = { + [Asteroids.LEFT]: false, + [Asteroids.UP]: false, + [Asteroids.RIGHT]: false, + [Asteroids.DOWN]: false, + [Asteroids.FIRE]: false + }; + + return { + on: function(key) { + state[key] = true; + }, + off: function(key) { + state[key] = false; + }, + getState: function(key) { + if (typeof state[key] != "undefined") return state[key]; + return false; + } + }; +}; + +Asteroids.listen = function(game) { + const keyMap = { + ArrowLeft: Asteroids.LEFT, + KeyA: Asteroids.LEFT, + ArrowRight: Asteroids.RIGHT, + KeyD: Asteroids.RIGHT, + ArrowUp: Asteroids.UP, + KeyW: Asteroids.UP, + Space: Asteroids.FIRE + }; + + window.addEventListener( + "keydown", + function(e) { + const state = keyMap[e.code]; + if (state) { + e.preventDefault(); + e.stopPropagation(); + game.keyState.on(state); + return false; + } + return true; + }, + true + ); + + window.addEventListener( + "keyup", + function(e) { + const state = keyMap[e.code]; + if (state) { + e.preventDefault(); + e.stopPropagation(); + game.keyState.off(state); + return false; + } + return true; + }, + true + ); +}; + +Asteroids.asteroid = function(game, _gen) { + // implements IScreenObject + var position = [0, 0], + velocity = [0, 0], + direction = 0, + generation = _gen, + radius = 7, + path = [ + [1, 7], + [5, 5], + [7, 1], + [5, -3], + [7, -7], + [3, -9], + [-1, -5], + [-4, -2], + [-8, -1], + [-9, 3], + [-5, 5], + [-1, 3], + [1, 7] + ]; + + return { + getPosition: function() { + return position; + }, + setPosition: function(pos) { + position = pos; + }, + getVelocity: function() { + return velocity; + }, + setVelocity: function(vel) { + velocity = vel; + direction = Math.atan2(vel[1], vel[0]); + }, + getSpeed: function() { + return Math.sqrt(Math.pow(velocity[0], 2) + Math.pow(velocity[1], 2)); + }, + getRadius: function() { + return radius * generation; + }, + getGeneration: function() { + return generation; + }, + move: function() { + Asteroids.move(position, velocity); + }, + draw: function(ctx) { + Asteroids.drawPath(ctx, position, direction, generation, path); + // ctx.setTransform(1, 0, 0, 1, position[0], position[1]); + // ctx.beginPath(); + // ctx.arc(0, 0, radius*generation, 0, Math.PI*2, false); + // ctx.stroke(); + // ctx.closePath(); + } + }; +}; + +Asteroids.collision = function(a, b) { + // if a.getPosition() inside b.getBounds? + var a_pos = a.getPosition(), + b_pos = b.getPosition(); + + function sq(x) { + return Math.pow(x, 2); + } + + var distance = Math.sqrt(sq(a_pos[0] - b_pos[0]) + sq(a_pos[1] - b_pos[1])); + + if (distance <= a.getRadius() + b.getRadius()) return true; + return false; +}; + +Asteroids.level = function(game) { + var level = 0, + speed = ASTEROID_SPEED, + hspeed = ASTEROID_SPEED / 2; + + return { + getLevel: function() { + return level; + }, + levelUp: function(game) { + level++; + game.log.debug("Congrats! On to level " + level); + while ( + game.asteroids.generationCount(ASTEROID_GENERATIONS) < + level + ASTEROID_COUNT + ) { + var a = Asteroids.asteroid(game, ASTEROID_GENERATIONS); + a.setPosition([ + Math.random() * GAME_WIDTH, + Math.random() * GAME_HEIGHT + ]); + a.setVelocity([ + Math.random() * speed - hspeed, + Math.random() * speed - hspeed + ]); + game.asteroids.push(a); + } + } + }; +}; + +Asteroids.gameOver = function(game) { + return function() { + game.log.debug("Game over!"); + + if (game.player.getScore() > 0) { + game.highScores.addScore("Player", game.player.getScore()); + } + + game.overlays.add({ + // implements IOverlay + draw: function(ctx) { + ctx.font = "30px System, monospace"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.fillText("GAME OVER", GAME_WIDTH / 2, GAME_HEIGHT / 2); + + var scores = game.highScores.getScores(); + ctx.font = "12px System, monospace"; + for (var i = 0; i < scores.length; i++) { + ctx.fillText( + scores[i].name + " " + scores[i].score, + GAME_WIDTH / 2, + GAME_HEIGHT / 2 + 20 + 14 * i + ); + } + } + }); + }; +}; + +Asteroids.highScores = function(game) { + var scores = []; + + if ((t = localStorage.getItem("high-scores"))) { + scores = JSON.parse(t); + } + + return { + getScores: function() { + return scores; + }, + addScore: function(_name, _score) { + scores.push({ name: _name, score: _score }); + scores.sort(function(a, b) { + return b.score - a.score; + }); + if (scores.length > 10) { + scores.length = 10; + } + game.log.debug("Saving high scores."); + var str = JSON.stringify(scores); + localStorage.setItem("high-scores", str); + } + }; +}; + +Asteroids.drawPath = function(ctx, position, direction, scale, path, color) { + if (!color) { + color = "#fff"; + } + ctx.strokeStyle = color; + ctx.setTransform( + Math.cos(direction) * scale, + Math.sin(direction) * scale, + -Math.sin(direction) * scale, + Math.cos(direction) * scale, + position[0], + position[1] + ); + + ctx.beginPath(); + ctx.moveTo(path[0][0], path[0][1]); + for (i = 1; i < path.length; i++) { + ctx.lineTo(path[i][0], path[i][1]); + } + ctx.stroke(); + ctx.closePath(); + ctx.strokeStyle = "#fff"; +}; + +Asteroids.move = function(position, velocity) { + position[0] += velocity[0]; + if (position[0] < 0) position[0] = GAME_WIDTH + position[0]; + else if (position[0] > GAME_WIDTH) position[0] -= GAME_WIDTH; + + position[1] += velocity[1]; + if (position[1] < 0) position[1] = GAME_HEIGHT + position[1]; + else if (position[1] > GAME_HEIGHT) position[1] -= GAME_HEIGHT; +}; + +Asteroids.stars = function() { + var stars = []; + for (var i = 0; i < 50; i++) { + stars.push([Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT]); + } + + return { + draw: function(ctx) { + var ii = stars.length; + for (var i = 0; i < ii; i++) { + ctx.fillRect(stars[i][0], stars[i][1], 1, 1); + } + } + }; +}; + +Asteroids.play = function(game) { + var ctx = game.playfield.getContext("2d"); + ctx.fillStyle = "white"; + ctx.strokeStyle = "white"; + + var speed = ASTEROID_SPEED, + hspeed = ASTEROID_SPEED / 2; + + game.level.levelUp(game); + + var bullets = [], + last_fire_state = false, + last_asteroid_count = 0; + + var extra_lives = 0; + + // Add a star field. + game.overlays.add(Asteroids.stars()); + + game.pulse = setInterval(function() { + var kill_asteroids = [], + new_asteroids = [], + kill_bullets = []; + + ctx.save(); + ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT); + + // Be nice and award extra lives first. + var t_extra_lives = game.player.getScore() / POINTS_TO_EXTRA_LIFE; + t_extra_lives = Math.floor(t_extra_lives); + if (t_extra_lives > extra_lives) { + game.player.extraLife(game); + } + extra_lives = t_extra_lives; + + if (game.keyState.getState(Asteroids.UP)) { + game.player.thrust(THRUST_ACCEL); + } + + if (game.keyState.getState(Asteroids.LEFT)) { + game.player.rotate(-ROTATE_SPEED); + } + + if (game.keyState.getState(Asteroids.RIGHT)) { + game.player.rotate(ROTATE_SPEED); + } + + var fire_state = game.keyState.getState(Asteroids.FIRE); + if ( + fire_state && + fire_state != last_fire_state && + bullets.length < MAX_BULLETS + ) { + var b = game.player.fire(game); + bullets.push(b); + } + last_fire_state = fire_state; + + if (!game.player.isDead()) { + game.player.move(); + game.player.draw(ctx); + } + + for (var k = 0; k < bullets.length; k++) { + if (!bullets[k]) continue; + + if (bullets[k].getAge() > MAX_BULLET_AGE) { + kill_bullets.push(k); + continue; + } + bullets[k].birthday(); + bullets[k].move(); + bullets[k].draw(ctx); + } + + for (var r = kill_bullets.length - 1; r >= 0; r--) { + bullets.splice(r, 1); + } + + var asteroids = game.asteroids.getIterator(); + for (var i = 0; i < game.asteroids.length; i++) { + var killit = false; + asteroids[i].move(); + asteroids[i].draw(ctx); + + // Destroy the asteroid + for (var j = 0; j < bullets.length; j++) { + if (!bullets[j]) continue; + if (Asteroids.collision(bullets[j], asteroids[i])) { + game.log.debug("You shot an asteroid!"); + // Destroy the bullet. + bullets.splice(j, 1); + killit = true; // JS doesn't have "continue 2;" + continue; + } + } + + // Kill the asteroid? + if (killit) { + var _gen = asteroids[i].getGeneration() - 1; + if (_gen > 0) { + // Create children ;) + for (var n = 0; n < ASTEROID_CHILDREN; n++) { + var a = Asteroids.asteroid(game, _gen); + var _pos = [ + asteroids[i].getPosition()[0], + asteroids[i].getPosition()[1] + ]; + a.setPosition(_pos); + a.setVelocity([ + Math.random() * speed - hspeed, + Math.random() * speed - hspeed + ]); + new_asteroids.push(a); + } + } + game.player.addScore(ASTEROID_SCORE); + kill_asteroids.push(i); + continue; + } + + // Kill the player? + if ( + !game.player.isDead() && + !game.player.isInvincible() && + Asteroids.collision(game.player, asteroids[i]) + ) { + game.player.die(game); + } + } + + kill_asteroids.sort(function(a, b) { + return a - b; + }); + for (var m = kill_asteroids.length - 1; m >= 0; m--) { + game.asteroids.splice(kill_asteroids[m], 1); + } + + for (var o = 0; o < new_asteroids.length; o++) { + game.asteroids.push(new_asteroids[o]); + } + + ctx.restore(); + + // Do we need to level up? + if (0 == game.asteroids.length && last_asteroid_count != 0) { + setTimeout(function() { + game.level.levelUp(game); + }, LEVEL_TIMEOUT); + } + + last_asteroid_count = game.asteroids.length; + + // Draw overlays. + game.overlays.draw(ctx); + + // Update the info pane. + game.info.setLives(game, game.player.getLives()); + game.info.setScore(game, game.player.getScore()); + game.info.setLevel(game, game.level.getLevel()); + }, FRAME_PERIOD); +}; + +// Some boring constants. +Asteroids.LOG_ALL = 0; +Asteroids.LOG_INFO = 1; +Asteroids.LOG_DEBUG = 2; +Asteroids.LOG_WARNING = 3; +Asteroids.LOG_ERROR = 4; +Asteroids.LOG_CRITICAL = 5; +Asteroids.LOG_NONE = 6; + +Asteroids.LEFT = 37; +Asteroids.UP = 38; +Asteroids.RIGHT = 39; +Asteroids.DOWN = 40; +Asteroids.FIRE = 32; + +// Load it up! +window.onload = Asteroids(document.getElementById("asteroids")); diff --git a/pandora_console/include/asteroids/index.html b/pandora_console/include/asteroids/index.html new file mode 100644 index 0000000000..3c1dfbd690 --- /dev/null +++ b/pandora_console/include/asteroids/index.html @@ -0,0 +1,14 @@ + + + + + Asteroids + + + + +
Asteroids game goes here!
+ + + + diff --git a/pandora_console/include/asteroids/style.css b/pandora_console/include/asteroids/style.css new file mode 100644 index 0000000000..ab877caa06 --- /dev/null +++ b/pandora_console/include/asteroids/style.css @@ -0,0 +1,46 @@ +/* Style for Asteroids.js + * Copyright (c) 2010 James Socol + * See LICENSE.txt for license. + */ + +body { + background-color: #000; + color: #fff; + font-family: "Calibri", "System", monospace; + font-size: 14px; +} + +div#asteroids { + margin: 50px auto; + width: 640px; + border: 1px solid #fff; + padding: 5px; +} + +div#asteroids > * { + color: #fff; +} + +div#asteroids > div { + font-family: "System", monospace; + font-size: 11px; + padding-bottom: 5px; +} + +div#asteroids > div > span { + float: right; + padding-left: 20px; +} + +div#instructions { + width: 640px; + margin: 20px auto; +} + +h1 { + font-size: 18px; +} + +h2 { + font-size: 16px; +} diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index 86b84376c5..f1453ce493 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -1739,3 +1739,48 @@ function loadModal() { } } window.onload = loadModal; + +// Load Asteroids game. +$(window).on("load", function() { + let counter = 0; + $("#button-sound_events_button") + .off("click") + .on("click", function(e) { + counter++; + if (counter == 12) { + $("#modal-asteroids") + .dialog({ + title: "Asteroids", + resizable: true, + modal: true, + width: 900, + height: 700, + open: function() { + $.ajax({ + method: "post", + url: getUrlAjax(), + data: { + page: "include/ajax/events", + playAsteroids: 1 + }, + dataType: "html", + success: function(data) { + $("#modal-asteroids").html(data); + $(".ui-widget-content").css("background", "#222"); + $(".ui-dialog-title").css("color", "#fff"); + }, + error: function(error) { + console.error(error); + } + }); + }, + close: function() { + counter = 0; + $(".ui-widget-content").css("background", "#fff"); + $(".ui-dialog-title").css("color", "rgb(51, 51, 51)"); + } + }) + .show(); + } + }); +}); diff --git a/pandora_console/include/styles/asteroids.css b/pandora_console/include/styles/asteroids.css new file mode 100644 index 0000000000..8b434b59ba --- /dev/null +++ b/pandora_console/include/styles/asteroids.css @@ -0,0 +1,65 @@ +/** + * + * Name: Default theme + * Pandora Stylesheet + * + * @category Stylesheet + * @package Pandora FMS + * @subpackage Community + * @version 1.0.0 + * @license See below + * + * ______ ___ _______ _______ ________ + * | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __| + * | __/| _ | | _ || _ | _| _ | | ___| |__ | + * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| + * + * ============================================================================ + * Copyright (c) 2005-2023 Pandora FMS + * Please see https://pandorafms.com for full contribution list + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation for version 2. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * ============================================================================ + */ + +div#asteroids { + background-color: #000; + color: #fff; + margin: 50px auto; + width: 640px; + border: 1px solid #fff; + padding: 5px; +} + +div#asteroids > * { + color: #fff; +} + +div#asteroids > div { + font-family: "System", monospace; + font-size: 11px; + padding-bottom: 5px; +} + +div#asteroids > div > span { + float: right; + padding-left: 20px; +} + +div#instructions { + width: 640px; + margin: 20px auto; +} + +h1 { + font-size: 18px; +} + +h2 { + font-size: 16px; +} diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 3794a30ae3..2ec659f51a 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -603,6 +603,7 @@ if ($access_console_node === true) { $sub[$javascript]['type'] = 'direct'; echo ''; + echo ''; ui_require_javascript_file('pandora_events'); From 51a152d86d50886b090d1908cf7a41cb1bbc32f6 Mon Sep 17 00:00:00 2001 From: Jorge Rincon Date: Fri, 24 Nov 2023 13:25:42 +0100 Subject: [PATCH 03/13] #12202 Added setup flag for easter egg --- pandora_console/include/javascript/pandora_events.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index f1453ce493..a95ce68899 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -1747,7 +1747,8 @@ $(window).on("load", function() { .off("click") .on("click", function(e) { counter++; - if (counter == 12) { + let flagEasternEgg = $("#flagEasternEgg").val(); + if (counter == 12 && flagEasternEgg == true) { $("#modal-asteroids") .dialog({ title: "Asteroids", From 276cf73e49a113fbd3a80c5591c929c96f5695be Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 12 Dec 2023 10:23:47 +0100 Subject: [PATCH 04/13] #12575 fixed order columns in dashboard --- pandora_console/include/ajax/dashboard.ajax.php | 17 +++++++++++++++-- pandora_console/views/dashboard/list.php | 6 +++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/ajax/dashboard.ajax.php b/pandora_console/include/ajax/dashboard.ajax.php index 50a0e0b7a1..40497a2ebc 100644 --- a/pandora_console/include/ajax/dashboard.ajax.php +++ b/pandora_console/include/ajax/dashboard.ajax.php @@ -41,7 +41,20 @@ if ($method === 'draw') { $length = get_parameter('length', $config['block_size']); $orderBy = get_datatable_order(true); - $sort_field = $orderBy['field']; + switch ($orderBy['field']) { + case 'groups': + $sort_field = 'nombre'; + break; + + case 'favorite': + $sort_field = 'active'; + break; + + default: + $sort_field = $orderBy['field']; + break; + } + $order = $orderBy['direction']; $pagination = ''; @@ -121,7 +134,7 @@ if ($method === 'draw') { ); } - $sql = 'SELECT * FROM tdashboard '.$where.' ORDER BY id '.$pagination; + $sql = 'SELECT * FROM tdashboard LEFT JOIN tgrupo ON tgrupo.id_grupo = tdashboard.id_group '.$where.' ORDER BY '.$sort_field.' '.$order.$pagination; $dashboards = db_get_all_rows_sql($sql); $count = db_get_value_sql('SELECT COUNT(*) FROM tdashboard '.$where); foreach ($dashboards as $dashboard) { diff --git a/pandora_console/views/dashboard/list.php b/pandora_console/views/dashboard/list.php index aae6778f6d..aaf675e64a 100644 --- a/pandora_console/views/dashboard/list.php +++ b/pandora_console/views/dashboard/list.php @@ -112,7 +112,11 @@ if (empty($dashboards) === true) { 'manageDashboards' => $manageDashboards, ], 'default_pagination' => $config['block_size'], - 'no_sortable_columns' => [], + 'no_sortable_columns' => [ + 4, + 5, + 6, + ], 'order' => [ 'field' => 'name', 'direction' => 'desc', From 065b096f14515ebee793f85f097bcf02de63663c Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 14 Dec 2023 10:03:58 +0100 Subject: [PATCH 05/13] #12366 user list 5 users bug styles --- pandora_console/godmode/users/user_list.php | 65 +++++++-------------- pandora_console/include/styles/pandora.css | 11 ++++ 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/pandora_console/godmode/users/user_list.php b/pandora_console/godmode/users/user_list.php index d488b4faad..89607ced69 100644 --- a/pandora_console/godmode/users/user_list.php +++ b/pandora_console/godmode/users/user_list.php @@ -689,7 +689,7 @@ foreach ($info as $user_id => $user_info) { // User profiles. if ($user_is_admin || $user_id == $config['id_user'] || isset($group_um[0])) { $user_profiles = db_get_all_rows_sql( - 'SELECT * FROM tusuario_perfil where id_usuario LIKE "'.$user_id.'" LIMIT 5' + 'SELECT * FROM tusuario_perfil where id_usuario LIKE "'.$user_id.'"' ); } else { $user_profiles_aux = users_get_user_profile($user_id, 'LIMIT 5'); @@ -778,17 +778,24 @@ foreach ($info as $user_id => $user_info) { if ($user_profiles !== false) { $total_profile = 0; - $data[4] .= '
'; + $data[4] .= '
'; foreach ($user_profiles as $row) { + if ($total_profile > 5) { + $data[4] .= "'; + } + + if ($total_profile == 0 && count($user_profiles) > 5) { + $data[4] .= ''.html_print_image( 'images/zoom.png', true, [ @@ -804,8 +811,6 @@ foreach ($info as $user_id => $user_info) { ); } - $data[4] .= '
'; - $total_profile++; } @@ -1052,43 +1057,13 @@ if ($is_management_allowed === true) { ?> diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 53d559b1d0..65212bed73 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -985,6 +985,12 @@ select:-internal-list-box { justify-content: flex-start !important; } +.flex-column-start { + display: flex; + flex-direction: column; + align-items: flex-start; +} + .padding-2 { padding: 2em; } @@ -5530,6 +5536,11 @@ input:checked + .p-slider:before { color: #4d4d4d; } +.show-profiles { + position: absolute; + margin-left: 15%; +} + /* Tables to upload files */ #table_filemanager tr:first-child th span { font-weight: bold; From 1b034d696ca7d3893045c3857f275b7cd2e00af3 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 20 Dec 2023 13:54:20 +0100 Subject: [PATCH 06/13] fix timezone events pandora_enterprise#12677 --- pandora_console/operation/events/events.php | 31 ++++++--------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index e0263ea844..fc04211ef6 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -641,32 +641,17 @@ if (is_ajax() === true) { } if (empty($user_timezone) === true) { - if (date_default_timezone_get() !== $config['timezone']) { - $timezone = timezone_open(date_default_timezone_get()); - $datetime_eur = date_create('now', timezone_open($config['timezone'])); - $dif = timezone_offset_get($timezone, $datetime_eur); - date($config['date_format'], $dif); - if (!date('I')) { - // For summer -3600sec. - $dif -= 3600; - } - - $total_sec = strtotime($tmp->timestamp); - $total_sec += $dif; - $last_contact = date($config['date_format'], $total_sec); - $last_contact_value = ui_print_timestamp($last_contact, true, $options); - } else { - $title = date($config['date_format'], strtotime($tmp->timestamp)); - $value = ui_print_timestamp(strtotime($tmp->timestamp), true, $options); - $last_contact_value = ''.$value.''; + $user_timezone = $config['timezone']; + if (empty($user_timezone) === true) { + $user_timezone = date_default_timezone_get(); } - } else { - date_default_timezone_set($user_timezone); - $title = date($config['date_format'], strtotime($tmp->timestamp)); - $value = ui_print_timestamp(strtotime($tmp->timestamp), true, $options); - $last_contact_value = ''.$value.''; } + date_default_timezone_set($user_timezone); + $title = date($config['date_format'], $tmp->utimestamp); + $value = ui_print_timestamp($tmp->utimestamp, true, $options); + $last_contact_value = ''.$value.''; + $tmp->timestamp = $last_contact_value; if (is_numeric($tmp->data) === true) { From d16f8e689381d63e7853393c377013aa666c42e0 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 21 Dec 2023 10:22:32 +0100 Subject: [PATCH 07/13] #12666 fix events severity color for firefox --- pandora_console/include/styles/events.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandora_console/include/styles/events.css b/pandora_console/include/styles/events.css index 8bcdd7187f..86d2b05f7b 100644 --- a/pandora_console/include/styles/events.css +++ b/pandora_console/include/styles/events.css @@ -129,6 +129,12 @@ table#table_events > tbody > tr > td.column-estado { padding: 0px !important; text-align: center; } +@-moz-document url-prefix() { + table#table_events > tbody > tr, + table#table_events > tbody > tr > td { + height: 100%; + } +} .sorting_desc { background: url(../../images/sort_down_green.png) no-repeat; background-position-x: left; From 706426471ecfa0c453a550ac68a450d5efcfb5fd Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 8 Jan 2024 10:57:32 +0100 Subject: [PATCH 08/13] #12366 fix for spaces on users --- pandora_console/godmode/users/user_list.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pandora_console/godmode/users/user_list.php b/pandora_console/godmode/users/user_list.php index 89607ced69..832c85027e 100644 --- a/pandora_console/godmode/users/user_list.php +++ b/pandora_console/godmode/users/user_list.php @@ -780,8 +780,9 @@ foreach ($info as $user_id => $user_info) { $data[4] .= '
'; foreach ($user_profiles as $row) { + $total_profile++; if ($total_profile > 5) { - $data[4] .= "