123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- require("./statistics.js");
- require("./view_stats.js");
- const { count } = require('console');
- const express = require('express');
- const https=require('https')
- const app = express();
- const port = 1337;
- const fs = require('fs');
- const path=require('path');
- var os = require('os');
- stats_start();
- view_stats( app );
- const args = process.argv;
- console.log("Args:");
- console.log(args);
- console.log( "local? = " + ( args['--local'] ) );
- // constants -------------------------------
- const CLEANUP_INTERVAL = 1000 * 1 ; // 1 seconds
- const LOBBY_TIMEOUT_THRESHOLD = 1000 * 60 * 10 ; // 10 minutes
- const PLAYER_TIMEOUT_THRESHOLD = 1000 * 1.5 ; // 1.5 seconds
- const STATS_RESET_TIMER = 1000 * 60; // 1 minutes
- // intervals -----------------------------------
- setInterval( cleanup_stats , STATS_RESET_TIMER );
- function cleanup_stats()
- {
- let d = (new Date());
- let file_date = d.getYear() + "_" + d.getMonth() + "_" + d.getDate() ;
- let csv_file = `./log/stats_${file_date}.csv`;
- // append data
- stats_data[ 'activeLobbies' ] = lobbies.filter( x => x.isActive ).length;
- // csv output
- csv_header = Object.keys( stats_data );
- csv_line = Object.values( stats_data ).toString();
- // handle file
- fs.stat( csv_file , function( err, file_stat ) {
- if (err == null) {
- // console.log('File exists');
- } else if (err.code === 'ENOENT') {
- // file does not exist
- fs.writeFileSync( csv_file , csv_header + os.EOL );
- } else console.log('Error: ', err.code );
- fs.open( csv_file , 'a', 666 , function( e, id ) {
- fs.write( id, csv_line + os.EOL, null, 'utf8', function(){
- fs.close(id, function(){
- // console.log('file is updated');
- });
- });
- });
- // reset stats
- stats_reset();
- });
- }
- setInterval( cleanup, CLEANUP_INTERVAL);
- // app configuration -----------------------
- app.use(express.json()); // Middleware to parse JSON bodies
- if( args.indexOf('--local') != -1)
- {
- app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); });
- }
- else
- {
- const options = {
- key:fs.readFileSync(path.join(__dirname,'../cert/key.pem')),
- cert:fs.readFileSync(path.join(__dirname,'../cert/cert.pem'))
- }
- const sslServer=https.createServer(options,app);
-
- sslServer.listen(port,()=>{ console.log( 'Secure server is listening on port ' + port ); })
- }
- process.on('exit', () => {
- writeAppLog();
- });
- process.on('SIGINT', () => {
- writeAppLog();
- process.exit();
- });
- function cleanup()
- {
- const now = Date.now();
- lobbies.forEach( _L => {
-
- let host_left = false;
- let active_player_count = 0;
- _L.players.forEach( _P => {
- _P.isActive = ( now - _P.lastActive ) < PLAYER_TIMEOUT_THRESHOLD ;
- if( _P.isActive ) active_player_count ++ ;
- if( ! _P.isActive && _P.playerId == _L.hostId )
- {
- host_left = true;
- }
- } );
- _L.isActive = active_player_count > 0 ;
- if( host_left )
- {
- let active_players = _L.players.filter( x => x.isActive );
- if( active_players.length < 1 )
- {
- // lobby is empty
- }
- else
- {
- _L.joinCode = ""; // clean prev join code
- _L.hostMigration = true;
- _L.hostId = active_players[ 0 ].playerId;
- }
- }
- } );
- lobbies = lobbies.filter(x => ( ( now - x.lastActive ) < LOBBY_TIMEOUT_THRESHOLD ) );
- writeAppLog();
- }
- // app log -----------------------------------
- function writeAppLog()
- {
- let out_text = "";
-
- out_text += `"stats":${JSON.stringify(stats_data,null,3)} , \n`;
- const activeLobbies = lobbies.filter( x => x.isActive );
- out_text += `"lobbies":${JSON.stringify(activeLobbies,null,4)}\n`;
- out_text = `{\n${out_text}}`;
- fs.writeFileSync('./log/applog.log', out_text );
- }
- app.get('/viewLog', (req, res) => {
- stats_RecordRequest(req);
- fs.readFile('./log/applog.log', 'utf8', (err, data) => {
- if (err) {
- console.error("Error reading ./log/applog.log:", err);
- res.status(500).send('Error reading log file');
- return;
- }
- res.type('text/plain');
- res.send(data);
- });
- });
- app.get('/viewStats', (req, res ) => {
- stats_RecordRequest(req);
- res.send(stats_data);
- });
- // players & lobby ------------------------------
- let lobbies = [];
- let lobby_index = lobbyKey => lobbies.findIndex( x => x.lobbyKey === lobbyKey );
- function lobby_new( lobbyKey , playerId , lobbyName ) {
- return {
- lobbyKey ,
- lobbyName ,
- isActive : true ,
- hostId : playerId ,
- hostMigration : false ,
- joinCode : "" ,
- region : "",
- createdAt : Date.now(),
- lastActive : Date.now(),
- players : [ player_new( playerId ) ]
- };
- }
- function player_new( playerId ) {
- return {
- playerId ,
- lastActive: Date.now() ,
- isActive : true
- };
- }
- app.post("/lobbies" , (req, res) => {
-
- stats_RecordRequest(req);
-
- let now = Date.now();
- let active_lobbies = lobbies.filter( _L => {
- // filter ( optional )
- for( let k in req.body )
- if( _L[ k ] !== req.body[ k ] )
- return false;
- let active_players = _L.players.filter( x => x.isActive );
- return _L.isActive && active_players.length > 0;
- } );
- active_lobbies = active_lobbies.map( _L => ( {
- lobbyKey : _L.lobbyKey ,
- lobbyName : _L.lobbyName ,
- joinCode : _L.joinCode ,
- aliveDuration : ( now - _L.createdAt ),
- playerCount : _L.players.filter( x => x.isActive ).length
- } ) );
- res.send( { count : active_lobbies.length , data : active_lobbies } );
- });
- app.post("/lobby" , (req, res ) =>
- {
- stats_RecordRequest(req);
-
- output = { found : false };
- const { lobbyKey } = req.body;
-
- let index = lobby_index( lobbyKey );
- if( index >= 0 )
- {
- output.found = true;
- output.data = lobbies[ index ];
- }
- res.send( output );
- } );
- app.post('/lobbySet', ( req, res ) =>
- {
- stats_RecordRequest(req);
-
- output = { found : false };
- const { lobbyKey } = req.body;
-
- let index = lobby_index( lobbyKey );
- if( index >= 0 )
- {
- let lobby = lobbies[ index ];
- for( let k in req.body )
- if( k !== "lobbyKey" )
- lobby[ k ] = req.body[ k ];
- output.found = true;
- output.data = lobbies[ index ];
- }
- res.send( output );
- } );
- app.post('/lobbyJoin', ( req, res ) =>
- {
- stats_RecordRequest(req);
-
- const { lobbyKey , playerId , lobbyName } = req.body;
- let output = { created : false, joined : false, alreadyJoined : false };
- let index = lobby_index( lobbyKey );
- if( index< 0 )
- {
- let lobby = lobby_new( lobbyKey , playerId , lobbyName );
- lobbies.push( lobby );
- output.created = true;
- }
- else
- {
- let lobby = lobbies[ index ];
- lobby.lastActive = Date.now();
-
- let player_index = lobby.players.findIndex( x => x.playerId == playerId );
- if( player_index < 0 )
- {
- lobby.players.push( player_new ( playerId ) );
- output.joined = true;
- }
- else
- {
- let player = lobby.players[ player_index ];
- player.lastActive = Date.now();
- lobby.players[ player_index ] = player;
- output.alreadyJoined = true;
- }
-
- lobbies[ index ] = lobby;
- }
-
- res.send( output );
- });
|