@combos-fun/plugin-development-tool 0.0.22 → 0.0.24
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.
- package/agent-skill.md +19 -0
- package/dist/plugin-development-tool.cjs.js +193 -1
- package/dist/plugin-development-tool.cjs.js.map +1 -1
- package/dist/plugin-development-tool.cjs.prod.js +1 -1
- package/dist/plugin-development-tool.d.ts +53 -1
- package/dist/plugin-development-tool.esm.js +188 -2
- package/dist/plugin-development-tool.esm.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/plugin-renderer"),o=require("@combos-fun/plugin-renderer-graphics"),s=require("@combos-fun/plugin-renderer-event");const i="combos-development-tool:set",r="combos-development-tool:set-success",a="combos-development-tool:refresh",c="combos-development-tool:gameobject-selected",l="combos-development-tool:apply-property";class h extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const d=new Set(["gameObject","name","started","__componentDefaultParams","destroyed","inScene","worldTransform","children","_parent"]),u={Graphics:new Set(["graphics"]),Physics:new Set(["body","Body","PhysicsEngine","World","Constraint","mouseConstraint","bodyParams"]),Event:new Set(["hitArea"])};function p(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>p(e,t+1));if("object"==typeof e){const n={};for(const[o,s]of Object.entries(e)){if("function"==typeof s)continue;const e=p(s,t+1);void 0!==e&&(n[o]=e)}return n}}}function f(e){const t={},n=u[e.name];for(const o of Object.keys(e)){if(d.has(o)||o.startsWith("_"))continue;if(n?.has(o))continue;const s=e[o];if("function"==typeof s)continue;const i=p(s);void 0!==i&&(t[o]=i)}return t}function m(e){const t=e.getComponent(h),n=t?.payload?.source;var o;if((o=n)&&"object"==typeof o&&"string"==typeof o.file)return{file:n.file,anchor:n.anchor??e.name}}function g(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fields:f(e)}));return{id:e.id,name:e.name,components:t,source:m(e)}}function y(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;let i=s;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const b=new Set(["position","size","origin","anchor","scale","skew"]);function w(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const O={Transform:function(e,t,n,o){const s=e.transform??t,i=s;if(1===n.length&&"rotation"===n[0]){const e=w(o);return void 0!==e&&(s.rotation=e,!0)}if(2===n.length&&b.has(n[0])){const t=n[0],s=n[1],r=w(o);if(void 0===r)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[s]=r,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const s=t;if(1===n.length&&"text"===n[0])return s.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...s.style??{},[e]:o};return s.style=t,!0}return!1},Sound:function(e,t,n,o){const s=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=w(o);return void 0!==e&&(s.volume=e,!0)}return!1}};function v(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;const i=O[t];return!!i?.(e,s,n,o)||y(e,t,n,o)}const E="__combosDevelopmentToolOutline";let G=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.enabled=!1,this.outlineGo=null,this.selected=null,this.tapHandlers=new Map,this.tapOwners=new Map,this.disabledGameEventGoIds=new Set,this.pickEvents=new Set,this.needsRescan=!1,this.lastOutlineBounds=null,this.onWindowSet=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowMessage=e=>{const t=e.data;t&&"object"==typeof t&&(t.type===i&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===a?this.requestSceneRescan():t.type===l&&this.handleApplyProperty(t))},this.onGameSet=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onWindowRefresh=()=>{this.requestSceneRescan()}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*","undefined"!=typeof window&&(window.addEventListener(i,this.onWindowSet),window.addEventListener(a,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(i,this.onGameSet),this.game.on(a,this.onGameRefresh),this.enabled&&(this.needsRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(i,this.onWindowSet),window.removeEventListener(a,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(i,this.onGameSet),this.game.off(a,this.onGameRefresh),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.clearSelection()}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?this.needsRescan=!0:(this.clearSelection(),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}update(e){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.attachEditMode(),this.postSetSuccess(!0));for(const e of[...this.tapOwners.values()])e.destroyed&&this.releasePick(e);this.enabled&&this.selected&&this.outlineGo&&this.updateSelectionOutline()}componentChanged(e){if(!this.enabled)return;const{type:n,gameObject:o,componentName:s}=e;o&&"CombosDevelopmentToolTarget"===s&&(n===t.OBSERVER_TYPE.ADD?(this.stripGameEvent(o),this.ensurePick(o)):n===t.OBSERVER_TYPE.REMOVE&&(this.releasePick(o),this.selected===o&&this.clearSelection()))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0)}attachEditMode(){this.detachAllPicks();const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)this.isIgnoredPickGo(t)||this.stripGameEvent(t);for(const t of e)this.isIgnoredPickGo(t)||t.getComponent(h)&&this.ensurePick(t)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}isIgnoredPickGo(e){return e.name===E||e===this.outlineGo}stripGameEvent(e){if(this.disabledGameEventGoIds.has(e.id))return;if(!e.getComponent(s.Event))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!1,this.disabledGameEventGoIds.add(e.id)}catch{}}restoreDisabledGameEvents(){for(const e of[...this.disabledGameEventGoIds]){const t=this.findGameObjectById(e);if(!t||t.destroyed){this.disabledGameEventGoIds.delete(e);continue}const n=this.getRendererContainer(t);if(n)try{n.interactive=!0}catch{}this.disabledGameEventGoIds.delete(e)}}detachAllPicks(){for(const e of[...this.tapOwners.values()])this.releasePick(e)}ensurePick(e){if(this.tapHandlers.has(e.id))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!0}catch{}let n=e.getComponent(s.Event);n||(n=e.addComponent(this.createPickEvent(e)),this.pickEvents.add(e.id));const o=t=>this.onSelect(e,t);this.tapHandlers.set(e.id,o),this.tapOwners.set(e.id,e),n.on("tap",o)}createPickEvent(e){const t=this.resolvePickBounds(e);return t.width>0&&t.height>0?new s.Event({hitArea:{type:s.HIT_AREA_TYPE.Rect,style:{x:t.x,y:t.y,width:t.width,height:t.height}}}):new s.Event}resolvePickBounds(e){if(this.shouldPreferRenderedBounds(e)){const t=this.resolveOwnGraphicsLocalBounds(e);if(t)return t;const n=this.resolveContainerLocalBounds(e);if(n)return n}const{width:t,height:n}=e.transform.size;if(t>0&&n>0)return{x:0,y:0,width:t,height:n};const o=this.resolveContainerLocalBounds(e);return o||{x:0,y:0,width:1,height:1}}shouldPreferRenderedBounds(e){return null!=e.getComponent(o.Graphics)}resolveOwnGraphicsLocalBounds(e){const t=e.getComponent(o.Graphics);if(!t?.graphics)return null;try{const e=t.graphics.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}return null}resolveContainerLocalBounds(e){const t=this.getRendererContainer(e);if(!t)return null;const n=this.getOutlineContainerIfChildOf(e);let o=!1;n?.parent===t&&(t.removeChild(n),o=!0);try{const e=t.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}finally{o&&n&&t.addChild(n)}return null}getOutlineContainerIfChildOf(e){return this.outlineGo&&this.outlineGo.parent===e?this.getRendererContainer(this.outlineGo):null}getRendererContainer(e){const t=this.game.getSystem(n.RendererSystem);if(!t?.containerManager)return null;try{return t.containerManager.getContainer(e.id)}catch{return null}}releasePick(e){const t=this.tapHandlers.get(e.id);if(!t)return;const n=e.getComponent(s.Event);if(n?.off("tap",t),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),this.pickEvents.has(e.id)){try{e.removeComponent(s.Event)}catch{}this.pickEvents.delete(e.id)}}postSetSuccess(e){const t={type:r,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(r,{enabled:e})}ensureOutline(){if(this.outlineGo)return;const e=new t.GameObject(E,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});e.addComponent(new o.Graphics),this.outlineGo=e}onSelect(e,t){if(!this.enabled)return;if(t?.stopPropagation?.(),this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo),this.invalidateOutlineBounds(),this.updateSelectionOutline();const n=g(e),o={type:c,snapshot:n,pointer:t?.data?.position??null};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin)}findGameObjectById(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);return t.find(t=>t.id===e)??null}findGameObjectBySource(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);const n=e.file.trim(),o=(e.anchor??"").trim();if(!o)return null;for(const e of t){const t=m(e);if(!t||t.file!==n)continue;if((t.anchor??e.name)===o)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,s=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!s||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;v(i,t,n,e.value)&&this.selected?.id===i.id&&(this.invalidateOutlineBounds(),this.updateSelectionOutline(),this.postSnapshotUpdate(i))}postSnapshotUpdate(e){const t=g(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:c,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelection(){this.selected=null,this.invalidateOutlineBounds(),this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(o.Graphics);e?.graphics&&e.graphics.clear()}updateSelectionOutline(){if(!this.enabled||!this.selected||!this.outlineGo)return;const e=this.outlineGo.getComponent(o.Graphics);if(!e?.graphics)return;const t=this.resolvePickBounds(this.selected);if(this.lastOutlineBounds&&this.pickBoundsEqual(this.lastOutlineBounds,t))return;this.lastOutlineBounds=t;const n=e.graphics;n.clear(),n.rect(t.x,t.y,t.width,t.height),n.stroke({width:4,color:5636010,alpha:1})}invalidateOutlineBounds(){this.lastOutlineBounds=null}pickBoundsEqual(e,t){const n=.01;return Math.abs(e.x-t.x)<n&&Math.abs(e.y-t.y)<n&&Math.abs(e.width-t.width)<n&&Math.abs(e.height-t.height)<n}};G=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],G);var S=G;Object.assign(S,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.21"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=l,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=c,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=a,exports.COMBOS_DEVELOPMENT_TOOL_SET=i,exports.COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS=r,exports.CombosDevelopmentToolSystem=S,exports.CombosDevelopmentToolTarget=h,exports.applyPropertyValue=y,exports.applyPropertyWithHooks=v,exports.buildGameObjectSnapshot=g,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let s=o;for(const e of n){if(null==s||"object"!=typeof s)return;s=s[e]}return s},exports.readSourceAnchor=m;
|
|
1
|
+
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/plugin-renderer"),o=require("@combos-fun/plugin-renderer-graphics"),s=require("@combos-fun/plugin-renderer-event");const i="combos-development-tool:set",r="combos-development-tool:set-success",a="combos-development-tool:refresh",d="combos-development-tool:gameobject-selected",c="combos-development-tool:apply-property",h="combos-development-tool:set-paused",l="combos-development-tool:set-muted",u="combos-development-tool:state-changed";class p extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const m=["knoffice.tech","converge.ai"];function f(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let n;try{n=new URL(e)}catch{return!1}const o=e.toLowerCase(),s=n.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(o===t.toLowerCase())return!0;continue}const n=t.toLowerCase().replace(/^\./,"");if(s===n||s.endsWith(`.${n}`))return!0}return!1}function g(e){if(!e?.length)return[...m];if(e.includes("*"))return["*"];const t=new Set,n=[];for(const o of[...m,...e]){const e=o.trim();e&&!t.has(e)&&(t.add(e),n.push(e))}return n}const y=new Set(["gameObject","name","started","__componentDefaultParams","destroyed","inScene","worldTransform","children","_parent"]),w={Graphics:new Set(["graphics"]),Physics:new Set(["body","Body","PhysicsEngine","World","Constraint","mouseConstraint","bodyParams"]),Event:new Set(["hitArea"])};function b(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>b(e,t+1));if("object"==typeof e){const n={};for(const[o,s]of Object.entries(e)){if("function"==typeof s)continue;const e=b(s,t+1);void 0!==e&&(n[o]=e)}return n}}}function O(e){const t={},n=w[e.name];for(const o of Object.keys(e)){if(y.has(o)||o.startsWith("_"))continue;if(n?.has(o))continue;const s=e[o];if("function"==typeof s)continue;const i=b(s);void 0!==i&&(t[o]=i)}return t}function E(e){const t=e.getComponent(p),n=t?.payload?.source;var o;if((o=n)&&"object"==typeof o&&"string"==typeof o.file)return{file:n.file,anchor:n.anchor??e.name}}function S(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fields:O(e)}));return{id:e.id,name:e.name,components:t,source:E(e)}}function v(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;let i=s;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const G=new Set(["position","size","origin","anchor","scale","skew"]);function C(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const M={Transform:function(e,t,n,o){const s=e.transform??t,i=s;if(1===n.length&&"rotation"===n[0]){const e=C(o);return void 0!==e&&(s.rotation=e,!0)}if(2===n.length&&G.has(n[0])){const t=n[0],s=n[1],r=C(o);if(void 0===r)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[s]=r,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const s=t;if(1===n.length&&"text"===n[0])return s.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...s.style??{},[e]:o};return s.style=t,!0}return!1},Sound:function(e,t,n,o){const s=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=C(o);return void 0!==e&&(s.volume=e,!0)}return!1}};function P(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;const i=M[t];return!!i?.(e,s,n,o)||v(e,t,n,o)}const T="__combosDevelopmentToolOutline";let _=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.allowedMessageOrigins=g(),this.enabled=!1,this.outlineGo=null,this.selected=null,this.tapHandlers=new Map,this.tapOwners=new Map,this.disabledGameEventGoIds=new Set,this.pickEvents=new Set,this.needsRescan=!1,this.lastOutlineBounds=null,this.mutedWithoutSoundSystem=!1,this.onWindowSet=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowSetPaused=e=>{const t=e.detail;t&&"boolean"==typeof t.paused&&this.setPaused(t.paused)},this.onWindowSetMuted=e=>{const t=e.detail;t&&"boolean"==typeof t.muted&&this.setMuted(t.muted)},this.onWindowMessage=e=>{if(!f(e.origin,this.allowedMessageOrigins))return;const t=e.data;t&&"object"==typeof t&&(t.type===i&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===h&&"boolean"==typeof t.paused?this.setPaused(t.paused):t.type===l&&"boolean"==typeof t.muted?this.setMuted(t.muted):t.type===a?this.requestSceneRescan():t.type===c&&this.handleApplyProperty(t))},this.onGameSet=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onGameSetPaused=e=>{e&&"boolean"==typeof e.paused&&this.setPaused(e.paused)},this.onGameSetMuted=e=>{e&&"boolean"==typeof e.muted&&this.setMuted(e.muted)},this.onWindowRefresh=()=>{this.requestSceneRescan()}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*",this.allowedMessageOrigins=g(e?.allowedMessageOrigins),"undefined"!=typeof window&&(window.addEventListener(i,this.onWindowSet),window.addEventListener(h,this.onWindowSetPaused),window.addEventListener(l,this.onWindowSetMuted),window.addEventListener(a,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(i,this.onGameSet),this.game.on(h,this.onGameSetPaused),this.game.on(l,this.onGameSetMuted),this.game.on(a,this.onGameRefresh),this.enabled&&(this.needsRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(i,this.onWindowSet),window.removeEventListener(h,this.onWindowSetPaused),window.removeEventListener(l,this.onWindowSetMuted),window.removeEventListener(a,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(i,this.onGameSet),this.game.off(h,this.onGameSetPaused),this.game.off(l,this.onGameSetMuted),this.game.off(a,this.onGameRefresh),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.clearSelection()}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?this.needsRescan=!0:(this.clearSelection(),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}get isPaused(){return!this.game.playing}get isMuted(){const e=this.getSoundSystem();return e?e.muted:this.mutedWithoutSoundSystem}setPaused(e){e?this.game.playing&&this.game.pause():this.game.playing||this.game.resume(),this.postStateChanged()}setMuted(e){const t=this.getSoundSystem();t?t.muted=e:this.mutedWithoutSoundSystem=e,this.postStateChanged()}update(e){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.attachEditMode(),this.postSetSuccess(!0));for(const e of[...this.tapOwners.values()])e.destroyed&&this.releasePick(e);this.enabled&&this.selected&&this.outlineGo&&this.updateSelectionOutline()}componentChanged(e){if(!this.enabled)return;const{type:n,gameObject:o,componentName:s}=e;o&&"CombosDevelopmentToolTarget"===s&&(n===t.OBSERVER_TYPE.ADD?(this.stripGameEvent(o),this.ensurePick(o)):n===t.OBSERVER_TYPE.REMOVE&&(this.releasePick(o),this.selected===o&&this.clearSelection()))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0)}attachEditMode(){this.detachAllPicks();const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)this.isIgnoredPickGo(t)||this.stripGameEvent(t);for(const t of e)this.isIgnoredPickGo(t)||t.getComponent(p)&&this.ensurePick(t)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}isIgnoredPickGo(e){return e.name===T||e===this.outlineGo}stripGameEvent(e){if(this.disabledGameEventGoIds.has(e.id))return;if(!e.getComponent(s.Event))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!1,this.disabledGameEventGoIds.add(e.id)}catch{}}restoreDisabledGameEvents(){for(const e of[...this.disabledGameEventGoIds]){const t=this.findGameObjectById(e);if(!t||t.destroyed){this.disabledGameEventGoIds.delete(e);continue}const n=this.getRendererContainer(t);if(n)try{n.interactive=!0}catch{}this.disabledGameEventGoIds.delete(e)}}detachAllPicks(){for(const e of[...this.tapOwners.values()])this.releasePick(e)}ensurePick(e){if(this.tapHandlers.has(e.id))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!0}catch{}let n=e.getComponent(s.Event);n||(n=e.addComponent(this.createPickEvent(e)),this.pickEvents.add(e.id));const o=t=>this.onSelect(e,t);this.tapHandlers.set(e.id,o),this.tapOwners.set(e.id,e),n.on("tap",o)}createPickEvent(e){const t=this.resolvePickBounds(e);return t.width>0&&t.height>0?new s.Event({hitArea:{type:s.HIT_AREA_TYPE.Rect,style:{x:t.x,y:t.y,width:t.width,height:t.height}}}):new s.Event}resolvePickBounds(e){if(this.shouldPreferRenderedBounds(e)){const t=this.resolveOwnGraphicsLocalBounds(e);if(t)return t;const n=this.resolveContainerLocalBounds(e);if(n)return n}const{width:t,height:n}=e.transform.size;if(t>0&&n>0)return{x:0,y:0,width:t,height:n};const o=this.resolveContainerLocalBounds(e);return o||{x:0,y:0,width:1,height:1}}shouldPreferRenderedBounds(e){return null!=e.getComponent(o.Graphics)}resolveOwnGraphicsLocalBounds(e){const t=e.getComponent(o.Graphics);if(!t?.graphics)return null;try{const e=t.graphics.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}return null}resolveContainerLocalBounds(e){const t=this.getRendererContainer(e);if(!t)return null;const n=this.getOutlineContainerIfChildOf(e);let o=!1;n?.parent===t&&(t.removeChild(n),o=!0);try{const e=t.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}finally{o&&n&&t.addChild(n)}return null}getOutlineContainerIfChildOf(e){return this.outlineGo&&this.outlineGo.parent===e?this.getRendererContainer(this.outlineGo):null}getRendererContainer(e){const t=this.game.getSystem(n.RendererSystem);if(!t?.containerManager)return null;try{return t.containerManager.getContainer(e.id)}catch{return null}}releasePick(e){const t=this.tapHandlers.get(e.id);if(!t)return;const n=e.getComponent(s.Event);if(n?.off("tap",t),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),this.pickEvents.has(e.id)){try{e.removeComponent(s.Event)}catch{}this.pickEvents.delete(e.id)}}postSetSuccess(e){const t={type:r,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(r,{enabled:e})}postStateChanged(){const e={paused:this.isPaused,muted:this.isMuted},t={type:u,...e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(u,e)}getSoundSystem(){const e=this.game.getSystem("SoundSystem");return e&&"object"==typeof e&&"muted"in e&&"boolean"==typeof e.muted?e:null}ensureOutline(){if(this.outlineGo)return;const e=new t.GameObject(T,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});e.addComponent(new o.Graphics),this.outlineGo=e}onSelect(e,t){if(!this.enabled)return;if(t?.stopPropagation?.(),this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo),this.invalidateOutlineBounds(),this.updateSelectionOutline();const n=S(e),o={type:d,snapshot:n,pointer:t?.data?.position??null};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin)}findGameObjectById(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);return t.find(t=>t.id===e)??null}findGameObjectBySource(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);const n=e.file.trim(),o=(e.anchor??"").trim();if(!o)return null;for(const e of t){const t=E(e);if(!t||t.file!==n)continue;if((t.anchor??e.name)===o)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,s=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!s||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;P(i,t,n,e.value)&&this.selected?.id===i.id&&(this.invalidateOutlineBounds(),this.updateSelectionOutline(),this.postSnapshotUpdate(i))}postSnapshotUpdate(e){const t=S(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:d,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelection(){this.selected=null,this.invalidateOutlineBounds(),this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(o.Graphics);e?.graphics&&e.graphics.clear()}updateSelectionOutline(){if(!this.enabled||!this.selected||!this.outlineGo)return;const e=this.outlineGo.getComponent(o.Graphics);if(!e?.graphics)return;const t=this.resolvePickBounds(this.selected);if(this.lastOutlineBounds&&this.pickBoundsEqual(this.lastOutlineBounds,t))return;this.lastOutlineBounds=t;const n=e.graphics;n.clear(),n.rect(t.x,t.y,t.width,t.height),n.stroke({width:4,color:5636010,alpha:1})}invalidateOutlineBounds(){this.lastOutlineBounds=null}pickBoundsEqual(e,t){const n=.01;return Math.abs(e.x-t.x)<n&&Math.abs(e.y-t.y)<n&&Math.abs(e.width-t.width)<n&&Math.abs(e.height-t.height)<n}};_=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],_);var B=_;Object.assign(B,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.23"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=c,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=d,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=a,exports.COMBOS_DEVELOPMENT_TOOL_SET=i,exports.COMBOS_DEVELOPMENT_TOOL_SET_MUTED=l,exports.COMBOS_DEVELOPMENT_TOOL_SET_PAUSED=h,exports.COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS=r,exports.COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED=u,exports.CombosDevelopmentToolSystem=B,exports.CombosDevelopmentToolTarget=p,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=m,exports.applyPropertyValue=v,exports.applyPropertyWithHooks=P,exports.buildGameObjectSnapshot=S,exports.isAllowedMessageOrigin=f,exports.mergeAllowedMessageOrigins=g,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let s=o;for(const e of n){if(null==s||"object"!=typeof s)return;s=s[e]}return s},exports.readSourceAnchor=E;
|
|
@@ -12,6 +12,26 @@ declare const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED: "combos-development-t
|
|
|
12
12
|
declare const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY: "combos-development-tool:apply-property";
|
|
13
13
|
/** iframe → parent: game scene bootstrap finished; parent may enable pick mode. */
|
|
14
14
|
declare const COMBOS_DEVELOPMENT_TOOL_READY: "combos-development-tool:ready";
|
|
15
|
+
/** Parent → iframe: pause or resume the game loop. Payload: `{ paused: boolean }`. */
|
|
16
|
+
declare const COMBOS_DEVELOPMENT_TOOL_SET_PAUSED: "combos-development-tool:set-paused";
|
|
17
|
+
/** Parent → iframe: mute or unmute audio when `SoundSystem` is registered. Payload: `{ muted: boolean }`. */
|
|
18
|
+
declare const COMBOS_DEVELOPMENT_TOOL_SET_MUTED: "combos-development-tool:set-muted";
|
|
19
|
+
/** iframe → parent (and `game.emit`): current pause/mute snapshot after a successful change. */
|
|
20
|
+
declare const COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED: "combos-development-tool:state-changed";
|
|
21
|
+
|
|
22
|
+
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
23
|
+
declare const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES: readonly ["knoffice.tech", "converge.ai"];
|
|
24
|
+
/**
|
|
25
|
+
* Returns whether `origin` is allowed by `allowed`.
|
|
26
|
+
*
|
|
27
|
+
* Each entry in `allowed` is either:
|
|
28
|
+
* - a **host suffix** (e.g. `knoffice.tech`) — matches that host and `*.knoffice.tech`;
|
|
29
|
+
* - a **full origin** (e.g. `https://creator.knoffice.tech`) — exact match;
|
|
30
|
+
* - `'*'` — accept any origin (escape hatch).
|
|
31
|
+
*/
|
|
32
|
+
declare function isAllowedMessageOrigin(origin: string, allowed: readonly string[]): boolean;
|
|
33
|
+
/** Defaults plus any extra entries (deduped). `['*']` alone accepts any origin. */
|
|
34
|
+
declare function mergeAllowedMessageOrigins(extra?: string[]): string[];
|
|
15
35
|
|
|
16
36
|
interface CombosDevelopmentToolTargetParams extends ComponentParams {
|
|
17
37
|
/** Extra JSON-serializable fields included in postMessage to parent. */
|
|
@@ -31,6 +51,11 @@ declare class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToo
|
|
|
31
51
|
interface CombosDevelopmentToolSystemParams {
|
|
32
52
|
/** postMessage `targetOrigin` when notifying parent (default `'*'`). */
|
|
33
53
|
postMessageOrigin?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Extra inbound `postMessage` origins merged with {@link DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES}.
|
|
56
|
+
* Each entry is a host suffix (e.g. `localhost`) or full origin. Pass `['*']` to accept any origin.
|
|
57
|
+
*/
|
|
58
|
+
allowedMessageOrigins?: string[];
|
|
34
59
|
}
|
|
35
60
|
/**
|
|
36
61
|
* **Off** at start. While enabled:
|
|
@@ -42,12 +67,20 @@ interface CombosDevelopmentToolSystemParams {
|
|
|
42
67
|
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
43
68
|
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
44
69
|
*
|
|
70
|
+
* Pause / mute (independent of pick mode; parent toolbar or in-game debug UI):
|
|
71
|
+
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, paused: true })`
|
|
72
|
+
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_MUTED, muted: true })`
|
|
73
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, { paused: true })` or `.setPaused(true)`
|
|
74
|
+
* Mute applies when `SoundSystem` is registered; otherwise the desired value is remembered until it appears.
|
|
75
|
+
* Both emit / post `COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED` with `{ paused, muted }`.
|
|
76
|
+
*
|
|
45
77
|
* While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
|
|
46
78
|
* or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
47
79
|
*/
|
|
48
80
|
declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSystemParams> {
|
|
49
81
|
static systemName: string;
|
|
50
82
|
private postMessageOrigin;
|
|
83
|
+
private allowedMessageOrigins;
|
|
51
84
|
private enabled;
|
|
52
85
|
private outlineGo;
|
|
53
86
|
private selected;
|
|
@@ -59,16 +92,33 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
59
92
|
private readonly pickEvents;
|
|
60
93
|
private needsRescan;
|
|
61
94
|
private lastOutlineBounds;
|
|
95
|
+
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
96
|
+
private mutedWithoutSoundSystem;
|
|
62
97
|
private readonly onWindowSet;
|
|
98
|
+
private readonly onWindowSetPaused;
|
|
99
|
+
private readonly onWindowSetMuted;
|
|
63
100
|
private readonly onWindowMessage;
|
|
64
101
|
private readonly onGameSet;
|
|
65
102
|
private readonly onGameRefresh;
|
|
103
|
+
private readonly onGameSetPaused;
|
|
104
|
+
private readonly onGameSetMuted;
|
|
66
105
|
private readonly onWindowRefresh;
|
|
67
106
|
init(params?: CombosDevelopmentToolSystemParams): void;
|
|
68
107
|
onDestroy(): void;
|
|
69
108
|
/** Programmatic toggle (same effect as events). */
|
|
70
109
|
setEnabled(on: boolean): void;
|
|
71
110
|
get isEnabled(): boolean;
|
|
111
|
+
/** Whether the game loop is paused (`!game.playing`). */
|
|
112
|
+
get isPaused(): boolean;
|
|
113
|
+
/** Master mute when `SoundSystem` exists; otherwise the last requested value. */
|
|
114
|
+
get isMuted(): boolean;
|
|
115
|
+
/** Pause or resume the game loop (same as `game.pause()` / `game.resume()`). */
|
|
116
|
+
setPaused(paused: boolean): void;
|
|
117
|
+
/**
|
|
118
|
+
* Mute or unmute audio via `SoundSystem` when registered.
|
|
119
|
+
* No-op on the audio graph if `SoundSystem` is missing; value is remembered for `isMuted`.
|
|
120
|
+
*/
|
|
121
|
+
setMuted(muted: boolean): void;
|
|
72
122
|
update(e: UpdateParams): void;
|
|
73
123
|
componentChanged(changed: ComponentChanged): void;
|
|
74
124
|
/** Re-bind pick targets after dynamic scene changes while enabled. */
|
|
@@ -91,6 +141,8 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
91
141
|
private getRendererContainer;
|
|
92
142
|
private releasePick;
|
|
93
143
|
private postSetSuccess;
|
|
144
|
+
private postStateChanged;
|
|
145
|
+
private getSoundSystem;
|
|
94
146
|
private ensureOutline;
|
|
95
147
|
private onSelect;
|
|
96
148
|
private findGameObjectById;
|
|
@@ -136,5 +188,5 @@ declare function readPropertyValue(go: GameObject, componentName: string, path:
|
|
|
136
188
|
|
|
137
189
|
declare function applyPropertyWithHooks(go: GameObject, componentName: string, path: string[], value: unknown): boolean;
|
|
138
190
|
|
|
139
|
-
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
|
|
191
|
+
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, isAllowedMessageOrigin, mergeAllowedMessageOrigins, readPropertyValue, readSourceAnchor };
|
|
140
192
|
export type { CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams, SceneEditComponentSnapshot, SceneEditGameObjectSnapshot, SceneEditPropertyRef, SceneSourceAnchor };
|
|
@@ -16,6 +16,12 @@ const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = 'combos-development-tool:gam
|
|
|
16
16
|
const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = 'combos-development-tool:apply-property';
|
|
17
17
|
/** iframe → parent: game scene bootstrap finished; parent may enable pick mode. */
|
|
18
18
|
const COMBOS_DEVELOPMENT_TOOL_READY = 'combos-development-tool:ready';
|
|
19
|
+
/** Parent → iframe: pause or resume the game loop. Payload: `{ paused: boolean }`. */
|
|
20
|
+
const COMBOS_DEVELOPMENT_TOOL_SET_PAUSED = 'combos-development-tool:set-paused';
|
|
21
|
+
/** Parent → iframe: mute or unmute audio when `SoundSystem` is registered. Payload: `{ muted: boolean }`. */
|
|
22
|
+
const COMBOS_DEVELOPMENT_TOOL_SET_MUTED = 'combos-development-tool:set-muted';
|
|
23
|
+
/** iframe → parent (and `game.emit`): current pause/mute snapshot after a successful change. */
|
|
24
|
+
const COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED = 'combos-development-tool:state-changed';
|
|
19
25
|
|
|
20
26
|
/**
|
|
21
27
|
* Marks a `GameObject` as selectable in editor pick mode. While the development tool is enabled,
|
|
@@ -33,6 +39,74 @@ class CombosDevelopmentToolTarget extends Component {
|
|
|
33
39
|
}
|
|
34
40
|
}
|
|
35
41
|
|
|
42
|
+
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
43
|
+
const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES = [
|
|
44
|
+
'knoffice.tech',
|
|
45
|
+
'converge.ai',
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Returns whether `origin` is allowed by `allowed`.
|
|
49
|
+
*
|
|
50
|
+
* Each entry in `allowed` is either:
|
|
51
|
+
* - a **host suffix** (e.g. `knoffice.tech`) — matches that host and `*.knoffice.tech`;
|
|
52
|
+
* - a **full origin** (e.g. `https://creator.knoffice.tech`) — exact match;
|
|
53
|
+
* - `'*'` — accept any origin (escape hatch).
|
|
54
|
+
*/
|
|
55
|
+
function isAllowedMessageOrigin(origin, allowed) {
|
|
56
|
+
if (allowed.includes('*')) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
if (allowed.length === 0) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = new URL(origin);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const originLower = origin.toLowerCase();
|
|
70
|
+
const hostLower = parsed.hostname.toLowerCase();
|
|
71
|
+
for (const entry of allowed) {
|
|
72
|
+
const trimmed = entry.trim();
|
|
73
|
+
if (!trimmed) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (trimmed.includes('://')) {
|
|
77
|
+
if (originLower === trimmed.toLowerCase()) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const suffix = trimmed.toLowerCase().replace(/^\./, '');
|
|
83
|
+
if (hostLower === suffix || hostLower.endsWith(`.${suffix}`)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
/** Defaults plus any extra entries (deduped). `['*']` alone accepts any origin. */
|
|
90
|
+
function mergeAllowedMessageOrigins(extra) {
|
|
91
|
+
if (!extra?.length) {
|
|
92
|
+
return [...DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES];
|
|
93
|
+
}
|
|
94
|
+
if (extra.includes('*')) {
|
|
95
|
+
return ['*'];
|
|
96
|
+
}
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const result = [];
|
|
99
|
+
for (const entry of [...DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, ...extra]) {
|
|
100
|
+
const trimmed = entry.trim();
|
|
101
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
seen.add(trimmed);
|
|
105
|
+
result.push(trimmed);
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
36
110
|
function isSceneSourceAnchor(v) {
|
|
37
111
|
return (!!v &&
|
|
38
112
|
typeof v === 'object' &&
|
|
@@ -282,6 +356,13 @@ const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
|
282
356
|
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
283
357
|
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
284
358
|
*
|
|
359
|
+
* Pause / mute (independent of pick mode; parent toolbar or in-game debug UI):
|
|
360
|
+
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, paused: true })`
|
|
361
|
+
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_MUTED, muted: true })`
|
|
362
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, { paused: true })` or `.setPaused(true)`
|
|
363
|
+
* Mute applies when `SoundSystem` is registered; otherwise the desired value is remembered until it appears.
|
|
364
|
+
* Both emit / post `COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED` with `{ paused, muted }`.
|
|
365
|
+
*
|
|
285
366
|
* While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
|
|
286
367
|
* or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
287
368
|
*/
|
|
@@ -289,6 +370,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
289
370
|
constructor() {
|
|
290
371
|
super(...arguments);
|
|
291
372
|
this.postMessageOrigin = '*';
|
|
373
|
+
this.allowedMessageOrigins = mergeAllowedMessageOrigins();
|
|
292
374
|
this.enabled = false;
|
|
293
375
|
this.outlineGo = null;
|
|
294
376
|
this.selected = null;
|
|
@@ -300,19 +382,42 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
300
382
|
this.pickEvents = new Set();
|
|
301
383
|
this.needsRescan = false;
|
|
302
384
|
this.lastOutlineBounds = null;
|
|
385
|
+
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
386
|
+
this.mutedWithoutSoundSystem = false;
|
|
303
387
|
this.onWindowSet = (e) => {
|
|
304
388
|
const d = e.detail;
|
|
305
389
|
if (d && typeof d.enabled === 'boolean') {
|
|
306
390
|
this.setEnabled(d.enabled);
|
|
307
391
|
}
|
|
308
392
|
};
|
|
393
|
+
this.onWindowSetPaused = (e) => {
|
|
394
|
+
const d = e.detail;
|
|
395
|
+
if (d && typeof d.paused === 'boolean') {
|
|
396
|
+
this.setPaused(d.paused);
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
this.onWindowSetMuted = (e) => {
|
|
400
|
+
const d = e.detail;
|
|
401
|
+
if (d && typeof d.muted === 'boolean') {
|
|
402
|
+
this.setMuted(d.muted);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
309
405
|
this.onWindowMessage = (e) => {
|
|
406
|
+
if (!isAllowedMessageOrigin(e.origin, this.allowedMessageOrigins)) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
310
409
|
const d = e.data;
|
|
311
410
|
if (!d || typeof d !== 'object')
|
|
312
411
|
return;
|
|
313
412
|
if (d.type === COMBOS_DEVELOPMENT_TOOL_SET && typeof d.enabled === 'boolean') {
|
|
314
413
|
this.setEnabled(d.enabled);
|
|
315
414
|
}
|
|
415
|
+
else if (d.type === COMBOS_DEVELOPMENT_TOOL_SET_PAUSED && typeof d.paused === 'boolean') {
|
|
416
|
+
this.setPaused(d.paused);
|
|
417
|
+
}
|
|
418
|
+
else if (d.type === COMBOS_DEVELOPMENT_TOOL_SET_MUTED && typeof d.muted === 'boolean') {
|
|
419
|
+
this.setMuted(d.muted);
|
|
420
|
+
}
|
|
316
421
|
else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {
|
|
317
422
|
this.requestSceneRescan();
|
|
318
423
|
}
|
|
@@ -328,6 +433,16 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
328
433
|
this.onGameRefresh = () => {
|
|
329
434
|
this.requestSceneRescan();
|
|
330
435
|
};
|
|
436
|
+
this.onGameSetPaused = (payload) => {
|
|
437
|
+
if (payload && typeof payload.paused === 'boolean') {
|
|
438
|
+
this.setPaused(payload.paused);
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
this.onGameSetMuted = (payload) => {
|
|
442
|
+
if (payload && typeof payload.muted === 'boolean') {
|
|
443
|
+
this.setMuted(payload.muted);
|
|
444
|
+
}
|
|
445
|
+
};
|
|
331
446
|
this.onWindowRefresh = () => {
|
|
332
447
|
this.requestSceneRescan();
|
|
333
448
|
};
|
|
@@ -335,12 +450,17 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
335
450
|
static { this.systemName = 'CombosDevelopmentToolSystem'; }
|
|
336
451
|
init(params) {
|
|
337
452
|
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
453
|
+
this.allowedMessageOrigins = mergeAllowedMessageOrigins(params?.allowedMessageOrigins);
|
|
338
454
|
if (typeof window !== 'undefined') {
|
|
339
455
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
456
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onWindowSetPaused);
|
|
457
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onWindowSetMuted);
|
|
340
458
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
341
459
|
window.addEventListener('message', this.onWindowMessage);
|
|
342
460
|
}
|
|
343
461
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
462
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onGameSetPaused);
|
|
463
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onGameSetMuted);
|
|
344
464
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
345
465
|
if (this.enabled) {
|
|
346
466
|
this.needsRescan = true;
|
|
@@ -349,10 +469,14 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
349
469
|
onDestroy() {
|
|
350
470
|
if (typeof window !== 'undefined') {
|
|
351
471
|
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
472
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onWindowSetPaused);
|
|
473
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onWindowSetMuted);
|
|
352
474
|
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
353
475
|
window.removeEventListener('message', this.onWindowMessage);
|
|
354
476
|
}
|
|
355
477
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
478
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onGameSetPaused);
|
|
479
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onGameSetMuted);
|
|
356
480
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
357
481
|
this.detachAllPicks();
|
|
358
482
|
this.restoreDisabledGameEvents();
|
|
@@ -376,6 +500,44 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
376
500
|
get isEnabled() {
|
|
377
501
|
return this.enabled;
|
|
378
502
|
}
|
|
503
|
+
/** Whether the game loop is paused (`!game.playing`). */
|
|
504
|
+
get isPaused() {
|
|
505
|
+
return !this.game.playing;
|
|
506
|
+
}
|
|
507
|
+
/** Master mute when `SoundSystem` exists; otherwise the last requested value. */
|
|
508
|
+
get isMuted() {
|
|
509
|
+
const sound = this.getSoundSystem();
|
|
510
|
+
if (sound) {
|
|
511
|
+
return sound.muted;
|
|
512
|
+
}
|
|
513
|
+
return this.mutedWithoutSoundSystem;
|
|
514
|
+
}
|
|
515
|
+
/** Pause or resume the game loop (same as `game.pause()` / `game.resume()`). */
|
|
516
|
+
setPaused(paused) {
|
|
517
|
+
if (paused) {
|
|
518
|
+
if (this.game.playing) {
|
|
519
|
+
this.game.pause();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
else if (!this.game.playing) {
|
|
523
|
+
this.game.resume();
|
|
524
|
+
}
|
|
525
|
+
this.postStateChanged();
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Mute or unmute audio via `SoundSystem` when registered.
|
|
529
|
+
* No-op on the audio graph if `SoundSystem` is missing; value is remembered for `isMuted`.
|
|
530
|
+
*/
|
|
531
|
+
setMuted(muted) {
|
|
532
|
+
const sound = this.getSoundSystem();
|
|
533
|
+
if (sound) {
|
|
534
|
+
sound.muted = muted;
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
this.mutedWithoutSoundSystem = muted;
|
|
538
|
+
}
|
|
539
|
+
this.postStateChanged();
|
|
540
|
+
}
|
|
379
541
|
update(e) {
|
|
380
542
|
if (this.enabled && this.needsRescan) {
|
|
381
543
|
this.needsRescan = false;
|
|
@@ -644,6 +806,30 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
644
806
|
}
|
|
645
807
|
this.game.emit(COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, { enabled });
|
|
646
808
|
}
|
|
809
|
+
postStateChanged() {
|
|
810
|
+
const state = {
|
|
811
|
+
paused: this.isPaused,
|
|
812
|
+
muted: this.isMuted,
|
|
813
|
+
};
|
|
814
|
+
const payload = {
|
|
815
|
+
type: COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED,
|
|
816
|
+
...state,
|
|
817
|
+
};
|
|
818
|
+
if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
|
|
819
|
+
window.parent.postMessage(payload, this.postMessageOrigin);
|
|
820
|
+
}
|
|
821
|
+
this.game.emit(COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, state);
|
|
822
|
+
}
|
|
823
|
+
getSoundSystem() {
|
|
824
|
+
const system = this.game.getSystem('SoundSystem');
|
|
825
|
+
if (!system ||
|
|
826
|
+
typeof system !== 'object' ||
|
|
827
|
+
!('muted' in system) ||
|
|
828
|
+
typeof system.muted !== 'boolean') {
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
return system;
|
|
832
|
+
}
|
|
647
833
|
ensureOutline() {
|
|
648
834
|
if (this.outlineGo)
|
|
649
835
|
return;
|
|
@@ -805,8 +991,8 @@ var CombosDevelopmentToolSystem$1 = CombosDevelopmentToolSystem;
|
|
|
805
991
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
806
992
|
Object.assign(CombosDevelopmentToolSystem$1, {
|
|
807
993
|
packageName: "@combos-fun/plugin-development-tool",
|
|
808
|
-
packageVersion: "0.0.
|
|
994
|
+
packageVersion: "0.0.23",
|
|
809
995
|
});
|
|
810
996
|
|
|
811
|
-
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
|
|
997
|
+
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, isAllowedMessageOrigin, mergeAllowedMessageOrigins, readPropertyValue, readSourceAnchor };
|
|
812
998
|
//# sourceMappingURL=plugin-development-tool.esm.js.map
|