@nodecraft/rendermite 1.4.1 → 1.6.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.
- package/README.md +3 -0
- package/dist/blocks/cli.js +1 -1
- package/dist/blocks/entities.d.ts +30 -0
- package/dist/blocks/entities.js +2 -0
- package/dist/blocks/entity-geo.d.ts +18 -0
- package/dist/blocks/entity-geo.js +2 -0
- package/dist/blocks/entity-models.d.ts +2 -0
- package/dist/blocks/entity-models.js +2 -0
- package/dist/blocks/export.d.ts +1 -1
- package/dist/blocks/export.js +1 -1
- package/dist/blocks/item-sprites.d.ts +34 -0
- package/dist/blocks/item-sprites.js +2 -0
- package/dist/blocks/obj-mesh.js +1 -1
- package/dist/blocks/pack-format.d.ts +2 -2
- package/dist/blocks/sprite-sheet.d.ts +59 -0
- package/dist/blocks/sprite-sheet.js +2 -0
- package/dist/classfile-BwaQjnUM.d.ts +51 -0
- package/dist/classfile-CAhS5qNf.js +255 -0
- package/dist/{cli-DqJtT-Ms.js → cli-BSKnXBPr.js} +31 -4
- package/dist/cli.js +5 -5
- package/dist/{discovery-CsZu08re.js → discovery-CD0QqxSF.js} +1 -1
- package/dist/{discovery-C5ZR4aoG.d.ts → discovery-Cmir3QfC.d.ts} +8 -1
- package/dist/entities/classfile.d.ts +2 -0
- package/dist/entities/classfile.js +2 -0
- package/dist/entities/geo-model.d.ts +13 -0
- package/dist/entities/geo-model.js +2 -0
- package/dist/entities/inherit.d.ts +29 -0
- package/dist/entities/inherit.js +2 -0
- package/dist/entities/jar-classes.d.ts +26 -0
- package/dist/entities/jar-classes.js +2 -0
- package/dist/entities/link.d.ts +71 -0
- package/dist/entities/link.js +2 -0
- package/dist/entities/mappings.d.ts +2 -0
- package/dist/entities/mappings.js +2 -0
- package/dist/entities/merge.d.ts +18 -0
- package/dist/entities/merge.js +2 -0
- package/dist/entities/model-bytecode.d.ts +31 -0
- package/dist/entities/model-bytecode.js +2 -0
- package/dist/entities/model-code.d.ts +2 -0
- package/dist/entities/model-code.js +2 -0
- package/dist/entities/model.d.ts +2 -0
- package/dist/entities/model.js +1 -0
- package/dist/entities-DvmA9fEV.js +175 -0
- package/dist/{entity-fallback-BTkM8j0V.js → entity-fallback-Bth0fa7m.js} +1 -1
- package/dist/entity-geo-B2CkuMWx.js +100 -0
- package/dist/entity-models-B6-0r2gR.js +123 -0
- package/dist/entity-models-c2HpfdWV.d.ts +49 -0
- package/dist/{export-Bllg8Fw7.d.ts → export-D8fLC1wS.d.ts} +30 -1
- package/dist/{export-kMoMes_a.js → export-DT_drDoI.js} +182 -160
- package/dist/geo-CmjrXu0G.d.ts +59 -0
- package/dist/{geo-BguldlU-.js → geo-Desq-gRC.js} +5 -4
- package/dist/geo-model-Bo1gpEwX.js +163 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -10
- package/dist/inherit-KkDsM2N_.js +77 -0
- package/dist/item-sprites-G-yikdfV.js +126 -0
- package/dist/items/discovery.d.ts +2 -2
- package/dist/items/discovery.js +2 -2
- package/dist/jar-classes-Bj15hjdr.js +75 -0
- package/dist/link-Bm5oQYh6.js +331 -0
- package/dist/mappings-BEPVaiwE.js +139 -0
- package/dist/mappings-DxX4KoZl.d.ts +75 -0
- package/dist/merge-3HkeQ_6A.js +46 -0
- package/dist/model-PnQ4gV0-.d.ts +49 -0
- package/dist/model-bytecode-C1nw2G8O.js +732 -0
- package/dist/model-code-B7jSFQqd.d.ts +16 -0
- package/dist/model-code-BKMEMXxF.js +49 -0
- package/dist/mods/prepare.js +1 -1
- package/dist/mods/tints.js +1 -1
- package/dist/{obj-bvs3gwex.js → obj-CJHEHpki.js} +4 -4
- package/dist/{obj-mesh-rnYbSbpv.js → obj-mesh-JwPkZEWL.js} +1 -1
- package/dist/pack-format-QcVFxG_b.d.ts +280 -0
- package/dist/pack.d.ts +1 -1
- package/dist/{pipeline-B8e6x8Hh.js → pipeline-BUIMzMzg.js} +6 -6
- package/dist/{prepare-C9gjqQTt.js → prepare-Myd_ec4v.js} +2 -2
- package/dist/render/entity-fallback.js +1 -1
- package/dist/render/face.js +1 -1
- package/dist/render/geo.d.ts +2 -54
- package/dist/render/geo.js +2 -2
- package/dist/render/obj.js +1 -1
- package/dist/render/pipeline.js +1 -1
- package/dist/render/renderer.js +1 -1
- package/dist/resources/descriptor.js +1 -1
- package/dist/{run-B_JAUbXe.js → run-BQJkqc5f.js} +3 -3
- package/dist/run.js +1 -1
- package/dist/sprite-sheet-LQAEtGkp.js +185 -0
- package/dist/versions/prepare.js +1 -1
- package/dist/workers/render-worker.js +2 -2
- package/package.json +1 -1
- package/dist/pack-format-BVC_B-ZW.d.ts +0 -140
- package/dist/{descriptor-D7VKgeGT.js → descriptor-JyXhfd-c.js} +1 -1
- package/dist/{face-CKHboPfh.js → face-B2JjWT46.js} +1 -1
- package/dist/{prepare-8LswFoS-.js → prepare-D49Gu4Lv.js} +1 -1
- package/dist/{tints-C1tT6pKk.js → tints-BspVCz2G.js} +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,9 @@ blocks/1.21.8/
|
|
|
75
75
|
blockstates.json # block id -> variants/multipart, keys and predicates pre-parsed
|
|
76
76
|
tints.json # plains tints, colormaps, ramps, per-block tint semantics
|
|
77
77
|
colormap/*.png # the version's own grass/foliage/dry_foliage maps
|
|
78
|
+
items.json # flat item sprite stacks + their own atlas, for drawing dropped stacks
|
|
79
|
+
entities.json # entity names, marker colours, and which model each uses
|
|
80
|
+
entity-models.json # entity geometry recovered from the client's own bytecode + its atlas
|
|
78
81
|
failures.json # anything not fully handled, with reasons, never silent
|
|
79
82
|
meta.json # version, counts, sha256 of every other file
|
|
80
83
|
```
|
package/dist/blocks/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as runBlocksCli } from "../cli-
|
|
1
|
+
import { t as runBlocksCli } from "../cli-BSKnXBPr.js";
|
|
2
2
|
export { runBlocksCli };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { a as ResourceManager } from "../manager-exOIcdyx.js";
|
|
2
|
+
import { i as TextureLoader } from "../loader-DUlx29PC.js";
|
|
3
|
+
import { x as EntityPackEntry } from "../pack-format-QcVFxG_b.js";
|
|
4
|
+
//#region src/blocks/entities.d.ts
|
|
5
|
+
interface EntityPackResult {
|
|
6
|
+
entities: Record<string, EntityPackEntry>;
|
|
7
|
+
failures: Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Every entity type a namespace registers, by its lang keys.
|
|
14
|
+
*
|
|
15
|
+
* Keys with more segments than `<prefix>.<ns>.<name>` are dropped: those are a variant's own label
|
|
16
|
+
* (`entity.minecraft.villager.farmer`) or a death message, never a type.
|
|
17
|
+
*/
|
|
18
|
+
declare function entityTypesOf(resources: ResourceManager, namespace: string): Promise<Array<{
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
}>>;
|
|
22
|
+
interface CollectEntitiesOptions {
|
|
23
|
+
resources: ResourceManager;
|
|
24
|
+
textures: TextureLoader;
|
|
25
|
+
namespaces: readonly string[];
|
|
26
|
+
onProgress?: (done: number, total: number) => void;
|
|
27
|
+
}
|
|
28
|
+
declare function collectEntities(options: CollectEntitiesOptions): Promise<EntityPackResult>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { CollectEntitiesOptions, EntityPackResult, collectEntities, entityTypesOf };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { a as ResourceManager } from "../manager-exOIcdyx.js";
|
|
2
|
+
import { r as ExtractedModel } from "../model-PnQ4gV0-.js";
|
|
3
|
+
//#region src/blocks/entity-geo.d.ts
|
|
4
|
+
interface GeoEntityModel {
|
|
5
|
+
/** Model id: the resource that produced it, which is also what makes it unique in the pack. */
|
|
6
|
+
id: string;
|
|
7
|
+
model: ExtractedModel;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The geometry for one entity, or null when the mod does not ship any under that name.
|
|
11
|
+
*
|
|
12
|
+
* `namespace` and `name` come from the entity id, so `occultism:afrit` looks for
|
|
13
|
+
* `assets/occultism/geo/entity/afrit.geo.json` and its neighbours. Nothing is inferred from the
|
|
14
|
+
* *class* here: a GeckoLib mob has no model class to inspect.
|
|
15
|
+
*/
|
|
16
|
+
declare function findGeoForEntity(resources: ResourceManager, namespace: string, name: string): Promise<GeoEntityModel | null>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { GeoEntityModel, findGeoForEntity };
|
package/dist/blocks/export.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as exportBlockPack, n as BlockPackResult, r as ExportBlockPackOptions, t as BlockPackFailure } from "../export-
|
|
1
|
+
import { i as exportBlockPack, n as BlockPackResult, r as ExportBlockPackOptions, t as BlockPackFailure } from "../export-D8fLC1wS.js";
|
|
2
2
|
export { BlockPackFailure, BlockPackResult, ExportBlockPackOptions, exportBlockPack };
|
package/dist/blocks/export.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as exportBlockPack } from "../export-
|
|
1
|
+
import { t as exportBlockPack } from "../export-DT_drDoI.js";
|
|
2
2
|
export { exportBlockPack };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { a as ResourceManager } from "../manager-exOIcdyx.js";
|
|
2
|
+
import { i as TextureLoader } from "../loader-DUlx29PC.js";
|
|
3
|
+
import { t as ModelLoader } from "../loader-DSir1-P0.js";
|
|
4
|
+
import { w as ItemPackEntry } from "../pack-format-QcVFxG_b.js";
|
|
5
|
+
//#region src/blocks/item-sprites.d.ts
|
|
6
|
+
interface ItemSpriteFailure {
|
|
7
|
+
id: string;
|
|
8
|
+
reason: string;
|
|
9
|
+
}
|
|
10
|
+
interface ItemSpriteResult {
|
|
11
|
+
/** Flat items only, by item id; anything absent is the consumer's block-model job. */
|
|
12
|
+
items: Record<string, ItemPackEntry>;
|
|
13
|
+
/** Sprite ids to pack, which is every layer of every entry. */
|
|
14
|
+
spriteIds: Set<string>;
|
|
15
|
+
failures: ItemSpriteFailure[];
|
|
16
|
+
}
|
|
17
|
+
interface CollectItemSpritesOptions {
|
|
18
|
+
resources: ResourceManager;
|
|
19
|
+
models: ModelLoader;
|
|
20
|
+
textures: TextureLoader;
|
|
21
|
+
namespaces: readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* Ids the pack describes as blocks. Only used to decide whether a non-flat item
|
|
24
|
+
* is worth reporting: a stone block item drawing from `blockstates.json` is the
|
|
25
|
+
* design, while one nothing describes is a gap somebody should hear about.
|
|
26
|
+
*/
|
|
27
|
+
blocks: ReadonlySet<string>;
|
|
28
|
+
/** Item ids to consider, as `discoverItems` yields them. */
|
|
29
|
+
itemIds: readonly string[];
|
|
30
|
+
onProgress?: (done: number, total: number) => void;
|
|
31
|
+
}
|
|
32
|
+
declare function collectItemSprites(options: CollectItemSpritesOptions): Promise<ItemSpriteResult>;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { CollectItemSpritesOptions, ItemSpriteFailure, ItemSpriteResult, collectItemSprites };
|
package/dist/blocks/obj-mesh.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as buildObjMesh, t as ObjMeshError } from "../obj-mesh-
|
|
1
|
+
import { n as buildObjMesh, t as ObjMeshError } from "../obj-mesh-JwPkZEWL.js";
|
|
2
2
|
export { ObjMeshError, buildObjMesh };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as BlockPackBlockStatesFile, c as
|
|
2
|
-
export { BlockPackAtlasFile, BlockPackAtlasPage, BlockPackBiomesFile, BlockPackBlockState, BlockPackBlockStatesFile, BlockPackElement, BlockPackFace, BlockPackMetaFile, BlockPackModel, BlockPackModelsFile, BlockPackRenderLayer, BlockPackSprite, BlockPackSpriteFrame, BlockPackTintsFile, BlockPackVariant };
|
|
1
|
+
import { C as EntityPackPart, S as EntityPackModel, T as ItemPackLayer, _ as BlockPackTintsFile, a as BlockPackBlockStatesFile, b as EntityPackCubeFace, c as BlockPackEntityModelsFile, d as BlockPackMetaFile, f as BlockPackModel, g as BlockPackSpriteFrame, h as BlockPackSprite, i as BlockPackBlockState, l as BlockPackFace, m as BlockPackRenderLayer, n as BlockPackAtlasPage, o as BlockPackElement, p as BlockPackModelsFile, r as BlockPackBiomesFile, s as BlockPackEntitiesFile, t as BlockPackAtlasFile, u as BlockPackItemsFile, v as BlockPackVariant, w as ItemPackEntry, x as EntityPackEntry, y as EntityPackCube } from "../pack-format-QcVFxG_b.js";
|
|
2
|
+
export { BlockPackAtlasFile, BlockPackAtlasPage, BlockPackBiomesFile, BlockPackBlockState, BlockPackBlockStatesFile, BlockPackElement, BlockPackEntitiesFile, BlockPackEntityModelsFile, BlockPackFace, BlockPackItemsFile, BlockPackMetaFile, BlockPackModel, BlockPackModelsFile, BlockPackRenderLayer, BlockPackSprite, BlockPackSpriteFrame, BlockPackTintsFile, BlockPackVariant, EntityPackCube, EntityPackCubeFace, EntityPackEntry, EntityPackModel, EntityPackPart, ItemPackEntry, ItemPackLayer };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { i as TextureLoader, r as Texture } from "../loader-DUlx29PC.js";
|
|
2
|
+
import { i as PackedPage } from "../atlas-pack-D8745_wo.js";
|
|
3
|
+
import { h as BlockPackSprite, m as BlockPackRenderLayer } from "../pack-format-QcVFxG_b.js";
|
|
4
|
+
//#region src/blocks/sprite-sheet.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Vanilla's own id for the missing-texture sprite. A face whose texture does
|
|
7
|
+
* not resolve is drawn by the game in black and magenta rather than skipped —
|
|
8
|
+
* Blockbench leaves `"texture": "#missing"` on unassigned faces and mods ship
|
|
9
|
+
* models naming textures they forgot to include. Dropping those faces would
|
|
10
|
+
* put holes in geometry the player can see, and would read as our bug rather
|
|
11
|
+
* than the mod's.
|
|
12
|
+
*/
|
|
13
|
+
declare const MISSING_SPRITE = "minecraft:missingno";
|
|
14
|
+
/** `MissingTextureAtlasSprite`: 16x16, black and magenta in 8px quarters. */
|
|
15
|
+
declare function missingTexture(): Texture;
|
|
16
|
+
/**
|
|
17
|
+
* Alpha decides the render layer: vanilla assets do not state cutout versus
|
|
18
|
+
* translucent (`render_type` is a loader extension adopted only recently), and
|
|
19
|
+
* inferring it covers mods for free.
|
|
20
|
+
*/
|
|
21
|
+
declare function inferRenderLayer(frames: Texture[]): BlockPackRenderLayer;
|
|
22
|
+
interface SpriteSheetFailure {
|
|
23
|
+
id: string;
|
|
24
|
+
reason: string;
|
|
25
|
+
}
|
|
26
|
+
interface BuildSpriteSheetOptions {
|
|
27
|
+
/** Edge-extended border per sprite side (default 4). */
|
|
28
|
+
padding?: number;
|
|
29
|
+
/** Ceiling on a page's dimensions (default 4096). */
|
|
30
|
+
maxPageSize?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Pack the black-and-magenta missing-texture sprite whether or not anything
|
|
33
|
+
* named it, and throw if it does not fit. What a consumer draws for something
|
|
34
|
+
* this pack does not describe at all; a guarantee worth its 256 pixels.
|
|
35
|
+
*/
|
|
36
|
+
includeMissing?: boolean;
|
|
37
|
+
onProgress?: (done: number, total: number) => void;
|
|
38
|
+
}
|
|
39
|
+
interface SpriteSheet {
|
|
40
|
+
pages: PackedPage[];
|
|
41
|
+
/** Ready for `atlas.json`, unsorted — the caller decides the key order. */
|
|
42
|
+
sprites: Record<string, BlockPackSprite>;
|
|
43
|
+
/**
|
|
44
|
+
* Ids that never loaded or never fit a page, so have no rect. A caller must
|
|
45
|
+
* not emit anything naming one of these; the block path rewrites those
|
|
46
|
+
* references to `MISSING_SPRITE`, and the item path drops the item.
|
|
47
|
+
*/
|
|
48
|
+
missing: Set<string>;
|
|
49
|
+
failures: SpriteSheetFailure[];
|
|
50
|
+
padding: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Loads every id, packs the frames, and returns the sheet plus everything that
|
|
54
|
+
* did not make it. Ids are packed in sorted order so an unchanged input produces
|
|
55
|
+
* a byte-identical atlas.
|
|
56
|
+
*/
|
|
57
|
+
declare function buildSpriteSheet(ids: Iterable<string>, textures: TextureLoader, options?: BuildSpriteSheetOptions): Promise<SpriteSheet>;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { BuildSpriteSheetOptions, MISSING_SPRITE, SpriteSheet, SpriteSheetFailure, buildSpriteSheet, inferRenderLayer, missingTexture };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/entities/classfile.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* A minimal JVM class-file reader: constant pool, methods, and each method's `Code`.
|
|
4
|
+
*
|
|
5
|
+
* Written rather than taken from npm because the whole of what is needed is the constant pool and one
|
|
6
|
+
* attribute — every published class-file library is an order of magnitude more than that, and this
|
|
7
|
+
* runs in a package whose entire dependency list is three entries.
|
|
8
|
+
*
|
|
9
|
+
* It exists because entity models are Java code at every version (see docs/entity-geometry.md), so
|
|
10
|
+
* the only automatic way to recover their geometry is to read the code.
|
|
11
|
+
*
|
|
12
|
+
* Spec: https://docs.oracle.com/javase/specs/jvms/se21/html/jvms-4.html
|
|
13
|
+
*/
|
|
14
|
+
type ConstantTag = 'utf8' | 'integer' | 'float' | 'long' | 'double' | 'class' | 'string' | 'fieldref' | 'methodref' | 'interfaceMethodref' | 'nameAndType' | 'methodHandle' | 'methodType' | 'dynamic' | 'invokeDynamic' | 'module' | 'package';
|
|
15
|
+
interface Constant {
|
|
16
|
+
tag: ConstantTag;
|
|
17
|
+
/** Utf8 text, or the numeric value of an integer/float/long/double. */
|
|
18
|
+
value?: string | number | bigint;
|
|
19
|
+
/** Indexes into the pool, by whatever the tag needs. */
|
|
20
|
+
nameIndex?: number;
|
|
21
|
+
classIndex?: number;
|
|
22
|
+
nameAndTypeIndex?: number;
|
|
23
|
+
descriptorIndex?: number;
|
|
24
|
+
stringIndex?: number;
|
|
25
|
+
}
|
|
26
|
+
interface MethodInfo {
|
|
27
|
+
name: string;
|
|
28
|
+
descriptor: string;
|
|
29
|
+
accessFlags: number;
|
|
30
|
+
/** Raw bytecode of the `Code` attribute, absent on an abstract or native method. */
|
|
31
|
+
code?: Uint8Array;
|
|
32
|
+
}
|
|
33
|
+
interface ClassFile {
|
|
34
|
+
thisClass: string;
|
|
35
|
+
superClass: string | null;
|
|
36
|
+
constants: Array<Constant | null>;
|
|
37
|
+
methods: MethodInfo[];
|
|
38
|
+
/** A pool entry as text, for a `utf8` or anything that resolves to one. */
|
|
39
|
+
utf8: (index: number) => string;
|
|
40
|
+
/** `owner.name:descriptor` for a field or method reference. */
|
|
41
|
+
reference: (index: number) => {
|
|
42
|
+
owner: string;
|
|
43
|
+
name: string;
|
|
44
|
+
descriptor: string;
|
|
45
|
+
} | null;
|
|
46
|
+
/** The value an `ldc` of this index pushes: a number for numeric constants, a string for `string`. */
|
|
47
|
+
literal: (index: number) => string | number | bigint | null;
|
|
48
|
+
}
|
|
49
|
+
declare function parseClassFile(bytes: Uint8Array): ClassFile;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { parseClassFile as a, MethodInfo as i, Constant as n, ConstantTag as r, ClassFile as t };
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
//#region src/entities/classfile.ts
|
|
2
|
+
var Reader = class {
|
|
3
|
+
at = 0;
|
|
4
|
+
bytes;
|
|
5
|
+
view;
|
|
6
|
+
constructor(bytes) {
|
|
7
|
+
this.bytes = bytes;
|
|
8
|
+
this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
9
|
+
}
|
|
10
|
+
u1() {
|
|
11
|
+
return this.view.getUint8(this.at++);
|
|
12
|
+
}
|
|
13
|
+
u2() {
|
|
14
|
+
const value = this.view.getUint16(this.at);
|
|
15
|
+
this.at += 2;
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
u4() {
|
|
19
|
+
const value = this.view.getUint32(this.at);
|
|
20
|
+
this.at += 4;
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
i4() {
|
|
24
|
+
const value = this.view.getInt32(this.at);
|
|
25
|
+
this.at += 4;
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
f4() {
|
|
29
|
+
const value = this.view.getFloat32(this.at);
|
|
30
|
+
this.at += 4;
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
f8() {
|
|
34
|
+
const value = this.view.getFloat64(this.at);
|
|
35
|
+
this.at += 8;
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
i8() {
|
|
39
|
+
const value = this.view.getBigInt64(this.at);
|
|
40
|
+
this.at += 8;
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
utf8(length) {
|
|
44
|
+
const text = new TextDecoder("utf-8").decode(this.bytes.subarray(this.at, this.at + length));
|
|
45
|
+
this.at += length;
|
|
46
|
+
return text;
|
|
47
|
+
}
|
|
48
|
+
skip(count) {
|
|
49
|
+
this.at += count;
|
|
50
|
+
}
|
|
51
|
+
take(count) {
|
|
52
|
+
const slice = this.bytes.subarray(this.at, this.at + count);
|
|
53
|
+
this.at += count;
|
|
54
|
+
return slice;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
/** Pool tags, by their spec number. `null` marks the two that take two slots. */
|
|
58
|
+
const TAGS = {
|
|
59
|
+
1: "utf8",
|
|
60
|
+
3: "integer",
|
|
61
|
+
4: "float",
|
|
62
|
+
5: "long",
|
|
63
|
+
6: "double",
|
|
64
|
+
7: "class",
|
|
65
|
+
8: "string",
|
|
66
|
+
9: "fieldref",
|
|
67
|
+
10: "methodref",
|
|
68
|
+
11: "interfaceMethodref",
|
|
69
|
+
12: "nameAndType",
|
|
70
|
+
15: "methodHandle",
|
|
71
|
+
16: "methodType",
|
|
72
|
+
17: "dynamic",
|
|
73
|
+
18: "invokeDynamic",
|
|
74
|
+
19: "module",
|
|
75
|
+
20: "package"
|
|
76
|
+
};
|
|
77
|
+
function readConstantPool(reader) {
|
|
78
|
+
const count = reader.u2();
|
|
79
|
+
const constants = [null];
|
|
80
|
+
for (let index = 1; index < count; index++) {
|
|
81
|
+
const raw = reader.u1();
|
|
82
|
+
const tag = TAGS[raw];
|
|
83
|
+
if (!tag) throw new Error(`Unknown constant pool tag ${raw} at ${index}`);
|
|
84
|
+
switch (tag) {
|
|
85
|
+
case "utf8":
|
|
86
|
+
constants.push({
|
|
87
|
+
tag,
|
|
88
|
+
value: reader.utf8(reader.u2())
|
|
89
|
+
});
|
|
90
|
+
break;
|
|
91
|
+
case "integer":
|
|
92
|
+
constants.push({
|
|
93
|
+
tag,
|
|
94
|
+
value: reader.i4()
|
|
95
|
+
});
|
|
96
|
+
break;
|
|
97
|
+
case "float":
|
|
98
|
+
constants.push({
|
|
99
|
+
tag,
|
|
100
|
+
value: reader.f4()
|
|
101
|
+
});
|
|
102
|
+
break;
|
|
103
|
+
case "long":
|
|
104
|
+
constants.push({
|
|
105
|
+
tag,
|
|
106
|
+
value: reader.i8()
|
|
107
|
+
});
|
|
108
|
+
constants.push(null);
|
|
109
|
+
index++;
|
|
110
|
+
break;
|
|
111
|
+
case "double":
|
|
112
|
+
constants.push({
|
|
113
|
+
tag,
|
|
114
|
+
value: reader.f8()
|
|
115
|
+
});
|
|
116
|
+
constants.push(null);
|
|
117
|
+
index++;
|
|
118
|
+
break;
|
|
119
|
+
case "class":
|
|
120
|
+
case "module":
|
|
121
|
+
case "package":
|
|
122
|
+
constants.push({
|
|
123
|
+
tag,
|
|
124
|
+
nameIndex: reader.u2()
|
|
125
|
+
});
|
|
126
|
+
break;
|
|
127
|
+
case "string":
|
|
128
|
+
constants.push({
|
|
129
|
+
tag,
|
|
130
|
+
stringIndex: reader.u2()
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
case "fieldref":
|
|
134
|
+
case "methodref":
|
|
135
|
+
case "interfaceMethodref":
|
|
136
|
+
constants.push({
|
|
137
|
+
tag,
|
|
138
|
+
classIndex: reader.u2(),
|
|
139
|
+
nameAndTypeIndex: reader.u2()
|
|
140
|
+
});
|
|
141
|
+
break;
|
|
142
|
+
case "nameAndType":
|
|
143
|
+
constants.push({
|
|
144
|
+
tag,
|
|
145
|
+
nameIndex: reader.u2(),
|
|
146
|
+
descriptorIndex: reader.u2()
|
|
147
|
+
});
|
|
148
|
+
break;
|
|
149
|
+
case "methodHandle":
|
|
150
|
+
reader.skip(1);
|
|
151
|
+
constants.push({
|
|
152
|
+
tag,
|
|
153
|
+
nameAndTypeIndex: reader.u2()
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
156
|
+
case "methodType":
|
|
157
|
+
constants.push({
|
|
158
|
+
tag,
|
|
159
|
+
descriptorIndex: reader.u2()
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
case "dynamic":
|
|
163
|
+
case "invokeDynamic":
|
|
164
|
+
reader.skip(2);
|
|
165
|
+
constants.push({
|
|
166
|
+
tag,
|
|
167
|
+
nameAndTypeIndex: reader.u2()
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return constants;
|
|
172
|
+
}
|
|
173
|
+
/** Skips an attribute table, returning the `Code` bytes if one of them is a Code attribute. */
|
|
174
|
+
function readAttributes(reader, utf8) {
|
|
175
|
+
let code;
|
|
176
|
+
const count = reader.u2();
|
|
177
|
+
for (let index = 0; index < count; index++) {
|
|
178
|
+
const name = utf8(reader.u2());
|
|
179
|
+
const length = reader.u4();
|
|
180
|
+
if (name !== "Code") {
|
|
181
|
+
reader.skip(length);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
reader.skip(4);
|
|
185
|
+
code = reader.take(reader.u4());
|
|
186
|
+
reader.skip(reader.u2() * 8);
|
|
187
|
+
readAttributes(reader, utf8);
|
|
188
|
+
}
|
|
189
|
+
return code;
|
|
190
|
+
}
|
|
191
|
+
function parseClassFile(bytes) {
|
|
192
|
+
const reader = new Reader(bytes);
|
|
193
|
+
if (reader.u4() !== 3405691582) throw new Error("Not a class file: bad magic");
|
|
194
|
+
reader.skip(4);
|
|
195
|
+
const constants = readConstantPool(reader);
|
|
196
|
+
const utf8 = (index) => {
|
|
197
|
+
const entry = constants[index];
|
|
198
|
+
if (!entry) return "";
|
|
199
|
+
if (entry.tag === "utf8") return String(entry.value);
|
|
200
|
+
const next = entry.nameIndex ?? entry.stringIndex ?? entry.descriptorIndex;
|
|
201
|
+
return next === void 0 ? "" : utf8(next);
|
|
202
|
+
};
|
|
203
|
+
reader.skip(2);
|
|
204
|
+
const thisClass = utf8(reader.u2());
|
|
205
|
+
const superIndex = reader.u2();
|
|
206
|
+
const superClass = superIndex === 0 ? null : utf8(superIndex);
|
|
207
|
+
reader.skip(reader.u2() * 2);
|
|
208
|
+
const fieldCount = reader.u2();
|
|
209
|
+
for (let index = 0; index < fieldCount; index++) {
|
|
210
|
+
reader.skip(6);
|
|
211
|
+
readAttributes(reader, utf8);
|
|
212
|
+
}
|
|
213
|
+
const methods = [];
|
|
214
|
+
const methodCount = reader.u2();
|
|
215
|
+
for (let index = 0; index < methodCount; index++) {
|
|
216
|
+
const accessFlags = reader.u2();
|
|
217
|
+
const name = utf8(reader.u2());
|
|
218
|
+
const descriptor = utf8(reader.u2());
|
|
219
|
+
const code = readAttributes(reader, utf8);
|
|
220
|
+
methods.push({
|
|
221
|
+
name,
|
|
222
|
+
descriptor,
|
|
223
|
+
accessFlags,
|
|
224
|
+
code
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const reference = (index) => {
|
|
228
|
+
const entry = constants[index];
|
|
229
|
+
if (!entry || entry.classIndex === void 0 || entry.nameAndTypeIndex === void 0) return null;
|
|
230
|
+
const nameAndType = constants[entry.nameAndTypeIndex];
|
|
231
|
+
if (!nameAndType?.nameIndex || !nameAndType.descriptorIndex) return null;
|
|
232
|
+
return {
|
|
233
|
+
owner: utf8(entry.classIndex),
|
|
234
|
+
name: utf8(nameAndType.nameIndex),
|
|
235
|
+
descriptor: utf8(nameAndType.descriptorIndex)
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
const literal = (index) => {
|
|
239
|
+
const entry = constants[index];
|
|
240
|
+
if (!entry) return null;
|
|
241
|
+
if (entry.tag === "string") return utf8(index);
|
|
242
|
+
return entry.value ?? null;
|
|
243
|
+
};
|
|
244
|
+
return {
|
|
245
|
+
thisClass,
|
|
246
|
+
superClass,
|
|
247
|
+
constants,
|
|
248
|
+
methods,
|
|
249
|
+
utf8,
|
|
250
|
+
reference,
|
|
251
|
+
literal
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
export { parseClassFile as t };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { n as builtinPackPath } from "./builtin-WkWjATeh.js";
|
|
2
2
|
import { n as LayeredResourceManager, t as FolderResourceManager } from "./manager-BNibYkmI.js";
|
|
3
|
-
import { t as exportBlockPack } from "./export-
|
|
4
|
-
import {
|
|
3
|
+
import { t as exportBlockPack } from "./export-DT_drDoI.js";
|
|
4
|
+
import { t as JarClassReader } from "./jar-classes-Bj15hjdr.js";
|
|
5
|
+
import { n as prepareModResources } from "./prepare-Myd_ec4v.js";
|
|
5
6
|
import { t as downloadClientJar } from "./download-1wAfrGKx.js";
|
|
6
|
-
import { a as prepareVersionResources, r as compareVersions } from "./prepare-
|
|
7
|
+
import { a as prepareVersionResources, r as compareVersions } from "./prepare-D49Gu4Lv.js";
|
|
7
8
|
import path from "node:path";
|
|
8
9
|
import os from "node:os";
|
|
9
10
|
import { parseArgs } from "node:util";
|
|
@@ -34,6 +35,9 @@ Options:
|
|
|
34
35
|
--max-page-size <px> atlas page ceiling (default 4096)
|
|
35
36
|
--builtin <dir> override the vendored geometry pack
|
|
36
37
|
--no-builtin do not substitute geometry for code-drawn blocks
|
|
38
|
+
--no-items do not export items.json (flat sprites for non-block items)
|
|
39
|
+
--no-entities do not export entities.json (entity names and marker colours)
|
|
40
|
+
--no-entity-geometry do not read the jar's code for entity model geometry
|
|
37
41
|
--cache-dir <dir> jar download cache (default ~/.rendermite)
|
|
38
42
|
`;
|
|
39
43
|
/**
|
|
@@ -93,6 +97,18 @@ async function runBlocksCli(argv) {
|
|
|
93
97
|
type: "boolean",
|
|
94
98
|
default: false
|
|
95
99
|
},
|
|
100
|
+
"no-items": {
|
|
101
|
+
type: "boolean",
|
|
102
|
+
default: false
|
|
103
|
+
},
|
|
104
|
+
"no-entities": {
|
|
105
|
+
type: "boolean",
|
|
106
|
+
default: false
|
|
107
|
+
},
|
|
108
|
+
"no-entity-geometry": {
|
|
109
|
+
type: "boolean",
|
|
110
|
+
default: false
|
|
111
|
+
},
|
|
96
112
|
"help": {
|
|
97
113
|
type: "boolean",
|
|
98
114
|
short: "h",
|
|
@@ -115,12 +131,15 @@ async function runBlocksCli(argv) {
|
|
|
115
131
|
}
|
|
116
132
|
const cacheDir = values["cache-dir"] ?? path.join(os.homedir(), ".rendermite");
|
|
117
133
|
let resources;
|
|
134
|
+
let classes = null;
|
|
118
135
|
if (values.version) {
|
|
119
136
|
console.log(`Fetching client jar for ${values.version}…`);
|
|
137
|
+
const jar = await downloadClientJar(values.version, cacheDir);
|
|
120
138
|
resources = await prepareVersionResources({
|
|
121
139
|
version: values.version,
|
|
122
|
-
jar
|
|
140
|
+
jar
|
|
123
141
|
});
|
|
142
|
+
if (!values["no-entity-geometry"]) classes = new JarClassReader(jar);
|
|
124
143
|
} else {
|
|
125
144
|
const managers = (values.assets ?? []).map((root) => new FolderResourceManager(root));
|
|
126
145
|
resources = managers.length === 1 ? managers[0] : new LayeredResourceManager(managers);
|
|
@@ -146,16 +165,24 @@ async function runBlocksCli(argv) {
|
|
|
146
165
|
namespaces,
|
|
147
166
|
padding: sizes.padding,
|
|
148
167
|
maxPageSize: sizes.maxPageSize,
|
|
168
|
+
items: !values["no-items"],
|
|
169
|
+
entities: !values["no-entities"],
|
|
170
|
+
classes: classes ?? void 0,
|
|
171
|
+
cacheDir,
|
|
149
172
|
onProgress: (stage, done, total) => {
|
|
150
173
|
if (done === total || done % 250 === 0) console.log(`${stage}: ${done}/${total}`);
|
|
151
174
|
}
|
|
152
175
|
});
|
|
153
176
|
console.log(`\n${result.blocks} blocks, ${result.models} models, ${result.sprites} sprites across ${result.pages} atlas page(s); ${result.writtenFiles} files written.`);
|
|
177
|
+
console.log(result.items > 0 ? `${result.items} flat items described in items.json.` : "No flat item sprites exported.");
|
|
178
|
+
console.log(result.entities > 0 ? `${result.entities} entity types described in entities.json.` : "No entity types exported.");
|
|
179
|
+
console.log(result.entityModels > 0 ? `${result.entityModels} entity models recovered from the jar's own code.` : "No entity geometry recovered.");
|
|
154
180
|
console.log(result.biomes > 0 ? `${result.biomes} biomes described in biomes.json.` : "No biomes to describe; biomes.json not written.");
|
|
155
181
|
console.log(`${result.failures.length} entries in failures.json.`);
|
|
156
182
|
return 0;
|
|
157
183
|
} finally {
|
|
158
184
|
await closeMods?.();
|
|
185
|
+
await classes?.close();
|
|
159
186
|
}
|
|
160
187
|
}
|
|
161
188
|
//#endregion
|
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as builtinPackPath, t as bedCompatPath } from "./builtin-WkWjATeh.js";
|
|
3
3
|
import { n as LayeredResourceManager, t as FolderResourceManager } from "./manager-BNibYkmI.js";
|
|
4
|
-
import { t as curatedModelOverrides } from "./models-CZjCOjs4.js";
|
|
5
|
-
import { n as harvestTintOverrides, t as curatedTintOverrides } from "./tints-C1tT6pKk.js";
|
|
6
4
|
import { t as JarResourceManager } from "./jar-W2cV2ZVO.js";
|
|
5
|
+
import { t as curatedModelOverrides } from "./models-CZjCOjs4.js";
|
|
6
|
+
import { n as harvestTintOverrides, t as curatedTintOverrides } from "./tints-BspVCz2G.js";
|
|
7
7
|
import { t as downloadClientJar } from "./download-1wAfrGKx.js";
|
|
8
|
-
import { a as prepareVersionResources, i as eraForVersion, n as GEOMETRY_DONOR_VERSIONS } from "./prepare-
|
|
9
|
-
import { t as runBlocksCli } from "./cli-
|
|
10
|
-
import { t as run } from "./run-
|
|
8
|
+
import { a as prepareVersionResources, i as eraForVersion, n as GEOMETRY_DONOR_VERSIONS } from "./prepare-D49Gu4Lv.js";
|
|
9
|
+
import { t as runBlocksCli } from "./cli-BSKnXBPr.js";
|
|
10
|
+
import { t as run } from "./run-BQJkqc5f.js";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import os from "node:os";
|
|
13
13
|
import { parseArgs } from "node:util";
|
|
@@ -99,4 +99,4 @@ async function resolveItem(resources, id, properties) {
|
|
|
99
99
|
throw new ItemResolutionError(`No item definition or item model for ${id}`);
|
|
100
100
|
}
|
|
101
101
|
//#endregion
|
|
102
|
-
export { discoverItems as n,
|
|
102
|
+
export { resolveItem as i, discoverItems as n, langRegistry as r, ItemResolutionError as t };
|
|
@@ -17,6 +17,13 @@ interface ItemDiscoveryOptions {
|
|
|
17
17
|
filterUntranslatedModels?: boolean;
|
|
18
18
|
}
|
|
19
19
|
declare function discoverItems(resources: ResourceManager, namespace: string, options?: ItemDiscoveryOptions): Promise<DiscoveredItem[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Item/block names with a translation key in the namespace's en_us.json — the
|
|
22
|
+
* closest thing to the game's item registry a jar contains (datagen writes a
|
|
23
|
+
* key per registered item). Null (no gating) when the namespace has no modern
|
|
24
|
+
* lang file or no item/block keys: 1.7.10-era mods use unkeyed .lang files.
|
|
25
|
+
*/
|
|
26
|
+
declare function langRegistry(resources: ResourceManager, namespace: string): Promise<Set<string> | null>;
|
|
20
27
|
/**
|
|
21
28
|
* Resolve an item id to the models to render. Definitions are evaluated with
|
|
22
29
|
* static-icon properties; plain model items render the model with no tints
|
|
@@ -24,4 +31,4 @@ declare function discoverItems(resources: ResourceManager, namespace: string, op
|
|
|
24
31
|
*/
|
|
25
32
|
declare function resolveItem(resources: ResourceManager, id: string, properties?: ItemProperties): Promise<ItemRenderInstruction[]>;
|
|
26
33
|
//#endregion
|
|
27
|
-
export {
|
|
34
|
+
export { langRegistry as a, discoverItems as i, ItemDiscoveryOptions as n, resolveItem as o, ItemResolutionError as r, DiscoveredItem as t };
|