@nodecraft/rendermite 1.5.0 → 1.6.1
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 +2 -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 +45 -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 +1 -1
- package/dist/blocks/obj-mesh.js +1 -1
- package/dist/blocks/pack-format.d.ts +2 -2
- package/dist/blocks/sprite-sheet.d.ts +1 -1
- package/dist/classfile-BdLIk4Pe.d.ts +67 -0
- package/dist/classfile-Bo7FUrrD.js +287 -0
- package/dist/{cli-DMTaIbDI.js → cli-D2KJc_yl.js} +28 -4
- package/dist/cli.js +4 -4
- 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 +2 -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-DutR9Hdz.js → entity-fallback-Bth0fa7m.js} +1 -1
- package/dist/entity-geo-B2CkuMWx.js +100 -0
- package/dist/entity-models-_EZ3PVtN.js +127 -0
- package/dist/{export-wvt0Fryo.d.ts → export-B8tPsf4K.d.ts} +22 -1
- package/dist/{export-sadR0pWp.js → export-BfEIwSxY.js} +93 -1
- package/dist/geo-CmjrXu0G.d.ts +59 -0
- package/dist/{geo-BC8jtG5Q.js → geo-Desq-gRC.js} +6 -5
- package/dist/geo-model-Bo1gpEwX.js +163 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -8
- package/dist/inherit-ByHjOJX3.js +77 -0
- package/dist/jar-classes-CSRrPAUy.d.ts +41 -0
- package/dist/jar-classes-DCtELr1i.js +102 -0
- package/dist/link-5GmBLTzk.js +355 -0
- package/dist/mappings-BEPVaiwE.js +139 -0
- package/dist/mappings-DxX4KoZl.d.ts +75 -0
- package/dist/merge-NDYxpmL8.js +48 -0
- package/dist/model-PnQ4gV0-.d.ts +49 -0
- package/dist/model-bytecode-gWy5_uCj.js +742 -0
- package/dist/model-code-1Vuk-zj_.js +49 -0
- package/dist/model-code-BY44ao27.d.ts +16 -0
- package/dist/mods/prepare.js +1 -1
- package/dist/{obj-BaGvPUbb.js → obj-CJHEHpki.js} +5 -5
- package/dist/{obj-mesh-CazmV8ya.js → obj-mesh-JwPkZEWL.js} +1 -1
- package/dist/{pack-format-oRExIeD3.d.ts → pack-format-QcVFxG_b.d.ts} +100 -1
- package/dist/pack.d.ts +1 -1
- package/dist/{pipeline-AAfohoHU.js → pipeline-BUIMzMzg.js} +4 -4
- 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-UKgVb-kW.js → run-BQJkqc5f.js} +2 -2
- package/dist/run.js +1 -1
- package/dist/versions/prepare.js +1 -1
- package/dist/workers/render-worker.js +2 -2
- package/package.json +1 -1
- package/dist/{descriptor-D7VKgeGT.js → descriptor-JyXhfd-c.js} +1 -1
- package/dist/{face-CMJ3b3Ae.js → face-B2JjWT46.js} +1 -1
- package/dist/{prepare-8LswFoS-.js → prepare-D49Gu4Lv.js} +1 -1
- package/dist/{prepare-B_tRy9lB.js → prepare-Myd_ec4v.js} +1 -1
package/README.md
CHANGED
|
@@ -76,6 +76,8 @@ blocks/1.21.8/
|
|
|
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
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
|
|
79
81
|
failures.json # anything not fully handled, with reasons, never silent
|
|
80
82
|
meta.json # version, counts, sha256 of every other file
|
|
81
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-D2KJc_yl.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 };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { a as ResourceManager } from "../manager-exOIcdyx.js";
|
|
2
|
+
import { S as EntityPackModel } from "../pack-format-QcVFxG_b.js";
|
|
3
|
+
import { t as ClassSource } from "../jar-classes-CSRrPAUy.js";
|
|
4
|
+
//#region src/blocks/entity-models.d.ts
|
|
5
|
+
interface EntityGeometryResult {
|
|
6
|
+
/** Model id (the class it came from) → geometry. */
|
|
7
|
+
models: Record<string, EntityPackModel>;
|
|
8
|
+
/** Entity id → model id, for the entity table to point with. */
|
|
9
|
+
modelOf: Map<string, string>;
|
|
10
|
+
/** Entity sheets the models address, to be stitched into the pack's own atlas. */
|
|
11
|
+
spriteIds: Set<string>;
|
|
12
|
+
failures: Array<{
|
|
13
|
+
id: string;
|
|
14
|
+
reason: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
interface CollectEntityGeometryOptions {
|
|
18
|
+
version: string;
|
|
19
|
+
/** Where mappings cache; the same directory the jars do. */
|
|
20
|
+
cacheDir: string;
|
|
21
|
+
classes: ClassSource;
|
|
22
|
+
/** Entity ids to look for, as the registry named them. */
|
|
23
|
+
entityIds: readonly string[];
|
|
24
|
+
/** The sheet each entity resolved to, from the entity registry, keyed by entity id. */
|
|
25
|
+
textureOf: ReadonlyMap<string, string>;
|
|
26
|
+
/**
|
|
27
|
+
* The assets, for the mods whose geometry is not in code at all.
|
|
28
|
+
*
|
|
29
|
+
* A GeckoLib mob ships Blockbench's bedrock format and registers it by resource location, so there
|
|
30
|
+
* is nothing for the interpreter to read; `entity-geo.ts` finds and converts it instead.
|
|
31
|
+
*/
|
|
32
|
+
resources?: ResourceManager;
|
|
33
|
+
onProgress?: (done: number, total: number) => void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Recovers geometry for as many of `entityIds` as the code describes.
|
|
37
|
+
*
|
|
38
|
+
* Mappings are resolved once: downloaded for an obfuscated jar, and the identity for one that is not
|
|
39
|
+
* (from the 26 line the client ships in the clear, and a mod jar never was obfuscated). A version that
|
|
40
|
+
* is obfuscated *and* unmapped — 1.13.x — yields nothing, with the reason recorded once rather than
|
|
41
|
+
* per entity.
|
|
42
|
+
*/
|
|
43
|
+
declare function collectEntityGeometry(options: CollectEntityGeometryOptions): Promise<EntityGeometryResult>;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { CollectEntityGeometryOptions, EntityGeometryResult, collectEntityGeometry };
|
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-B8tPsf4K.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-BfEIwSxY.js";
|
|
2
2
|
export { exportBlockPack };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as ResourceManager } from "../manager-exOIcdyx.js";
|
|
2
2
|
import { i as TextureLoader } from "../loader-DUlx29PC.js";
|
|
3
3
|
import { t as ModelLoader } from "../loader-DSir1-P0.js";
|
|
4
|
-
import {
|
|
4
|
+
import { w as ItemPackEntry } from "../pack-format-QcVFxG_b.js";
|
|
5
5
|
//#region src/blocks/item-sprites.d.ts
|
|
6
6
|
interface ItemSpriteFailure {
|
|
7
7
|
id: string;
|
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 { _ as
|
|
2
|
-
export { BlockPackAtlasFile, BlockPackAtlasPage, BlockPackBiomesFile, BlockPackBlockState, BlockPackBlockStatesFile, BlockPackElement, BlockPackFace, BlockPackItemsFile, BlockPackMetaFile, BlockPackModel, BlockPackModelsFile, BlockPackRenderLayer, BlockPackSprite, BlockPackSpriteFrame, BlockPackTintsFile, BlockPackVariant, ItemPackEntry, ItemPackLayer };
|
|
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 };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as TextureLoader, r as Texture } from "../loader-DUlx29PC.js";
|
|
2
2
|
import { i as PackedPage } from "../atlas-pack-D8745_wo.js";
|
|
3
|
-
import {
|
|
3
|
+
import { h as BlockPackSprite, m as BlockPackRenderLayer } from "../pack-format-QcVFxG_b.js";
|
|
4
4
|
//#region src/blocks/sprite-sheet.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* Vanilla's own id for the missing-texture sprite. A face whose texture does
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
/** A `methodHandle`'s target: an index of a `methodref`, not of a `nameAndType`. */
|
|
26
|
+
referenceIndex?: number;
|
|
27
|
+
/** An `invokeDynamic`'s row in the `BootstrapMethods` attribute. */
|
|
28
|
+
bootstrapIndex?: number;
|
|
29
|
+
}
|
|
30
|
+
interface MethodInfo {
|
|
31
|
+
name: string;
|
|
32
|
+
descriptor: string;
|
|
33
|
+
accessFlags: number;
|
|
34
|
+
/** Raw bytecode of the `Code` attribute, absent on an abstract or native method. */
|
|
35
|
+
code?: Uint8Array;
|
|
36
|
+
}
|
|
37
|
+
interface ClassFile {
|
|
38
|
+
thisClass: string;
|
|
39
|
+
superClass: string | null;
|
|
40
|
+
constants: Array<Constant | null>;
|
|
41
|
+
methods: MethodInfo[];
|
|
42
|
+
/** A pool entry as text, for a `utf8` or anything that resolves to one. */
|
|
43
|
+
utf8: (index: number) => string;
|
|
44
|
+
/** `owner.name:descriptor` for a field or method reference. */
|
|
45
|
+
reference: (index: number) => {
|
|
46
|
+
owner: string;
|
|
47
|
+
name: string;
|
|
48
|
+
descriptor: string;
|
|
49
|
+
} | null;
|
|
50
|
+
/** The value an `ldc` of this index pushes: a number for numeric constants, a string for `string`. */
|
|
51
|
+
literal: (index: number) => string | number | bigint | null;
|
|
52
|
+
/**
|
|
53
|
+
* The method a lambda actually runs, for an `invokedynamic`'s pool index.
|
|
54
|
+
*
|
|
55
|
+
* A lambda compiles to a call through `LambdaMetafactory` with the real body in a synthetic method,
|
|
56
|
+
* so this is two hops: the pool entry names a row of the `BootstrapMethods` attribute, and that
|
|
57
|
+
* row's second argument is a method handle pointing at the body.
|
|
58
|
+
*/
|
|
59
|
+
lambdaTarget: (index: number) => {
|
|
60
|
+
owner: string;
|
|
61
|
+
name: string;
|
|
62
|
+
descriptor: string;
|
|
63
|
+
} | null;
|
|
64
|
+
}
|
|
65
|
+
declare function parseClassFile(bytes: Uint8Array): ClassFile;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { parseClassFile as a, MethodInfo as i, Constant as n, ConstantTag as r, ClassFile as t };
|
|
@@ -0,0 +1,287 @@
|
|
|
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
|
+
referenceIndex: 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": constants.push({
|
|
164
|
+
tag,
|
|
165
|
+
bootstrapIndex: reader.u2(),
|
|
166
|
+
nameAndTypeIndex: reader.u2()
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return constants;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Skips an attribute table, keeping the two that say what a method does: `Code`, and the class-level
|
|
174
|
+
* `BootstrapMethods` that a lambda's real body is reachable through.
|
|
175
|
+
*/
|
|
176
|
+
function readAttributes(reader, utf8, bootstraps) {
|
|
177
|
+
let code;
|
|
178
|
+
const count = reader.u2();
|
|
179
|
+
for (let index = 0; index < count; index++) {
|
|
180
|
+
const name = utf8(reader.u2());
|
|
181
|
+
const length = reader.u4();
|
|
182
|
+
if (name === "BootstrapMethods" && bootstraps) {
|
|
183
|
+
const rows = reader.u2();
|
|
184
|
+
for (let row = 0; row < rows; row++) {
|
|
185
|
+
const handleIndex = reader.u2();
|
|
186
|
+
const argumentCount = reader.u2();
|
|
187
|
+
const argumentIndexes = [];
|
|
188
|
+
for (let argument = 0; argument < argumentCount; argument++) argumentIndexes.push(reader.u2());
|
|
189
|
+
bootstraps.push({
|
|
190
|
+
handleIndex,
|
|
191
|
+
argumentIndexes
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (name !== "Code") {
|
|
197
|
+
reader.skip(length);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
reader.skip(4);
|
|
201
|
+
code = reader.take(reader.u4());
|
|
202
|
+
reader.skip(reader.u2() * 8);
|
|
203
|
+
readAttributes(reader, utf8);
|
|
204
|
+
}
|
|
205
|
+
return code;
|
|
206
|
+
}
|
|
207
|
+
function parseClassFile(bytes) {
|
|
208
|
+
const reader = new Reader(bytes);
|
|
209
|
+
if (reader.u4() !== 3405691582) throw new Error("Not a class file: bad magic");
|
|
210
|
+
reader.skip(4);
|
|
211
|
+
const constants = readConstantPool(reader);
|
|
212
|
+
const utf8 = (index) => {
|
|
213
|
+
const entry = constants[index];
|
|
214
|
+
if (!entry) return "";
|
|
215
|
+
if (entry.tag === "utf8") return String(entry.value);
|
|
216
|
+
const next = entry.nameIndex ?? entry.stringIndex ?? entry.descriptorIndex;
|
|
217
|
+
return next === void 0 ? "" : utf8(next);
|
|
218
|
+
};
|
|
219
|
+
reader.skip(2);
|
|
220
|
+
const thisClass = utf8(reader.u2());
|
|
221
|
+
const superIndex = reader.u2();
|
|
222
|
+
const superClass = superIndex === 0 ? null : utf8(superIndex);
|
|
223
|
+
reader.skip(reader.u2() * 2);
|
|
224
|
+
const fieldCount = reader.u2();
|
|
225
|
+
for (let index = 0; index < fieldCount; index++) {
|
|
226
|
+
reader.skip(6);
|
|
227
|
+
readAttributes(reader, utf8);
|
|
228
|
+
}
|
|
229
|
+
const methods = [];
|
|
230
|
+
const methodCount = reader.u2();
|
|
231
|
+
for (let index = 0; index < methodCount; index++) {
|
|
232
|
+
const accessFlags = reader.u2();
|
|
233
|
+
const name = utf8(reader.u2());
|
|
234
|
+
const descriptor = utf8(reader.u2());
|
|
235
|
+
const code = readAttributes(reader, utf8);
|
|
236
|
+
methods.push({
|
|
237
|
+
name,
|
|
238
|
+
descriptor,
|
|
239
|
+
accessFlags,
|
|
240
|
+
code
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
const bootstraps = [];
|
|
244
|
+
readAttributes(reader, utf8, bootstraps);
|
|
245
|
+
const reference = (index) => {
|
|
246
|
+
const entry = constants[index];
|
|
247
|
+
if (!entry || entry.classIndex === void 0 || entry.nameAndTypeIndex === void 0) return null;
|
|
248
|
+
const nameAndType = constants[entry.nameAndTypeIndex];
|
|
249
|
+
if (!nameAndType?.nameIndex || !nameAndType.descriptorIndex) return null;
|
|
250
|
+
return {
|
|
251
|
+
owner: utf8(entry.classIndex),
|
|
252
|
+
name: utf8(nameAndType.nameIndex),
|
|
253
|
+
descriptor: utf8(nameAndType.descriptorIndex)
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
const literal = (index) => {
|
|
257
|
+
const entry = constants[index];
|
|
258
|
+
if (!entry) return null;
|
|
259
|
+
if (entry.tag === "string") return utf8(index);
|
|
260
|
+
return entry.value ?? null;
|
|
261
|
+
};
|
|
262
|
+
const lambdaTarget = (index) => {
|
|
263
|
+
const entry = constants[index];
|
|
264
|
+
const row = entry?.bootstrapIndex === void 0 ? void 0 : bootstraps[entry.bootstrapIndex];
|
|
265
|
+
if (!row) return null;
|
|
266
|
+
for (const argument of row.argumentIndexes) {
|
|
267
|
+
const handle = constants[argument];
|
|
268
|
+
if (handle?.tag === "methodHandle" && handle.referenceIndex !== void 0) {
|
|
269
|
+
const target = reference(handle.referenceIndex);
|
|
270
|
+
if (target) return target;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return null;
|
|
274
|
+
};
|
|
275
|
+
return {
|
|
276
|
+
thisClass,
|
|
277
|
+
superClass,
|
|
278
|
+
constants,
|
|
279
|
+
methods,
|
|
280
|
+
utf8,
|
|
281
|
+
reference,
|
|
282
|
+
literal,
|
|
283
|
+
lambdaTarget
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
//#endregion
|
|
287
|
+
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 { n as
|
|
3
|
+
import { t as exportBlockPack } from "./export-BfEIwSxY.js";
|
|
4
|
+
import { n as layeredClasses, t as JarClassReader } from "./jar-classes-DCtELr1i.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";
|
|
@@ -35,6 +36,8 @@ Options:
|
|
|
35
36
|
--builtin <dir> override the vendored geometry pack
|
|
36
37
|
--no-builtin do not substitute geometry for code-drawn blocks
|
|
37
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
|
|
38
41
|
--cache-dir <dir> jar download cache (default ~/.rendermite)
|
|
39
42
|
`;
|
|
40
43
|
/**
|
|
@@ -98,6 +101,14 @@ async function runBlocksCli(argv) {
|
|
|
98
101
|
type: "boolean",
|
|
99
102
|
default: false
|
|
100
103
|
},
|
|
104
|
+
"no-entities": {
|
|
105
|
+
type: "boolean",
|
|
106
|
+
default: false
|
|
107
|
+
},
|
|
108
|
+
"no-entity-geometry": {
|
|
109
|
+
type: "boolean",
|
|
110
|
+
default: false
|
|
111
|
+
},
|
|
101
112
|
"help": {
|
|
102
113
|
type: "boolean",
|
|
103
114
|
short: "h",
|
|
@@ -120,12 +131,15 @@ async function runBlocksCli(argv) {
|
|
|
120
131
|
}
|
|
121
132
|
const cacheDir = values["cache-dir"] ?? path.join(os.homedir(), ".rendermite");
|
|
122
133
|
let resources;
|
|
134
|
+
let classes = null;
|
|
123
135
|
if (values.version) {
|
|
124
136
|
console.log(`Fetching client jar for ${values.version}…`);
|
|
137
|
+
const jar = await downloadClientJar(values.version, cacheDir);
|
|
125
138
|
resources = await prepareVersionResources({
|
|
126
139
|
version: values.version,
|
|
127
|
-
jar
|
|
140
|
+
jar
|
|
128
141
|
});
|
|
142
|
+
if (!values["no-entity-geometry"]) classes = new JarClassReader(jar);
|
|
129
143
|
} else {
|
|
130
144
|
const managers = (values.assets ?? []).map((root) => new FolderResourceManager(root));
|
|
131
145
|
resources = managers.length === 1 ? managers[0] : new LayeredResourceManager(managers);
|
|
@@ -141,6 +155,10 @@ async function runBlocksCli(argv) {
|
|
|
141
155
|
closeMods = () => prepared.close();
|
|
142
156
|
for (const { jar, reason } of prepared.rejected) console.error(`Rejected mod jar ${jar}: ${reason}`);
|
|
143
157
|
namespaces = values.namespace?.length ? values.namespace : prepared.namespaces;
|
|
158
|
+
if (!values["no-entity-geometry"]) {
|
|
159
|
+
const modClasses = values.mod.map((jar) => new JarClassReader(jar));
|
|
160
|
+
classes = layeredClasses(classes ? [classes, ...modClasses] : modClasses);
|
|
161
|
+
}
|
|
144
162
|
}
|
|
145
163
|
try {
|
|
146
164
|
const result = await exportBlockPack({
|
|
@@ -152,17 +170,23 @@ async function runBlocksCli(argv) {
|
|
|
152
170
|
padding: sizes.padding,
|
|
153
171
|
maxPageSize: sizes.maxPageSize,
|
|
154
172
|
items: !values["no-items"],
|
|
173
|
+
entities: !values["no-entities"],
|
|
174
|
+
classes: classes ?? void 0,
|
|
175
|
+
cacheDir,
|
|
155
176
|
onProgress: (stage, done, total) => {
|
|
156
177
|
if (done === total || done % 250 === 0) console.log(`${stage}: ${done}/${total}`);
|
|
157
178
|
}
|
|
158
179
|
});
|
|
159
180
|
console.log(`\n${result.blocks} blocks, ${result.models} models, ${result.sprites} sprites across ${result.pages} atlas page(s); ${result.writtenFiles} files written.`);
|
|
160
181
|
console.log(result.items > 0 ? `${result.items} flat items described in items.json.` : "No flat item sprites exported.");
|
|
182
|
+
console.log(result.entities > 0 ? `${result.entities} entity types described in entities.json.` : "No entity types exported.");
|
|
183
|
+
console.log(result.entityModels > 0 ? `${result.entityModels} entity models recovered from the jar's own code.` : "No entity geometry recovered.");
|
|
161
184
|
console.log(result.biomes > 0 ? `${result.biomes} biomes described in biomes.json.` : "No biomes to describe; biomes.json not written.");
|
|
162
185
|
console.log(`${result.failures.length} entries in failures.json.`);
|
|
163
186
|
return 0;
|
|
164
187
|
} finally {
|
|
165
188
|
await closeMods?.();
|
|
189
|
+
await classes?.close();
|
|
166
190
|
}
|
|
167
191
|
}
|
|
168
192
|
//#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 JarResourceManager } from "./jar-W2cV2ZVO.js";
|
|
4
5
|
import { t as curatedModelOverrides } from "./models-CZjCOjs4.js";
|
|
5
6
|
import { n as harvestTintOverrides, t as curatedTintOverrides } from "./tints-BspVCz2G.js";
|
|
6
|
-
import { t as JarResourceManager } from "./jar-W2cV2ZVO.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-D2KJc_yl.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";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { r as ExtractedModel } from "../model-PnQ4gV0-.js";
|
|
2
|
+
import { t as ParsedGeo } from "../geo-CmjrXu0G.js";
|
|
3
|
+
//#region src/entities/geo-model.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Converts one parsed `.geo.json` into a model.
|
|
6
|
+
*
|
|
7
|
+
* Bones are a flat list joined by `parent` name, so the tree is rebuilt here. A bone whose parent is
|
|
8
|
+
* missing becomes a root rather than being dropped, and a cube carrying its own rotation becomes a part
|
|
9
|
+
* of its own: `Cube` has nowhere to put a rotation, and 18% of the corpus's cubes have one.
|
|
10
|
+
*/
|
|
11
|
+
declare function geoToModel(geo: ParsedGeo): ExtractedModel;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { geoToModel };
|