76 lines
7.0 KiB
JavaScript
76 lines
7.0 KiB
JavaScript
// Local component fixture, using the installed Cocos 2.4 engine and a real Asset Bundle.
|
|
// No game login, network API or real payment is called. Run: node tools/coin-madness/preview.cjs
|
|
const http = require('http');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const ts = require('typescript');
|
|
const root = path.resolve(__dirname, '../..');
|
|
const creator = process.env.COCOS_CREATOR_PATH || 'C:/ProgramData/cocos/editors/Creator/2.4.15';
|
|
const engine = path.join(creator, 'resources/engine/bin/cocos2d-js-for-preview.js');
|
|
const uuid = JSON.parse(fs.readFileSync(path.join(root, 'assets/coin_madness/CoinMadness.prefab.meta'))).uuid;
|
|
const scriptUuid = JSON.parse(fs.readFileSync(path.join(root, 'assets/coin_madness/CoinMadnessPanel.ts.meta'))).uuid;
|
|
const hex=scriptUuid.replaceAll('-',''), alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
const scriptId=hex.slice(0,5)+hex.slice(5).match(/.{3}/g).map(s=>alphabet[parseInt(s,16)>>6]+alphabet[parseInt(s,16)&63]).join('');
|
|
const html = `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
|
|
<style>html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#16394b}canvas{display:block}</style></head>
|
|
<body><canvas id="GameCanvas"></canvas><script src="/engine.js"></script><script src="/host.js"></script><script>
|
|
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]]},()=>{
|
|
cc.view.setDesignResolutionSize(720,1280,cc.ResolutionPolicy.SHOW_ALL);cc.view.resizeWithBrowserSize(true);
|
|
const scene=new cc.Scene(),canvas=new cc.Node('Canvas');scene.addChild(canvas);canvas.setContentSize(720,1280);
|
|
canvas.addComponent(cc.Canvas).designResolution=cc.size(720,1280);cc.director.runScene(scene);
|
|
const storage=new Map();cc.fx={GameConfig:{GM_INFO:{uid:'fixture',coin:1000,level:10}},StorageMessage:{getStorage:k=>storage.get(k),setStorage:(k,v)=>storage.set(k,v)},GameTool:{}};
|
|
const now=Date.now();window.demo={data:{available:true,serverNow:now,state:{config:{title:'金币狂热',periodId:'fixture',startsAt:now-1000,endsAt:now+604800000,priceCents:99,stages:[{wins:2,coins:150},{wins:3,coins:200},{wins:5,coins:250},{wins:10,coins:300},{wins:15,coins:400},{wins:20,coins:500},{wins:30,coins:700}]},paidAt:0,stage:0,progress:0,settled:false}}};
|
|
window.fixturePost=(url,body,done)=>{if(url!=='coinMadness')throw Error('Real payment disabled in fixture');
|
|
const d=window.demo.data;d.serverNow=Date.now();
|
|
if(body.action==='claim'){const stage=d.state.stage,coins=d.state.config.stages[stage].coins;d.state.stage++;d.state.progress=0;d.pending={id:'fixture:'+stage,coins,balance:body.coinAmount+coins};}
|
|
if(body.action==='settle'){d.state.settled=true;d.needsSettlement=false;}
|
|
if(body.action==='ack')d.pending=null;
|
|
setTimeout(()=>done({code:1,data:JSON.parse(JSON.stringify(d))}),10);
|
|
};
|
|
const host=canvas.addComponent(cc.js.getClassByName('CoinMadnessHost'));
|
|
window.demo.open=()=>new Promise(resolve=>{host.open();const timer=setInterval(()=>{if(canvas.getChildByName('CoinMadness')){clearInterval(timer);resolve();}},10);});
|
|
window.demo.close=()=>new Promise(resolve=>{host.close();cc.director.once(cc.Director.EVENT_AFTER_DRAW,resolve);});
|
|
window.demo.set=(patch)=>{Object.assign(window.demo.data.state,patch);host.refresh();};
|
|
window.demo.snapshot=()=>({bundle:!!cc.assetManager.getBundle('coin_madness'),panels:canvas.children.filter(n=>n.name==='CoinMadness').length,assets:cc.assetManager.assets.count});
|
|
setTimeout(()=>{window.demo.ready=true;if(new URLSearchParams(location.search).has('open'))window.demo.open();},100);
|
|
});});</script></body></html>`;
|
|
const server = http.createServer((req,res)=>{
|
|
const url = req.url.split('?')[0].replace(/^\/assets\//, '/');
|
|
if(url==='/favicon.ico'){res.statusCode=204;return res.end();}
|
|
if(url==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');return res.end(html);}
|
|
if(url==='/engine.js'){res.setHeader('Content-Type','text/javascript');return fs.createReadStream(engine).pipe(res);}
|
|
if(url==='/host.js'){
|
|
const source=fs.readFileSync(path.join(root,'assets/Script/CoinMadnessHost.ts'),'utf8');
|
|
const output=ts.transpileModule(source,{compilerOptions:{target:ts.ScriptTarget.ES5,module:ts.ModuleKind.CommonJS,experimentalDecorators:true}}).outputText;
|
|
res.setHeader('Content-Type','text/javascript');return res.end('(function(){var exports={};function require(name){if(name.includes("Utils"))return {default:{POST:(u,b,d)=>window.fixturePost(u,b,d)}};if(name.includes("MiniGameSdk"))return {MiniGameSdk:{API:{showToast:console.log}}};return {default:{get:()=>({enqueue:(k,p,run)=>run(()=>{})})}};}cc._RF.push({},"CoinMadnessHost","CoinMadnessHost");'+output+';cc._RF.pop();})();');
|
|
}
|
|
if(/^\/native\/[a-f0-9]{2}\/[a-f0-9-]+\.png$/.test(url)){
|
|
const target=path.join(root,'library/imports',url.slice('/native/'.length));
|
|
if(fs.existsSync(target)){res.setHeader('Content-Type','image/png');return fs.createReadStream(target).pipe(res);}
|
|
}
|
|
if(/^\/imports\/[a-f0-9]{2}\/[a-f0-9-]+\.json$/.test(url)){
|
|
const target=path.join(root,'library',url.slice(1));
|
|
if(fs.existsSync(target)){res.setHeader('Content-Type','application/json');return fs.createReadStream(target).pipe(res);}
|
|
}
|
|
if(url.startsWith('/internal/')){
|
|
const base=path.join(creator,'resources/cocos2d-x/simulator/win32/assets/internal');
|
|
const target=path.resolve(base,url.slice('/internal/'.length));
|
|
if(!target.startsWith(base+path.sep)||!fs.existsSync(target)){res.statusCode=404;return res.end();}
|
|
res.setHeader('Content-Type',target.endsWith('.json')?'application/json':target.endsWith('.js')?'text/javascript':'application/octet-stream');
|
|
return fs.createReadStream(target).pipe(res);
|
|
}
|
|
if(url==='/coin_madness/config.json'){res.setHeader('Content-Type','application/json');return res.end(JSON.stringify({name:'coin_madness',debug:true,importBase:'import',nativeBase:'native',deps:[],uuids:[uuid],paths:{[uuid]:['CoinMadness','cc.Prefab']},scenes:{},packs:{},versions:{import:[],native:[]}}));}
|
|
if(url==='/coin_madness/index.js'){
|
|
const source=fs.readFileSync(path.join(root,'assets/coin_madness/CoinMadnessPanel.ts'),'utf8');
|
|
const output=ts.transpileModule(source,{compilerOptions:{target:ts.ScriptTarget.ES5,module:ts.ModuleKind.CommonJS,experimentalDecorators:true}}).outputText;
|
|
res.setHeader('Content-Type','text/javascript');return res.end('(function(){var exports={};cc._RF.push({},'+JSON.stringify(scriptId)+',"CoinMadnessPanel");'+output+';cc._RF.pop();})();');
|
|
}
|
|
if(url==='/coin_madness/import/'+uuid.slice(0,2)+'/'+uuid+'.json'){
|
|
res.setHeader('Content-Type','application/json');return res.end(fs.readFileSync(path.join(root,'assets/coin_madness/CoinMadness.prefab')));
|
|
}
|
|
res.statusCode=404;res.end('Not found');
|
|
});
|
|
server.listen(Number(process.env.PORT)||8765,'127.0.0.1',()=>console.log('Coin Madness fixture: http://127.0.0.1:'+server.address().port));
|