Skip to content

Commit

Permalink
Merge pull request #37 from eaglerforge/main
Browse files Browse the repository at this point in the history
keygen module
  • Loading branch information
ZXMushroom63 authored Dec 1, 2024
2 parents acc4df7 + 81e31e4 commit 403d41d
Show file tree
Hide file tree
Showing 14 changed files with 346 additions and 47 deletions.
6 changes: 4 additions & 2 deletions docs/apidoc/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ Events broadcast data for use in mods.
- `frame`:
- Called just when a frame is rendered on the client.
- Event object is blank.


- `render`:
- Called when 3D is rendered.
- Event object is has one property:
- `partialTicks`: number representing the fraction of ticks passed at this frame.
### Server Side Events
Can only be used in the context of the dedicated server. More: [DedicatedServerDocumentation](dedicatedserver.md)
- `serverstart`:
Expand Down
9 changes: 6 additions & 3 deletions docs/apidoc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,16 @@ The global object has the following properties:
- Once the dedicated server worker has started, it is unuseable.
- More: [DedicatedServerDocumentation](dedicatedserver.md)
- `ModAPI.meta`
- This object is used to register metadata for mods such as their title, credits, icon and description.
- This module is used to register metadata for mods such as their title, credits, icon and description.
- More: [MetaDocumentation](meta.md)
- `ModAPI.array`
- This object is used to interact and create arrays easily.
- This module is used to interact and create arrays easily.
- More: [ArrayDocumentation](array.md)
- `ModAPI.keygen`
- This module is used to get IDs for registering blocks and items without hardcoding an ID.
- More: [KeygenDocumentation](keygen.md)
- `ModAPI.resolution`
- This object is used to query information about GUI dimensions, to make drawing to the screen easier, generated when the `frame` event is fired.
- This module is used to query information about GUI dimensions, to make drawing to the screen easier, generated when the `frame` event is fired.
- Deprecated alias (please do not use): `ModAPI.ScaledResolution`
- More: [ArrayDocumentation](array.md)
- `ModAPI.version: String`
Expand Down
8 changes: 8 additions & 0 deletions docs/apidoc/keygen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## ModAPI.keygen
ModAPI.keygen contains the API for getting item and block IDs from a string. It looks at the registries for items and blocks to derive the IDs, so IDs will not be automatically reserved until a block/item is actually registered. Ideally, you'd want to call a keygen method just before registering your block.

Methods:
- `ModAPI.keygen.item(itemId: String) : number`
- Example usage is: `var id = ModAPI.keygen.item("my_example_item");`
- `ModAPI.keygen.block(blockId: String) : number`
- Example usage is: `var id = ModAPI.keygen.block("my_example_block");`
32 changes: 30 additions & 2 deletions docs/tutorials/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
## Mod tutorials with ModAPI



### Beginner

Prerequisites:
- Basic knowledge of JavaScript
- A good code editor (recommended: https://vscode.dev)

### Beginner
Tutorials:
- [Step Hack](step.md)
- [Spider Hack](spider.md)
- [VClip Exploit](comingsoon)
- [VClip Exploit](comingsoon)

### Intermediate
Prerequisites:
- Basic knowledge of JavaScript
- A good code editor (recommended: https://vscode.dev)
- A copy of the eaglercraft workspace (optional, get it at: https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace)

Tutorials:
- [Disable All Particles](comingsoon)
- [/hat mod](comingsoon)
- [/spawnxp command](comingsoon)
- [Slippery Mod](comingsoon)

### Advanced
Prerequisites:
- Basic knowledge of JavaScript
- A good code editor (recommended: https://vscode.dev)
- A copy of the eaglercraft workspace (get it at: https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace)
- Your EaglerForgeInjector processed.html opened in an editor (optional)

Tutorials:
- [Custom Blocks](comingsoon)
- [Custom Items](comingsoon)
- [Timescale Command](comingsoon)
74 changes: 41 additions & 33 deletions examplemods/AsyncSink.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,39 +188,47 @@ ModAPI.meta.credits("By ZXMushroom63");
const objectStore = transaction.objectStore("filesystem");
var object = (await promisifyIDBRequest(objectStore.get(["resourcepacks/manifest.json"])))?.data;
var resourcePackList = object ? JSON.parse(dec.decode(object)) : { resourcePacks: [] };
if (!resourcePackList.resourcePacks.find(x => x.name === "AsyncSinkLib")) {
resourcePackList.resourcePacks.push({
domains: ["minecraft"],
folder: "AsyncSinkLib",
name: "AsyncSinkLib",
timestamp: Date.now()
});
const writeableTransaction = db.transaction(["filesystem"], "readwrite");
const writeableObjectStore = writeableTransaction.objectStore("filesystem");
await promisifyIDBRequest(writeableObjectStore.put({
path: "resourcepacks/manifest.json",
data: enc.encode(JSON.stringify(resourcePackList)).buffer
}));
await promisifyIDBRequest(writeableObjectStore.put({
path: "resourcepacks/AsyncSinkLib/pack.mcmeta",
data: enc.encode(JSON.stringify({
"pack": {
"pack_format": 1,
"description": "AsyncSink Library Resources"
}
})).buffer
}));

var icon = {
path: "resourcepacks/AsyncSinkLib/pack.png",
data: await (await fetch(asyncSinkIcon)).arrayBuffer()
};

const imageTransaction = db.transaction(["filesystem"], "readwrite");
const imageObjectStore = imageTransaction.objectStore("filesystem");

await promisifyIDBRequest(imageObjectStore.put(icon));
var pack = {
domains: ["minecraft", "eagler"],
folder: "AsyncSinkLib",
name: "AsyncSinkLib",
timestamp: Date.now()
};
if (!Array.isArray(resourcePackList.resourcePacks)) {
resourcePackList.resourcePacks = [];
}
if (resourcePackList.resourcePacks.find(x => x.name === "AsyncSinkLib")) {
var idx = resourcePackList.resourcePacks.indexOf(resourcePackList.resourcePacks.find(x => x.name === "AsyncSinkLib"));
resourcePackList.resourcePacks[idx] = pack;
} else {
resourcePackList.resourcePacks.push(pack);
}

const writeableTransaction = db.transaction(["filesystem"], "readwrite");
const writeableObjectStore = writeableTransaction.objectStore("filesystem");
await promisifyIDBRequest(writeableObjectStore.put({
path: "resourcepacks/manifest.json",
data: enc.encode(JSON.stringify(resourcePackList)).buffer
}));
await promisifyIDBRequest(writeableObjectStore.put({
path: "resourcepacks/AsyncSinkLib/pack.mcmeta",
data: enc.encode(JSON.stringify({
"pack": {
"pack_format": 1,
"description": "AsyncSink Library Resources"
}
})).buffer
}));

var icon = {
path: "resourcepacks/AsyncSinkLib/pack.png",
data: await (await fetch(asyncSinkIcon)).arrayBuffer()
};

const imageTransaction = db.transaction(["filesystem"], "readwrite");
const imageObjectStore = imageTransaction.objectStore("filesystem");

await promisifyIDBRequest(imageObjectStore.put(icon));
}

// Client side reminders to enable the AsyncSink Resource Pack
Expand All @@ -235,7 +243,7 @@ ModAPI.meta.credits("By ZXMushroom63");
var resourcePackEntries = ModAPI.mc.mcResourcePackRepository.getRepositoryEntries().getCorrective();
var array = resourcePackEntries.array || [resourcePackEntries.element];
asyncSinkInstallStatus = array.find(x => ModAPI.util.ustr(x.reResourcePack.resourcePackFile.getRef()) === "AsyncSinkLib") ? true : false;
assureAsyncSinkResources();
//assureAsyncSinkResources();
if (asyncSinkInstallStatus) {
installMessage.style.display = "none";
} else {
Expand Down
56 changes: 56 additions & 0 deletions examplemods/arbitrary_model.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examplemods/block_of_steve_advanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function registerSteveClientSide() {
ModAPI.util.str("steve")
);
blockClass.staticMethods.registerBlock0.method(
198, //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.keygen.block("steve"),
ModAPI.util.str("steve"),
block_of_steve
);
Expand Down Expand Up @@ -112,7 +112,7 @@ function registerSteveServerSide() {
ModAPI.util.str("steve")
);
blockClass.staticMethods.registerBlock0.method(
198, //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.keygen.block("steve"), //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.util.str("steve"),
block_of_steve
);
Expand Down
4 changes: 2 additions & 2 deletions examplemods/block_of_steve_simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function registerSteveClientSide() {
ModAPI.util.str("steve")
).$setCreativeTab(creativeBlockTab);
blockClass.staticMethods.registerBlock0.method(
198, //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.keygen.block("steve"), //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.util.str("steve"),
block_of_steve
);
Expand Down Expand Up @@ -97,7 +97,7 @@ function registerSteveServerSide() {
ModAPI.util.str("steve")
).$setCreativeTab(creativeBlockTab);
blockClass.staticMethods.registerBlock0.method(
198, //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.keygen.block("steve"), //use blockid 198. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.util.str("steve"),
block_of_steve
);
Expand Down
42 changes: 42 additions & 0 deletions examplemods/jenny_skin.js

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions examplemods/microphone.js

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions examplemods/render_arbitrary_highpolyskin.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examplemods/unlucky_blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
ModAPI.util.str("unluckiness")
);
blockClass.staticMethods.registerBlock0.method(
544, //use blockid 544. MAKE SURE TO CHANGE IF YOU ARE MAKING A MOD USING THIS, MAXIMUM BLOCK ID IS 4095.
ModAPI.keygen.block("unluckiness"),
ModAPI.util.str("unluckiness"),
block_of_unluckiness
);
Expand Down
2 changes: 1 addition & 1 deletion examplemods/useless_item_example_mod.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
var example_item = (new nmi_ItemExample()).$setUnlocalizedName(
ModAPI.util.str("exampleitem")
);
itemClass.staticMethods.registerItem0.method(432, ModAPI.util.str("exampleitem"), example_item);
itemClass.staticMethods.registerItem0.method(ModAPI.keygen.item("exampleitem"), ModAPI.util.str("exampleitem"), example_item);
ModAPI.items["exampleitem"] = example_item;

return example_item;
Expand Down
35 changes: 34 additions & 1 deletion postinit.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ globalThis.modapi_postinit = "(" + (() => {
ModAPI.meta._versionMap = {};
ModAPI.array = {};

ModAPI.version = "v2.2";
ModAPI.version = "v2.3";
ModAPI.flavour = "injector";
ModAPI.GNU = "terry pratchett";
ModAPI.credits = ["ZXMushroom63", "radmanplays", "Murturtle", "OtterCodes101", "TheIdiotPlays", "OeildeLynx31", "Stpv22"];
Expand Down Expand Up @@ -952,4 +952,37 @@ globalThis.modapi_postinit = "(" + (() => {
ModAPI.events.newEvent(eventName, "patcher");
});
}

function qhash(txt, arr) {
var interval = 4095 - arr.length;
var x = 1;
for (let i = 0; i < txt.length; i++) {
x += txt.charCodeAt(i);
x = x << txt.charCodeAt(i);
x = Math.abs(x);
x = x % interval;
}
var hash = x + arr.length;
while (arr.includes(hash)) {
hash = (hash + 1) % (interval + arr.length);
}
return hash;
}


ModAPI.keygen = {};
var registryNamespaceMethod = ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.util.RegistryNamespaced", "register")];
ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.util.RegistryNamespaced", "register")] = function (...args) {
args[0].$modapi_specmap ||= new Map();
args[0].$modapi_specmap.set(args[2], args[1]);
return registryNamespaceMethod.apply(this, args);
}
ModAPI.keygen.item = function (item) {
var values = [...ModAPI.reflect.getClassById("net.minecraft.item.Item").staticVariables.itemRegistry.$modapi_specmap.values()];
return qhash(item, values);
}
ModAPI.keygen.block = function (block) {
var values = [...ModAPI.reflect.getClassById("net.minecraft.block.Block").staticVariables.blockRegistry.$modapi_specmap.values()];
return qhash(block, values);
}
}).toString() + ")();";

0 comments on commit 403d41d

Please sign in to comment.