Upload via GUI (18 Dateien)

This commit is contained in:
Git Manager GUI
2026-08-01 07:43:21 +02:00
parent 1978358f21
commit afe02f81be
10 changed files with 721 additions and 27 deletions
+121
View File
@@ -0,0 +1,121 @@
'use strict';
/*
* icons.js echte Minecraft-Item-Icons
* -------------------------------------
* Die Original-Texturen werden aus der bereits heruntergeladenen client.jar
* des Nutzers extrahiert (also aus seinen eigenen Spieldateien) und lokal
* als Icons abgelegt. Es werden keine fremden Assets mitgeliefert.
*/
const fs = require('fs');
const path = require('path');
const forge = require('./forge');
// Auswahl gut erkennbarer 16x16-Texturen (Pfade im client.jar)
const WANTED = [
['grass', 'block/grass_block_side.png', 'Grasblock'],
['dirt', 'block/dirt.png', 'Erde'],
['stone', 'block/cobblestone.png', 'Bruchstein'],
['planks', 'block/oak_planks.png', 'Holzbretter'],
['tnt', 'block/tnt_side.png', 'TNT'],
['obsidian', 'block/obsidian.png', 'Obsidian'],
['netherrack', 'block/netherrack.png', 'Netherrack'],
['crafting', 'block/crafting_table_front.png', 'Werkbank'],
['furnace', 'block/furnace_front.png', 'Ofen'],
['bookshelf', 'block/bookshelf.png', 'Bücherregal'],
['diamondblock', 'block/diamond_block.png', 'Diamantblock'],
['goldblock', 'block/gold_block.png', 'Goldblock'],
['emeraldblock', 'block/emerald_block.png', 'Smaragdblock'],
['redstoneblock', 'block/redstone_block.png', 'Redstoneblock'],
['diamond', 'item/diamond.png', 'Diamant'],
['emerald', 'item/emerald.png', 'Smaragd'],
['gold', 'item/gold_ingot.png', 'Goldbarren'],
['iron', 'item/iron_ingot.png', 'Eisenbarren'],
['redstone', 'item/redstone.png', 'Redstone'],
['coal', 'item/coal.png', 'Kohle'],
['sword', 'item/diamond_sword.png', 'Diamantschwert'],
['pickaxe', 'item/diamond_pickaxe.png', 'Diamantspitzhacke'],
['axe', 'item/diamond_axe.png', 'Diamantaxt'],
['bow', 'item/bow.png', 'Bogen'],
['apple', 'item/apple.png', 'Apfel'],
['goldenapple', 'item/golden_apple.png', 'Goldener Apfel'],
['book', 'item/book.png', 'Buch'],
['enchantedbook', 'item/enchanted_book.png', 'Verzaubertes Buch'],
['map', 'item/map.png', 'Karte'],
['star', 'item/nether_star.png', 'Netherstern'],
['endereye', 'item/ender_eye.png', 'Enderauge'],
['enderpearl', 'item/ender_pearl.png', 'Enderperle'],
['blaze', 'item/blaze_powder.png', 'Lohenstaub'],
['xp', 'item/experience_bottle.png', 'Erfahrungsfläschchen'],
['cake', 'item/cake.png', 'Kuchen'],
['bucket', 'item/water_bucket.png', 'Wassereimer'],
['lava', 'item/lava_bucket.png', 'Lavaeimer'],
['tnt_item', 'item/gunpowder.png', 'Schwarzpulver'],
];
// sucht die neueste vorhandene client.jar (auch im Datenordner vor der Umbenennung)
function findClientJars(sharedDirs) {
const jars = [];
for (const shared of sharedDirs) {
const vdir = path.join(shared, 'versions');
if (!fs.existsSync(vdir)) continue;
for (const entry of fs.readdirSync(vdir, { withFileTypes: true })) {
if (!entry.isDirectory()) continue;
const jar = path.join(vdir, entry.name, entry.name + '.jar');
try {
if (fs.existsSync(jar) && fs.statSync(jar).size > 1024 * 1024) {
jars.push({ version: entry.name, path: jar, mtime: fs.statSync(jar).mtimeMs });
}
} catch { /* überspringen */ }
}
}
jars.sort((a, b) => b.mtime - a.mtime);
return jars;
}
/*
* Extrahiert die Texturen in <outDir>. Gibt die Liste der gefundenen Icons zurück.
*/
function extractIcons(sharedDirs, outDir) {
const jars = findClientJars(sharedDirs);
if (!jars.length) return { ok: false, reason: 'no-jar' };
const jar = jars[0];
const buf = fs.readFileSync(jar.path);
const zip = forge.readZipIndex(buf);
fs.mkdirSync(outDir, { recursive: true });
const found = [];
for (const [key, rel, label] of WANTED) {
const entry = zip['assets/minecraft/textures/' + rel];
if (!entry) continue;
try {
const png = forge.readZipEntry(buf, entry);
// sehr große Dateien überspringen (animierte Texturen sind gestreckt)
if (png.length > 64 * 1024) continue;
const dest = path.join(outDir, key + '.png');
fs.writeFileSync(dest, png);
found.push({ key, label, file: dest });
} catch { /* Textur überspringen */ }
}
return { ok: true, version: jar.version, count: found.length, icons: found };
}
// liest die extrahierten Icons als data:-URIs (für die Anzeige)
function listIcons(outDir) {
if (!fs.existsSync(outDir)) return [];
const labels = Object.fromEntries(WANTED.map(([k, , l]) => [k, l]));
return fs.readdirSync(outDir)
.filter((f) => f.endsWith('.png'))
.map((f) => {
const key = path.basename(f, '.png');
try {
const data = fs.readFileSync(path.join(outDir, f)).toString('base64');
return { key, label: labels[key] || key, dataUri: 'data:image/png;base64,' + data };
} catch { return null; }
})
.filter(Boolean);
}
module.exports = { extractIcons, listIcons, findClientJars, WANTED };