gdcore-tools 2.0.0-gd-v5.4.217-autobuild → 2.0.0-gd-v5.4.218-autobuild

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/Runtime/Extensions/3D/JsExtension.js +7 -3
  2. package/dist/Runtime/Extensions/DialogueTree/JsExtension.js +44 -32
  3. package/dist/Runtime/Extensions/DialogueTree/dialoguetools.js +2 -2
  4. package/dist/Runtime/Extensions/DialogueTree/dialoguetools.js.map +2 -2
  5. package/dist/Runtime/Extensions/Multiplayer/JsExtension.js +15 -0
  6. package/dist/Runtime/Extensions/Multiplayer/messageManager.js +1 -1
  7. package/dist/Runtime/Extensions/Multiplayer/messageManager.js.map +2 -2
  8. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js +1 -1
  9. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
  10. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js +1 -1
  11. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
  12. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-atlas-manager.js +1 -1
  13. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-atlas-manager.js.map +2 -2
  14. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-manager.js +1 -1
  15. package/dist/Runtime/Extensions/Spine/managers/pixi-spine-manager.js.map +2 -2
  16. package/dist/Runtime/Model3DManager.js +1 -1
  17. package/dist/Runtime/Model3DManager.js.map +2 -2
  18. package/dist/Runtime/ResourceLoader.js +1 -1
  19. package/dist/Runtime/ResourceLoader.js.map +2 -2
  20. package/dist/Runtime/capturemanager.js +2 -0
  21. package/dist/Runtime/capturemanager.js.map +7 -0
  22. package/dist/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js +1 -1
  23. package/dist/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js.map +2 -2
  24. package/dist/Runtime/howler-sound-manager/howler-sound-manager.js +1 -1
  25. package/dist/Runtime/howler-sound-manager/howler-sound-manager.js.map +2 -2
  26. package/dist/Runtime/jsonmanager.js +1 -1
  27. package/dist/Runtime/jsonmanager.js.map +2 -2
  28. package/dist/Runtime/layer.js +1 -1
  29. package/dist/Runtime/layer.js.map +2 -2
  30. package/dist/Runtime/pixi-renderers/pixi-bitmapfont-manager.js +1 -1
  31. package/dist/Runtime/pixi-renderers/pixi-bitmapfont-manager.js.map +2 -2
  32. package/dist/Runtime/pixi-renderers/pixi-image-manager.js +1 -1
  33. package/dist/Runtime/pixi-renderers/pixi-image-manager.js.map +2 -2
  34. package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js +1 -1
  35. package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js.map +2 -2
  36. package/dist/Runtime/runtimegame.js +1 -1
  37. package/dist/Runtime/runtimegame.js.map +2 -2
  38. package/dist/Runtime/runtimewatermark.js +2 -2
  39. package/dist/Runtime/runtimewatermark.js.map +2 -2
  40. package/dist/Runtime/scenestack.js +1 -1
  41. package/dist/Runtime/scenestack.js.map +2 -2
  42. package/dist/Runtime/spriteruntimeobject.js +1 -1
  43. package/dist/Runtime/spriteruntimeobject.js.map +2 -2
  44. package/dist/lib/libGD.cjs +1 -1
  45. package/dist/lib/libGD.wasm +0 -0
  46. package/gd.d.ts +22 -6
  47. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- var gdjs;(function(s){const k=new s.Logger("Multiplayer"),g=new s.Logger("Multiplayer - Debug");s.Logger.getDefaultConsoleLoggerOutput().discardGroup("Multiplayer - Debug");class je{constructor(S){this.clear=()=>{this.cache.clear(),this.keys=[]};this.maxSize=S,this.cache=new Set,this.keys=[]}has(S){return this.cache.has(S)}add(S){if(this.cache.size>=this.maxSize){const D=this.keys.shift();D&&this.cache.delete(D)}this.cache.add(S),this.keys.push(S)}}class ue{constructor(){this._updates=[]}store(S){this._updates.push(S),this._updates.length>10&&this._updates.shift()}getUpdates(){return this._updates}remove(S){const D=this._updates.indexOf(S);D!==-1&&this._updates.splice(D,1)}clear(){this._updates=[]}}const Te=({target:C,source:S})=>{for(const D in S)S.hasOwnProperty(D)&&!C.hasOwnProperty(D)&&(C[D]=S[D]);for(const D in C)C.hasOwnProperty(D)&&!S.hasOwnProperty(D)&&delete C[D]};s.makeMultiplayerMessageManager=()=>{const C=0,S=0,D=0,Je=0,v=window.performance&&typeof window.performance.now=="function"?window.performance.now.bind(window.performance):Date.now,_e=200,Le=4,W=new je(500);let O={},H={};const xe=1;let me=0,Q=null,V=0,F=new ue;const Ge=1;let de=0,J=null,B=0,K=new ue;const Ee=1;let E=0,U={},pe={},M={},A=[],$=[],Y={};const x=({originalMessageName:e,originalData:t,expectedMessageName:n,otherPeerIds:r,shouldCancelMessageIfTimesOut:a,maxNumberOfRetries:o,messageRetryTime:l})=>{!s.multiplayer.isLobbyGameRunning()||(O[n]||(O[n]={}),g.info(`Adding expected message ${n} from ${r.join(", ")}.`),r.forEach(c=>{O[n][c]={acknowledged:!1,lastMessageSentAt:v(),originalMessageName:e,originalData:t,shouldCancelMessageIfTimesOut:a,numberOfRetries:0,maxNumberOfRetries:o||Le,messageRetryTime:l||_e}}))},fe=({sceneNetworkId:e,instanceNetworkId:t})=>(H[e]||(H[e]={}),H[e][t]||0),ye=({sceneNetworkId:e,instanceNetworkId:t,clock:n})=>{H[e]||(H[e]={}),H[e][t]=n},w=(e,t,n)=>{if(!(S>0&&Math.random()<S)){if(D>0&&Math.random()<D){setTimeout(()=>{s.multiplayerPeerJsHelper.sendDataTo(e,t,n)},Je);return}if(C>0){setTimeout(()=>{s.multiplayerPeerJsHelper.sendDataTo(e,t,n)},C);return}s.multiplayerPeerJsHelper.sendDataTo(e,t,n)}},Ue=(e,t,n)=>{if(!e.length)return null;let r=null,a=1/0;for(let o=0;o<e.length;++o){if(e[o].networkId)continue;const l=e[o],c=Math.pow(l.getX()-t,2)+Math.pow(l.getY()-n,2);c<a&&(r=l,a=c)}return r},Z=({runtimeScene:e,objectName:t,instanceNetworkId:n,instanceX:r,instanceY:a,shouldCreateIfNotFound:o})=>{const l=e.getInstancesOf(t);if(!l)return null;let c=l.find(i=>i.networkId===n)||null;if(!c&&r!==void 0&&a!==void 0){g.info(`instance ${t} ${n} not found with network ID, trying to find it with position ${r}/${a}.`);const i=Ue(l,r,a);i&&(g.info(`Found closest instance for object ${t} ${n} with no network ID.`),c=i,c.networkId=n)}if(!c&&o){g.info(`Instance ${n} still not found, Creating instance ${t}.`);const i=e.createObject(t);if(!i)return null;i.networkId=n,c=i}return c},q="#changeInstanceOwner",he=/#changeInstanceOwner#owner_(\d+)#object_(.+)#instance_(.+)/,We=({objectOwner:e,objectName:t,instanceNetworkId:n,newObjectOwner:r,instanceX:a,instanceY:o,sceneNetworkId:l})=>({messageName:`${q}#owner_${e}#object_${t}#instance_${n}`,messageData:{previousOwner:e,newOwner:r,instanceX:a,instanceY:o,sceneNetworkId:l}}),ee="#instanceOwnerChanged",Ve=/#instanceOwnerChanged#owner_(\d+)#object_(.+)#instance_(.+)/,be=e=>e.replace(q,ee),Fe=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(q)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender(),p=he.exec(a);if(!p)return;const f=p[2],u=p[3],d=i.previousOwner,y=i.newOwner,I=i.sceneNetworkId;if(I!==e.networkId){g.info(`Object ${f} is in scene ${I}, but we are on ${e.networkId}. Skipping.`);return}const P=Z({runtimeScene:e,objectName:f,instanceNetworkId:u,instanceX:i.instanceX,instanceY:i.instanceY});if(!P){g.info(`Instance ${u} not found, it must have been destroyed.`);return}const h=P.getBehavior("MultiplayerObject");if(!h){g.info(`Object ${f} does not have the MultiplayerObjectBehavior, cannot change ownership.`);return}const b=h.getPlayerObjectOwnership(),N=b===d||b===y;if(s.multiplayer.isCurrentPlayerHost()&&!N){g.info(`Object ${f} with instance network ID ${u} does not have the expected owner. Wanted to change from ${d} to ${y}, but object has owner ${b}.`);return}g.info(`Changing ownership of object ${f} to ${y}.`),h.playerNumber=y;const _=be(a);if(g.info(`Sending acknowledgment of ownership change of object ${f} from ${d} to ${y} with instance network ID ${u} to ${m}.`),w([m],_,{}),s.multiplayer.isCurrentPlayerHost()){const j=s.multiplayerPeerJsHelper.getAllPeers().filter(R=>R!==m);if(!j.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:_,otherPeerIds:j,shouldCancelMessageIfTimesOut:!1}),g.info(`Relaying ownership change of object ${f} with instance network ID ${u} to ${j.join(", ")}.`),w(j,a,i)}})})},Me="#updateInstance",Be=/#updateInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,Ke=({objectOwner:e,objectName:t,instanceNetworkId:n,objectNetworkSyncData:r,sceneNetworkId:a})=>({messageName:`${Me}#owner_${e}#object_${t}#instance_${n}#scene_${a}`,messageData:r}),Ye=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(Me)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();if(!l.length)return;l.slice().reverse().forEach(i=>{const m=i.getData(),p=i.getSender(),f=Be.exec(a);if(!f)return;const u=parseInt(f[1],10);if(u===s.multiplayer.playerNumber)return;const d=f[2],y=f[3],I=f[4];if(I!==e.networkId){g.info(`Object ${d} is in scene ${I}, but we are on ${e.networkId}. Skipping.`);return}const P=m._clock,h=fe({sceneNetworkId:I,instanceNetworkId:y});if(P<=h)return;const b=Z({runtimeScene:e,objectName:d,instanceNetworkId:y,shouldCreateIfNotFound:!0,instanceX:m.x,instanceY:m.y});if(!b){k.error("Instance could not be found or created.");return}const N=b.getBehavior("MultiplayerObject");if(!N){k.error(`Object ${d} does not have the MultiplayerObjectBehavior, cannot update it.`);return}if(N.getPlayerObjectOwnership()===s.multiplayer.playerNumber){g.info(`Object ${d} with instance network ID ${y} is owned by us ${s.multiplayer.playerNumber}, ignoring update message from ${u}.`);return}if(N.getPlayerObjectOwnership()!==u&&(g.info(`Object ${d} with instance network ID ${y} is owned by ${N.getPlayerObjectOwnership()} on our game, changing ownership to ${u} as part of the update event.`),N.playerNumber=u),b.updateFromNetworkSyncData(m),ye({sceneNetworkId:I,instanceNetworkId:y,clock:P}),N._clock=P,s.multiplayer.isCurrentPlayerHost()){const T=s.multiplayerPeerJsHelper.getAllPeers().filter(j=>j!==p);if(!T.length)return;w(T,a,m)}})})},X="#changeVariableOwner",we=/#changeVariableOwner#owner_(\d+)#variable_(.+)/,qe=({variableOwner:e,variableNetworkId:t,newVariableOwner:n})=>({messageName:`${X}#owner_${e}#variable_${t}`,messageData:{previousOwner:e,newOwner:n}}),te="#variableOwnerChanged",Xe=/#variableOwnerChanged#owner_(\d+)#variable_(.+)/,Ie=e=>e.replace(X,te),ze=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(X)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender(),p=we.exec(a);if(!p)return;const f=p[2],u=i.previousOwner,d=i.newOwner,{type:y,name:I,containerId:P}=s.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(f);if(y==="scene"&&P!==e.networkId){g.info(`Variable ${I} is in scene ${P}, but we are on ${e.networkId}. Skipping.`);return}const h=P==="game"?e.getGame().getVariables():e.getVariables();if(!h.has(I)){k.error(`Variable with ID ${f} not found whilst syncing. This should not happen.`);return}const b=h.get(I),N=b.getPlayerOwnership(),_=N===u||N===d;if(s.multiplayer.isCurrentPlayerHost()&&!_){g.info(`Variable with ID ${f} does not have the expected owner. Wanted to change from ${u} to ${d}, but variable has owner ${N}.`);return}g.info(`Changing ownership of variable ${I} to ${d}.`),b.setPlayerOwnership(d);const T=Ie(a);if(g.info(`Sending acknowledgment of ownership change of variable with ID ${f} from ${u} to ${d} to ${m}.`),w([m],T,{}),s.multiplayer.isCurrentPlayerHost()){const R=s.multiplayerPeerJsHelper.getAllPeers().filter(G=>G!==m);if(!R.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:T,otherPeerIds:R,shouldCancelMessageIfTimesOut:!1});for(const G of R)g.info(`Relaying ownership change of variable with Id ${f} to ${G}.`),w(R,a,i)}})})},Qe=e=>e.startsWith(ne)?at:e.startsWith(ee)?Ve:e.startsWith(te)?Xe:e.startsWith(re)?ct:null,Ze=e=>e.startsWith(ne)||e.startsWith(ee)||e.startsWith(te)||e.startsWith(re),et=()=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(Ze).forEach(r=>{const a=e.get(r);if(!a)return;const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender();g.info(`Received acknowledgment for message ${r}.`);const m=Qe(r);if(!m){k.error(`Invalid acknowledgment message ${r}.`);return}const p=m.exec(r);if(!p){k.error(`Invalid acknowledgment message ${r}.`);return}if(!O[r]||!O[r][i])return;const f=c._clock;if(f!==void 0){const u=p[3],d=p[4],y=fe({sceneNetworkId:d,instanceNetworkId:u});if(f<=y)return;ye({sceneNetworkId:d,instanceNetworkId:u,clock:f})}g.info(`Marking message ${r} as acknowledged from ${i}.`),O[r][i].acknowledged=!0})})},tt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;Object.keys(O).forEach(n=>{const r=O[n],a=Object.keys(r).filter(o=>!r[o].acknowledged);if(!a.length)g.info(`All peers have acknowledged message ${n}.`),delete O[n];else for(const o of a){const{lastMessageSentAt:l,originalMessageName:c,originalData:i,numberOfRetries:m,maxNumberOfRetries:p,messageRetryTime:f}=r[o];if(v()-l>f){if(m>=p){if(g.info(`Giving up on message ${n} for ${o}.`),r[o].shouldCancelMessageIfTimesOut){if(c.startsWith(q)){const u=he.exec(c);if(!u){delete O[n];return}const d=u[2],y=u[3],I=e.getInstancesOf(d);if(!I){delete O[n];return}let P=I.find(N=>N.networkId===y);if(!P){delete O[n];return}const h=P.getBehavior("MultiplayerObject");if(!h){k.error(`Object ${d} does not have the MultiplayerObjectBehavior, cannot revert ownership.`),delete O[n];return}const b=i.previousOwner;if(b===void 0){delete O[n];return}h.playerNumber=b||0}if(c.startsWith(X)){const u=we.exec(c);if(!u){delete O[n];return}const d=u[2],y=i.previousOwner,{type:I,name:P,containerId:h}=s.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(d);if(I==="scene"&&h!==e.networkId){g.info(`Variable ${P} is in scene ${h}, but we are on ${e.networkId}. Skipping ownership revert.`),delete O[n];return}const b=h==="game"?e.getGame().getVariables():e.getVariables();if(!b.has(P)){k.error(`Variable with ID ${d} not found while reverting ownership. This should not happen.`),delete O[n];return}const N=b.get(P);if(y===void 0){delete O[n];return}N.setPlayerOwnership(y||0)}}delete O[n];continue}w([o],c,i),r[o].lastMessageSentAt=v(),r[o].numberOfRetries=m+1}}})},se="#destroyInstance",st=/#destroyInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,nt=({objectOwner:e,objectName:t,instanceNetworkId:n,sceneNetworkId:r})=>({messageName:`${se}#owner_${e}#object_${t}#instance_${n}#scene_${r}`,messageData:{}}),ne="#instanceDestroyed",at=/#instanceDestroyed#owner_(\d+)#object_(.+)#instance_(.+)/,Pe=e=>e.replace(se,ne),rt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(se)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender();g.info(`Received message ${a} with data ${JSON.stringify(i)}.`);const p=st.exec(a);if(!p||parseInt(p[1],10)===s.multiplayer.playerNumber)return;const u=p[2],d=p[3],y=p[4];if(y!==e.networkId){g.info(`Object ${u} is in scene ${y}, but we are on ${e.networkId}. Skipping.`);return}const I=Z({runtimeScene:e,objectName:u,instanceNetworkId:d}),P=Pe(a);if(!I){g.info("Instance was not found in the scene, sending acknowledgment anyway."),w([m],P,{});return}if(g.info(`Destroying object ${u} with instance network ID ${d}.`),I.deleteFromScene(e),g.info(`Sending acknowledgment of destruction of object ${u} with instance network ID ${d} to ${m}.`),w([m],P,{}),s.multiplayer.isCurrentPlayerHost()){const b=s.multiplayerPeerJsHelper.getAllPeers().filter(N=>N!==m);if(!b.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:P,otherPeerIds:b,shouldCancelMessageIfTimesOut:!1}),w(b,a,i)}})})},ae="#customMessage",ot=/#customMessage#(.+)/,z=e=>`${ae}#${e}`,it=({userMessageName:e,userMessageData:t,senderPlayerNumber:n})=>{const r=s.makeUuid();return{messageName:z(e),messageData:{data:t,uniqueId:r,senderPlayerNumber:n}}},re="#ackCustomMessage",ct=/#ackCustomMessage#(.+)/,Ne=e=>e.replace(ae,re),Oe=(e,t)=>{const n=s.multiplayerPeerJsHelper.getAllPeers(),r=s.multiplayer.getCurrentPlayerNumber(),{messageName:a,messageData:o}=it({userMessageName:e,userMessageData:t,senderPlayerNumber:r}),l=Ne(a);x({originalMessageName:a,originalData:o,expectedMessageName:l,otherPeerIds:n,shouldCancelMessageIfTimesOut:!1}),g.info(`Sending custom message ${e} with data ${JSON.stringify(t)}.`),w(n,a,o),s.multiplayer.isCurrentPlayerHost()&&s.multiplayerPeerJsHelper.getOrCreateMessagesList(a).pushMessage(o,s.multiplayerPeerJsHelper.getCurrentId())},lt=(e,t)=>{const n=t.toJSObject();g.info(`Sending custom message ${e} with data ${JSON.stringify(n)}.`),Oe(e,n)},gt=e=>{const t=z(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const a=r.getMessages();if(!a.length)return;g.info(`custom message ${e} has been received.`);let o=!1;return a.forEach(l=>{const i=l.getData().uniqueId,m=`${t}#${i}`;W.has(m)||(W.add(m),o=!0)}),o},Se=e=>{const t=z(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const a=r.getMessages();return a.length?a[a.length-1].getData().data:void 0},ut=(e,t)=>{const n=Se(e);!n||(g.info(`Received custom message ${e} with data ${JSON.stringify(n)}.`),t.fromJSObject(n))},mt=e=>{const t=z(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return 0;const a=r.getMessages();return a.length?a[a.length-1].getData().senderPlayerNumber:0},dt=()=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(ae)).forEach(r=>{const a=e.get(r);if(!a){k.error(`No messages list found for ${r}.`);return}const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender(),m=c.uniqueId;if(g.info(`Received custom message ${r} with data ${JSON.stringify(c)}.`),!ot.exec(r)){k.error(`Invalid custom message ${r}.`);return}const f=`${r}#${m}`;if(W.has(f)){g.info(`Message ${r} has already been processed, skipping.`);return}const u=Ne(r);if(g.info(`Sending acknowledgment of custom message ${r} to ${i}.`),w([i],u,{}),s.multiplayer.isCurrentPlayerHost()){const d=s.multiplayerPeerJsHelper.getAllPeers();if(!d.length)return;x({originalMessageName:r,originalData:c,expectedMessageName:u,otherPeerIds:d,shouldCancelMessageIfTimesOut:!1}),w(d,r,c)}})})},De="#updateScene",ke=({sceneNetworkSyncData:e})=>({messageName:`${De}`,messageData:e}),pt=e=>e.var?Q?JSON.stringify(e.var)!==JSON.stringify(Q.var):!0:!1,ft=()=>v()-me<1e3/xe,yt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getNetworkSyncData({playerNumber:s.multiplayer.getCurrentPlayerNumber(),isHost:s.multiplayer.isCurrentPlayerHost()});if(!t)return;const n=pt(t),r=!ft()||n||V>0;if(n&&(V=3),!r)return;const a=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:l}=ke({sceneNetworkSyncData:t});w(a,o,l),me=v(),Q=t,V=Math.max(V-1,0)},ht=e=>{const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(De)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender(),p=i.id;if(s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages()){if(p!==e.networkId){g.info(`Received update of scene ${p}, but we are on ${e.networkId}. Skipping.`);return}e.updateFromNetworkSyncData(i)}else{g.info(`Saving scene ${p} update message for later use.`),F.store(i);return}if(s.multiplayer.isCurrentPlayerHost()){const u=s.multiplayerPeerJsHelper.getAllPeers().filter(d=>d!==m);w(u,a,i)}})})},ve="#updateGame",$e=({gameNetworkSyncData:e})=>({messageName:`${ve}`,messageData:e}),bt=e=>{const t=e.var,n=e.ss;if(!t&&!n)return!1;if(!J||!J.var||!J.ss||t&&JSON.stringify(t)!==JSON.stringify(J.var))return!0;if(n){if(n.length!==J.ss.length)return!0;for(let r=0;r<n.length;++r){const a=n[r],o=J.ss[r];if(a.name!==o.name||a.networkId!==o.networkId)return!0}}return!1},Mt=()=>v()-de<1e3/Ge,wt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getGame().getNetworkSyncData({playerNumber:s.multiplayer.getCurrentPlayerNumber(),isHost:s.multiplayer.isCurrentPlayerHost()});if(!t)return;const n=bt(t),r=!Mt()||n||B>0;if(n&&(B=3),!r)return;const a=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:l}=$e({gameNetworkSyncData:t});w(a,o,l),de=v(),J=t,B=Math.max(B-1,0)},It=e=>{const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(ve)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),m=c.getSender();if(s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())e.getGame().updateFromNetworkSyncData(i);else{g.info("Saving game update message for later use."),K.store(i);return}if(s.multiplayer.isCurrentPlayerHost()){const f=s.multiplayerPeerJsHelper.getAllPeers().filter(u=>u!==m);w(f,a,i)}})})},Pt=e=>{K.getUpdates().forEach(t=>{g.info("Reapplying saved update of game."),e.getGame().updateFromNetworkSyncData(t)}),K.clear(),F.getUpdates().forEach(t=>{const n=t.id;if(n!==e.networkId){g.info(`Trying to apply saved update of scene ${n}, but we are on ${e.networkId}. Skipping.`);return}g.info(`Reapplying saved update of scene ${n}.`),e.updateFromNetworkSyncData(t),F.remove(t)})},oe="#heartbeat",Nt=/#heartbeat#(.+)/,ie=()=>{M[s.multiplayer.getCurrentPlayerNumber()]={ping:0,playerId:s.playerAuthentication.getUserId(),username:s.playerAuthentication.getUsername()};for(const e in M)M[e]={...M[e],ping:ce(parseInt(e,10))};return{messageName:`${oe}#${s.multiplayer.getCurrentPlayerNumber()}`,messageData:{now:v(),playersInfo:M}}},Ot=({heartbeatSentAt:e})=>({messageName:`${oe}#${s.multiplayer.getCurrentPlayerNumber()}`,messageData:{sentAt:e,playerId:s.playerAuthentication.getUserId(),username:s.playerAuthentication.getUsername()}}),St=()=>!!E&&v()-E<1e3/Ee,Dt=()=>{if(!s.multiplayer.isCurrentPlayerHost()||!!St())return;const t=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:n,messageData:r}=ie();w(t,n,r),E=v()},kt=()=>{const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(oe)).forEach(r=>{const a=e.get(r);if(!a)return;const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender(),m=Nt.exec(r);if(!m)return;const p=parseInt(m[1],10);if(pe[i]=p,!s.multiplayer.isCurrentPlayerHost()){const h=s.multiplayer.getCurrentPlayerNumber(),b=Object.keys(M).map(R=>parseInt(R,10)),N=Object.keys(c.playersInfo).map(R=>parseInt(R,10)),_=M[h]&&M[h].ping;if(b.length){const R=N.filter(L=>!b.includes(L)&&L!==h);$.push(...R);const G=b.filter(L=>!N.includes(L));A.push(...G);for(const L of G)Y[L]=le(L)}Te({source:c.playersInfo,target:M});const{messageName:T,messageData:j}=Ot({heartbeatSentAt:c.now});w([i],T,j),M[h]!==void 0&&M[h].ping!==void 0&&(s.multiplayer.markConnectionAsConnected(),_===void 0&&$.push(h));return}M[p]||$.push(p);const f=v(),u=c.sentAt,d=Math.round(f-u),y=U[p]||[];y.push(d),y.length>5&&y.shift(),U[p]=y;let I=0;for(const h of y)I+=h;const P=Math.round(I/y.length/2);if(M[p]={ping:P,playerId:c.playerId,username:c.username},$.length){const h=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:b,messageData:N}=ie();w(h,b,N),E=v()}})})},vt=e=>(U[e]||[]).length>0,ce=e=>{const t=M[e];return t&&t.ping||0},$t=()=>{const e=s.multiplayer.getCurrentPlayerNumber();return ce(e)},Re=({runtimeScene:e,playerNumber:t,peerId:n})=>{if(k.info(`Marking player ${t} as disconnected.`),A.push(t),Y[t]=le(t),Qt(t),n&&n===s.multiplayer.hostPeerId)if(s.multiplayer.shouldEndLobbyWhenHostLeaves())k.info("Host has disconnected, ending the game."),ge(),s.multiplayer.handleLobbyGameEnded();else{k.info("Host has disconnected, switching host."),s.multiplayer.handleHostDisconnected({runtimeScene:e});return}if(s.multiplayer.isCurrentPlayerHost()){const r=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:a,messageData:o}=ie();w(r,a,o),E=v()}},le=e=>(M[e]||{}).username||Y[e]||`Player ${e}`,Rt=e=>(M[e]||{}).playerId||"",Ct=e=>{if(!s.multiplayer.isLobbyGameRunning())return;const t=[],n=s.multiplayerPeerJsHelper.getJustDisconnectedPeers();if(n.length)for(const r of n){const a=pe[r];if(!a)return;k.info(`Player ${a} has disconnected.`),t.push({playerNumber:a,peerId:r})}for(const{playerNumber:r,peerId:a}of t){if(s.multiplayer.isCurrentPlayerHost()){const o=e.getAdhocListOfAllInstances();for(const l of o){const c=l.getBehavior("MultiplayerObject");if(c&&c.getPlayerObjectOwnership()===r){const i=c.getActionOnPlayerDisconnect();i==="DestroyObject"?l.deleteFromScene(e):i==="GiveOwnershipToHost"&&c.removeObjectOwnership()}}}Re({runtimeScene:e,playerNumber:r,peerId:a})}},At=()=>A.length>0,jt=e=>A.includes(e),Tt=()=>A,Ht=()=>A[0]||0,Jt=()=>{const e=A[0];e!==void 0&&(A=A.slice(1),delete Y[e])},_t=()=>$.length>0,Lt=e=>$.includes(e),xt=()=>$,Gt=()=>$[0]||0,Et=()=>{$[0]!==void 0&&($=$.slice(1))},Ut=()=>Object.keys(M).map(e=>({playerNumber:parseInt(e,10),playerId:M[e].playerId})),Wt=()=>Object.keys(M).length,Vt=e=>M[e]!==void 0,Ft=()=>M,Ce="#endGame",Bt=()=>({messageName:Ce,messageData:{}}),Kt=()=>{if(!s.multiplayer.isCurrentPlayerHost())return;g.info("Sending endgame message.");const e=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=Bt();w(e,t,n)},Yt=()=>{if(s.multiplayer.isCurrentPlayerHost())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap().get(Ce);!t||!t.getMessages().length||(k.info("Received endgame message."),ge(),s.multiplayer.handleLobbyGameEnded())},Ae="#resumeGame",qt=()=>({messageName:Ae,messageData:{}}),Xt=()=>{if(!s.multiplayer.isCurrentPlayerHost())return;g.info("Sending resumeGame message.");const e=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=qt();w(e,t,n)},zt=e=>{if(s.multiplayer.isCurrentPlayerHost())return;const n=s.multiplayerPeerJsHelper.getAllMessagesMap().get(Ae);!n||!n.getMessages().length||(k.info("Received resumeGame message."),s.multiplayer.resumeGame(e))},ge=()=>{U={},M={},K.clear(),F.clear(),W.clear(),A=[],$=[],O={},H={}},Qt=e=>{delete U[e],delete M[e]};return{sendDataTo:w,addExpectedMessageAcknowledgement:x,handleAcknowledgeMessagesReceived:et,resendClearOrCancelAcknowledgedMessages:tt,createChangeInstanceOwnerMessage:We,createInstanceOwnerChangedMessageNameFromChangeInstanceOwnerMessage:be,handleChangeInstanceOwnerMessagesReceived:Fe,createUpdateInstanceMessage:Ke,handleUpdateInstanceMessagesReceived:Ye,createDestroyInstanceMessage:nt,createInstanceDestroyedMessageNameFromDestroyInstanceMessage:Pe,handleDestroyInstanceMessagesReceived:rt,createChangeVariableOwnerMessage:qe,createVariableOwnerChangedMessageNameFromChangeVariableOwnerMessage:Ie,handleChangeVariableOwnerMessagesReceived:ze,sendCustomMessage:Oe,getCustomMessageData:Se,sendVariableCustomMessage:lt,getVariableCustomMessageData:ut,hasCustomMessageBeenReceived:gt,handleCustomMessagesReceived:dt,getCustomMessageSender:mt,createUpdateSceneMessage:ke,handleUpdateSceneMessagesToSend:yt,handleUpdateSceneMessagesReceived:ht,createUpdateGameMessage:$e,handleUpdateGameMessagesToSend:wt,handleUpdateGameMessagesReceived:It,handleSavedUpdateMessages:Pt,handleHeartbeatsToSend:Dt,handleHeartbeatsReceived:kt,hasReceivedHeartbeatFromPlayer:vt,getPlayerPing:ce,getCurrentPlayerPing:$t,getPlayerUsername:le,getPlayerId:Rt,handleJustDisconnectedPeers:Ct,getConnectedPlayers:Ut,getNumberOfConnectedPlayers:Wt,isPlayerConnected:Vt,getPlayersInfo:Ft,hasAnyPlayerJustLeft:At,hasPlayerJustLeft:jt,getPlayersWhoJustLeft:Tt,getLatestPlayerWhoJustLeft:Ht,removePlayerWhoJustLeft:Jt,markPlayerAsDisconnected:Re,hasAnyPlayerJustJoined:_t,hasPlayerJustJoined:Lt,getPlayersWhoJustJoined:xt,getLatestPlayerWhoJustJoined:Gt,removePlayerWhoJustJoined:Et,sendEndGameMessage:Kt,handleEndGameMessagesReceived:Yt,clearAllMessagesTempData:ge,sendResumeGameMessage:Xt,handleResumeGameMessagesReceived:zt}},s.multiplayerMessageManager=s.makeMultiplayerMessageManager()})(gdjs||(gdjs={}));
1
+ var gdjs;(function(s){const k=new s.Logger("Multiplayer"),g=new s.Logger("Multiplayer - Debug");s.Logger.getDefaultConsoleLoggerOutput().discardGroup("Multiplayer - Debug");class je{constructor(S){this.clear=()=>{this.cache.clear(),this.keys=[]};this.maxSize=S,this.cache=new Set,this.keys=[]}has(S){return this.cache.has(S)}add(S){if(this.cache.size>=this.maxSize){const D=this.keys.shift();D&&this.cache.delete(D)}this.cache.add(S),this.keys.push(S)}}class ue{constructor(){this._updates=[]}store(S){this._updates.push(S),this._updates.length>10&&this._updates.shift()}getUpdates(){return this._updates}remove(S){const D=this._updates.indexOf(S);D!==-1&&this._updates.splice(D,1)}clear(){this._updates=[]}}const Te=({target:C,source:S})=>{for(const D in S)S.hasOwnProperty(D)&&!C.hasOwnProperty(D)&&(C[D]=S[D]);for(const D in C)C.hasOwnProperty(D)&&!S.hasOwnProperty(D)&&delete C[D]};s.makeMultiplayerMessageManager=()=>{const C=0,S=0,D=0,Je=0,v=window.performance&&typeof window.performance.now=="function"?window.performance.now.bind(window.performance):Date.now,_e=200,Le=4,U=new je(500);let O={},H={};const xe=1;let me=0,Q=null,W=0,V=new ue;const Ge=1;let de=0,J=null,F=0,B=new ue;const Ee=1;let G=0,E={},pe={},M={},A=[],$=[],K={};const x=({originalMessageName:e,originalData:t,expectedMessageName:n,otherPeerIds:r,shouldCancelMessageIfTimesOut:a,maxNumberOfRetries:o,messageRetryTime:l})=>{!s.multiplayer.isLobbyGameRunning()||(O[n]||(O[n]={}),g.info(`Adding expected message ${n} from ${r.join(", ")}.`),r.forEach(c=>{O[n][c]={acknowledged:!1,lastMessageSentAt:v(),originalMessageName:e,originalData:t,shouldCancelMessageIfTimesOut:a,numberOfRetries:0,maxNumberOfRetries:o||Le,messageRetryTime:l||_e}}))},fe=({sceneNetworkId:e,instanceNetworkId:t})=>(H[e]||(H[e]={}),H[e][t]||0),ye=({sceneNetworkId:e,instanceNetworkId:t,clock:n})=>{H[e]||(H[e]={}),H[e][t]=n},w=(e,t,n)=>{if(!(S>0&&Math.random()<S)){if(D>0&&Math.random()<D){setTimeout(()=>{s.multiplayerPeerJsHelper.sendDataTo(e,t,n)},Je);return}if(C>0){setTimeout(()=>{s.multiplayerPeerJsHelper.sendDataTo(e,t,n)},C);return}s.multiplayerPeerJsHelper.sendDataTo(e,t,n)}},Ue=(e,t,n)=>{if(!e.length)return null;let r=null,a=1/0;for(let o=0;o<e.length;++o){if(e[o].networkId)continue;const l=e[o],c=Math.pow(l.getX()-t,2)+Math.pow(l.getY()-n,2);c<a&&(r=l,a=c)}return r},Z=({runtimeScene:e,objectName:t,instanceNetworkId:n,instanceX:r,instanceY:a,shouldCreateIfNotFound:o})=>{const l=e.getInstancesOf(t);if(!l)return null;let c=l.find(i=>i.networkId===n)||null;if(!c&&r!==void 0&&a!==void 0){g.info(`instance ${t} ${n} not found with network ID, trying to find it with position ${r}/${a}.`);const i=Ue(l,r,a);i&&(g.info(`Found closest instance for object ${t} ${n} with no network ID.`),c=i,c.networkId=n)}if(!c&&o){g.info(`Instance ${n} still not found, Creating instance ${t}.`);const i=e.createObject(t);if(!i)return null;i.networkId=n,c=i}return c},Y="#changeInstanceOwner",he=/#changeInstanceOwner#owner_(\d+)#object_(.+)#instance_(.+)/,We=({objectOwner:e,objectName:t,instanceNetworkId:n,newObjectOwner:r,instanceX:a,instanceY:o,sceneNetworkId:l})=>({messageName:`${Y}#owner_${e}#object_${t}#instance_${n}`,messageData:{previousOwner:e,newOwner:r,instanceX:a,instanceY:o,sceneNetworkId:l}}),ee="#instanceOwnerChanged",Ve=/#instanceOwnerChanged#owner_(\d+)#object_(.+)#instance_(.+)/,be=e=>e.replace(Y,ee),Fe=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(Y)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),d=c.getSender(),p=he.exec(a);if(!p)return;const f=p[2],u=p[3],m=i.previousOwner,y=i.newOwner,I=i.sceneNetworkId;if(I!==e.networkId){g.info(`Object ${f} is in scene ${I}, but we are on ${e.networkId}. Skipping.`);return}const P=Z({runtimeScene:e,objectName:f,instanceNetworkId:u,instanceX:i.instanceX,instanceY:i.instanceY});if(!P){g.info(`Instance ${u} not found, it must have been destroyed.`);return}const h=P.getBehavior("MultiplayerObject");if(!h){g.info(`Object ${f} does not have the MultiplayerObjectBehavior, cannot change ownership.`);return}const b=h.getPlayerObjectOwnership(),N=b===m||b===y;if(s.multiplayer.isCurrentPlayerHost()&&!N){g.info(`Object ${f} with instance network ID ${u} does not have the expected owner. Wanted to change from ${m} to ${y}, but object has owner ${b}.`);return}g.info(`Changing ownership of object ${f} to ${y}.`),h.playerNumber=y;const _=be(a);if(g.info(`Sending acknowledgment of ownership change of object ${f} from ${m} to ${y} with instance network ID ${u} to ${d}.`),w([d],_,{}),s.multiplayer.isCurrentPlayerHost()){const j=s.multiplayerPeerJsHelper.getAllPeers().filter(R=>R!==d);if(!j.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:_,otherPeerIds:j,shouldCancelMessageIfTimesOut:!1}),g.info(`Relaying ownership change of object ${f} with instance network ID ${u} to ${j.join(", ")}.`),w(j,a,i)}})})},Me="#updateInstance",Be=/#updateInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,Ke=({objectOwner:e,objectName:t,instanceNetworkId:n,objectNetworkSyncData:r,sceneNetworkId:a})=>({messageName:`${Me}#owner_${e}#object_${t}#instance_${n}#scene_${a}`,messageData:r}),Ye=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(Me)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();if(!l.length)return;l.slice().reverse().forEach(i=>{const d=i.getData(),p=i.getSender(),f=Be.exec(a);if(!f)return;const u=parseInt(f[1],10);if(u===s.multiplayer.playerNumber)return;const m=f[2],y=f[3],I=f[4];if(I!==e.networkId){g.info(`Object ${m} is in scene ${I}, but we are on ${e.networkId}. Skipping.`);return}const P=d._clock,h=fe({sceneNetworkId:I,instanceNetworkId:y});if(P<=h)return;const b=Z({runtimeScene:e,objectName:m,instanceNetworkId:y,shouldCreateIfNotFound:!0,instanceX:d.x,instanceY:d.y});if(!b){k.error("Instance could not be found or created.");return}const N=b.getBehavior("MultiplayerObject");if(!N){k.error(`Object ${m} does not have the MultiplayerObjectBehavior, cannot update it.`);return}if(N.getPlayerObjectOwnership()===s.multiplayer.playerNumber){g.info(`Object ${m} with instance network ID ${y} is owned by us ${s.multiplayer.playerNumber}, ignoring update message from ${u}.`);return}if(N.getPlayerObjectOwnership()!==u&&(g.info(`Object ${m} with instance network ID ${y} is owned by ${N.getPlayerObjectOwnership()} on our game, changing ownership to ${u} as part of the update event.`),N.playerNumber=u),b.updateFromNetworkSyncData(d),ye({sceneNetworkId:I,instanceNetworkId:y,clock:P}),N._clock=P,s.multiplayer.isCurrentPlayerHost()){const T=s.multiplayerPeerJsHelper.getAllPeers().filter(j=>j!==p);if(!T.length)return;w(T,a,d)}})})},q="#changeVariableOwner",we=/#changeVariableOwner#owner_(\d+)#variable_(.+)/,qe=({variableOwner:e,variableNetworkId:t,newVariableOwner:n})=>({messageName:`${q}#owner_${e}#variable_${t}`,messageData:{previousOwner:e,newOwner:n}}),te="#variableOwnerChanged",Xe=/#variableOwnerChanged#owner_(\d+)#variable_(.+)/,Ie=e=>e.replace(q,te),ze=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(q)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),d=c.getSender(),p=we.exec(a);if(!p)return;const f=p[2],u=i.previousOwner,m=i.newOwner,{type:y,name:I,containerId:P}=s.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(f);if(y==="scene"&&P!==e.networkId){g.info(`Variable ${I} is in scene ${P}, but we are on ${e.networkId}. Skipping.`);return}const h=P==="game"?e.getGame().getVariables():e.getVariables();if(!h.has(I)){k.error(`Variable with ID ${f} not found whilst syncing. This should not happen.`);return}const b=h.get(I),N=b.getPlayerOwnership(),_=N===u||N===m;if(s.multiplayer.isCurrentPlayerHost()&&!_){g.info(`Variable with ID ${f} does not have the expected owner. Wanted to change from ${u} to ${m}, but variable has owner ${N}.`);return}g.info(`Changing ownership of variable ${I} to ${m}.`),b.setPlayerOwnership(m);const T=Ie(a);if(g.info(`Sending acknowledgment of ownership change of variable with ID ${f} from ${u} to ${m} to ${d}.`),w([d],T,{}),s.multiplayer.isCurrentPlayerHost()){const R=s.multiplayerPeerJsHelper.getAllPeers().filter(z=>z!==d);if(!R.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:T,otherPeerIds:R,shouldCancelMessageIfTimesOut:!1}),g.info(`Relaying ownership change of variable with Id ${f} to ${R.join(", ")}.`),w(R,a,i)}})})},Qe=e=>e.startsWith(ne)?at:e.startsWith(ee)?Ve:e.startsWith(te)?Xe:e.startsWith(re)?ct:null,Ze=e=>e.startsWith(ne)||e.startsWith(ee)||e.startsWith(te)||e.startsWith(re),et=()=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(Ze).forEach(r=>{const a=e.get(r);if(!a)return;const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender();g.info(`Received acknowledgment for message ${r}.`);const d=Qe(r);if(!d){k.error(`Invalid acknowledgment message ${r}.`);return}const p=d.exec(r);if(!p){k.error(`Invalid acknowledgment message ${r}.`);return}if(!O[r]||!O[r][i])return;const f=c._clock;if(f!==void 0){const u=p[3],m=p[4],y=fe({sceneNetworkId:m,instanceNetworkId:u});if(f<=y)return;ye({sceneNetworkId:m,instanceNetworkId:u,clock:f})}g.info(`Marking message ${r} as acknowledged from ${i}.`),O[r][i].acknowledged=!0})})},tt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;Object.keys(O).forEach(n=>{const r=O[n],a=Object.keys(r).filter(o=>!r[o].acknowledged);if(!a.length)g.info(`All peers have acknowledged message ${n}.`),delete O[n];else for(const o of a){const{lastMessageSentAt:l,originalMessageName:c,originalData:i,numberOfRetries:d,maxNumberOfRetries:p,messageRetryTime:f}=r[o];if(v()-l>f){if(d>=p){if(g.info(`Giving up on message ${n} for ${o}.`),r[o].shouldCancelMessageIfTimesOut){if(c.startsWith(Y)){const u=he.exec(c);if(!u){delete O[n];return}const m=u[2],y=u[3],I=e.getInstancesOf(m);if(!I){delete O[n];return}let P=I.find(N=>N.networkId===y);if(!P){delete O[n];return}const h=P.getBehavior("MultiplayerObject");if(!h){k.error(`Object ${m} does not have the MultiplayerObjectBehavior, cannot revert ownership.`),delete O[n];return}const b=i.previousOwner;if(b===void 0){delete O[n];return}h.playerNumber=b||0}if(c.startsWith(q)){const u=we.exec(c);if(!u){delete O[n];return}const m=u[2],y=i.previousOwner,{type:I,name:P,containerId:h}=s.multiplayerVariablesManager.getVariableTypeAndNameFromNetworkId(m);if(I==="scene"&&h!==e.networkId){g.info(`Variable ${P} is in scene ${h}, but we are on ${e.networkId}. Skipping ownership revert.`),delete O[n];return}const b=h==="game"?e.getGame().getVariables():e.getVariables();if(!b.has(P)){k.error(`Variable with ID ${m} not found while reverting ownership. This should not happen.`),delete O[n];return}const N=b.get(P);if(y===void 0){delete O[n];return}N.setPlayerOwnership(y||0)}}delete O[n];continue}w([o],c,i),r[o].lastMessageSentAt=v(),r[o].numberOfRetries=d+1}}})},se="#destroyInstance",st=/#destroyInstance#owner_(\d+)#object_(.+)#instance_(.+)#scene_(.+)/,nt=({objectOwner:e,objectName:t,instanceNetworkId:n,sceneNetworkId:r})=>({messageName:`${se}#owner_${e}#object_${t}#instance_${n}#scene_${r}`,messageData:{}}),ne="#instanceDestroyed",at=/#instanceDestroyed#owner_(\d+)#object_(.+)#instance_(.+)/,Pe=e=>e.replace(se,ne),rt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(se)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),d=c.getSender();g.info(`Received message ${a} with data ${JSON.stringify(i)}.`);const p=st.exec(a);if(!p||parseInt(p[1],10)===s.multiplayer.playerNumber)return;const u=p[2],m=p[3],y=p[4];if(y!==e.networkId){g.info(`Object ${u} is in scene ${y}, but we are on ${e.networkId}. Skipping.`);return}const I=Z({runtimeScene:e,objectName:u,instanceNetworkId:m}),P=Pe(a);if(!I){g.info("Instance was not found in the scene, sending acknowledgment anyway."),w([d],P,{});return}if(g.info(`Destroying object ${u} with instance network ID ${m}.`),I.deleteFromScene(e),g.info(`Sending acknowledgment of destruction of object ${u} with instance network ID ${m} to ${d}.`),w([d],P,{}),s.multiplayer.isCurrentPlayerHost()){const b=s.multiplayerPeerJsHelper.getAllPeers().filter(N=>N!==d);if(!b.length)return;x({originalMessageName:a,originalData:i,expectedMessageName:P,otherPeerIds:b,shouldCancelMessageIfTimesOut:!1}),g.info(`Relaying instance destroyed message for object ${u} with instance network ID ${m} to ${b.join(", ")}.`),w(b,a,i)}})})},ae="#customMessage",ot=/#customMessage#(.+)/,X=e=>`${ae}#${e}`,it=({userMessageName:e,userMessageData:t,senderPlayerNumber:n})=>{const r=s.makeUuid();return{messageName:X(e),messageData:{data:t,uniqueId:r,senderPlayerNumber:n}}},re="#ackCustomMessage",ct=/#ackCustomMessage#(.+)/,Ne=e=>e.replace(ae,re),Oe=(e,t)=>{const n=s.multiplayerPeerJsHelper.getAllPeers(),r=s.multiplayer.getCurrentPlayerNumber(),{messageName:a,messageData:o}=it({userMessageName:e,userMessageData:t,senderPlayerNumber:r}),l=Ne(a);x({originalMessageName:a,originalData:o,expectedMessageName:l,otherPeerIds:n,shouldCancelMessageIfTimesOut:!1}),g.info(`Sending custom message ${e} with data ${JSON.stringify(t)}.`),w(n,a,o),s.multiplayer.isCurrentPlayerHost()&&s.multiplayerPeerJsHelper.getOrCreateMessagesList(a).pushMessage(o,s.multiplayerPeerJsHelper.getCurrentId())},lt=(e,t)=>{const n=t.toJSObject();g.info(`Sending custom message ${e} with data ${JSON.stringify(n)}.`),Oe(e,n)},gt=e=>{const t=X(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const a=r.getMessages();if(!a.length)return;g.info(`custom message ${e} has been received.`);let o=!1;return a.forEach(l=>{const i=l.getData().uniqueId,d=`${t}#${i}`;U.has(d)||(U.add(d),o=!0)}),o},Se=e=>{const t=X(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return;const a=r.getMessages();return a.length?a[a.length-1].getData().data:void 0},ut=(e,t)=>{const n=Se(e);!n||(g.info(`Received custom message ${e} with data ${JSON.stringify(n)}.`),t.fromJSObject(n))},mt=e=>{const t=X(e),r=s.multiplayerPeerJsHelper.getAllMessagesMap().get(t);if(!r)return 0;const a=r.getMessages();return a.length?a[a.length-1].getData().senderPlayerNumber:0},dt=()=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(ae)).forEach(r=>{const a=e.get(r);if(!a){k.error(`No messages list found for ${r}.`);return}const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender(),d=c.uniqueId;if(g.info(`Received custom message ${r} with data ${JSON.stringify(c)}.`),!ot.exec(r)){k.error(`Invalid custom message ${r}.`);return}const f=`${r}#${d}`;if(U.has(f)){g.info(`Message ${r} has already been processed, skipping.`);return}const u=Ne(r);if(g.info(`Sending acknowledgment of custom message ${r} to ${i}.`),w([i],u,{}),s.multiplayer.isCurrentPlayerHost()){const m=s.multiplayerPeerJsHelper.getAllPeers();if(!m.length)return;x({originalMessageName:r,originalData:c,expectedMessageName:u,otherPeerIds:m,shouldCancelMessageIfTimesOut:!1}),w(m,r,c)}})})},De="#updateScene",ke=({sceneNetworkSyncData:e})=>({messageName:`${De}`,messageData:e}),pt=e=>e.var?Q?JSON.stringify(e.var)!==JSON.stringify(Q.var):!0:!1,ft=()=>v()-me<1e3/xe,yt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getNetworkSyncData({playerNumber:s.multiplayer.getCurrentPlayerNumber(),isHost:s.multiplayer.isCurrentPlayerHost()});if(!t)return;const n=pt(t),r=!ft()||n||W>0;if(n&&(W=3),!r)return;const a=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:l}=ke({sceneNetworkSyncData:t});w(a,o,l),me=v(),Q=t,W=Math.max(W-1,0)},ht=e=>{const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(De)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),d=c.getSender(),p=i.id;if(s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages()){if(p!==e.networkId){g.info(`Received update of scene ${p}, but we are on ${e.networkId}. Skipping.`);return}e.updateFromNetworkSyncData(i)}else{g.info(`Saving scene ${p} update message for later use.`),V.store(i);return}if(s.multiplayer.isCurrentPlayerHost()){const u=s.multiplayerPeerJsHelper.getAllPeers().filter(m=>m!==d);w(u,a,i)}})})},ve="#updateGame",$e=({gameNetworkSyncData:e})=>({messageName:`${ve}`,messageData:e}),bt=e=>{const t=e.var,n=e.ss;if(!t&&!n)return!1;if(!J||!J.var||!J.ss||t&&JSON.stringify(t)!==JSON.stringify(J.var))return!0;if(n){if(n.length!==J.ss.length)return!0;for(let r=0;r<n.length;++r){const a=n[r],o=J.ss[r];if(a.name!==o.name||a.networkId!==o.networkId)return!0}}return!1},Mt=()=>v()-de<1e3/Ge,wt=e=>{if(!s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())return;const t=e.getGame().getNetworkSyncData({playerNumber:s.multiplayer.getCurrentPlayerNumber(),isHost:s.multiplayer.isCurrentPlayerHost()});if(!t)return;const n=bt(t),r=!Mt()||n||F>0;if(n&&(F=3),!r)return;const a=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:o,messageData:l}=$e({gameNetworkSyncData:t});w(a,o,l),de=v(),J=t,F=Math.max(F-1,0)},It=e=>{const t=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(t.keys()).filter(a=>a.startsWith(ve)).forEach(a=>{const o=t.get(a);if(!o)return;const l=o.getMessages();!l.length||l.forEach(c=>{const i=c.getData(),d=c.getSender();if(s.multiplayer.isReadyToSendOrReceiveGameUpdateMessages())e.getGame().updateFromNetworkSyncData(i);else{g.info("Saving game update message for later use."),B.store(i);return}if(s.multiplayer.isCurrentPlayerHost()){const f=s.multiplayerPeerJsHelper.getAllPeers().filter(u=>u!==d);w(f,a,i)}})})},Pt=e=>{B.getUpdates().forEach(t=>{g.info("Reapplying saved update of game."),e.getGame().updateFromNetworkSyncData(t)}),B.clear(),V.getUpdates().forEach(t=>{const n=t.id;if(n!==e.networkId){g.info(`Trying to apply saved update of scene ${n}, but we are on ${e.networkId}. Skipping.`);return}g.info(`Reapplying saved update of scene ${n}.`),e.updateFromNetworkSyncData(t),V.remove(t)})},oe="#heartbeat",Nt=/#heartbeat#(.+)/,ie=()=>{M[s.multiplayer.getCurrentPlayerNumber()]={ping:0,playerId:s.playerAuthentication.getUserId(),username:s.playerAuthentication.getUsername()};for(const e in M)M[e]={...M[e],ping:ce(parseInt(e,10))};return{messageName:`${oe}#${s.multiplayer.getCurrentPlayerNumber()}`,messageData:{now:v(),playersInfo:M}}},Ot=({heartbeatSentAt:e})=>({messageName:`${oe}#${s.multiplayer.getCurrentPlayerNumber()}`,messageData:{sentAt:e,playerId:s.playerAuthentication.getUserId(),username:s.playerAuthentication.getUsername()}}),St=()=>!!G&&v()-G<1e3/Ee,Dt=()=>{if(!s.multiplayer.isCurrentPlayerHost()||!!St())return;const t=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:n,messageData:r}=ie();w(t,n,r),G=v()},kt=()=>{const e=s.multiplayerPeerJsHelper.getAllMessagesMap();Array.from(e.keys()).filter(r=>r.startsWith(oe)).forEach(r=>{const a=e.get(r);if(!a)return;const o=a.getMessages();!o.length||o.forEach(l=>{const c=l.getData(),i=l.getSender(),d=Nt.exec(r);if(!d)return;const p=parseInt(d[1],10);if(pe[i]=p,!s.multiplayer.isCurrentPlayerHost()){const h=s.multiplayer.getCurrentPlayerNumber(),b=Object.keys(M).map(R=>parseInt(R,10)),N=Object.keys(c.playersInfo).map(R=>parseInt(R,10)),_=M[h]&&M[h].ping;if(b.length){const R=N.filter(L=>!b.includes(L)&&L!==h);$.push(...R);const z=b.filter(L=>!N.includes(L));A.push(...z);for(const L of z)K[L]=le(L)}Te({source:c.playersInfo,target:M});const{messageName:T,messageData:j}=Ot({heartbeatSentAt:c.now});w([i],T,j),M[h]!==void 0&&M[h].ping!==void 0&&(s.multiplayer.markConnectionAsConnected(),_===void 0&&$.push(h));return}M[p]||$.push(p);const f=v(),u=c.sentAt,m=Math.round(f-u),y=E[p]||[];y.push(m),y.length>5&&y.shift(),E[p]=y;let I=0;for(const h of y)I+=h;const P=Math.round(I/y.length/2);if(M[p]={ping:P,playerId:c.playerId,username:c.username},$.length){const h=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:b,messageData:N}=ie();w(h,b,N),G=v()}})})},vt=e=>(E[e]||[]).length>0,ce=e=>{const t=M[e];return t&&t.ping||0},$t=()=>{const e=s.multiplayer.getCurrentPlayerNumber();return ce(e)},Re=({runtimeScene:e,playerNumber:t,peerId:n})=>{if(k.info(`Marking player ${t} as disconnected.`),A.push(t),K[t]=le(t),Qt(t),n&&n===s.multiplayer.hostPeerId)if(s.multiplayer.shouldEndLobbyWhenHostLeaves())k.info("Host has disconnected, ending the game."),ge(),s.multiplayer.handleLobbyGameEnded();else{k.info("Host has disconnected, switching host."),s.multiplayer.handleHostDisconnected({runtimeScene:e});return}if(s.multiplayer.isCurrentPlayerHost()){const r=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:a,messageData:o}=ie();w(r,a,o),G=v()}},le=e=>(M[e]||{}).username||K[e]||`Player ${e}`,Rt=e=>(M[e]||{}).playerId||"",Ct=e=>{if(!s.multiplayer.isLobbyGameRunning())return;const t=[],n=s.multiplayerPeerJsHelper.getJustDisconnectedPeers();if(n.length)for(const r of n){const a=pe[r];if(!a)return;k.info(`Player ${a} has disconnected.`),t.push({playerNumber:a,peerId:r})}for(const{playerNumber:r,peerId:a}of t){if(s.multiplayer.isCurrentPlayerHost()){const o=e.getAdhocListOfAllInstances();for(const l of o){const c=l.getBehavior("MultiplayerObject");if(c&&c.getPlayerObjectOwnership()===r){const i=c.getActionOnPlayerDisconnect();i==="DestroyObject"?l.deleteFromScene(e):i==="GiveOwnershipToHost"&&c.removeObjectOwnership()}}}Re({runtimeScene:e,playerNumber:r,peerId:a})}},At=()=>A.length>0,jt=e=>A.includes(e),Tt=()=>A,Ht=()=>A[0]||0,Jt=()=>{const e=A[0];e!==void 0&&(A=A.slice(1),delete K[e])},_t=()=>$.length>0,Lt=e=>$.includes(e),xt=()=>$,Gt=()=>$[0]||0,Et=()=>{$[0]!==void 0&&($=$.slice(1))},Ut=()=>Object.keys(M).map(e=>({playerNumber:parseInt(e,10),playerId:M[e].playerId})),Wt=()=>Object.keys(M).length,Vt=e=>M[e]!==void 0,Ft=()=>M,Ce="#endGame",Bt=()=>({messageName:Ce,messageData:{}}),Kt=()=>{if(!s.multiplayer.isCurrentPlayerHost())return;g.info("Sending endgame message.");const e=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=Bt();w(e,t,n)},Yt=()=>{if(s.multiplayer.isCurrentPlayerHost())return;const t=s.multiplayerPeerJsHelper.getAllMessagesMap().get(Ce);!t||!t.getMessages().length||(k.info("Received endgame message."),ge(),s.multiplayer.handleLobbyGameEnded())},Ae="#resumeGame",qt=()=>({messageName:Ae,messageData:{}}),Xt=()=>{if(!s.multiplayer.isCurrentPlayerHost())return;g.info("Sending resumeGame message.");const e=s.multiplayerPeerJsHelper.getAllPeers(),{messageName:t,messageData:n}=qt();w(e,t,n)},zt=e=>{if(s.multiplayer.isCurrentPlayerHost())return;const n=s.multiplayerPeerJsHelper.getAllMessagesMap().get(Ae);!n||!n.getMessages().length||(k.info("Received resumeGame message."),s.multiplayer.resumeGame(e))},ge=()=>{E={},M={},B.clear(),V.clear(),U.clear(),A=[],$=[],O={},H={}},Qt=e=>{delete E[e],delete M[e]};return{sendDataTo:w,addExpectedMessageAcknowledgement:x,handleAcknowledgeMessagesReceived:et,resendClearOrCancelAcknowledgedMessages:tt,createChangeInstanceOwnerMessage:We,createInstanceOwnerChangedMessageNameFromChangeInstanceOwnerMessage:be,handleChangeInstanceOwnerMessagesReceived:Fe,createUpdateInstanceMessage:Ke,handleUpdateInstanceMessagesReceived:Ye,createDestroyInstanceMessage:nt,createInstanceDestroyedMessageNameFromDestroyInstanceMessage:Pe,handleDestroyInstanceMessagesReceived:rt,createChangeVariableOwnerMessage:qe,createVariableOwnerChangedMessageNameFromChangeVariableOwnerMessage:Ie,handleChangeVariableOwnerMessagesReceived:ze,sendCustomMessage:Oe,getCustomMessageData:Se,sendVariableCustomMessage:lt,getVariableCustomMessageData:ut,hasCustomMessageBeenReceived:gt,handleCustomMessagesReceived:dt,getCustomMessageSender:mt,createUpdateSceneMessage:ke,handleUpdateSceneMessagesToSend:yt,handleUpdateSceneMessagesReceived:ht,createUpdateGameMessage:$e,handleUpdateGameMessagesToSend:wt,handleUpdateGameMessagesReceived:It,handleSavedUpdateMessages:Pt,handleHeartbeatsToSend:Dt,handleHeartbeatsReceived:kt,hasReceivedHeartbeatFromPlayer:vt,getPlayerPing:ce,getCurrentPlayerPing:$t,getPlayerUsername:le,getPlayerId:Rt,handleJustDisconnectedPeers:Ct,getConnectedPlayers:Ut,getNumberOfConnectedPlayers:Wt,isPlayerConnected:Vt,getPlayersInfo:Ft,hasAnyPlayerJustLeft:At,hasPlayerJustLeft:jt,getPlayersWhoJustLeft:Tt,getLatestPlayerWhoJustLeft:Ht,removePlayerWhoJustLeft:Jt,markPlayerAsDisconnected:Re,hasAnyPlayerJustJoined:_t,hasPlayerJustJoined:Lt,getPlayersWhoJustJoined:xt,getLatestPlayerWhoJustJoined:Gt,removePlayerWhoJustJoined:Et,sendEndGameMessage:Kt,handleEndGameMessagesReceived:Yt,clearAllMessagesTempData:ge,sendResumeGameMessage:Xt,handleResumeGameMessagesReceived:zt}},s.multiplayerMessageManager=s.makeMultiplayerMessageManager()})(gdjs||(gdjs={}));
2
2
  //# sourceMappingURL=messageManager.js.map