Files
MatchMaster/tools/preview-pyramid-settlement.cjs
2026-10-12 15:00:49 +08:00

43 lines
6.0 KiB
JavaScript

// Local Cocos preview of the actual prefab and component; no login or reward writes.
const http=require('http'),fs=require('fs'),path=require('path'),ts=require('typescript');
const root=path.resolve(__dirname,'..'),creator='C:/ProgramData/cocos/editors/Creator/2.4.15';
const metas=new Map(),textures=new Map();
for(const name of fs.readdirSync(path.join(root,'assets/pyramid'),{recursive:true}).filter(n=>n.endsWith('.meta'))){
const m=JSON.parse(fs.readFileSync(path.join(root,'assets/pyramid',name))),file='assets/pyramid/'+name.slice(0,-5).replaceAll('\\','/');
if(m.importer==='texture')textures.set(m.uuid,file);
for(const s of Object.values(m.subMetas||{}))if(s.importer==='sprite-frame')metas.set(s.uuid,s);
}
const html=`<!doctype html><meta charset="utf-8"><style>html,body{margin:0;height:100%;background:#292929}canvas{display:block}#controls{position:absolute;z-index:2;top:0;left:0}button{padding:8px}</style><div id="controls"><button onclick="fixture('maximum')">最高档位</button><button onclick="fixture('reference')">效果图数量</button><button onclick="fixture('mixed')">27小时25分钟</button></div><canvas id="GameCanvas"></canvas><script src="/engine.js"></script><script src="/component.js"></script><script src="/boot.js"></script>`;
const boot=`
const texCache={},frameCache={};window.errors=[];window.addEventListener('error',e=>errors.push(e.message));window.addEventListener('unhandledrejection',e=>errors.push(String(e.reason)));
const json=p=>fetch(p).then(r=>r.json());
async function frame(uuid){if(frameCache[uuid])return frameCache[uuid];const m=await json('/frame/'+uuid);const texture=texCache[m.rawTextureUuid]||(texCache[m.rawTextureUuid]=await new Promise((resolve,reject)=>cc.assetManager.loadRemote('/texture/'+m.rawTextureUuid+(m.texture.endsWith('.jpg')?'.jpg':'.png'),(e,t)=>e?reject(e):resolve(t))));
const f=new cc.SpriteFrame(texture,cc.rect(m.trimX||0,m.trimY||0,m.width,m.height),!!m.rotated,cc.v2(m.offsetX||0,m.offsetY||0),cc.size(m.rawWidth||m.width,m.rawHeight||m.height));f.insetTop=m.borderTop||0;f.insetBottom=m.borderBottom||0;f.insetLeft=m.borderLeft||0;f.insetRight=m.borderRight||0;return frameCache[uuid]=f;}
cc.assetManager.init({importBase:'/imports',nativeBase:'/native'});cc.assetManager.loadBundle('/internal',error=>{if(error)throw error;cc.game.run({id:'GameCanvas',debugMode:1,frameRate:30,renderMode:0,groupList:['default'],collisionMatrix:[[true]]},async()=>{
cc.view.setDesignResolutionSize(1080,2200,cc.ResolutionPolicy.SHOW_ALL);cc.view.resizeWithBrowserSize(true);const scene=new cc.Scene(),canvas=new cc.Node('Canvas');scene.addChild(canvas);canvas.setContentSize(1080,2200);canvas.addComponent(cc.Canvas).designResolution=cc.size(1080,2200);cc.director.runScene(scene);
const data=await json('/file/assets/pyramid/prefab/PyramidSettlement.prefab');const root=data[data[0].data.__id__];root._components=root._components.filter(r=>!data[r.__id__].numberAtlas);
for(let i=0;i<data.length;i++)if(data[i].numberAtlas)data[i]={__type__:'cc.Component',node:{__id__:data[0].data.__id__},_enabled:false};
const details=new cc.deserialize.Details(),prefab=cc.deserialize(data,details);
await Promise.all(details.uuidList.map(async(uuid,i)=>{if(uuid==='eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432')return;details.uuidObjList[i][details.uuidPropList[i]]=await frame(uuid);}));
const atlasData=await json('/file/assets/pyramid/art/settlement/publicFont.plist.meta'),atlas=new cc.SpriteAtlas();atlas._spriteFrames={};
for(const [name,m]of Object.entries(atlasData.subMetas))atlas._spriteFrames[name.replace(/\\.png$/,'')]=await frame(m.uuid);
window.fixture=mode=>{if(window.popup)popup.destroy();const popup=cc.instantiate(prefab);canvas.addChild(popup);window.popup=popup;
const view=popup.addComponent(window.Settlement);view.numberAtlas=atlas;
const counts=mode==='reference'?[1000,3,3,3,1800]:[82800,262,137,132,(mode==='mixed'?1645:1635)*60];
view.show({goods:[1001,2001,2002,2003,2005].map((id,i)=>({id,count:counts[i]}))},()=>popup.destroy());window.ready=true;};fixture('maximum');
});});`;
http.createServer((req,res)=>{const url=decodeURIComponent(new URL(req.url,'http://localhost').pathname);const json=v=>{res.setHeader('Content-Type','application/json');res.end(JSON.stringify(v));};
if(url==='/'){res.setHeader('Content-Type','text/html');return res.end(html);}
if(url==='/boot.js'){res.setHeader('Content-Type','text/javascript');return res.end(boot);}
if(url==='/component.js'){res.setHeader('Content-Type','text/javascript');return res.end('window.Settlement=(function(){var exports={};'+ts.transpileModule(fs.readFileSync(path.join(root,'assets/pyramid/scripts/PyramidSettlement.ts'),'utf8'),{compilerOptions:{target:7,module:1,experimentalDecorators:true}}).outputText+';return exports.default;})();');}
let target;
if(url==='/engine.js')target=path.join(creator,'resources/engine/bin/cocos2d-js-for-preview.js');
else if(/^\/imports\/[a-f0-9]{2}\/[a-f0-9-]+\.json$/.test(url))target=path.join(root,'library',url.slice(1));
else if(/^\/native\/[a-f0-9]{2}\/[a-f0-9-]+\.png$/.test(url))target=path.join(root,'library/imports',url.slice('/native/'.length));
else if(url.startsWith('/internal/')||url.startsWith('/assets/internal/'))target=path.join(creator,'resources/cocos2d-x/simulator/win32/assets',url.replace(/^\/(assets\/)?/,''));
else if(url.startsWith('/file/assets/')){target=path.resolve(root,url.slice(6));if(!target.startsWith(path.join(root,'assets')+path.sep)){res.statusCode=403;return res.end();}}
else if(url.startsWith('/frame/')){const m=metas.get(url.slice(7));if(m)return json({...m,texture:textures.get(m.rawTextureUuid)});}
else if(url.startsWith('/texture/')){const id=path.basename(url,path.extname(url));if(textures.has(id))target=path.join(root,textures.get(id));}
if(target&&fs.existsSync(target)){res.setHeader('Content-Type',target.endsWith('.js')?'text/javascript':target.endsWith('.png')?'image/png':target.endsWith('.jpg')?'image/jpeg':'application/json');return fs.createReadStream(target).pipe(res);}res.statusCode=404;res.end('not found');
}).listen(8791,'127.0.0.1',()=>console.log('http://127.0.0.1:8791'));