You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

192 lines
3.7 KiB

  1. //External Modules
  2. const objects = require('../objects/objects');
  3. //Helpers
  4. const { route, routeGlobal } = require('./connections/route');
  5. //Module
  6. module.exports = {
  7. players: [],
  8. sockets: null,
  9. playing: 0,
  10. onHandshake: function (socket) {
  11. if (this.players.some(f => f.socket.id === socket.id))
  12. return;
  13. const p = objects.build();
  14. p.socket = socket;
  15. p.addComponent('auth');
  16. p.addComponent('player');
  17. objects.pushObjectToList(p);
  18. this.players.push(p);
  19. },
  20. onDisconnect: function (socket) {
  21. let player = this.players.find(p => p.socket.id === socket.id);
  22. if (!player)
  23. return;
  24. let sessionDuration = 0;
  25. if (player.has('id')) {
  26. if (player.social)
  27. player.social.dc();
  28. sessionDuration = ~~(((+new Date()) - player.player.sessionStart) / 1000);
  29. atlas.updateObject(player, {
  30. components: [{
  31. type: 'stats',
  32. sessionDuration: sessionDuration
  33. }]
  34. });
  35. atlas.removeObject(player);
  36. }
  37. if (player.name) {
  38. this.emit('events', {
  39. onGetMessages: [{
  40. messages: [{
  41. class: 'color-blueB',
  42. message: player.name + ' has gone offline'
  43. }]
  44. }],
  45. onGetDisconnectedPlayer: [player.name]
  46. });
  47. if (player.has('id'))
  48. this.modifyPlayerCount(-1);
  49. }
  50. this.players.spliceWhere(p => p.socket.id === socket.id);
  51. },
  52. route: function (socket, msg) {
  53. route.call(this, socket, msg);
  54. },
  55. routeGlobal: function (msg) {
  56. routeGlobal.call(this, msg);
  57. },
  58. unzone: function (msg) {
  59. let socket = msg.socket;
  60. let player = this.players.find(p => p.socket.id === socket.id);
  61. if (!player)
  62. return;
  63. if (player.social)
  64. player.social.dc();
  65. atlas.removeObject(player, true, this.onUnzone.bind(this, player, msg));
  66. let keys = Object.keys(player);
  67. keys.forEach(function (k) {
  68. let val = player[k];
  69. if (val && val.type) {
  70. if (['player', 'auth', 'syncer'].indexOf(val.type) === -1)
  71. delete player[k];
  72. }
  73. });
  74. this.emit('events', {
  75. onGetMessages: [{
  76. messages: [{
  77. class: 'color-blueB',
  78. message: player.name + ' has gone offline'
  79. }]
  80. }],
  81. onGetDisconnectedPlayer: [player.name]
  82. });
  83. //If we don't do this, the atlas will try to remove it from the thread
  84. delete player.zoneName;
  85. delete player.name;
  86. //A hack to allow us to actually call methods again (like retrieve the player list)
  87. player.dead = false;
  88. player.permadead = false;
  89. delete player.auth.charname;
  90. this.modifyPlayerCount(-1);
  91. },
  92. onUnzone: async function (player, msg) {
  93. msg.callback();
  94. },
  95. logOut: async function (exclude) {
  96. let players = this.players;
  97. let pLen = players.length;
  98. for (let i = 0; i < pLen; i++) {
  99. let p = players[i];
  100. if ((!p) || (p === exclude) || (!p.auth))
  101. continue;
  102. if (p.auth.username === exclude.auth.username) {
  103. if (p.name && p.zoneId)
  104. await atlas.forceSavePlayer(p.name, p.zoneId);
  105. p.socket.emit('dc', {});
  106. }
  107. }
  108. },
  109. emit: function (event, msg) {
  110. this.sockets.emit(event, msg);
  111. },
  112. getCharacterList: function () {
  113. let result = [];
  114. let players = this.players;
  115. let pLen = players.length;
  116. for (let i = 0; i < pLen; i++) {
  117. let p = players[i];
  118. if (!p.name)
  119. continue;
  120. result.push({
  121. zoneName: p.zoneName,
  122. zoneId: p.zoneId,
  123. name: p.name,
  124. level: p.level,
  125. class: p.class,
  126. id: p.id
  127. });
  128. }
  129. return result;
  130. },
  131. forceSaveAll: async function () {
  132. const promises = this.players
  133. .filter(p => p.zoneName !== undefined)
  134. .map(p => {
  135. const promise = new Promise(res => {
  136. const msg = {
  137. cpn: 'auth',
  138. method: 'doSaveManual',
  139. data: {
  140. callbackId: atlas.registerCallback(res)
  141. }
  142. };
  143. atlas.performAction(p, msg);
  144. });
  145. return promise;
  146. });
  147. await Promise.all(promises);
  148. },
  149. modifyPlayerCount: function (delta) {
  150. this.playing += delta;
  151. }
  152. };