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.
 
 
 

216 line
4.5 KiB

  1. define([
  2. '../misc/fileLister',
  3. 'child_process',
  4. 'objects/objects',
  5. 'config/maps/mapList',
  6. 'security/connections'
  7. ], function (
  8. fileLister,
  9. childProcess,
  10. objects,
  11. mapList,
  12. connections
  13. ) {
  14. return {
  15. nextId: 0,
  16. nextCallbackId: 0,
  17. threads: [],
  18. callbacks: [],
  19. init: function () {
  20. this.getMapFiles();
  21. },
  22. addObject: function (obj, keepPos, transfer) {
  23. var thread = this.getThreadFromName(obj.zoneName);
  24. var instanceId = obj.instanceId;
  25. if ((!thread) || (obj.zoneName != thread.name))
  26. instanceId = -1;
  27. if (!thread) {
  28. thread = this.getThreadFromName('fjolarok');
  29. obj.zoneName = thread.name;
  30. }
  31. obj.zone = thread.id;
  32. this.send(obj.zone, {
  33. method: 'addObject',
  34. args: {
  35. keepPos: keepPos,
  36. obj: obj.getSimple ? obj.getSimple(true) : obj,
  37. instanceId: instanceId,
  38. transfer: transfer
  39. }
  40. });
  41. },
  42. removeObject: function (obj, skipLocal) {
  43. if (!skipLocal)
  44. objects.removeObject(obj);
  45. var thread = this.getThreadFromName(obj.zoneName);
  46. if (!thread)
  47. return;
  48. obj.zone = thread.id;
  49. this.send(obj.zone, {
  50. method: 'removeObject',
  51. args: {
  52. obj: obj.getSimple(true),
  53. instanceId: obj.instanceId
  54. }
  55. });
  56. },
  57. updateObject: function (obj, msgObj) {
  58. this.send(obj.zone, {
  59. method: 'updateObject',
  60. args: {
  61. id: obj.id,
  62. instanceId: obj.instanceId,
  63. obj: msgObj
  64. }
  65. });
  66. },
  67. queueAction: function (obj, action) {
  68. this.send(obj.zone, {
  69. method: 'queueAction',
  70. args: {
  71. id: obj.id,
  72. instanceId: obj.instanceId,
  73. action: action
  74. }
  75. });
  76. },
  77. performAction: function (obj, action) {
  78. this.send(obj.zone, {
  79. method: 'performAction',
  80. args: {
  81. id: obj.id,
  82. instanceId: obj.instanceId,
  83. action: action
  84. }
  85. });
  86. },
  87. registerCallback: function (callback) {
  88. this.callbacks.push({
  89. id: this.nextCallbackId++,
  90. callback: callback
  91. });
  92. return this.nextCallbackId - 1;
  93. },
  94. resolveCallback: function (msg) {
  95. var callback = this.callbacks.spliceFirstWhere(c => c.id == msg.id);
  96. if (!callback)
  97. return;
  98. callback.callback(msg.result);
  99. },
  100. send: function (zone, msg) {
  101. var thread = this.getThreadFromId(zone);
  102. if (thread) {
  103. try {
  104. thread.worker.send(msg);
  105. } catch (e) {
  106. console.log(msg);
  107. }
  108. }
  109. },
  110. getThreadFromId: function (id) {
  111. return this.threads.find(t => t.id == id);
  112. },
  113. getThreadFromName: function (name) {
  114. return this.threads.find(t => t.name == name);
  115. },
  116. getMapFiles: function () {
  117. mapList.forEach(m => this.spawnMap(m));
  118. },
  119. spawnMap: function (name) {
  120. var worker = childProcess.fork('./world/worker');
  121. var thread = {
  122. id: this.nextId++,
  123. name: name.replace('.json', ''),
  124. worker: worker
  125. };
  126. var onMessage = this.onMessage.bind(this, thread);
  127. worker.on('message', function (m) {
  128. onMessage(m);
  129. });
  130. this.threads.push(thread);
  131. },
  132. onMessage: function (thread, message) {
  133. if (message.module)
  134. global[message.module][message.method](message);
  135. else if (message.event == 'onCrashed') {
  136. thread.worker.kill();
  137. process.exit();
  138. } else
  139. this.thread[message.method].call(this, thread, message);
  140. },
  141. thread: {
  142. onReady: function (thread) {
  143. thread.worker.send({
  144. method: 'init',
  145. args: {
  146. name: thread.name,
  147. zoneId: thread.id
  148. }
  149. });
  150. },
  151. event: function (thread, message) {
  152. objects.sendEvent(message);
  153. },
  154. events: function (thread, message) {
  155. objects.sendEvents(message);
  156. },
  157. object: function (thread, message) {
  158. objects.updateObject(message);
  159. },
  160. callDifferentThread: function (thread, message) {
  161. var obj = connections.players.find(p => (p.name == message.playerName));
  162. if (!obj)
  163. return;
  164. var thread = this.getThreadFromName(obj.zoneName);
  165. if (!thread)
  166. return;
  167. thread.worker.send({
  168. module: message.data.module,
  169. method: message.data.method,
  170. args: message.data.args
  171. });
  172. },
  173. rezone: function (thread, message) {
  174. var obj = message.args.obj;
  175. obj.destroyed = false;
  176. obj.zoneName = message.args.newZone;
  177. obj.id = obj.serverId;
  178. var serverObj = objects.objects.find(o => o.id == obj.id);
  179. serverObj.zoneName = obj.zoneName;
  180. var thread = this.getThreadFromName(obj.zoneName);
  181. if (!thread) {
  182. thread = this.getThreadFromName('fjolarok');
  183. obj.zoneName = thread.name;
  184. serverObj.zoneName = thread.name;
  185. }
  186. serverObj.zone = thread.id;
  187. obj.zone = thread.id;
  188. serverObj.player.broadcastSelf();
  189. this.addObject(obj, true, true);
  190. }
  191. }
  192. };
  193. });