Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
fandy committed Oct 29, 2019
0 parents commit e5b7032
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package-lock.json
node_modules

resources/master
resources/story
/test*
/temp*
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "dltext-parser",
"version": "1.0.0",
"description": "parse drag lost text data",
"main": "main.ts",
"scripts": {
"tool": "ts-node -P tsconfig.json",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"chalk": "^2.4.2",
"nexline": "^1.1.0"
},
"devDependencies": {
"@types/node": "^12.11.7",
"ts-node": "^8.4.1",
"typescript": "~3.5.3"
},
"author": "",
"license": "ISC"
}
Empty file added resources/.placeholder
Empty file.
188 changes: 188 additions & 0 deletions src/mono/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import chalk from "chalk";

const EOP = 'EOP'

type MonoType = 'object' | 'array' | 'array-index'| 'number' | 'string' | 'null'

interface MonoProperty {
key: string;
type: MonoType;
typeInMono: string;
value: null | string | number | { [name: string]: any } | any[];
}

export class MonoBehaviour {

static getObjectToken(items: string[]) {
if (items.length !== 2) {
return null
}

let typeInMono: string = ''
let key: string = ''
if (items[0].match(/^(MonoBehaviour|PPtr<)/)) {
[typeInMono, key] = items
}
else if (items[1].match(/^(dict|data)/)) {
[key, typeInMono] = items
}
return !key ? null : {
type: 'object',
value: {},
typeInMono,
key
} as MonoProperty
}

static getArrayToken(items: string[]) {
if (items.length !== 2) {
return null
}

let typeInMono: string = ''
let key: string = ''
if (items[0].match(/^(vector)/)) {
[typeInMono, key] = items
}
else if (items[1].match(/^(list|entriesValue)/)) {
[key, typeInMono] = items
}
return !key ? null : {
type: 'array',
value: [],
typeInMono,
key
} as MonoProperty
}

static getArrayIndexToken(items: string[]) {
if (items.length !== 1) {
return null
}

if (items[0].match(/^(\[\d+\])/)) {
return {
type: 'array-index',
value: items[0].replace(/\[|\]/g, ''),
typeInMono: '',
key: ''
} as MonoProperty
}
else {
return null
}
}

// SInt64 m_PathID = -7917755486195054967
static getPropertyToken(items: string[]) {
if (items.length !== 4 || items[2] !== '=') {
return null
}

if (items[0].match(/^(string)/)) {
return {
type: 'string',
key: items[1],
typeInMono: items[0],
value: items[3].replace(/(^")|("$)/g, '')
} as MonoProperty
}
else if (items[0].match(/^(int|UInt8|SInt64)/)) {
return {
type: 'number',
key: items[1],
typeInMono: items[0],
value: parseInt(items[3], 10)
} as MonoProperty
}
else if (items[0].match(/^(float)/)) {
return {
type: 'number',
key: items[1],
typeInMono: items[0],
value: parseFloat(items[3])
} as MonoProperty
}
else {
return null
}
}

static async parse(reader: any, tabs: number, overread: any) {
let line: string | null
if (overread.readed) {
line = overread.line
overread.line = ''
overread.readed = false
// console.log(`[overread] ${line}`)
}
else {
line = await reader.next()
}
if (!line || (line.match(/\t/g) || []).length !== tabs + 1) {
overread.readed = true
overread.line = line
return EOP
}

const items = line.replace(/\t|\r/g, '').split(/\s+/)

const propertyToken = this.getPropertyToken(items)
if (propertyToken) {
return propertyToken
}

const objectToken = this.getObjectToken(items)
// console.log('[object]', objectEntry)
if (objectToken) {
while (true) {
const next = await this.parse(reader, tabs + 1, overread)
if (!next || next === EOP || next.type === 'array-index') {
break;
}

if (next.key) {
(objectToken.value as any)[next.key] = next
}
}
return objectToken
}

const arrayToken = this.getArrayToken(items)
if (arrayToken) {
const a1 = await reader.next()
const a2 = await reader.next()
if (!a1.match(/Array Array/) || !a2.match(/int size = \d+/)) {
console.log(chalk.red(`[ERROR] array token: ${line} ${a1} ${a2}`))
}
// TODO:
while (true) {
const next = await this.parse(reader, tabs + 2, overread)
if (!next || next === EOP || next.type !== 'array-index') {
break;
}

const token = await this.parse(reader, tabs + 2, overread)
if (!token || token === EOP || token.type === 'array-index') {
break;
}
(arrayToken.value as any[]).push(token)
}
return arrayToken
}

const arrayIndexToken = this.getArrayIndexToken(items)
if (arrayIndexToken) {
return arrayIndexToken
}

console.log(chalk.red(`[ERROR] unknown line ${line}`))
return {
key: '',
type: 'null',
typeInMono: '',
value: null
} as MonoProperty
}
}

21 changes: 21 additions & 0 deletions src/tool/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import chalk from 'chalk'
import nexline from 'nexline'
import * as fs from 'fs'
import { MonoBehaviour } from '../mono/parser'

const input = 'resources/master/CharaRarity.txt'

async function boot() {
const fd = fs.openSync(input, 'r')
const reader = nexline({
input: fd
})

const x = await MonoBehaviour.parse(reader, -1, {})
if (x !== 'EOP') {
console.log(chalk.green(JSON.stringify(x, null, 4)))
}

}

boot()
9 changes: 9 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"strict": true,
"target": "es5",
"module": "commonjs",
"noImplicitAny": false,
"esModuleInterop": true
}
}

0 comments on commit e5b7032

Please sign in to comment.