cyclops-infobook-html 4.0.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +23 -2
  2. package/bin/compress-icons.d.ts +2 -0
  3. package/bin/compress-icons.js +47 -0
  4. package/bin/generate-icons.d.ts +2 -0
  5. package/bin/generate-icons.js +68 -0
  6. package/bin/generate-infobook-html.js +16 -8
  7. package/bin/generate-mod-metadata.js +15 -7
  8. package/index.d.ts +2 -0
  9. package/index.js +39 -24
  10. package/lib/icon/IconsCompressor.d.ts +18 -0
  11. package/lib/icon/IconsCompressor.js +81 -0
  12. package/lib/icon/IconsGenerator.d.ts +128 -0
  13. package/lib/icon/IconsGenerator.js +597 -0
  14. package/lib/infobook/FileWriter.d.ts +1 -2
  15. package/lib/infobook/FileWriter.js +21 -6
  16. package/lib/infobook/IFileWriter.d.ts +1 -2
  17. package/lib/infobook/IInfoAppendix.d.ts +1 -1
  18. package/lib/infobook/InfoBookInitializer.js +10 -2
  19. package/lib/infobook/appendix/InfoBookAppendixAd.d.ts +1 -1
  20. package/lib/infobook/appendix/InfoBookAppendixAd.js +13 -2
  21. package/lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe.d.ts +1 -1
  22. package/lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe.js +13 -4
  23. package/lib/infobook/appendix/InfoBookAppendixHandlerAdvancementRewards.js +14 -5
  24. package/lib/infobook/appendix/InfoBookAppendixHandlerCraftingRecipe.d.ts +1 -1
  25. package/lib/infobook/appendix/InfoBookAppendixHandlerCraftingRecipe.js +39 -28
  26. package/lib/infobook/appendix/InfoBookAppendixHandlerImage.js +13 -4
  27. package/lib/infobook/appendix/InfoBookAppendixHandlerKeybinding.js +12 -3
  28. package/lib/infobook/appendix/InfoBookAppendixHandlerSmeltingRecipe.d.ts +1 -1
  29. package/lib/infobook/appendix/InfoBookAppendixHandlerSmeltingRecipe.js +16 -5
  30. package/lib/infobook/appendix/InfoBookAppendixHandlerTextfield.js +11 -2
  31. package/lib/infobook/appendix/InfoBookAppendixTagIndex.d.ts +1 -1
  32. package/lib/infobook/appendix/InfoBookAppendixTagIndex.js +31 -20
  33. package/lib/modloader/ModLoader.d.ts +2 -3
  34. package/lib/modloader/ModLoader.js +56 -48
  35. package/lib/parse/XmlInfoBookParser.js +2 -2
  36. package/lib/resource/ResourceHandler.d.ts +2 -1
  37. package/lib/resource/ResourceHandler.js +7 -3
  38. package/lib/resource/ResourceLoader.d.ts +5 -5
  39. package/lib/resource/ResourceLoader.js +37 -28
  40. package/lib/serialize/HtmlInfoBookSerializer.d.ts +2 -2
  41. package/lib/serialize/HtmlInfoBookSerializer.js +80 -65
  42. package/package.json +10 -6
package/README.md CHANGED
@@ -13,11 +13,12 @@ This tool is the basis for the following mod-specific plugins:
13
13
 
14
14
  ## Usage
15
15
 
16
- This tool allows Cyclops infobooks to be exported as an HTML website in three phases:
16
+ This tool allows Cyclops infobooks to be exported as an HTML website in four phases:
17
17
 
18
18
  1. Metadata generation: A preparation step for generating all required metadata that is needed for serializing the infobook to HTML.
19
19
  2. Icon generation: Exporting item and block icons to PNG files.
20
20
  3. HTML generation: Serialization to HTML based on the infook XML and metadata.
21
+ 4. Icon compression: Optionally compress icons within the output directory.
21
22
 
22
23
  ### 1. Metadata Generation
23
24
 
@@ -64,13 +65,28 @@ If you want to re-download the mods without re-installing Forge, you can run `ge
64
65
 
65
66
  ### 2. Icon Generation
66
67
 
67
- This phase should be done using the [Icon Exporter mod](https://github.com/CyclopsMC/IconExporter).
68
+ This phase can be done manually using the [Icon Exporter mod](https://github.com/CyclopsMC/IconExporter), or automatically.
69
+
70
+ #### Manual icon generation
68
71
 
69
72
  Simply create a modpack with all the mods that were downloaded in the previous step (including the Item Exporter mod),
70
73
  start a world, and run the `/iconexporter export 64` command.
71
74
 
72
75
  Next, copy the resulting contents of `icon-exports-x64` to `icons` in your project directory.
73
76
 
77
+ #### Automatic icon generation
78
+
79
+ The `generate-icons` command can be executed,
80
+ which will cause a Headless Minecraft instance to be downloaded and started,
81
+ and the Icon Exporter mod to be ran.
82
+
83
+ When running this on a headless machine, you should have `xvfb` installed and running.
84
+ For example:
85
+ ```
86
+ $ sudo apt-get install -y xvfb
87
+ $ xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" generate-icons
88
+ ```
89
+
74
90
  ### 3. HTML Generation
75
91
 
76
92
  Before you start this phase, make sure the following files and directories are present:
@@ -130,6 +146,11 @@ Before you start this phase, make sure the following files and directories are p
130
146
  This phase can be started by executing `generate-cyclops-infobook-html config.json /output`.
131
147
  Afterwards, the contents of `/output` can be hosted on any Web server.
132
148
 
149
+ ### 4. Icon Compression
150
+
151
+ Using the `compress-icons` command, icons within the `output/` directory will be compressed.
152
+ This is recommended when deploying the output to a web server.
153
+
133
154
  ### Plugins
134
155
 
135
156
  Optionally, plugins can be loaded to for example add support for non-default appendix handlers.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const fs = require("fs");
14
+ const minimist = require("minimist");
15
+ const path_1 = require("path");
16
+ const IconsCompressor_1 = require("../lib/icon/IconsCompressor");
17
+ // Process CLI args
18
+ const args = minimist(process.argv.slice(2));
19
+ if (args.help || args._.length < 1) {
20
+ printUsage();
21
+ }
22
+ function run(outputDir) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const iconsDir = (0, path_1.resolve)(outputDir, 'assets', 'icon');
25
+ if (!fs.existsSync(iconsDir)) {
26
+ process.stderr.write(`Icons directory not found: ${iconsDir}\n`);
27
+ process.exit(1);
28
+ }
29
+ const compressor = new IconsCompressor_1.IconsCompressor(iconsDir);
30
+ yield compressor.compress();
31
+ });
32
+ }
33
+ function printUsage() {
34
+ process.stdout.write(`compress-icons Losslessly compress PNG icons in the HTML output directory
35
+ Usage:
36
+ compress-icons /path/to/output
37
+ Options:
38
+ --help print this help message
39
+ `);
40
+ process.exit(1);
41
+ }
42
+ run(args._[0]).catch((e) => {
43
+ // tslint:disable-next-line:no-console
44
+ console.error(e);
45
+ process.exit(1);
46
+ });
47
+ //# sourceMappingURL=compress-icons.js.map
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const fs = require("fs");
14
+ const minimist = require("minimist");
15
+ const path_1 = require("path");
16
+ const IconsGenerator_1 = require("../lib/icon/IconsGenerator");
17
+ // Process CLI args
18
+ const args = minimist(process.argv.slice(2));
19
+ if (args.help || args._.length < 1) {
20
+ printUsage();
21
+ }
22
+ function run(configPath) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
25
+ if (!config.minecraft) {
26
+ process.stderr.write('Missing "minecraft" field in config\n');
27
+ process.exit(1);
28
+ }
29
+ if (!config.neoforge && !config.forge) {
30
+ process.stderr.write('Missing "neoforge" or "forge" field in config\n');
31
+ process.exit(1);
32
+ }
33
+ const generator = new IconsGenerator_1.IconsGenerator({
34
+ modsDir: (0, path_1.join)(process.cwd(), args['mods-dir'] || (0, path_1.join)('server', 'mods')),
35
+ iconsDir: (0, path_1.join)(process.cwd(), args['icons-dir'] || 'icon'),
36
+ workDir: (0, path_1.join)(process.cwd(), args['work-dir'] || 'headlessmc'),
37
+ minecraftVersion: config.minecraft,
38
+ neoforgeVersion: config.neoforge || config.forge,
39
+ githubToken: args['github-token'] || process.env.GITHUB_TOKEN,
40
+ iconExporterVersion: args['icon-exporter-version'],
41
+ headlessMcVersion: args['headlessmc-version'],
42
+ launchTimeoutMs: args.timeout ? parseInt(args.timeout, 10) * 1000 : undefined,
43
+ });
44
+ yield generator.generate();
45
+ });
46
+ }
47
+ function printUsage() {
48
+ process.stdout.write(`generate-icons Download IconExporter and HeadlessMC, launches Minecraft headlessly, and exports item icons
49
+ Usage:
50
+ generate-icons /path/to/modpack.json
51
+ Options:
52
+ --help print this help message
53
+ --mods-dir directory containing mod JARs (default: server/mods)
54
+ --icons-dir output directory for icons (default: icons)
55
+ --work-dir working directory for HeadlessMC (default: headlessmc)
56
+ --github-token GitHub token for downloading from GitHub Packages
57
+ --icon-exporter-version version of the IconExporter artifact (default: 1.4.0-174)
58
+ --headlessmc-version version of HeadlessMC to use (default: 2.8.0)
59
+ --timeout timeout in seconds for the full icon generation (default: 1800)
60
+ `);
61
+ process.exit(1);
62
+ }
63
+ run(args._[0]).catch((e) => {
64
+ // tslint:disable-next-line:no-console
65
+ console.error(e);
66
+ process.exit(1);
67
+ });
68
+ //# sourceMappingURL=generate-icons.js.map
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
3
12
  Object.defineProperty(exports, "__esModule", { value: true });
4
- const tslib_1 = require("tslib");
5
13
  const fs = require("fs");
6
14
  const minimist = require("minimist");
7
15
  const path_1 = require("path");
@@ -26,7 +34,7 @@ Options:
26
34
  process.exit(1);
27
35
  }
28
36
  function create() {
29
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
37
+ return __awaiter(this, void 0, void 0, function* () {
30
38
  // Create infobook from config
31
39
  const config = JSON.parse(fs.readFileSync(args._[0], "utf8"));
32
40
  // Override baseUrl
@@ -43,18 +51,18 @@ function create() {
43
51
  process.stderr.write('Could not find a "mod_assets" folder, make sure to create one with generate-mod-metadata.\n');
44
52
  process.exit(1);
45
53
  }
46
- // Check if icons are available
47
- if (!fs.existsSync('icons')) {
48
- process.stderr.write('Could not find a "icons" folder, make sure to create one with output from the IconExporter mod.\n');
54
+ // Check if icon are available
55
+ if (!fs.existsSync('icon')) {
56
+ process.stderr.write('Could not find a "icon" folder, make sure to create one with output from the IconExporter mod.\n');
49
57
  process.exit(1);
50
58
  }
51
59
  // Read resources
52
60
  const resourceLoader = new ResourceLoader_1.ResourceLoader();
53
- yield resourceLoader.loadIcons('icons');
61
+ yield resourceLoader.loadIcons('icon');
54
62
  yield resourceLoader.loadItemTranslationKeys('registries');
55
63
  yield resourceLoader.loadFluidTranslationKeys('registries');
56
64
  yield resourceLoader.loadKeybindings(config.keybindings);
57
- yield resourceLoader.loadAll(process.cwd(), 'mod_assets');
65
+ yield resourceLoader.loadAll(process.cwd(), 'mod_assets', config.excludedModLanguages || []);
58
66
  // Setup infobook loader
59
67
  const infoBookInitializer = new InfoBookInitializer_1.InfoBookInitializer(config);
60
68
  infoBookInitializer.registerAppendixHandler('advancement_rewards', new InfoBookAppendixHandlerAdvancementRewards_1.InfoBookAppendixHandlerAdvancementRewards(resourceLoader.getResourceHandler()));
@@ -68,7 +76,7 @@ function create() {
68
76
  const headSuffixGetters = [];
69
77
  if (config.plugins) {
70
78
  for (const pluginPath of config.plugins) {
71
- const plugin = require(path_1.join(process.cwd(), pluginPath));
79
+ const plugin = require((0, path_1.join)(process.cwd(), pluginPath));
72
80
  plugin.load(infoBookInitializer, resourceLoader, config);
73
81
  if (plugin.assetsPath) {
74
82
  assetsPaths.push(plugin.assetsPath);
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
3
12
  Object.defineProperty(exports, "__esModule", { value: true });
4
- const tslib_1 = require("tslib");
5
13
  const fs = require("fs");
6
14
  const minimist = require("minimist");
7
15
  const path_1 = require("path");
@@ -12,12 +20,12 @@ if (args.help || args._.length !== 2) {
12
20
  printUsage();
13
21
  }
14
22
  function run(command, configPath) {
15
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
23
+ return __awaiter(this, void 0, void 0, function* () {
16
24
  // Create mod loader
17
25
  const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
18
26
  const modLoader = new ModLoader_1.ModLoader({
19
27
  mods: config.mods,
20
- path: path_1.join(process.cwd(), 'server'),
28
+ path: (0, path_1.join)(process.cwd(), 'server'),
21
29
  loader: 'forge' in config ? { versionForge: config.forge } : { versionNeoForge: config.neoforge },
22
30
  versionMinecraft: config.minecraft,
23
31
  });
@@ -30,11 +38,11 @@ function run(command, configPath) {
30
38
  break;
31
39
  case 'extractmc':
32
40
  yield modLoader.extractMinecraftAssets();
33
- yield modLoader.copyModAssets(path_1.join(process.cwd(), 'mod_assets'));
41
+ yield modLoader.copyModAssets((0, path_1.join)(process.cwd(), 'mod_assets'));
34
42
  break;
35
43
  case 'extractmods':
36
44
  yield modLoader.extractModsAssets();
37
- yield modLoader.copyModAssets(path_1.join(process.cwd(), 'mod_assets'));
45
+ yield modLoader.copyModAssets((0, path_1.join)(process.cwd(), 'mod_assets'));
38
46
  break;
39
47
  case 'generate':
40
48
  if (!modLoader.isForgeInstalled()) {
@@ -63,10 +71,10 @@ function run(command, configPath) {
63
71
  if (lastError) {
64
72
  throw lastError;
65
73
  }
66
- yield modLoader.copyRegistries(path_1.join(process.cwd(), 'registries'));
74
+ yield modLoader.copyRegistries((0, path_1.join)(process.cwd(), 'registries'));
67
75
  yield modLoader.extractMinecraftAssets();
68
76
  yield modLoader.extractModsAssets();
69
- yield modLoader.copyModAssets(path_1.join(process.cwd(), 'mod_assets'));
77
+ yield modLoader.copyModAssets((0, path_1.join)(process.cwd(), 'mod_assets'));
70
78
  break;
71
79
  default:
72
80
  printUsage();
package/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./lib/icon/IconsCompressor";
2
+ export * from "./lib/icon/IconsGenerator";
1
3
  export * from "./lib/infobook/appendix/IInfoBookAppendixHandler";
2
4
  export * from "./lib/infobook/appendix/InfoBookAppendixAd";
3
5
  export * from "./lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe";
package/index.js CHANGED
@@ -1,27 +1,42 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./lib/infobook/appendix/IInfoBookAppendixHandler"), exports);
5
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixAd"), exports);
6
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe"), exports);
7
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerAdvancementRewards"), exports);
8
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerCraftingRecipe"), exports);
9
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerSmeltingRecipe"), exports);
10
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerImage"), exports);
11
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerKeybinding"), exports);
12
- tslib_1.__exportStar(require("./lib/infobook/appendix/InfoBookAppendixTagIndex"), exports);
13
- tslib_1.__exportStar(require("./lib/infobook/FileWriter"), exports);
14
- tslib_1.__exportStar(require("./lib/infobook/IFileWriter"), exports);
15
- tslib_1.__exportStar(require("./lib/infobook/IFluid"), exports);
16
- tslib_1.__exportStar(require("./lib/infobook/IInfoAppendix"), exports);
17
- tslib_1.__exportStar(require("./lib/infobook/IInfoBook"), exports);
18
- tslib_1.__exportStar(require("./lib/infobook/IInfobookPlugin"), exports);
19
- tslib_1.__exportStar(require("./lib/infobook/IInfoSection"), exports);
20
- tslib_1.__exportStar(require("./lib/infobook/IItem"), exports);
21
- tslib_1.__exportStar(require("./lib/infobook/InfoBookInitializer"), exports);
22
- tslib_1.__exportStar(require("./lib/modloader/ModLoader"), exports);
23
- tslib_1.__exportStar(require("./lib/parse/XmlInfoBookParser"), exports);
24
- tslib_1.__exportStar(require("./lib/resource/ResourceHandler"), exports);
25
- tslib_1.__exportStar(require("./lib/resource/ResourceLoader"), exports);
26
- tslib_1.__exportStar(require("./lib/serialize/HtmlInfoBookSerializer"), exports);
17
+ __exportStar(require("./lib/icon/IconsCompressor"), exports);
18
+ __exportStar(require("./lib/icon/IconsGenerator"), exports);
19
+ __exportStar(require("./lib/infobook/appendix/IInfoBookAppendixHandler"), exports);
20
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixAd"), exports);
21
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerAbstractRecipe"), exports);
22
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerAdvancementRewards"), exports);
23
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerCraftingRecipe"), exports);
24
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerSmeltingRecipe"), exports);
25
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerImage"), exports);
26
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixHandlerKeybinding"), exports);
27
+ __exportStar(require("./lib/infobook/appendix/InfoBookAppendixTagIndex"), exports);
28
+ __exportStar(require("./lib/infobook/FileWriter"), exports);
29
+ __exportStar(require("./lib/infobook/IFileWriter"), exports);
30
+ __exportStar(require("./lib/infobook/IFluid"), exports);
31
+ __exportStar(require("./lib/infobook/IInfoAppendix"), exports);
32
+ __exportStar(require("./lib/infobook/IInfoBook"), exports);
33
+ __exportStar(require("./lib/infobook/IInfobookPlugin"), exports);
34
+ __exportStar(require("./lib/infobook/IInfoSection"), exports);
35
+ __exportStar(require("./lib/infobook/IItem"), exports);
36
+ __exportStar(require("./lib/infobook/InfoBookInitializer"), exports);
37
+ __exportStar(require("./lib/modloader/ModLoader"), exports);
38
+ __exportStar(require("./lib/parse/XmlInfoBookParser"), exports);
39
+ __exportStar(require("./lib/resource/ResourceHandler"), exports);
40
+ __exportStar(require("./lib/resource/ResourceLoader"), exports);
41
+ __exportStar(require("./lib/serialize/HtmlInfoBookSerializer"), exports);
27
42
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Losslessly compresses PNG icon files using OptiPNG.
3
+ * Mimics how ImgBot compresses images: lossless PNG compression at optimization level 7
4
+ * with metadata stripping.
5
+ */
6
+ export declare class IconsCompressor {
7
+ private readonly iconsDir;
8
+ constructor(iconsDir: string);
9
+ /**
10
+ * Compress all PNG files in the icon directory using OptiPNG.
11
+ */
12
+ compress(): Promise<void>;
13
+ /**
14
+ * Get the path to the optipng binary from optipng-bin package.
15
+ * Uses require.resolve to find the package root, then constructs the vendor binary path.
16
+ */
17
+ getOptipngPath(): string;
18
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.IconsCompressor = void 0;
13
+ const child_process_1 = require("child_process");
14
+ const fs = require("fs");
15
+ const path_1 = require("path");
16
+ const util_1 = require("util");
17
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
18
+ /**
19
+ * Losslessly compresses PNG icon files using OptiPNG.
20
+ * Mimics how ImgBot compresses images: lossless PNG compression at optimization level 7
21
+ * with metadata stripping.
22
+ */
23
+ class IconsCompressor {
24
+ constructor(iconsDir) {
25
+ if (!iconsDir) {
26
+ throw new Error('Missing iconsDir argument');
27
+ }
28
+ this.iconsDir = iconsDir;
29
+ }
30
+ /**
31
+ * Compress all PNG files in the icon directory using OptiPNG.
32
+ */
33
+ compress() {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const optipngPath = this.getOptipngPath();
36
+ if (!fs.existsSync(optipngPath)) {
37
+ throw new Error(`OptiPNG binary not found at: ${optipngPath}. Ensure optipng-bin is installed.`);
38
+ }
39
+ const files = yield fs.promises.readdir(this.iconsDir);
40
+ const pngFiles = files.filter((f) => f.endsWith('.png'));
41
+ if (pngFiles.length === 0) {
42
+ process.stdout.write(`No PNG files found in ${this.iconsDir}\n`);
43
+ return;
44
+ }
45
+ process.stdout.write(`Compressing ${pngFiles.length} icons in ${this.iconsDir}...\n`);
46
+ let compressed = 0;
47
+ let errors = 0;
48
+ let totalSavedBytes = 0;
49
+ for (const file of pngFiles) {
50
+ const filePath = (0, path_1.join)(this.iconsDir, file);
51
+ const sizeBefore = fs.statSync(filePath).size;
52
+ try {
53
+ yield execFileAsync(optipngPath, ['-o7', '-strip', 'all', '-quiet', filePath]);
54
+ const sizeAfter = fs.statSync(filePath).size;
55
+ totalSavedBytes += sizeBefore - sizeAfter;
56
+ compressed++;
57
+ }
58
+ catch (err) {
59
+ process.stderr.write(`Warning: failed to compress ${file}: ${err}\n`);
60
+ errors++;
61
+ }
62
+ }
63
+ const savedKb = (totalSavedBytes / 1024).toFixed(1);
64
+ process.stdout.write(`Compressed ${compressed} icons (saved ${savedKb} KB)` +
65
+ (errors > 0 ? `, ${errors} errors` : '') +
66
+ `\n`);
67
+ });
68
+ }
69
+ /**
70
+ * Get the path to the optipng binary from optipng-bin package.
71
+ * Uses require.resolve to find the package root, then constructs the vendor binary path.
72
+ */
73
+ getOptipngPath() {
74
+ const indexPath = require.resolve('optipng-bin');
75
+ const pkgRoot = (0, path_1.dirname)(indexPath);
76
+ const binaryName = process.platform === 'win32' ? 'optipng.exe' : 'optipng';
77
+ return (0, path_1.join)(pkgRoot, 'vendor', binaryName);
78
+ }
79
+ }
80
+ exports.IconsCompressor = IconsCompressor;
81
+ //# sourceMappingURL=IconsCompressor.js.map
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Generates icons using the IconExporter mod and HeadlessMC.
3
+ * This class downloads HeadlessMC and the IconExporter mod, sets up a headless
4
+ * Minecraft client with NeoForge and all specified mods, launches the game,
5
+ * runs the iconexporter export command, and copies the resulting icons.
6
+ */
7
+ export declare class IconsGenerator {
8
+ private static readonly HEADLESSMC_JAR;
9
+ private static readonly ICONEXPORTER_JAR;
10
+ private static readonly HMC_GAME_SUBDIR;
11
+ private static readonly HMC_CONFIG_SUBDIR;
12
+ private static readonly ICON_EXPORT_SUBDIR;
13
+ private static readonly DEFAULT_ICON_SIZE;
14
+ private static readonly HMC_SPECIFICS_REPO;
15
+ private readonly modsDir;
16
+ private readonly iconsDir;
17
+ private readonly workDir;
18
+ private readonly minecraftVersion;
19
+ private readonly neoforgeVersion;
20
+ private readonly githubToken;
21
+ private readonly iconExporterArtifact;
22
+ private readonly iconExporterVersion;
23
+ private readonly headlessMcVersion;
24
+ private readonly launchTimeoutMs;
25
+ constructor(args: IIconsGeneratorArgs);
26
+ /**
27
+ * Run the full icon generation pipeline.
28
+ */
29
+ generate(): Promise<void>;
30
+ /**
31
+ * Download the HeadlessMC launcher jar.
32
+ */
33
+ downloadHeadlessMc(): Promise<void>;
34
+ /**
35
+ * Download the IconExporter mod from GitHub Maven packages.
36
+ */
37
+ downloadIconExporter(): Promise<void>;
38
+ /**
39
+ * Set up the game directory with mods and options.
40
+ */
41
+ setupGameDirectory(): Promise<void>;
42
+ /**
43
+ * Write the HeadlessMC configuration file.
44
+ */
45
+ writeHmcConfig(): void;
46
+ /**
47
+ * Run the Minecraft client using HeadlessMC and export icons.
48
+ */
49
+ runGameAndExportIcons(): Promise<void>;
50
+ /**
51
+ * Copy exported icons to the output icons directory.
52
+ */
53
+ copyIcons(): Promise<void>;
54
+ /**
55
+ * Parse the HeadlessMC `gui` command output and find the numeric button ID for a given
56
+ * button text label. HeadlessMC's `click` command requires a numeric id, not the text.
57
+ * The gui table format is:
58
+ * id text x y w h on type
59
+ * 0 Multiplayer 140 123 200 20 1 Button
60
+ * 1 Singleplayer 140 99 200 20 1 Button
61
+ * Columns are separated by two or more spaces.
62
+ */
63
+ findButtonIdByText(guiOutput: string, buttonText: string): number | null;
64
+ /**
65
+ * Determine if the Minecraft game has fully loaded based on log output.
66
+ */
67
+ isGameFullyLoaded(output: string): boolean;
68
+ /**
69
+ * Determine if the HeadlessMC launcher is ready to accept commands based on its startup output.
70
+ * In non-TTY mode HeadlessMC does not print a '>' prompt, so we detect readiness from the
71
+ * version-table header or the DefaultCommandLineProvider warning it prints on startup.
72
+ */
73
+ isHeadlessMcReady(output: string): boolean;
74
+ /**
75
+ * Download the hmc-specifics mod from GitHub Releases into the given mods directory.
76
+ * This avoids relying on HeadlessMC's built-in `-specifics` auto-download which checks
77
+ * the GitHub API without authentication and can hit rate limits.
78
+ */
79
+ downloadHmcSpecifics(modsDir: string): Promise<void>;
80
+ /**
81
+ * Download a file from a URL to a destination path.
82
+ */
83
+ downloadFile(url: string, destPath: string, headers?: Record<string, string>): Promise<void>;
84
+ }
85
+ export type IGameState = 'waiting_for_prompt' | 'game_launching' | 'checking_screen' | 'navigating_singleplayer' | 'creating_world' | 'exporting_icons' | 'quitting';
86
+ export interface IIconsGeneratorArgs {
87
+ /**
88
+ * Directory containing mod JARs to include in the client (usually server/mods).
89
+ */
90
+ modsDir: string;
91
+ /**
92
+ * Directory where icons will be written.
93
+ */
94
+ iconsDir: string;
95
+ /**
96
+ * Working directory for HeadlessMC and game files.
97
+ */
98
+ workDir: string;
99
+ /**
100
+ * Minecraft version (e.g., "1.21.1").
101
+ */
102
+ minecraftVersion: string;
103
+ /**
104
+ * NeoForge version (e.g., "21.1.210").
105
+ */
106
+ neoforgeVersion: string;
107
+ /**
108
+ * GitHub token for downloading from GitHub Packages.
109
+ * Falls back to GITHUB_TOKEN environment variable.
110
+ */
111
+ githubToken?: string;
112
+ /**
113
+ * Maven artifact ID for IconExporter (default: iconexporter-{minecraftVersion}-neoforge).
114
+ */
115
+ iconExporterArtifact?: string;
116
+ /**
117
+ * Version of the IconExporter artifact to download (e.g., "1.4.0-174").
118
+ */
119
+ iconExporterVersion?: string;
120
+ /**
121
+ * Version of HeadlessMC to download (e.g., "2.8.0").
122
+ */
123
+ headlessMcVersion?: string;
124
+ /**
125
+ * Timeout in milliseconds for the full game launch and icon export (default: 30 minutes).
126
+ */
127
+ launchTimeoutMs?: number;
128
+ }