瀏覽代碼

release v1.5 - MuLTi.V3rSe

epsylon 4 年之前
父節點
當前提交
4709cc40cb

+ 1 - 1
Makefile

@@ -4,7 +4,7 @@ PYTHON=`which python`
 DESTDIR=/
 BUILDIR=$(CURDIR)/debian/ufonet
 PROJECT=ufonet
-VERSION=1.4
+VERSION=1.5
 
 all:
 	@echo "make source - Create source package"

+ 18 - 20
README.md

@@ -1,16 +1,12 @@
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-welcome_small.png "UFONet Welcome")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-welcome_small.png "UFONet Welcome")
 
 ----------
 
- + Web:   https://ufonet.03c8.net
-
- + Video: https://ufonet.03c8.net/ufonet/ufonet-timewars.ogv
+ + Project Website:   https://ufonet.03c8.net
 
 ----------
 
- + FAQ:   https://ufonet.03c8.net/FAQ.html
-
-----------
+#### Description:
 
   UFONet - is a free software, P2P and cryptographic -disruptive toolkit- that allows to perform DoS and DDoS attacks; 
 on the Layer 7 (APP/HTTP) through the exploitation of Open Redirect vectors on third-party websites to act as a botnet 
@@ -18,12 +14,12 @@ and on the Layer3 (Network) abusing the protocol.
 
   See these links for more info:
 
+   - FAQ:
+     https://ufonet.03c8.net/FAQ.html
+
    - CWE-601:Open Redirect: 
      https://cwe.mitre.org/data/definitions/601.html
 
-   - OWASP:URL Redirector Abuse: 
-     https://www.owasp.org/index.php/OWASP_Periodic_Table_of_Vulnerabilities_-_URL_Redirector_Abuse2
-
   ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-schema.png "UFONet Schema")
 
 ----------
@@ -82,21 +78,19 @@ in the [LICENSE](./docs/LICENSE) file.
 
 ####  Screenshots (current version!):
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-shell1_small.png "UFONet Shell")
-
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-shell2_small.png "UFONet Shell Board")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-shell-1.png "UFONet Shell")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-shell3_small.png "UFONet GUI Shell")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-shell-2.png "UFONet Shell Board")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-welcome_small.png "UFONet GUI Welcome")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-shell-3.png "UFONet GUI Shell")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-main_small.png "UFONet GUI Main Panel")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-main_small.png "UFONet GUI Main Panel")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-hydra-botnet_small.png "UFONet GUI Botnet")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-botnet_small.png "UFONet GUI Botnet")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-stats_small.png "UFONet GUI General Stats")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-stats.png "UFONet GUI General Stats")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-singularity-ranking_small.png "UFONet GUI Ranking")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-ranking_small.png "UFONet GUI Ranking")
 
   ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-hydra-board_small.png "UFONet GUI Board/Forum")
 
@@ -106,7 +100,11 @@ in the [LICENSE](./docs/LICENSE) file.
 
   ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-singularity-wargames_small.png "UFONet GUI Wargames")
 
-  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-timewars-attack_small.png "UFONet GUI Attack")
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-streams_small.png "UFONet GUI Streams")
+
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-globalnet_small.png "UFONet GUI GlobalNet")
+
+  ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-multiverse-attack_small.png "UFONet GUI Attack")
 
   ![UFONet](https://ufonet.03c8.net/ufonet/ufonet-gui3_small.png "UFONet GeoMap /deploying/")
 

+ 0 - 7
botnet/aliens.txt

@@ -1,8 +1 @@
 https://gtmetrix.com/analyze.html;$POST;url
-https://isitdown.co.uk/check/;$POST;domainname
-https://www.site24x7.com/check-website-availability.html;$POST;url
-https://nibbler.silktide.com/en_US/report/submit;$POST;url
-https://checkwebsiteonline.com/domain;$POST;url
-https://websitechecker.online/test_url;$POST;url
-https://isitdown.co.uk/check/;$POST;domainname
-https://wheresitup.com/demo/results;$POST;url

File diff suppressed because it is too large
+ 0 - 11561
botnet/dns.txt


+ 0 - 11
botnet/droids.txt

@@ -1,12 +1 @@
 https://jigsaw.w3.org/css-validator/validator?uri=$TARGET&profile=css3&usermedium=all&vextwarning=true
-https://www.openadmintools.com/en/$TARGET
-http://www.statscrop.com/www/$TARGET
-https://www.whatsmydns.net/#A/$TARGET
-http://sitecheck.sucuri.net/results/$TARGET
-https://www.sslshopper.com/ssl-checker.html#hostname=$TARGET
-http://developers.google.com/speed/pagespeed/insights/?url=$TARGET
-https://gsnedders.html5.org/outliner/process.py?url=$TARGET
-http://www.siteworthtraffic.com/report/$TARGET
-http://www.textise.net/showText.aspx?strURL=$TARGET
-http://www.htmlhelp.com/cgi-bin/validate.cgi?url=$TARGET&warnings=yes&spider=yes
-https://mxtoolbox.com/SuperTool.aspx?action=$TARGET

+ 0 - 110
botnet/ntp.txt

@@ -1,111 +1 @@
 185.144.161.170
-91.121.7.182
-81.16.47.5
-194.112.182.172
-129.6.15.29
-129.6.15.30
-129.6.15.27
-129.6.15.26
-132.163.97.1
-132.163.97.2
-132.163.97.3
-132.163.97.4
-132.163.97.6
-132.163.96.1
-132.163.96.2
-132.163.96.3
-132.163.96.4
-132.163.96.6
-132.163.97.7
-128.138.140.44
-128.138.141.172
-128.138.140.50
-194.35.252.7 	
-81.168.77.149
-194.164.127.6
-130.88.203.12
-130.88.200.4
-194.207.34.9
-193.201.200.83
-194.164.127.5
-194.164.127.4
-216.239.35.8
-139.78.97.128 
-137.92.140.80
-128.250.36.2
-138.194.21.154
-130.155.98.1
-130.95.156.206
-104.31.87.35
-103.126.53.123
-129.250.35.251
-146.164.48.5
-142.3.100.2
-52.34.132.170
-146.83.8.202
-200.54.149.24
-195.113.144.201
-131.188.3.220
-131.188.3.221
-131.188.3.222
-131.188.3.223
-130.149.17.21
-130.149.17.8
-192.53.103.108
-192.53.103.104
-129.69.1.153
-138.96.64.10
-145.238.203.14
-138.96.64.10
-140.203.204.77
-193.204.114.232
-193.204.114.233
-200.23.51.102
-193.67.79.202
-193.79.237.14
-129.242.4.241
-129.6.15.28
-150.254.190.51
-193.2.4.2
-118.189.138.5
-194.58.203.20
-194.58.203.148
-194.58.204.20
-194.58.204.148
-128.9.176.30
-208.91.196.74
-193.11.166.8
-193.11.166.20
-194.58.202.20
-194.58.202.148
-192.36.143.150
-192.36.143.151
-162.23.41.10
-195.186.1.100
-104.31.86.35
-193.62.22.98
-199.165.76.11
-204.123.2.5
-164.67.62.194
-149.20.64.28
-209.81.9.7
-192.12.19.20
-204.232.226.192
-208.91.196.74
-132.163.96.1
-132.163.96.2
-132.163.96.3
-132.163.96.4
-128.138.140.44
-192.5.41.209
-192.5.41.40
-128.4.1.1
-128.4.1.2
-128.175.60.175
-128.227.205.3
-130.207.244.240
-140.31.199.22
-96.126.107.76
-173.162.192.156
-192.101.21.1
-146.186.222.14

+ 0 - 55
botnet/rpcs.txt

@@ -1,56 +1 @@
 https://heightsmedia.com/xmlrpc.php
-http://www.ch-orthez.fr/xmlrpc.php
-http://178.62.42.31/xmlrpc.php
-http://131.220.122.225/xmlrpc.php
-http://192.81.222.191/xmlrpc.php
-http://104.236.21.36/xmlrpc.php
-http://128.199.97.120/xmlrpc.php
-http://122.117.66.52/xmlrpc.php
-http://apollomedia.de/xmlrpc.php
-http://www.lifequest-services.com/xmlrpc.php
-http://broketobooked.com/xmlrpc.php
-http://blog.libinpan.com/xmlrpc.php
-http://extensor.no/xmlrpc.php
-http://gotchacovered.bm/xmlrpc.php
-http://missionglobal.com/xmlrpc.php
-http://kompetensnavet.org/xmlrpc.php
-http://195.189.95.152/xmlrpc.php
-http://vatsim-scandinavia.org/xmlrpc.php
-http://www.skidmoreandhall.com/xmlrpc.php
-http://sgcl.ssu.ac.kr/xmlrpc.php
-http://stikespantirapih.ac.id/xmlrpc.php
-https://sifat.org/xmlrpc.php
-http://www.bankingonmainstreet.com/xmlrpc.php
-http://de.alanyatours.net/xmlrpc.php
-http://www.acupeace.com/xmlrpc.php
-http://www.aandd-ps.com/xmlrpc.php
-http://www.egpos.org/xmlrpc.php
-http://www.drivingsales.tv/xmlrpc.php
-http://www.idealvpn.com/xmlrpc.php
-http://www.meteo-agriculture.eu/xmlrpc.php
-http://www.formpac.com/xmlrpc.php
-http://www.mirchimusicawards.com/xmlrpc.php
-http://www.markgoessens.nl/xmlrpc.php
-http://www.openschooldns.com/xmlrpc.php
-http://www.theshawcentre.org.uk/xmlrpc.php
-http://www.fadhilza.com/xmlrpc.php
-http://www.tman.ca/hanas/xmlrpc.php
-http://www.supersupport.com/xmlrpc.php
-http://www.wheresmalta.com/xmlrpc.php
-http://www.unabashedresearch.com/xmlrpc.php
-http://blog.speedbit.com/xmlrpc.php
-http://clothingasconversation.com/xmlrpc.php
-http://preprod.chu-amiens.fr/xmlrpc.php
-http://wp.omni-tech.net/xmlrpc.php
-http://www.bedfactorycontracts.co.uk/xmlrpc.php
-http://www.zs18.wroc.pl/xmlrpc.php
-http://eldermet.ucc.ie/xmlrpc.php
-http://www.litteratureaudio.com/wordpress/xmlrpc.php
-http://digitalequality.net/xmlrpc.php
-http://www.niitsuhome.com/wp/xmlrpc.php
-http://www.fmfracing.com/wordpress/xmlrpc.php
-http://mpillumination.com/xmlrpc.php
-https://www.e-publicrealestate.gr/xmlrpc.php
-http://www.sbc4d.com/xmlrpc.php
-http://www.emotion.lu/xmlrpc.php
-https://mylivegym.gr/xmlrpc.php

+ 0 - 7
botnet/ucavs.txt

@@ -1,8 +1 @@
 https://website-down.com/
-https://isitup.org/
-https://www.downforeveryoneorjustme.com/
-https://www.isitdownrightnow.com/
-https://check-host.net/ip-info?host=
-https://www.isthissitedown.org/site/
-https://downdetector.com/search/?q=
-https://updowntoday.com/en/sites/

+ 0 - 3
botnet/zombies.txt

@@ -1,4 +1 @@
 https://validator.w3.org/nu/?doc=
-http://www.babalweb.net/ar/open.php?url=
-http://translate.google.com/translate?u=
-http://check-host.net/check-http?host=

File diff suppressed because it is too large
+ 1 - 0
core/images/aliens.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien1.txt


File diff suppressed because it is too large
+ 1 - 0
core/images/aliens/alien10.txt


File diff suppressed because it is too large
+ 1 - 0
core/images/aliens/alien11.txt


File diff suppressed because it is too large
+ 1 - 0
core/images/aliens/alien12.txt


File diff suppressed because it is too large
+ 1 - 0
core/images/aliens/alien13.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien2.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien3.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien4.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien5.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien6.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien7.txt


File diff suppressed because it is too large
+ 1 - 1
core/images/aliens/alien8.txt


File diff suppressed because it is too large
+ 1 - 0
core/images/aliens/alien9.txt


+ 827 - 0
core/js/spaceinvaders.js

@@ -0,0 +1,827 @@
+//  Constants for the keyboard.
+var KEY_LEFT = 37;
+var KEY_RIGHT = 39;
+var KEY_SPACE = 32;
+
+//  Creates an instance of the Game class.
+function Game() {
+
+    //  Set the initial config.
+    this.config = {
+        bombRate: 0.05,
+        bombMinVelocity: 50,
+        bombMaxVelocity: 50,
+        invaderInitialVelocity: 25,
+        invaderAcceleration: 0,
+        invaderDropDistance: 20,
+        rocketVelocity: 120,
+        rocketMaxFireRate: 2,
+        gameWidth: 400,
+        gameHeight: 300,
+        fps: 50,
+        debugMode: false,
+        invaderRanks: 5,
+        invaderFiles: 10,
+        shipSpeed: 120,
+        levelDifficultyMultiplier: 0.2,
+        pointsPerInvader: 5,
+        limitLevelIncrease: 25
+    };
+
+    //  All state is in the variables below.
+    this.lives = 3;
+    this.width = 0;
+    this.height = 0;
+    this.gameBounds = {left: 0, top: 0, right: 0, bottom: 0};
+    this.intervalId = 0;
+    this.score = 0;
+    this.level = 1;
+
+    //  The state stack.
+    this.stateStack = [];
+
+    //  Input/output
+    this.pressedKeys = {};
+    this.gameCanvas =  null;
+
+    //  All sounds.
+    this.sounds = null;
+
+    //  The previous x position, used for touch.
+    this.previousX = 0;
+}
+
+//  Initialis the Game with a canvas.
+Game.prototype.initialise = function(gameCanvas) {
+
+    //  Set the game canvas.
+    this.gameCanvas = gameCanvas;
+
+    //  Set the game width and height.
+    this.width = gameCanvas.width;
+    this.height = gameCanvas.height;
+
+    //  Set the state game bounds.
+    this.gameBounds = {
+        left: gameCanvas.width / 2 - this.config.gameWidth / 2,
+        right: gameCanvas.width / 2 + this.config.gameWidth / 2,
+        top: gameCanvas.height / 2 - this.config.gameHeight / 2,
+        bottom: gameCanvas.height / 2 + this.config.gameHeight / 2,
+    };
+};
+
+Game.prototype.moveToState = function(state) {
+ 
+   //  If we are in a state, leave it.
+   if(this.currentState() && this.currentState().leave) {
+     this.currentState().leave(game);
+     this.stateStack.pop();
+   }
+   
+   //  If there's an enter function for the new state, call it.
+   if(state.enter) {
+     state.enter(game);
+   }
+ 
+   //  Set the current state.
+   this.stateStack.pop();
+   this.stateStack.push(state);
+ };
+
+//  Start the Game.
+Game.prototype.start = function() {
+
+    //  Move into the 'welcome' state.
+    this.moveToState(new WelcomeState());
+
+    //  Set the game variables.
+    this.lives = 3;
+    this.config.debugMode = /debug=true/.test(window.location.href);
+
+    //  Start the game loop.
+    var game = this;
+    this.intervalId = setInterval(function () { GameLoop(game);}, 1000 / this.config.fps);
+
+};
+
+//  Returns the current state.
+Game.prototype.currentState = function() {
+    return this.stateStack.length > 0 ? this.stateStack[this.stateStack.length - 1] : null;
+};
+
+//  Mutes or unmutes the game.
+Game.prototype.mute = function(mute) {
+
+    //  If we've been told to mute, mute.
+    if(mute === true) {
+        this.sounds.mute = true;
+    } else if (mute === false) {
+        this.sounds.mute = false;
+    } else {
+        // Toggle mute instead...
+        this.sounds.mute = this.sounds.mute ? false : true;
+    }
+};
+
+//  The main loop.
+function GameLoop(game) {
+    var currentState = game.currentState();
+    if(currentState) {
+
+        //  Delta t is the time to update/draw.
+        var dt = 1 / game.config.fps;
+
+        //  Get the drawing context.
+        var ctx = this.gameCanvas.getContext("2d");
+        
+        //  Update if we have an update function. Also draw
+        //  if we have a draw function.
+        if(currentState.update) {
+            currentState.update(game, dt);
+        }
+        if(currentState.draw) {
+            currentState.draw(game, dt, ctx);
+        }
+    }
+}
+
+Game.prototype.pushState = function(state) {
+
+    //  If there's an enter function for the new state, call it.
+    if(state.enter) {
+        state.enter(game);
+    }
+    //  Set the current state.
+    this.stateStack.push(state);
+};
+
+Game.prototype.popState = function() {
+
+    //  Leave and pop the state.
+    if(this.currentState()) {
+        if(this.currentState().leave) {
+            this.currentState().leave(game);
+        }
+
+        //  Set the current state.
+        this.stateStack.pop();
+    }
+};
+
+//  The stop function stops the game.
+Game.prototype.stop = function Stop() {
+    clearInterval(this.intervalId);
+};
+
+//  Inform the game a key is down.
+Game.prototype.keyDown = function(keyCode) {
+    this.pressedKeys[keyCode] = true;
+    //  Delegate to the current state too.
+    if(this.currentState() && this.currentState().keyDown) {
+        this.currentState().keyDown(this, keyCode);
+    }
+};
+
+Game.prototype.touchstart = function(s) {
+    if(this.currentState() && this.currentState().keyDown) {
+        this.currentState().keyDown(this, KEY_SPACE);
+    }    
+};
+
+Game.prototype.touchend = function(s) {
+    delete this.pressedKeys[KEY_RIGHT];
+    delete this.pressedKeys[KEY_LEFT];
+};
+
+Game.prototype.touchmove = function(e) {
+	var currentX = e.changedTouches[0].pageX;
+    if (this.previousX > 0) {
+        if (currentX > this.previousX) {
+            delete this.pressedKeys[KEY_LEFT];
+            this.pressedKeys[KEY_RIGHT] = true;
+        } else {
+            delete this.pressedKeys[KEY_RIGHT];
+            this.pressedKeys[KEY_LEFT] = true;
+        }
+    }
+    this.previousX = currentX;
+};
+
+//  Inform the game a key is up.
+Game.prototype.keyUp = function(keyCode) {
+    delete this.pressedKeys[keyCode];
+    //  Delegate to the current state too.
+    if(this.currentState() && this.currentState().keyUp) {
+        this.currentState().keyUp(this, keyCode);
+    }
+};
+
+function WelcomeState() {
+
+}
+
+WelcomeState.prototype.enter = function(game) {
+
+    // Create and load the sounds.
+    game.sounds = new Sounds();
+    game.sounds.init();
+    game.sounds.loadSound('shoot', 'sounds/shoot.wav');
+    game.sounds.loadSound('bang', 'sounds/bang.wav');
+    game.sounds.loadSound('explosion', 'sounds/explosion.wav');
+};
+
+WelcomeState.prototype.update = function (game, dt) {
+
+
+};
+
+WelcomeState.prototype.draw = function(game, dt, ctx) {
+
+    //  Clear the background.
+    ctx.clearRect(0, 0, game.width, game.height);
+
+    ctx.font="30px Arial";
+    ctx.fillStyle = '#ffffff';
+    ctx.textBaseline="middle"; 
+    ctx.textAlign="center"; 
+    ctx.fillText("Space Invaders", game.width / 2, game.height/2 - 40); 
+    ctx.font="16px Arial";
+
+    ctx.fillText("Press 'Space' or touch to start.", game.width / 2, game.height/2); 
+};
+
+WelcomeState.prototype.keyDown = function(game, keyCode) {
+    if(keyCode == KEY_SPACE) {
+        //  Space starts the game.
+        game.level = 1;
+        game.score = 0;
+        game.lives = 3;
+        game.moveToState(new LevelIntroState(game.level));
+    }
+};
+
+function GameOverState() {
+
+}
+
+GameOverState.prototype.update = function(game, dt) {
+
+};
+
+GameOverState.prototype.draw = function(game, dt, ctx) {
+
+    //  Clear the background.
+    ctx.clearRect(0, 0, game.width, game.height);
+
+    ctx.font="30px Arial";
+    ctx.fillStyle = '#ffffff';
+    ctx.textBaseline="center"; 
+    ctx.textAlign="center"; 
+    ctx.fillText("Game Over!", game.width / 2, game.height/2 - 40); 
+    ctx.font="16px Arial";
+    ctx.fillText("You scored " + game.score + " and got to level " + game.level, game.width / 2, game.height/2);
+    ctx.font="16px Arial";
+    ctx.fillText("Press 'Space' to play again.", game.width / 2, game.height/2 + 40);   
+};
+
+GameOverState.prototype.keyDown = function(game, keyCode) {
+    if(keyCode == KEY_SPACE) {
+        //  Space restarts the game.
+        game.lives = 3;
+        game.score = 0;
+        game.level = 1;
+        game.moveToState(new LevelIntroState(1));
+    }
+};
+
+//  Create a PlayState with the game config and the level you are on.
+function PlayState(config, level) {
+    this.config = config;
+    this.level = level;
+
+    //  Game state.
+    this.invaderCurrentVelocity =  10;
+    this.invaderCurrentDropDistance =  0;
+    this.invadersAreDropping =  false;
+    this.lastRocketTime = null;
+
+    //  Game entities.
+    this.ship = null;
+    this.invaders = [];
+    this.rockets = [];
+    this.bombs = [];
+}
+
+PlayState.prototype.enter = function(game) {
+
+    //  Create the ship.
+    this.ship = new Ship(game.width / 2, game.gameBounds.bottom);
+
+    //  Setup initial state.
+    this.invaderCurrentVelocity =  10;
+    this.invaderCurrentDropDistance =  0;
+    this.invadersAreDropping =  false;
+
+    //  Set the ship speed for this level, as well as invader params.
+    var levelMultiplier = this.level * this.config.levelDifficultyMultiplier;
+    var limitLevel = (this.level < this.config.limitLevelIncrease ? this.level : this.config.limitLevelIncrease);
+    this.shipSpeed = this.config.shipSpeed;
+    this.invaderInitialVelocity = this.config.invaderInitialVelocity + 1.5 * (levelMultiplier * this.config.invaderInitialVelocity);
+    this.bombRate = this.config.bombRate + (levelMultiplier * this.config.bombRate);
+    this.bombMinVelocity = this.config.bombMinVelocity + (levelMultiplier * this.config.bombMinVelocity);
+    this.bombMaxVelocity = this.config.bombMaxVelocity + (levelMultiplier * this.config.bombMaxVelocity);
+    this.rocketMaxFireRate = this.config.rocketMaxFireRate + 0.4 * limitLevel;
+
+    //  Create the invaders.
+    var ranks = this.config.invaderRanks + 0.1 * limitLevel;
+    var files = this.config.invaderFiles + 0.2 * limitLevel;
+    var invaders = [];
+    for(var rank = 0; rank < ranks; rank++){
+        for(var file = 0; file < files; file++) {
+            invaders.push(new Invader(
+                (game.width / 2) + ((files/2 - file) * 200 / files),
+                (game.gameBounds.top + rank * 20),
+                rank, file, 'Invader'));
+        }
+    }
+    this.invaders = invaders;
+    this.invaderCurrentVelocity = this.invaderInitialVelocity;
+    this.invaderVelocity = {x: -this.invaderInitialVelocity, y:0};
+    this.invaderNextVelocity = null;
+};
+
+PlayState.prototype.update = function(game, dt) {
+    
+    //  If the left or right arrow keys are pressed, move
+    //  the ship. Check this on ticks rather than via a keydown
+    //  event for smooth movement, otherwise the ship would move
+    //  more like a text editor caret.
+    if(game.pressedKeys[KEY_LEFT]) {
+        this.ship.x -= this.shipSpeed * dt;
+    }
+    if(game.pressedKeys[KEY_RIGHT]) {
+        this.ship.x += this.shipSpeed * dt;
+    }
+    if(game.pressedKeys[KEY_SPACE]) {
+        this.fireRocket();
+    }
+
+    //  Keep the ship in bounds.
+    if(this.ship.x < game.gameBounds.left) {
+        this.ship.x = game.gameBounds.left;
+    }
+    if(this.ship.x > game.gameBounds.right) {
+        this.ship.x = game.gameBounds.right;
+    }
+
+    //  Move each bomb.
+    for(var i=0; i<this.bombs.length; i++) {
+        var bomb = this.bombs[i];
+        bomb.y += dt * bomb.velocity;
+
+        //  If the rocket has gone off the screen remove it.
+        if(bomb.y > this.height) {
+            this.bombs.splice(i--, 1);
+        }
+    }
+
+    //  Move each rocket.
+    for(i=0; i<this.rockets.length; i++) {
+        var rocket = this.rockets[i];
+        rocket.y -= dt * rocket.velocity;
+
+        //  If the rocket has gone off the screen remove it.
+        if(rocket.y < 0) {
+            this.rockets.splice(i--, 1);
+        }
+    }
+
+    //  Move the invaders.
+    var hitLeft = false, hitRight = false, hitBottom = false;
+    for(i=0; i<this.invaders.length; i++) {
+        var invader = this.invaders[i];
+        var newx = invader.x + this.invaderVelocity.x * dt;
+        var newy = invader.y + this.invaderVelocity.y * dt;
+        if(hitLeft == false && newx < game.gameBounds.left) {
+            hitLeft = true;
+        }
+        else if(hitRight == false && newx > game.gameBounds.right) {
+            hitRight = true;
+        }
+        else if(hitBottom == false && newy > game.gameBounds.bottom) {
+            hitBottom = true;
+        }
+
+        if(!hitLeft && !hitRight && !hitBottom) {
+            invader.x = newx;
+            invader.y = newy;
+        }
+    }
+
+    //  Update invader velocities.
+    if(this.invadersAreDropping) {
+        this.invaderCurrentDropDistance += this.invaderVelocity.y * dt;
+        if(this.invaderCurrentDropDistance >= this.config.invaderDropDistance) {
+            this.invadersAreDropping = false;
+            this.invaderVelocity = this.invaderNextVelocity;
+            this.invaderCurrentDropDistance = 0;
+        }
+    }
+    //  If we've hit the left, move down then right.
+    if(hitLeft) {
+        this.invaderCurrentVelocity += this.config.invaderAcceleration;
+        this.invaderVelocity = {x: 0, y:this.invaderCurrentVelocity };
+        this.invadersAreDropping = true;
+        this.invaderNextVelocity = {x: this.invaderCurrentVelocity , y:0};
+    }
+    //  If we've hit the right, move down then left.
+    if(hitRight) {
+        this.invaderCurrentVelocity += this.config.invaderAcceleration;
+        this.invaderVelocity = {x: 0, y:this.invaderCurrentVelocity };
+        this.invadersAreDropping = true;
+        this.invaderNextVelocity = {x: -this.invaderCurrentVelocity , y:0};
+    }
+    //  If we've hit the bottom, it's game over.
+    if(hitBottom) {
+        game.lives = 0;
+    }
+    
+    //  Check for rocket/invader collisions.
+    for(i=0; i<this.invaders.length; i++) {
+        var invader = this.invaders[i];
+        var bang = false;
+
+        for(var j=0; j<this.rockets.length; j++){
+            var rocket = this.rockets[j];
+
+            if(rocket.x >= (invader.x - invader.width/2) && rocket.x <= (invader.x + invader.width/2) &&
+                rocket.y >= (invader.y - invader.height/2) && rocket.y <= (invader.y + invader.height/2)) {
+                
+                //  Remove the rocket, set 'bang' so we don't process
+                //  this rocket again.
+                this.rockets.splice(j--, 1);
+                bang = true;
+                game.score += this.config.pointsPerInvader;
+                break;
+            }
+        }
+        if(bang) {
+            this.invaders.splice(i--, 1);
+            game.sounds.playSound('bang');
+        }
+    }
+
+    //  Find all of the front rank invaders.
+    var frontRankInvaders = {};
+    for(var i=0; i<this.invaders.length; i++) {
+        var invader = this.invaders[i];
+        //  If we have no invader for game file, or the invader
+        //  for game file is futher behind, set the front
+        //  rank invader to game one.
+        if(!frontRankInvaders[invader.file] || frontRankInvaders[invader.file].rank < invader.rank) {
+            frontRankInvaders[invader.file] = invader;
+        }
+    }
+
+    //  Give each front rank invader a chance to drop a bomb.
+    for(var i=0; i<this.config.invaderFiles; i++) {
+        var invader = frontRankInvaders[i];
+        if(!invader) continue;
+        var chance = this.bombRate * dt;
+        if(chance > Math.random()) {
+            //  Fire!
+            this.bombs.push(new Bomb(invader.x, invader.y + invader.height / 2, 
+                this.bombMinVelocity + Math.random()*(this.bombMaxVelocity - this.bombMinVelocity)));
+        }
+    }
+
+    //  Check for bomb/ship collisions.
+    for(var i=0; i<this.bombs.length; i++) {
+        var bomb = this.bombs[i];
+        if(bomb.x >= (this.ship.x - this.ship.width/2) && bomb.x <= (this.ship.x + this.ship.width/2) &&
+                bomb.y >= (this.ship.y - this.ship.height/2) && bomb.y <= (this.ship.y + this.ship.height/2)) {
+            this.bombs.splice(i--, 1);
+            game.lives--;
+            game.sounds.playSound('explosion');
+        }
+                
+    }
+
+    //  Check for invader/ship collisions.
+    for(var i=0; i<this.invaders.length; i++) {
+        var invader = this.invaders[i];
+        if((invader.x + invader.width/2) > (this.ship.x - this.ship.width/2) && 
+            (invader.x - invader.width/2) < (this.ship.x + this.ship.width/2) &&
+            (invader.y + invader.height/2) > (this.ship.y - this.ship.height/2) &&
+            (invader.y - invader.height/2) < (this.ship.y + this.ship.height/2)) {
+            //  Dead by collision!
+            game.lives = 0;
+            game.sounds.playSound('explosion');
+        }
+    }
+
+    //  Check for failure
+    if(game.lives <= 0) {
+        game.moveToState(new GameOverState());
+    }
+
+    //  Check for victory
+    if(this.invaders.length === 0) {
+        game.score += this.level * 50;
+        game.level += 1;
+        game.moveToState(new LevelIntroState(game.level));
+    }
+};
+
+PlayState.prototype.draw = function(game, dt, ctx) {
+
+    //  Clear the background.
+    ctx.clearRect(0, 0, game.width, game.height);
+    
+    //  Draw ship.
+    ctx.fillStyle = '#999999';
+    ctx.fillRect(this.ship.x - (this.ship.width / 2), this.ship.y - (this.ship.height / 2), this.ship.width, this.ship.height);
+
+    //  Draw invaders.
+    ctx.fillStyle = '#006600';
+    for(var i=0; i<this.invaders.length; i++) {
+        var invader = this.invaders[i];
+        ctx.fillRect(invader.x - invader.width/2, invader.y - invader.height/2, invader.width, invader.height);
+    }
+
+    //  Draw bombs.
+    ctx.fillStyle = '#ff5555';
+    for(var i=0; i<this.bombs.length; i++) {
+        var bomb = this.bombs[i];
+        ctx.fillRect(bomb.x - 2, bomb.y - 2, 4, 4);
+    }
+
+    //  Draw rockets.
+    ctx.fillStyle = '#ff0000';
+    for(var i=0; i<this.rockets.length; i++) {
+        var rocket = this.rockets[i];
+        ctx.fillRect(rocket.x, rocket.y - 2, 1, 4);
+    }
+
+    //  Draw info.
+    var textYpos = game.gameBounds.bottom + ((game.height - game.gameBounds.bottom) / 2) + 14/2;
+    ctx.font="14px Arial";
+    ctx.fillStyle = '#ffffff';
+    var info = "Lives: " + game.lives;
+    ctx.textAlign = "left";
+    ctx.fillText(info, game.gameBounds.left, textYpos);
+    info = "Score: " + game.score + ", Level: " + game.level;
+    ctx.textAlign = "right";
+    ctx.fillText(info, game.gameBounds.right, textYpos);
+
+    //  If we're in debug mode, draw bounds.
+    if(this.config.debugMode) {
+        ctx.strokeStyle = '#ff0000';
+        ctx.strokeRect(0,0,game.width, game.height);
+        ctx.strokeRect(game.gameBounds.left, game.gameBounds.top,
+            game.gameBounds.right - game.gameBounds.left,
+            game.gameBounds.bottom - game.gameBounds.top);
+    }
+
+};
+
+PlayState.prototype.keyDown = function(game, keyCode) {
+
+    if(keyCode == KEY_SPACE) {
+        //  Fire!
+        this.fireRocket();
+    }
+    if(keyCode == 80) {
+        //  Push the pause state.
+        game.pushState(new PauseState());
+    }
+};
+
+PlayState.prototype.keyUp = function(game, keyCode) {
+
+};
+
+PlayState.prototype.fireRocket = function() {
+    //  If we have no last rocket time, or the last rocket time 
+    //  is older than the max rocket rate, we can fire.
+    if(this.lastRocketTime === null || ((new Date()).valueOf() - this.lastRocketTime) > (1000 / this.rocketMaxFireRate))
+    {   
+        //  Add a rocket.
+        this.rockets.push(new Rocket(this.ship.x, this.ship.y - 12, this.config.rocketVelocity));
+        this.lastRocketTime = (new Date()).valueOf();
+
+        //  Play the 'shoot' sound.
+        game.sounds.playSound('shoot');
+    }
+};
+
+function PauseState() {
+
+}
+
+PauseState.prototype.keyDown = function(game, keyCode) {
+
+    if(keyCode == 80) {
+        //  Pop the pause state.
+        game.popState();
+    }
+};
+
+PauseState.prototype.draw = function(game, dt, ctx) {
+
+    //  Clear the background.
+    ctx.clearRect(0, 0, game.width, game.height);
+
+    ctx.font="14px Arial";
+    ctx.fillStyle = '#ffffff';
+    ctx.textBaseline="middle";
+    ctx.textAlign="center";
+    ctx.fillText("Paused", game.width / 2, game.height/2);
+    return;
+};
+
+/*  
+    Level Intro State
+
+    The Level Intro state shows a 'Level X' message and
+    a countdown for the level.
+*/
+function LevelIntroState(level) {
+    this.level = level;
+    this.countdownMessage = "3";
+}
+
+LevelIntroState.prototype.update = function(game, dt) {
+
+    //  Update the countdown.
+    if(this.countdown === undefined) {
+        this.countdown = 3; // countdown from 3 secs
+    }
+    this.countdown -= dt;
+
+    if(this.countdown < 2) { 
+        this.countdownMessage = "2"; 
+    }
+    if(this.countdown < 1) { 
+        this.countdownMessage = "1"; 
+    } 
+    if(this.countdown <= 0) {
+        //  Move to the next level, popping this state.
+        game.moveToState(new PlayState(game.config, this.level));
+    }
+
+};
+
+LevelIntroState.prototype.draw = function(game, dt, ctx) {
+
+    //  Clear the background.
+    ctx.clearRect(0, 0, game.width, game.height);
+
+    ctx.font="36px Arial";
+    ctx.fillStyle = '#ffffff';
+    ctx.textBaseline="middle"; 
+    ctx.textAlign="center"; 
+    ctx.fillText("Level " + this.level, game.width / 2, game.height/2);
+    ctx.font="24px Arial";
+    ctx.fillText("Ready in " + this.countdownMessage, game.width / 2, game.height/2 + 36);      
+    return;
+};
+
+
+/*
+ 
+  Ship
+
+  The ship has a position and that's about it.
+
+*/
+function Ship(x, y) {
+    this.x = x;
+    this.y = y;
+    this.width = 20;
+    this.height = 16;
+}
+
+/*
+    Rocket
+
+    Fired by the ship, they've got a position, velocity and state.
+
+    */
+function Rocket(x, y, velocity) {
+    this.x = x;
+    this.y = y;
+    this.velocity = velocity;
+}
+
+/*
+    Bomb
+
+    Dropped by invaders, they've got position, velocity.
+
+*/
+function Bomb(x, y, velocity) {
+    this.x = x;
+    this.y = y;
+    this.velocity = velocity;
+}
+ 
+/*
+    Invader 
+
+    Invader's have position, type, rank/file and that's about it. 
+*/
+
+function Invader(x, y, rank, file, type) {
+    this.x = x;
+    this.y = y;
+    this.rank = rank;
+    this.file = file;
+    this.type = type;
+    this.width = 18;
+    this.height = 14;
+}
+
+/*
+    Game State
+
+    A Game State is simply an update and draw proc.
+    When a game is in the state, the update and draw procs are
+    called, with a dt value (dt is delta time, i.e. the number)
+    of seconds to update or draw).
+
+*/
+function GameState(updateProc, drawProc, keyDown, keyUp, enter, leave) {
+    this.updateProc = updateProc;
+    this.drawProc = drawProc;
+    this.keyDown = keyDown;
+    this.keyUp = keyUp;
+    this.enter = enter;
+    this.leave = leave;
+}
+
+/*
+
+    Sounds
+
+    The sounds class is used to asynchronously load sounds and allow
+    them to be played.
+
+*/
+function Sounds() {
+
+    //  The audio context.
+    this.audioContext = null;
+
+    //  The actual set of loaded sounds.
+    this.sounds = {};
+}
+
+Sounds.prototype.init = function() {
+
+    //  Create the audio context, paying attention to webkit browsers.
+    context = window.AudioContext || window.webkitAudioContext;
+    this.audioContext = new context();
+    this.mute = false;
+};
+
+Sounds.prototype.loadSound = function(name, url) {
+
+    //  Reference to ourselves for closures.
+    var self = this;
+
+    //  Create an entry in the sounds object.
+    this.sounds[name] = null;
+
+    //  Create an asynchronous request for the sound.
+    var req = new XMLHttpRequest();
+    req.open('GET', url, true);
+    req.responseType = 'arraybuffer';
+    req.onload = function() {
+        self.audioContext.decodeAudioData(req.response, function(buffer) {
+            self.sounds[name] = {buffer: buffer};
+        });
+    };
+    try {
+      req.send();
+    } catch(e) {
+      console.log("An exception occured getting sound the sound " + name + " this might be " +
+         "because the page is running from the file system, not a webserver.");
+      console.log(e);
+    }
+};
+
+Sounds.prototype.playSound = function(name) {
+
+    //  If we've not got the sound, don't bother playing it.
+    if(this.sounds[name] === undefined || this.sounds[name] === null || this.mute === true) {
+        return;
+    }
+
+    //  Create a sound source, set the buffer, connect to the speakers and
+    //  play the sound.
+    var source = this.audioContext.createBufferSource();
+    source.buffer = this.sounds[name].buffer;
+    source.connect(this.audioContext.destination);
+    source.start(0);
+};

+ 49 - 19
core/main.py

@@ -52,9 +52,9 @@ class UFONet(object):
         self.external_check_service1 = 'https://status.ws/' # set external check service 1 [OK! 26/02/2020]
         self.external_check_service2 = 'https://downforeveryoneorjustme.com/' # set external check service 2 [OK! 26/02/2020]
         self.check_tor_url = 'https://check.torproject.org/' # TOR status checking site
-        self.check_ip_service1 = 'https://checkip.dyndns.com/' # set external check ip service 1 [OK! 28/02/2019]
-        self.check_ip_service2 = 'https://whatismyip.org/' # set external check ip service 2 [OK! 28/02/2019]
-        self.check_ip_service3 = 'https://ip.42.pl/ra' # set external check ip service 3 [OK! 28/02/2019]
+        self.check_ip_service1 = 'https://checkip.org/' # set external check ip service 1 [OK! 06/06/2020]
+        self.check_ip_service2 = 'https://whatismyip.org/' # set external check ip service 2 [OK! 06/06/2020]
+        self.check_ip_service3 = 'https://ip.42.pl/ra' # set external check ip service 3 [OK! [06/06/2020]
         self.agents_file = 'core/txt/user-agents.txt' # set source path to retrieve user-agents
         self.motherships_file = 'core/txt/motherships.txt' # set source path to retrieve mothership names
         self.zombies_file = 'botnet/zombies.txt' # set source path to retrieve [Zombies]
@@ -68,6 +68,9 @@ class UFONet(object):
         self.dorks_file = 'botnet/dorks.txt' # set source path to retrieve [Dorks]
         self.mothership_stats_file = 'core/json/stats.json' # set source for mothership stats
         self.timeline_file = 'docs/VERSION' # set source for code releases
+        self.links_file = "data/links.txt" # set source path to retrieve [Blackhole] [Links]
+        self.streams_file = "data/streams.txt" # set source path to retrieve [Blackhole] [Streams]
+        self.globalnet_file = "data/globalnet.txt" # set source path to retrieve [Blackhole] [Globalnet]
         self.news_file = "data/news.txt" # set source path to retrieve [Blackhole] [News]
         self.missions_file = "data/missions.txt" # set source path to retrieve [Blackhole] [Missions]
         self.board_file = "data/board.txt" # set source path to retrieve [Blackhole] [Board]
@@ -175,14 +178,14 @@ class UFONet(object):
     def banner_welcome(self):
         print("")
         print("                                                0=============================================0")
-        print("                                                ||                                           ||")
-        print("   ||                                     ||    ||  * Botnet -> [DDoS]:                      ||")
-        print(" -(00)-                                 -(00)-  ||      /Zombies : HTTP GET bots             ||")
-        print("   ||                (00)                 ||    ||      /Droids  : HTTP GET (+params) bots   ||")
-        print("        (O)_  (O)  0'----'0  (O)  _(O)          ||      /Aliens  : HTTP POST bots            ||")   
+        print("                   + (XX) +                     ||                                           ||")
+        print("   ||             *~~~~~~~~*              ||    ||  * Botnet -> [DDoS]:                      ||")
+        print(" -(00)-          (0)      (0)           -(00)-  ||      /ZOMBIES : HTTP GET bots             ||")
+        print("   ||             \| (00) |/              ||    ||      /DROIDS  : HTTP GET (+params) bots   ||")
+        print("        (O)_  (O)  0'----'0  (O)  _(O)          ||      /ALIENS  : HTTP POST bots            ||")   
         print("            |  |.''.( xx ).''.|  |              ||      /UCAVs   : Web Abusing bots          ||")
         print("            .'.'   X|'..'|X   '.'.              ||      /X-RPCs  : XML-RPC bots              ||")
-        print("     .-.  .' /'--.__|_00_|__.--'\ '.  .-.       ||      /DBSTRESS: HTTP DB attack            ||")
+        print("     .-.  .' /'--.__|_00_|__.--'\ '.  .-.       ||      /DBSTRESS: HTTP Database flooder     ||")
         print("    (O).)-|0|  \   x| ## |x   /  |0|-(.(O)      ||      /SPRAY   : TCP-SYN reflector         ||")
         print("     `-'  '-'-._'-./ -00- \.-'_.-'-'  `-'       ||      /SMURF   : ICMP echo flooder         ||")
         print("        _ | ||  '-.___||___.-'  || | _          ||      /TACHYON : DNS amplificator          ||")
@@ -192,9 +195,9 @@ class UFONet(object):
         print("    | |(0)| '.  0\||__**_ ||/0  .' |(0)| |      ||      /LOIC    : Fast HTTP requests        ||")
         print("    \ '._.'   '.  | \_##_/ |  .'   '._.' /      ||      /LORIS   : Slow HTTP requests        ||")
         print("     '.__ ____0_'.|__'--'__|.'_0____ __.'       ||      /UFOSYN  : TCP-SYN flooder           ||")
-        print("    .'_.-|                          |-._'.      ||      /XMAS    : TCP-XMAS flooder          ||")
+        print("    .'_.-|            YY            |-._'.      ||      /XMAS    : TCP-XMAS flooder          ||")
         print("                                                ||      /NUKE    : TCP-STARVATION attack     ||") 
-        print("    + Class: UFONet / ViPR404+ (model G) +      ||                                           ||")
+        print("    + Class: UFONet / ViPR404+ (model H) +      ||                                           ||")
         print("                                                0|===========================================|0") 
         print("")
 
@@ -1217,7 +1220,7 @@ class UFONet(object):
                 print("[Error] "+str(e)) 
                 print("\n[AI] Something was wrong generating [Blackhole]... -> [Aborting!]\n")
 
-        # create [Griger] server to share [Stats/Wargames/Messages]
+        # create [Grider] server to share [Stats/Wargames/Messages]
         if options.grider is not None:
             self.banner()
             try:
@@ -2060,6 +2063,12 @@ class UFONet(object):
             grid_reply = urllib.request.urlopen(grid, context=self.ctx, timeout=timeout).read().decode('utf-8')
             wargames = urllib.request.Request('https://'+self.blackhole+'/ufonet/wargames.txt', None, headers)
             wargames_reply = urllib.request.urlopen(wargames, context=self.ctx, timeout=timeout).read().decode('utf-8')
+            links = urllib.request.Request('https://'+self.blackhole+'/ufonet/links.txt', None, headers)
+            links_reply = urllib.request.urlopen(links, context=self.ctx, timeout=timeout).read().decode('utf-8')
+            streams = urllib.request.Request('https://'+self.blackhole+'/ufonet/streams.txt', None, headers)
+            streams_reply = urllib.request.urlopen(streams, context=self.ctx, timeout=timeout).read().decode('utf-8')
+            globalnet = urllib.request.Request('https://'+self.blackhole+'/ufonet/globalnet.txt', None, headers)
+            globalnet_reply = urllib.request.urlopen(globalnet, context=self.ctx, timeout=timeout).read().decode('utf-8')
         else:
             news = urllib.request.Request('http://'+self.blackhole+'/ufonet/news.txt', None, headers)
             news_reply = urllib.request.urlopen(news, context=self.ctx).read().decode('utf-8')
@@ -2071,6 +2080,12 @@ class UFONet(object):
             grid_reply = urllib.request.urlopen(grid, context=self.ctx).read().decode('utf-8')
             wargames = urllib.request.Request('http://'+self.blackhole+'/ufonet/wargames.txt', None, headers)
             wargames_reply = urllib.request.urlopen(wargames, context=self.ctx).read().decode('utf-8')
+            links = urllib.request.Request('http://'+self.blackhole+'/ufonet/links.txt', None, headers)
+            links_reply = urllib.request.urlopen(links, context=self.ctx).read().decode('utf-8')
+            streams = urllib.request.Request('http://'+self.blackhole+'/ufonet/streams.txt', None, headers)
+            streams_reply = urllib.request.urlopen(streams, context=self.ctx).read().decode('utf-8')
+            globalnet = urllib.request.Request('http://'+self.blackhole+'/ufonet/globalnet.txt', None, headers)
+            globalnet_reply = urllib.request.urlopen(globalnet, context=self.ctx).read().decode('utf-8')
         f = open(self.news_file, 'w')
         f.write(news_reply)
         f.close()
@@ -2086,18 +2101,33 @@ class UFONet(object):
         f = open(self.wargames_file, 'w')
         f.write(wargames_reply)
         f.close()
+        f = open(self.links_file, 'w')
+        f.write(links_reply)
+        f.close()
+        f = open(self.streams_file, 'w')
+        f.write(streams_reply)
+        f.close()
+        f = open(self.globalnet_file, 'w')
+        f.write(globalnet_reply)
+        f.close()
         print('-'*25 + "\n")
         print("[Info] [AI] GUI data correctly updated:\n")
         if news_reply:
-            print("[Info] [AI] [News]    : OK!")
+            print("[Info] [AI] [News]     : OK!")
         if missions_reply:
-            print("[Info] [AI] [Missions]: OK!")
+            print("[Info] [AI] [Missions] : OK!")
         if board_reply:
-            print("[Info] [AI] [Board]   : OK!")
+            print("[Info] [AI] [Board]    : OK!")
         if grid_reply:
-            print("[Info] [AI] [Grid]    : OK!")
+            print("[Info] [AI] [Grid]     : OK!")
         if wargames_reply:
-            print("[Info] [AI] [Wargames]: OK!")
+            print("[Info] [AI] [Wargames] : OK!")
+        if links_reply:
+            print("[Info] [AI] [Links]    : OK!")
+        if streams_reply:
+            print("[Info] [AI] [Streams]  : OK!")
+        if globalnet_reply:
+            print("[Info] [AI] [GlobalNet]: OK!")
         print('-'*25)
         print("\n[AI] "+self.exit_msg+"\n")
 
@@ -2435,7 +2465,7 @@ class UFONet(object):
             self.update_transferred_stats(self.trans_zombies) # update json file with transferred stats (blackhole)
             if not self.options.forceyes: # ask for update everything
                 print('-'*25 + "\n")
-                update_reply = input("[AI] You would also like to update other content: [News] [Grid] [Board]... (Y/n)")
+                update_reply = input("[AI] You would also like to update other content: [News] [Missions] [Grid] [Board]... (Y/n)")
             else:
                 update_reply = "Y"
             if update_reply == "n" or update_reply == "N":
@@ -2700,7 +2730,7 @@ class UFONet(object):
             self.update_transferred_stats(self.trans_zombies) # update json file with transferred stats (blackhole)
             if not self.options.forceyes: # ask for update everything
                 print('-'*25 + "\n")
-                update_reply = input("[AI] You would also like to update other content: [News] [Grid] [Board]... (Y/n)")
+                update_reply = input("[AI] You would also like to update other content: [News] [Missions] [Grid] [Board]... (Y/n)")
             else:
                 update_reply = "Y"
             if update_reply == "n" or update_reply == "N":

+ 10 - 5
core/options.py

@@ -41,9 +41,9 @@ class UFONetOptions(optparse.OptionParser):
         self.x_energy = self.extract_x_energy()
         self.formula = self.formula_x_energy()
         optparse.OptionParser.__init__(self, 
-        description='\n{(D)enial(OF)Fensive(S)ervice[ToolKit]}-{by_(io=psy+/03c8.net)}',
+        description='\n{(D)enial(OFF)ensive(S)ervice[ToolKit]}-{by_(io=psy+/03c8.net)}',
         prog='./ufonet',
-        version='\nCode: v1.4.1 [APT] T!M3-WaRS\n')
+        version='\nCode: v1.5 [MLV] - "MuLTi.V3rSe!"\n')
         self.add_option("-v", "--verbose", action="store_true", dest="verbose", help="active verbose on requests")
         self.add_option("--examples", action="store_true", dest="examples", help="print some examples")
         self.add_option("--timeline", action="store_true", dest="timeline", help="show program's code timeline")
@@ -135,17 +135,22 @@ class UFONetOptions(optparse.OptionParser):
         return sengines
 
     def extract_tools(self):
-        tools = ["CYPTER", "NETWORK", "XRAY", "WARPER", "INSPECTOR", "ABDUCTOR", "AI.BOTNET", "AI.GUI", "AI.STATS", "AI.EVASIVE", "BLACKHOLE"]
+        tools = ["CYPTER", "NETWORK", "XRAY", "WARPER", "INSPECTOR", "ABDUCTOR", "AI.BOTNET", "AI.GUI", "AI.STATS", "AI.EVASIVE", "BLACKHOLE", "AI.LINKS", "AI.STREAMS", "AI.BROWSER", "AI.GLOBALNET", "AI.GAMES"]
         tools = len(tools)
         return tools
 
     def extra_tools(self):
         etools =  '\n     _> ABDUCTOR                   * Defensive Shield Detector'
         etools += '\n     _> AI.BOTNET                  * Intelligent Attack System'
+        etools += '\n     _> AI.BROWSER                 * Private Sandbox Browser'
         etools += '\n     _> AI.EVASIVE                 * Automatic Evasion System'
+        etools += '\n     _> AI.GAMES                   * Fun & Games Center'
         etools += '\n     _> AI.GEO                     * Geomapping System'
+        etools += '\n     _> AI.GLOBAL_NET              * Global UFONET Network'
+        etools += '\n     _> AI.LIBRARY                 * Public (data.Links) Library'
         etools += '\n     _> AI.STATS                   * Live Stats Reporter'
-        etools += '\n     _> AI.WEB                     * Visual Interface'
+        etools += '\n     _> AI.STREAMING               * Video (data.Streams) Player'
+        etools += '\n     _> AI.WEB                     * Graphical User Web-Interface'
         etools += '\n     _> BLACKHOLE                  * Warper (p2p.Botnet) Generator'
         etools += '\n     _> CRYPTER                    * Telegram (crypto.Community) System'
         etools += '\n     _> INSPECTOR                  * Objective Scanning Crawler'
@@ -287,7 +292,7 @@ class UFONetOptions(optparse.OptionParser):
             print(self.description, "\n")
             print('='*75)
             self.version = self.version.replace("\n","")
-            print('\n  '+"\u25BC "+self.version+" \u25BC"+' {/Al13n_PerSYSt-[T4]Hunt1ng/}20++ '+"\u25BC"+'\n')
+            print('\n  '+"\u25BC "+self.version+" \u25BC"'\n')
             print("-"*75+"\n")
             print(' -> _BOTNET [DDoS]:   [', format(int(self.total_botnet), '06d'),'] '+"\u25BC"+' Bots (Available)'+ self.ebotnet)
             print('\n -> _DORKS:           [', format(int(self.dorks), '06d'), '] '+"\u25BC"+' Open Redirect (CWE-601) patterns')

+ 56 - 2
core/tools/grider.py

@@ -64,6 +64,21 @@ class Paster(Thread):
                             fc=open(self.parent.target_dir+"wargames.txt","a")
                             fc.write(data+"\n")
                             fc.close()
+                        elif data.find("#L#")!=-1:
+                            print("[Info] [AI] Adding to links")
+                            fc=open(self.parent.target_dir+"links.txt","a")
+                            fc.write(data+"\n")
+                            fc.close()
+                        elif data.find("#S#")!=-1:
+                            print("[Info] [AI] Adding to streams")
+                            fc=open(self.parent.target_dir+"streams.txt","a")
+                            fc.write(data+"\n")
+                            fc.close()
+                        elif data.find("#$#")!=-1:
+                            print("[Info] [AI] Adding to globalnet")
+                            fc=open(self.parent.target_dir+"globalnet.txt","a")
+                            fc.write(data+"\n")
+                            fc.close()
                     conn.close()
         print('[Info] [AI] Done!!!')
         self.sock.close()
@@ -110,6 +125,36 @@ class Grider ( Thread ):
                 wargames_fail = wargames_fail + 1
         else:
             wargames_fail = 0
+        if not os.path.exists(self.target_dir+"links.txt"):
+            links_fail = 0
+            try:
+                fc = open(self.target_dir+'links.txt', 'wb')
+                fc.close()
+            except:
+                print("[Error] [AI] No 'links.txt' file in "+self.target_dir)
+                links_fail = links_fail + 1
+        else:
+            links_fail = 0
+        if not os.path.exists(self.target_dir+"streams.txt"):
+            streams_fail = 0
+            try:
+                fc = open(self.target_dir+'streams.txt', 'wb')
+                fc.close()
+            except:
+                print("[Error] [AI] No 'streams.txt' file in "+self.target_dir)
+                streams_fail = streams_fail + 1
+        else:
+            streams_fail = 0
+        if not os.path.exists(self.target_dir+"globalnet.txt"):
+            globalnet_fail = 0
+            try:
+                fc = open(self.target_dir+'globalnet.txt', 'wb')
+                fc.close()
+            except:
+                print("[Error] [AI] No 'globalnet.txt' file in "+self.target_dir)
+                globalnet_fail = globalnet_fail + 1
+        else:
+            globalnet_fail = 0
         if not os.access(self.target_dir+"grid.txt",os.W_OK):
             print("[Error] [AI] Write access denied for grid file in "+self.target_dir)
             grid_fail = grid_fail + 1
@@ -119,8 +164,17 @@ class Grider ( Thread ):
         if not os.access(self.target_dir+"wargames.txt",os.W_OK):
             print("[Error] [AI] Write access denied for wargames file in "+self.target_dir)
             wargames_fail = wargames_fail + 1
-        if grid_fail > 0 and board_fail > 0 and wargames_fail > 0:
-            print("\n[Error] [AI] 'Grid', 'board' and 'wargames' are unuseable... -> [Aborting!]")
+        if not os.access(self.target_dir+"links.txt",os.W_OK):
+            print("[Error] [AI] Write access denied for links file in "+self.target_dir)
+            links_fail = links_fail + 1
+        if not os.access(self.target_dir+"streams.txt",os.W_OK):
+            print("[Error] [AI] Write access denied for streams file in "+self.target_dir)
+            streams_fail = streams_fail + 1
+        if not os.access(self.target_dir+"globalnet.txt",os.W_OK):
+            print("[Error] [AI] Write access denied for globalnet file in "+self.target_dir)
+            globalnet_fail = globalnet_fail + 1
+        if grid_fail > 0 and board_fail > 0 and wargames_fail > 0 and links_fail > 0 and streams_fail > 0 and globalnet_fail > 0:
+            print("\n[Error] [AI] 'Grid', 'board', 'wargames', 'links', 'streams' and 'globalnet' are unuseable... -> [Aborting!]")
             print("\n[Info] [AI] Suspend [Grider] with: Ctrl+z")
             sys.exit(2)
         self.paster = Paster(self)

File diff suppressed because it is too large
+ 1404 - 73
core/webgui.py


+ 1 - 0
data/games.txt

@@ -0,0 +1 @@
+SpaceInvaders#G#The classic Space Invaders videogame...

+ 0 - 0
data/globalnet.txt


+ 0 - 0
data/links.txt


+ 0 - 0
data/streams.txt


+ 6 - 1
docs/AUTHOR

@@ -17,21 +17,26 @@
 
  software/projects:
 
+ - Anarcha-Pragmatism: Intellectual model (and movement) based on the culture of the "action/reaction".
  - AnonTwi: Tool for OAuth2 applications (such as: GNUSocial, Twitter) that provides different layers of privacy/encryption.
+ - BrAInStocker: Tool to predict (using Linear Regression) the next number within a series of random numbers.
  - Bordercheck: Tool to visualize 'real-time' on a world map the geolocation of data when surfing the web.
- - BrAInStocker: Tool for predicting random numbers.
  - CIntruder: Tool to bypass captchas using OCR (Optical Character Recognition) bruteforcing methods.
  - Collatz: Tool to simulate the Collatz's conjeture.
+ - DiaNA: Tool for the search and recognition of patterns in DNA sequences.
  - DieKunstDerFuge: Video on different topics related to hacktivism recorded during 2013 from an intimate narrative perspective.
  - ECOin: Decentralized key/value registration and transfer system based on Bitcoin technology (a cryptocurrency).
  - Euler-Bricks: Tool to search for Euler's "bricks".
  - Goldbach: Tool to simulate the Goldbach's conjeture.
  - Lorea: Social networking autonomous project to build a distributed, encrypted and federated network.
+ - NeuraLIA tries to learn and reply the correct answer. 
  - Orb: Tool for massive footprinting.
+ - PandeMaths: Tool that simulates a mathematical model of pandemics.
  - pArAnoIA-Browser: Tool designed to surf the Internet using some "paranoic" methods.
  - Propagare: Tool for extraction, organization and semantic analysis of newspapers.
  - PyAISnake: Tool to train AI models on solve spatial problems through the classic video game "snake".
  - PyDog4Apache: Tool to sneak logs from Apache web server.
+ - Smuggler: Tool to detect and exploit HTTP Smuggling vulnerabilities.
  - UFONet: Denial of Service [DDoS & DoS attacks] Toolkit (a botnet of botnets).
  - XSSer: Automatic -framework- to detect, exploit and report XSS vulnerabilities.
 

+ 10 - 0
docs/LEEME.txt

@@ -442,14 +442,24 @@ más algunas "extra":
  - SHIP STATS: Permite consultar las estadísticas de tu "nave"
  - RANKING: Permite consultar tu posición en el "ranking"
  - BOARD: Permite enviar/recibir mensajes con una "nave madre" (un foro)
+ - SHIP LINKS: Permite revisar los enlaces publicados por otras "naves"
+ - SHIP STREAMS: Permite revisar los "streams" (video/audio/directo) publicados por otras "naves"
+ - SHIP GAMES: Permite revisar los "juegos" que contiene tu "nave madre"
+ - BROWSER: Permite navegar/surfear la Internet
+ - GLOBAL.NET: Permite revisar las localizaciones publicadas por otras "naves"
  - WARPS: Permite interactuar con una "nave madre" para subir/bajar 'zombies'
  - GLOBAL GRID: Permite revisar las estadísticas de otras "naves"
  - WARGAMES: Permite proponer y participar en algunos "juegos de guerra" reales
+ - [...]
 
 ###############################
 # Timelog
 ###############################
 
+--------------------------
+08.06.2020 : v.1.5
+--------------------------
+
 --------------------------
 01.02.2020 : v.1.4
 --------------------------

+ 10 - 0
docs/README.txt

@@ -437,14 +437,24 @@ This will open a tab on your default browser with all features of the tool and s
  - SHIP STATS: Allows to review statistics from your "spaceship"
  - RANKING: Allows to check your "ranking" position
  - BOARD: Allows to send/receive messages to/from a "mothership" (a forum)
+ - SHIP LINKS: Allows to review links published by a "mothership"
+ - SHIP STREAMS: Allows to review streams (video/audio/live) published by a "mothership"
+ - SHIP GAMES: Allows to review games from your "spaceship"
+ - BROWSER: Allows to navigate/surf the Internet from a sandbox
+ - GLOBAL.NET: Allows to review locations published by other "motherships"
  - WARPS: Allows to interact with a "mothership" to download/upload "zombies"
  - GLOBAL GRID: Allows to review statistics from other "spaceships"
  - WARGAMES: Allows to propose and join some real "wargames"
+ - [...]
 
 ###############################
 # Timelog
 ###############################
 
+--------------------------
+08.06.2020 : v.1.5
+--------------------------
+
 --------------------------
 01.02.2020 : v.1.4
 --------------------------

+ 18 - 17
docs/VERSION

@@ -1,17 +1,18 @@
-Date	    Size      Version  Alias
---------------------------------------------------
-2013-06-18  7.6kB     0.1b
-2013-06-22  8.3kB     0.2b
-2014-09-17  12.6kB    0.3b
-2014-09-27  12.8kB    0.3.1b   Abduction!
-2014-12-16  36.3kB    0.4b     Infection!
-2015-05-24  59.0kB    0.5b     Invasion!
-2016-02-20  287.5kB   0.6      Galactic Offensive!
-2016-08-18  301.9kB   0.7      Big Crunch!
-2016-12-12  450.8kB   0.8      U-NATi0n!
-2017-07-13  872.5kB   0.9      Blazar!
-2018-03-07  947.9kB   1.0      TachYon!
-2018-09-26  950.7kB   1.1      Quantum Hydra!
-2018-12-31  966.9Kb   1.2      Armageddon!
-2019-03-07    1.0Mb   1.3      SingularitY!
-2020-02-01   25.0Mb   1.4      T!M3-WaRS
+Date	    Size     Version    Alias               
+--------------------------------------------------  
+2013-06-18  7.6kB     0.1_pre_a -                   
+2013-06-22  8.3kB     0.2a      -                   
+2014-09-17  12.6kB    0.3_pre_b -                   
+2014-09-27  12.8kB    0.3.1b    Abduction!          
+2014-12-16  36.3kB    0.4b      Infection!          
+2015-05-24  59.0kB    0.5b      Invasion!           
+2016-02-20  287.5kB   0.6       Galactic Offensive! 
+2016-08-18  301.9kB   0.7       Big Crunch!         
+2016-12-12  450.8kB   0.8       U-NATi0n!           
+2017-07-13  872.5kB   0.9       Blazar!             
+2018-03-07  947.9kB   1.0       TachYon!            
+2018-09-26  950.7kB   1.1       Quantum Hydra!      
+2018-12-31  966.9Kb   1.2       Armageddon!         
+2019-03-07    1.0Mb   1.3       SingularitY!        
+2020-02-01   25.0Mb   1.4       T!M3-WaRS           
+2020-06-08   27.2Mb   1.5       MuLTi.V3rSe!        

+ 1 - 1
docs/release.date

@@ -1 +1 @@
-Sat Feb 01 20:00:02 2020
+Mon Jun  8 12:00:02 2020

+ 1 - 1
setup.py

@@ -18,7 +18,7 @@ from setuptools import setup, find_packages
 
 setup(
     name='ufonet',
-    version='1.4',
+    version='1.5',
     license='GPLv3',
     author_email='epsylon@riseup.net',
     author='psy',