server.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. const express = require('express');
  2. const app = express();
  3. const port = 4000;
  4. const fs = require('fs');
  5. const { join } = require('path');
  6. app.use(express.json()); // Middleware to parse JSON bodies
  7. // constants -------------------------------
  8. const CLEANUP_INTERVAL = 1000 * 7;
  9. const JOINCODE_TIMEOUT_THRESHOLD = 1000 * 10; // 10 seconds
  10. const MIGRATION_TIMEOUT_THRESHOLD = 1000 * 20; // = 60s
  11. // clean up ---------------------------------
  12. setInterval(cleanup, CLEANUP_INTERVAL);
  13. function cleanup() {
  14. const now = Date.now();
  15. joinCodes = joinCodes.filter(code => code.isActive && (now - code.lastActive < JOINCODE_TIMEOUT_THRESHOLD));
  16. // // -- Debug Log --
  17. // for( var i = 0 ; i < migrationCodes.length; ++i ) {
  18. // var code = migrationCodes [ i ] ;
  19. // var delta = now - code.lastActive;
  20. // console.log( `scan [${i}] delta=${delta} / ${MIGRATION_TIMEOUT_THRESHOLD}`);
  21. // if( delta > MIGRATION_TIMEOUT_THRESHOLD ) console.log(`pop ${i}`);
  22. // }
  23. migrationCodes = migrationCodes.filter(code => ( (now - code.lastActive) < MIGRATION_TIMEOUT_THRESHOLD ) );
  24. writeActiveCodesToLog();
  25. }
  26. // app configuration -----------------------
  27. app.listen(port, () => {
  28. console.log(`Server listening at http://localhost:${port}`);
  29. });
  30. process.on('exit', () => {
  31. writeActiveCodesToLog();
  32. });
  33. process.on('SIGINT', () => {
  34. writeActiveCodesToLog();
  35. process.exit();
  36. });
  37. // app log -----------------------------------
  38. function writeActiveCodesToLog()
  39. {
  40. let out_text = `${Date.now()}\n`;
  41. const activeJoinCodes = joinCodes.filter(code => code.isActive);
  42. out_text += `* JOIN CODES:\n${JSON.stringify(activeJoinCodes,null,2)}\n`;
  43. out_text += `* MIGRATION CODES:\n${JSON.stringify(migrationCodes,null,2)}\n`;
  44. fs.writeFileSync('applog.log', out_text );
  45. }
  46. app.get('/viewLog', (req, res) => {
  47. fs.readFile('applog.log', 'utf8', (err, data) => {
  48. if (err) {
  49. console.error("Error reading applog.log:", err);
  50. res.status(500).send('Error reading log file');
  51. return;
  52. }
  53. res.type('text/plain');
  54. res.send(data);
  55. });
  56. });
  57. // join codes ----------------------------------
  58. let joinCodes = [];
  59. app.post('/addJoinCode', (req, res) => {
  60. const { joinCode, isPublic, isActive, isFull } = req.body; // Updated to include isFull
  61. if (joinCode && typeof isPublic !== 'undefined' && typeof isActive !== 'undefined' && typeof isFull !== 'undefined') { // Check for isFull
  62. joinCodes.push({ joinCode, isPublic, isActive, isFull, lastActive: Date.now() }); // Updated to include isFull
  63. res.send({ message: 'Join code added' });
  64. } else {
  65. res.status(400).send({ error: 'Invalid request body' });
  66. }
  67. writeActiveCodesToLog();
  68. });
  69. app.post('/updateActiveStatus', (req, res) => {
  70. const { joinCode, isPublic, isActive, isFull } = req.body;
  71. const joinCodeIndex = joinCodes.findIndex(code => code.joinCode === joinCode);
  72. if (joinCodeIndex >= 0) {
  73. joinCodes[joinCodeIndex].isActive = isActive;
  74. joinCodes[joinCodeIndex].isPublic = isPublic;
  75. joinCodes[joinCodeIndex].isFull = isFull;
  76. joinCodes[joinCodeIndex].lastActive = Date.now();
  77. if (!isActive) {
  78. res.send('Join code will be deactivated');
  79. } else {
  80. res.send('Active status updated');
  81. }
  82. } else {
  83. res.status(404).send('Join code not found');
  84. }
  85. writeActiveCodesToLog();
  86. });
  87. app.get('/getRandomJoinCode', (req, res) => {
  88. const now = Date.now();
  89. const activeJoinCodes = joinCodes.filter(code => code.isPublic && code.isActive && !code.isFull && (now - code.lastActive < JOINCODE_TIMEOUT_THRESHOLD));
  90. if (activeJoinCodes.length === 0) {
  91. res.status(404).send({ error: 'No active public join codes available' });
  92. return;
  93. }
  94. const randomIndex = Math.floor(Math.random() * activeJoinCodes.length);
  95. res.send({ joinCode: activeJoinCodes[randomIndex].joinCode });
  96. });
  97. app.get('/getAllActiveJoinCodes', (req, res) => {
  98. const now = Date.now();
  99. const activeJoinCodes = joinCodes.filter(code => code.isPublic && code.isActive && !code.isFull && (now - code.lastActive < JOINCODE_TIMEOUT_THRESHOLD));
  100. if (activeJoinCodes.length === 0) {
  101. res.status(404).send({ error: 'No active public join codes available' });
  102. return;
  103. }
  104. res.send({ joinCodes: activeJoinCodes.map(code => code.joinCode) });
  105. });
  106. // migration codes ----------------------------------------
  107. let migrationCodes = [];
  108. app.post('/test', ( req, res ) => {
  109. const { lobbyKey , joinCode , hostMigrating , count } = req.body;
  110. const data = { lobbyKey, joinCode, hostMigrating, count };
  111. res.send( req.body );
  112. } );
  113. app.post('/startHostMigration', ( req, res ) =>
  114. {
  115. const { lobbyKey } = req.body;
  116. const idx = migrationCodes.findIndex( x => x.lobbyKey === lobbyKey );
  117. if( idx !== -1 )
  118. {
  119. res.status(403).send( 'migration for this lobbyKey has already started' );
  120. return;
  121. }
  122. if ( lobbyKey )
  123. {
  124. let data = {
  125. lobbyKey,
  126. hostMigrating : false,
  127. count : 0,
  128. joinCode : "null" ,
  129. lastActive: Date.now()
  130. };
  131. migrationCodes.push( data );
  132. res.send({ message: 'migration code added' });
  133. }
  134. else
  135. {
  136. res.status( 400 ).send({ error: 'Invalid request body' });
  137. }
  138. writeActiveCodesToLog();
  139. });
  140. app.post('/updateHostMigration', (req, res) => {
  141. const { lobbyKey , joinCode , hostMigrating , count } = req.body;
  142. const idx = migrationCodes.findIndex( x => x.lobbyKey === lobbyKey );
  143. if (idx >= 0)
  144. {
  145. if( migrationCodes[idx].hostMigrating && hostMigrating )
  146. {
  147. res.status(403).send( 'migration already progress' );
  148. }
  149. else
  150. {
  151. migrationCodes[idx].lastActive = Date.now();
  152. migrationCodes[idx].hostMigrating = hostMigrating;
  153. migrationCodes[idx].joinCode = joinCode;
  154. migrationCodes[idx].count = count;
  155. res.send("migration code updated");
  156. }
  157. }
  158. else
  159. {
  160. res.status(404).send('Lobby key not found');
  161. }
  162. writeActiveCodesToLog();
  163. });
  164. app.get('/getHostMigration', (req, res) => {
  165. const { lobbyKey } = req.body;
  166. const idx = migrationCodes.findIndex( x => x.lobbyKey === lobbyKey );
  167. if( idx < 0 )
  168. {
  169. res.status(404).send({ error: 'lobby key not found' });
  170. return;
  171. }
  172. migrationCodes[ idx ].lastActive = Date.now();
  173. let d_ = migrationCodes[ idx ];
  174. let output =
  175. {
  176. hostMigrating : d_.hostMigrating ,
  177. joinCode : d_.joinCode ,
  178. count : d_.count
  179. }
  180. res.send( output );
  181. });