Files
node-metaverse/tools/writePacketClasses.js

330 lines
10 KiB
JavaScript
Raw Normal View History

const messages = require('./msg_template.json');
const path = require('path');
const fs = require('fs');
messages.forEach((message) =>
{
let classString = '// This file has been automatically generated by writePacketClasses.js\n\n';
//First import required classes
let uuid = false;
let ipaddr = false;
let vector3 = false;
let vector4 = false;
let long = false;
let quaternion = false;
message.blocks.forEach((block) =>
{
block.params.forEach((param) =>
{
switch(param.type)
{
case 'BOOL':
case 'U32':
case 'S32':
case 'S8':
case 'U8':
case 'U16':
case 'S16':
case 'F32':
case 'F64':
case "IPPORT":
case "Fixed":
case 'Variable':
break;
case "LLVector3d":
vector3 = true;
break;
case "LLVector3":
vector3 = true;
break;
case "LLVector4":
vector4 = true;
break;
case "LLQuaternion":
quaternion = true;
break;
case "LLUUID":
uuid = true;
break;
case "IPADDR":
ipaddr = true;
break;
case "U64":
long = true;
break;
default:
console.log("UNKNOWN TYPE: "+param.type);
}
});
});
if (uuid)
{
classString += 'import {UUID} from \'../UUID\';\n'
}
if (ipaddr)
{
classString += 'import {IPAddress} from \'../IPAddress\';\n'
}
if (vector3)
{
classString += 'import {Vector3} from \'../Vector3\';\n'
}
if (vector4)
{
classString += 'import {Vector4} from \'../Vector4\';\n'
}
if (long)
{
classString += 'import Long = require(\'long\');\n'
}
if (quaternion)
{
classString += 'import {Quaternion} from \'../Quaternion\';\n'
}
classString += 'import {MessageFlags} from \'../../enums/MessageFlags\';\n' +
'import {Packet} from \'../Packet\';\n\n';
classString += 'export class ' + message.name + 'Packet implements Packet\n';
classString += '{\n';
classString += ' name = \''+message.name+'\';\n';
var flags = [];
message.flags.forEach((flag) =>
{
switch(flag.toUpperCase())
{
case 'TRUSTED':
flags.push('MessageFlags.Trusted');
break;
case 'UDPDEPRECATED':
case 'DEPRECATED':
flags.push('MessageFlags.Deprecated');
break;
case 'ZEROCODED':
flags.push('MessageFlags.Zerocoded');
break;
case 'UNENCODED':
break;
case 'NOTTRUSTED':
break;
case 'UDPBLACKLISTED':
flags.push('MessageFlags.Blacklisted');
break;
default:
console.log("UNKNOWN FLAG: "+flag);
break;
}
});
let id = parseInt(message.id);
switch(message.frequency)
{
case 'Low':
id += 4294901760;
flags.push('MessageFlags.FrequencyLow');
break;
case 'Medium':
id += 65280;
flags.push('MessageFlags.FrequencyMedium');
break;
case 'Fixed':
flags.push('MessageFlags.FrequencyFixed');
break;
case 'High':
flags.push('MessageFlags.FrequencyHigh');
break;
default:
console.log("UNKNOWN FREQUENCY: "+message.frequency);
break;
}
classString += ' flags = ' + flags.join(' | ')+';\n';
classString += ' id = ' + id+';\n';
classString += '\n';
let messageFixedSize = 0;
let messageVariableSize = [];
let calcVarVar = false;
message.blocks.forEach((block) =>
{
classString += ' '+block.name+': {\n';
let blockFixedSize = 0;
let blockVariableSize = [];
block.params.forEach((param) =>
{
classString += ' '+param.name+': ';
let jstype = 'string';
switch(param.type)
{
case 'LLUUID':
jstype = 'UUID';
blockFixedSize += 16;
break;
case 'F32':
case 'S32':
case 'U32':
blockFixedSize += 4;
jstype = 'number';
break;
case 'IPPORT':
case 'S16':
case 'U16':
blockFixedSize += 2;
jstype = 'number';
break;
case 'U64':
case 'S64':
jstype = 'Long';
blockFixedSize += 8;
break;
case 'F64':
blockFixedSize += 8;
jstype = 'number';
break;
case 'S8':
case 'U8':
blockFixedSize += 1;
jstype = 'number';
break;
case 'BOOL':
blockFixedSize += 1;
jstype = 'boolean';
break;
case 'Variable':
jstype = 'string';
if (block.type === 'Single')
{
blockVariableSize.push('this.' + block.name + '[\'' + param.name + '\'].length + ' + param.size);
}
else
{
//Variable parameter in variable or multi block - tricky edge case
blockVariableSize.push('this.calculateVarVarSize(this.'+block.name+', \''+param.name+'\', '+param.size+')')
calcVarVar = true;
}
break;
case 'LLVector4':
blockFixedSize += 16;
jstype = 'Vector4';
break;
case 'LLQuaternion':
// because it's always a unit quaternion, transmitted in messages as a triplet of floats, 12 bytes wide (represented in memory as a quad of floats, 16 bytes wide)
blockFixedSize += 12;
jstype = 'Quaternion';
break;
case 'LLVector3d':
blockFixedSize += 24;
jstype = 'Vector3';
break;
case 'LLVector3':
blockFixedSize += 12;
jstype = 'Vector3';
break;
case 'IPADDR':
blockFixedSize += 4;
jstype = 'IPAddress';
break;
case 'Fixed':
blockFixedSize += parseInt(param.size);
jstype = 'Buffer';
break;
default:
console.log('Unknown type: '+param.type);
}
classString += jstype + ';\n';
});
if (block.type === 'Single')
{
messageFixedSize += blockFixedSize;
if (blockVariableSize.length > 0)
{
messageVariableSize.push('(' + blockVariableSize.join(' + ') + ')');
}
}
else if (block.type === 'Multiple')
{
messageFixedSize += blockFixedSize * block.count;
if (blockVariableSize.length > 0)
{
messageVariableSize.push('((' + blockVariableSize.join(' + ') + ') * ' + block.count + ')');
}
}
else if (block.type === 'Variable')
{
messageFixedSize += 1; //variable block starts with a U8
if (blockFixedSize > 0)
{
blockVariableSize.push(blockFixedSize);
}
if (blockVariableSize.length > 0)
{
messageVariableSize.push('((' + blockVariableSize.join(' + ') + ') * this.' + block.name + '.length)');
}
}
switch(block.type)
{
case 'Single':
classString += ' };\n';
break;
case 'Variable':
case 'Multiple':
classString += ' }[];\n';
break;
default:
console.log("Unknown type: "+block.type);
}
});
classString+='\n';
classString+=' getSize(): number\n';
classString+=' {\n';
if (messageFixedSize > 0)
{
messageVariableSize.push(messageFixedSize);
}
if (messageVariableSize.length === 0)
{
classString += ' return 0;\n';
}
else
{
classString += ' return ' + messageVariableSize.join(' + ') + ';\n';
}
classString+=' }\n';
classString+='\n';
if (calcVarVar)
{
classString+=' calculateVarVarSize(block: object[], paramName: string, extraPerVar: number): number\n' +
' {\n' +
' let size = 0;\n' +
' block.forEach((bl: any) =>\n' +
' {\n' +
' size += bl[paramName].length + extraPerVar;\n' +
' });\n' +
' return size;\n' +
' }\n\n';
}
classString += '}\n';
const p = path.join(__dirname+'/../lib/classes/packets/'+message.name+'.ts');
fs.writeFile(p, classString, (err) =>
{
});
});