-
Notifications
You must be signed in to change notification settings - Fork 0
/
extract.js
134 lines (116 loc) · 4.23 KB
/
extract.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
125
126
127
128
129
130
131
132
133
134
import { glob } from "glob";
import { readFile, mkdir, copyFile, writeFile } from "node:fs/promises";
import { basename, join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const modelbinPattern = "./**/*.modelbin";
const parentDir = join(__dirname, "..");
const outputDir = join(__dirname, "ExtractedTextures");
const texturesDir = join(__dirname, "textures");
async function getSwatchbins() {
try {
const modelbins = await glob(modelbinPattern);
const uniqueMaterialPaths = new Set(); // Store unique .materialbin paths
const uniqueSwatchPaths = new Set(); // Store unique .swatchbin paths
// Extract unique .materialbin paths
for (const modelbin of modelbins) {
const data = await readFile(modelbin, "utf8");
const materialRegex =
/Game:[\/\\]Media[\/\\]cars[\/\\]_library[\/\\]materials[\/\\].+?\.materialbin/g;
let match;
while ((match = materialRegex.exec(data)) !== null) {
const fullPath = match[0];
const materialPath = fullPath.replace("Game:\\Media\\cars\\", "");
uniqueMaterialPaths.add(materialPath);
}
}
// Extract unique .swatchbin paths from each .materialbin file
for (const materialPath of uniqueMaterialPaths) {
const materialFullPath = join(parentDir, materialPath);
const materialData = await readFile(materialFullPath, "utf8");
const swatchRegex =
/Game:[\/\\]Media[\/\\]cars[\/\\]_library[\/\\]textures[\/\\].+?\.swatchbin/g;
let match;
while ((match = swatchRegex.exec(materialData)) !== null) {
const fullPath = match[0];
const swatchFile = fullPath.replace("Game:\\Media\\cars", parentDir);
uniqueSwatchPaths.add(swatchFile);
}
}
// Extract unique .swatchbin paths from each .modelbin file
for (const modelbin of modelbins) {
const modelbinData = await readFile(modelbin, "utf8");
const swatchRegex =
/Game:[\/\\]Media[\/\\]cars[\/\\]_library[\/\\]textures[\/\\].+?\.swatchbin/g;
let match;
while ((match = swatchRegex.exec(modelbinData)) !== null) {
const fullPath = match[0];
const swatchFile = fullPath.replace("Game:\\Media\\cars", parentDir);
uniqueSwatchPaths.add(swatchFile);
}
}
// Copy unique .swatchbin files to output directory
if (uniqueSwatchPaths.size > 0) {
await mkdir(outputDir, { recursive: true });
for (const swatchFile of uniqueSwatchPaths) {
const swatchFilename = basename(swatchFile);
const destination = join(outputDir, swatchFilename);
await copyFile(swatchFile, destination);
}
} else {
console.log("No unique swatchbin filenames found in materialbin files.");
}
// Copy .swatchbin files from textures directory to output directory
const textures = await glob(`${texturesDir}/**/*.swatchbin`);
if (textures.length > 0) {
for (const texture of textures) {
const textureFilename = basename(texture);
const destination = join(outputDir, textureFilename);
await copyFile(texture, destination);
}
console.log("Finished");
} else {
console.log("No swatchbin files found in textures directory.");
}
} catch (err) {
console.error("Error:", err);
}
}
async function searchMaterialbins() {
try {
const modelbins = await glob(modelbinPattern);
const pathMap = new Map();
for (const modelbin of modelbins) {
const data = await readFile(modelbin, "utf8");
const regex =
/Game:[\/\\]Media[\/\\]cars[\/\\]_library[\/\\]materials[\/\\].+?\.materialbin/g;
let match;
while ((match = regex.exec(data)) !== null) {
const relativePath = match[0].replace("Game:\\Media\\cars\\", ""); // Extract relative path
if (!pathMap.has(modelbin)) {
pathMap.set(modelbin, []);
}
pathMap.get(modelbin).push(relativePath); // Store relative path
}
}
const categorization = {};
if (pathMap.size > 0) {
pathMap.forEach((materials, modelbin) => {
categorization[modelbin] = materials;
});
await writeFile(
"materials.json",
JSON.stringify(categorization, null, 2),
"utf8",
);
console.log("Modelbins and their materials written to materials.json");
} else {
console.log("No modelbin files found.");
}
} catch (err) {
console.error("Error:", err);
}
}
await getSwatchbins();
await searchMaterialbins();