-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcddaUpdateJsonVolume.js
124 lines (99 loc) · 2.84 KB
/
cddaUpdateJsonVolume.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/***
Github: https://github.com/ampersand55/CddaTools/
Usage: node cddaUpdateJsonVolume.js "c:\Cataclysm-DDA\data\json"
***/
const FS = require('fs');
const PATH = require('path');
const pad = (str, n = 3) => String(str).padStart(n);
const L = (str, ...args) => console.info(pad(str, 30), ...args);
const matchVolume = /( *)("(?:(?:min_|max_|min_pet_|min_pet_|integral_)?volume|storage|contains)": )(\d+|"\d+ \w+")(,\r?\n)/g;
if (process.argv.length !== 3) {
L('must have exactly one argument');
L('usage: "' + process.argv[0] + '" "' + process.argv[1] + '" <.json file or root directory>');
process.exit(0);
}
if (!exists(process.argv[2])) {
L('path not found:', process.argv[2]);
process.exit(0);
}
handlePath(process.argv[2]);
function exists(path) {
return FS.existsSync(path);
}
function isDir(path) {
return FS.statSync(path).isDirectory();
}
function isJson(path) {
return path.endsWith('.json');
}
function handlePath(p) {
if (isJson(p))
handleFile(p);
else if (isDir(p))
handleDir(p);
else if (exists(p))
L('path is not .json or directory:', p);
else
L('path not found:', p);
}
function handleDir(dir) {
FS.readdir(dir, (err, files) => {
if (err)
throw err;
L('processing ' + pad(files.length) + ' files in:', dir);
files
.map(file => dir + PATH.sep + file)
.forEach(p => {
if (isJson(p))
handleFile(p);
else if (isDir(p))
handleDir(p);
});
});
}
function handleFile(file) {
FS.readFile(file, 'utf8', (err, data) => {
if (err)
throw err;
const matches = data.match(matchVolume);
if (!matches) {
L('no match(es) in:', file);
return;
}
const newData = data.replace(matchVolume, fixVolume);
if (newData !== data) {
FS.writeFile(file, newData, 'utf-8', function (err) {
if (err)
throw err;
L('updating ' + pad(matches.length) + ' match(es) in:', file);
});
} else {
L('"Volume" instance skipped in:', file); // musical_instrument
}
});
}
function fixVolume(fullMatch, whiteSpace, key, volume, EOL, offset, fullText) {
if (fullText.includes('musical_instrument') && whiteSpace.length === 6) // ugly and not robust, but works for now
return fullMatch;
if (volume === '0')
return fullMatch;
// L(typeof volume,volume);
if (typeof volume === 'string') {
const[, v, unit] = volume.match(/(\d+) (\w+)/);
let intVolume;
if (unit === 'L') {
intVolume = Number(v) * 4;
} else if (unit === 'ml') {
intVolume = Number(v) / 250;
}
// return whiteSpace + key + intVolume + EOL;
} else {
const liters = Number(volume) / 4;
let volumeStr = '';
if (Number.isInteger(liters))
volumeStr = '"' + liters + ' L"';
else
volumeStr = '"' + liters * 1000 + ' ml"';
return whiteSpace + key + volumeStr + EOL;
}
}