Complete room UI and protocol integration, move game definitions and resources behind bundle entries, publish authoritative version XML, and document single-game builds. Include all current resource changes and experiment artifacts.
29 lines
1.8 KiB
JavaScript
29 lines
1.8 KiB
JavaScript
'use strict';
|
|
// Shared by Cocos runtime and the build extension: one parser for the native contract.
|
|
const {DOMParser}=require('@xmldom/xmldom');
|
|
function parseVersionManifest(xml){
|
|
const fail=message=>{throw Error('version.xml: '+message);};
|
|
if(typeof xml!=='string'||!xml.trim())fail('empty document');
|
|
if(/<!DOCTYPE|<!ENTITY/i.test(xml))fail('DTD and entity declarations are unsupported');
|
|
let doc;
|
|
try {doc=new DOMParser({onError:(_level,message)=>fail(message)}).parseFromString(xml,'text/xml');}
|
|
catch(error){fail(error.message);}
|
|
const root=doc.documentElement;
|
|
if(!root||root.tagName!=='game'||root.namespaceURI)fail('expected game root');
|
|
const fields={};
|
|
for(let child=root.firstChild;child;child=child.nextSibling){
|
|
if(child.nodeType===3&&!child.nodeValue.trim()||child.nodeType===8)continue;
|
|
if(child.nodeType!==1||!['agent','game','channel','version'].includes(child.tagName)||child.namespaceURI)fail('unexpected child');
|
|
if(fields[child.tagName])fail('duplicate '+child.tagName);
|
|
fields[child.tagName]=child;
|
|
for(let nested=child.firstChild;nested;nested=nested.nextSibling){if(nested.nodeType!==3||nested.nodeValue.trim())fail('unexpected nested content');}
|
|
}
|
|
const attr=(tag,name)=>{const node=fields[tag];if(!node)fail('missing '+tag);const value=node.getAttribute(name);if(value===null||!value.trim())fail('missing '+tag+'@'+name);return value;};
|
|
const code=attr('version','value');
|
|
if(!/^\d+$/.test(code)||!Number.isSafeInteger(Number(code)))fail('version@value must be a nonnegative safe integer');
|
|
return Object.freeze({agentid:attr('agent','id'),agentName:attr('agent','name'),
|
|
gameid:attr('game','id'),gameName:attr('game','name'),channelid:attr('channel','id'),channelName:attr('channel','name'),
|
|
versionCode:Number(code),version:attr('version','name')});
|
|
}
|
|
exports.parseVersionManifest=parseVersionManifest;
|