Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

215 строки
4.2 KiB

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