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.
 
 
 

225 lines
4.4 KiB

  1. //Imports
  2. const objects = require('../objects/objects');
  3. const events = require('../misc/events');
  4. const {
  5. getThread, killThread, sendMessageToThread, getThreadFromId, doesThreadExist,
  6. returnWhenThreadsIdle, getPlayerCountInThread, killThreadIfEmpty
  7. } = require('./threadManager');
  8. const { registerCallback, removeCallback } = require('./atlas/registerCallback');
  9. //Exports
  10. module.exports = {
  11. nextId: 0,
  12. addObject: async function (obj, keepPos, transfer) {
  13. const serverObj = objects.objects.find(o => o.id === obj.id);
  14. if (!serverObj)
  15. return;
  16. //While rezoning, this is set to true. So we remove it
  17. delete serverObj.rezoning;
  18. events.emit('onBeforePlayerEnterWorld', obj);
  19. let { zoneName, zoneId } = obj;
  20. const partyIds = obj.components.find(c => c.type === 'social')?.party;
  21. if (partyIds) {
  22. const partyLeader = cons.players.find(p => {
  23. if (!partyIds.includes(p.id))
  24. return false;
  25. const cpnSocial = p.components.find(c => c.type === 'social');
  26. if (!cpnSocial)
  27. return false;
  28. return cpnSocial.isPartyLeader;
  29. });
  30. if (partyLeader?.zoneName === zoneName)
  31. zoneId = partyLeader.zoneId;
  32. }
  33. const eGetThread = {
  34. zoneName,
  35. zoneId
  36. };
  37. if (!doesThreadExist(eGetThread)) {
  38. serverObj.socket.emit('event', {
  39. event: 'onGetAnnouncement',
  40. data: {
  41. msg: 'Generating a new map, please wait as this may take a few moments..',
  42. ttl: 500
  43. }
  44. });
  45. }
  46. const { thread, resetObjPosition } = await getThread(eGetThread);
  47. //Perhaps the player disconnected while waiting for the thread to spawn
  48. if (!serverObj.socket.connected) {
  49. await killThreadIfEmpty(thread);
  50. return;
  51. }
  52. if (resetObjPosition) {
  53. delete obj.x;
  54. delete obj.y;
  55. }
  56. obj.zoneName = thread.name;
  57. obj.zoneId = thread.id;
  58. serverObj.zoneId = thread.id;
  59. serverObj.zoneName = thread.name;
  60. events.emit('playerObjChanged', {
  61. obj
  62. });
  63. const simpleObj = obj.getSimple ? obj.getSimple(true, true) : obj;
  64. sendMessageToThread({
  65. threadId: obj.zoneId,
  66. msg: {
  67. method: 'addObject',
  68. args: {
  69. keepPos: keepPos,
  70. obj: simpleObj,
  71. transfer: transfer
  72. }
  73. }
  74. });
  75. },
  76. removeObjectFromInstancedZone: async function (thread, objId, callback) {
  77. await new Promise(res => {
  78. const cb = this.registerCallback(res);
  79. thread.worker.send({
  80. method: 'forceSavePlayer',
  81. args: {
  82. playerId: objId,
  83. callbackId: cb
  84. }
  85. });
  86. });
  87. killThread(thread);
  88. if (callback)
  89. callback();
  90. },
  91. removeObject: async function (obj, skipLocal, callback) {
  92. //We need to store the player id because the calling thread might delete it (connections.unzone)
  93. const playerId = obj.id;
  94. if (!skipLocal)
  95. objects.removeObject(obj);
  96. const thread = getThreadFromId(obj.zoneId);
  97. if (!thread) {
  98. callback();
  99. return;
  100. }
  101. if (thread.instanced && (await getPlayerCountInThread(thread)) === 1) {
  102. this.removeObjectFromInstancedZone(thread, playerId, callback);
  103. return;
  104. }
  105. let callbackId = null;
  106. if (callback)
  107. callbackId = this.registerCallback(callback);
  108. sendMessageToThread({
  109. threadId: obj.zoneId,
  110. msg: {
  111. method: 'removeObject',
  112. args: {
  113. obj: obj.getSimple(true),
  114. callbackId: callbackId
  115. }
  116. }
  117. });
  118. },
  119. updateObject: function (obj, msgObj) {
  120. sendMessageToThread({
  121. threadId: obj.zoneId,
  122. msg: {
  123. method: 'updateObject',
  124. args: {
  125. id: obj.id,
  126. obj: msgObj
  127. }
  128. }
  129. });
  130. },
  131. queueAction: function (obj, action) {
  132. sendMessageToThread({
  133. threadId: obj.zoneId,
  134. msg: {
  135. method: 'queueAction',
  136. args: {
  137. id: obj.id,
  138. action: action
  139. }
  140. }
  141. });
  142. },
  143. performAction: function (obj, action) {
  144. sendMessageToThread({
  145. threadId: obj.zoneId,
  146. msg: {
  147. method: 'performAction',
  148. args: {
  149. id: obj.id,
  150. action: action
  151. }
  152. }
  153. });
  154. },
  155. registerCallback: function (callback) {
  156. return registerCallback(callback);
  157. },
  158. resolveCallback: function (msg) {
  159. const callback = removeCallback(msg.msg.id);
  160. if (!callback)
  161. return;
  162. callback.callback(msg.msg.result);
  163. },
  164. returnWhenZonesIdle: async function () {
  165. await returnWhenThreadsIdle();
  166. },
  167. forceSavePlayer: async function (playerId, zoneId) {
  168. const thread = getThreadFromId(zoneId);
  169. if (!thread)
  170. return;
  171. return new Promise(res => {
  172. const callbackId = this.registerCallback(res);
  173. thread.worker.send({
  174. method: 'forceSavePlayer',
  175. args: {
  176. playerId,
  177. callbackId
  178. }
  179. });
  180. });
  181. }
  182. };