Files
andromeda-viewer/tools/createMessageTemplate.js
T

121 lines
3.3 KiB
JavaScript

'use strict'
const fs = require('fs')
const path = require('path')
// parse the message_template.msg and creates the templates for the messages
// It is implemented as a loader for Webpack
// http://secondlife.com/app/message_template/master_message_template.msg
// results in:
// [
// {
// name: String,
// frequency: 'High'|'Medium'|'Low'|'Fixed',
// number: Number,
// trusted: Boolean,
// zerocoded: Boolean,
// isOld: undefined|String,
// body: [
// {
// name: String,
// quantity: 'Single'|'Multiple'|'Variable',
// times: Number, // only if quantity is Multiple
// variables: [
// {
// name: String,
// type: types,
// times: Number|NaN // by "Fixed"
// }
// ]
// }
// ]
// }
// ]
const templatePath = path.resolve('tools', 'message_template.msg')
const messageTemplateData = fs.readFileSync(templatePath, 'utf8')
const parsedTemplateString = parseMessageTemplate(messageTemplateData)
const outPath = path.resolve('src', 'network', 'messages.json')
fs.writeFileSync(outPath, parsedTemplateString, 'utf8')
function parseMessageTemplate (data) {
const allMessages = data.split('\n').map(line => {
// remove the commens
return line.replace(/\/\/.*$/, '').replace(/^\s+$/g, '')
}).filter(line => {
return line.length !== 0 && line !== 'version 2.0'
}).reduce(combineBlocks, {
finished: [], // All finished messages will be stored here
thisMessage: null // The message that is currently parsed is stored here
}).finished.map(parseMessage)
return JSON.stringify(allMessages)
}
function combineBlocks (combined, line) { // combine the blocks together
switch (line.charAt(0)) {
case '{': // start a new block
combined.thisMessage = []
break
case '}': // the block is done
combined.finished.push(combined.thisMessage)
break
default:
combined.thisMessage.push(line)
break
}
return combined
}
function parseMessage (message) {
// parse a message
const head = message[0].trim().split(/\s+/g)
const body = message.slice(1).reduce(parseBlocks, {
all: [],
thisBlock: null
}).all
return {
name: head[0],
frequency: head[1],
number: +head[2],
trusted: head[3] === 'Trusted',
zerocoded: head[4] === 'Zerocoded',
isOld: head[5],
body: body
}
}
function parseBlocks (blocks, line) {
const trimed = line.trim()
if (trimed.length === 1 && trimed.charAt(0) === '{') {
blocks.thisBlock = {
name: '',
quantity: '',
times: 0,
variables: []
}
} else if (trimed.length === 1 && trimed.charAt(0) === '}') {
blocks.all.push(blocks.thisBlock)
} else if (trimed.charAt(0) !== '{') {
// block info has no { at the beginning
const info = trimed.split(/\s+/g)
blocks.thisBlock.name = info[0]
blocks.thisBlock.quantity = info[1]
blocks.thisBlock.times = +info[2]
} else if (trimed.charAt(0) === '{' && trimed.length > 2) {
// all variables have the fromat { name type quantity? }
const variable = trimed.split(/\s+/g)
let type = variable[2]
if (type === 'Variable') {
type += variable[3].trim()
}
blocks.thisBlock.variables.push({
name: variable[1],
type: type,
times: +variable[3]
})
}
return blocks
}