2017-11-24 03:32:28 +00:00
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' ;
2017-11-24 03:39:53 +00:00
let flags = [ ] ;
2017-11-24 03:32:28 +00:00
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 ) =>
{
} ) ;
} ) ;