backup with fully working version, only one texture renders

This commit is contained in:
2026-08-04 17:49:14 -05:00
parent ac152ab19d
commit da5655293a
61 changed files with 49377 additions and 1117 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@@ -0,0 +1,89 @@
// packs_bootstrap.js — injected into the vendored Blockbench app (same origin).
// Loads the GeckoLib + Multi Actor Animator plugins and bridges model/texture
// loading from the parent page via postMessage.
(function () {
if (window.PacksBB) return;
function waitFor(fn, timeout) {
return new Promise((resolve) => {
const start = Date.now();
const iv = setInterval(() => {
if (fn()) { clearInterval(iv); resolve(true); }
else if (Date.now() - start > timeout) { clearInterval(iv); resolve(false); }
}, 100);
});
}
function notify(type, payload) {
if (window.parent && window.parent !== window) {
window.parent.postMessage(Object.assign({ type: 'packs-' + type }, payload || {}), window.location.origin);
}
}
async function loadPlugin(path, id) {
if (Plugins.registered[id]) {
// already registered (persisted from a previous session) — ensure active
const existing = Plugins.registered[id];
if (existing.installed && !existing.disabled && typeof existing.onload === 'function' && existing.source === 'file') {
return existing;
}
}
const code = await (await fetch(path, { cache: 'no-store' })).text();
if (!code || code.length < 20) throw new Error('empty plugin: ' + path);
const inst = new Plugin();
await inst.loadFromFile({ path: path, content: code }, true);
return inst;
}
async function openModel(msg) {
await waitFor(() => typeof loadModelFile === 'function', 15000);
const name = msg.name || 'model';
await loadModelFile({ content: JSON.stringify(msg.geo), name: name, path: name });
// Give the format importer a beat, then load the textures and let
// Blockbench's own default-texture logic apply them.
await new Promise((r) => setTimeout(r, 800));
for (const t of (msg.textures || [])) {
try {
const tex = new Texture({ name: t.name || 'texture', folder: 'entity' });
if (t.dataUrl) {
await tex.fromDataURL(t.dataUrl);
} else if (t.url) {
await tex.fromPath(t.url);
}
tex.add(false);
} catch (e) {
console.error('packs texture load failed', t && t.name, e);
}
}
await new Promise((r) => setTimeout(r, 400));
notify('model-open', { name: name });
}
window.addEventListener('message', (e) => {
if (!e.data || e.data.type !== 'packs-open-model') return;
openModel(e.data).then(
() => {},
(err) => {
console.error('packs-open-model failed', err);
notify('model-error', { name: e.data.name || '', error: String(err) });
}
);
});
async function boot() {
window.confirm = () => true;
const ok = await waitFor(() => window.Blockbench && window.Blockbench.setup_successful && window.Plugin && typeof loadModelFile === 'function', 30000);
if (!ok) { notify('error', { error: 'Blockbench did not initialize' }); return; }
try {
await loadPlugin('plugins/geckolib/geckolib.js', 'geckolib');
await loadPlugin('plugins/MultiactorEditor/MultiactorEditor.js', 'MultiactorEditor');
} catch (e) {
console.error('packs plugin load failed', e);
notify('plugin-error', { error: String(e) });
}
window.PacksBB = { ready: true, plugins: ['geckolib', 'MultiactorEditor'] };
notify('bb-ready', {});
}
boot();
})();