From a373b962d0105ec088768ddc2d4725b66ee7fac8 Mon Sep 17 00:00:00 2001 From: D4rkst3r Date: Sat, 22 Aug 2026 23:48:36 +0200 Subject: [PATCH] Beim Hochladen bleibt die Schreibweise -- sie war eine stille Verstuemmelung Der Betreiber setzte in FiveM `inventory:imagepath` auf das Portal, und die meisten Item-Icons blieben leer. Gemessen: WEAPON_COMBATPISTOL.png -> 404 weapon_combatpistol.png -> 200 ox_inventory fragt Item-Bilder unter dem EXAKTEN Item-Namen ab; seine Waffen heissen WEAPON_*. Der Dienst laeuft auf Linux, dort ist die Schreibweise ein Unterschied. Zur Gegenprobe die mitgelieferten Bilder von ox_inventory selbst: 113 von 198 sind grossgeschrieben. Die Ursache lag hier: `zaehmen()` machte beim Hochladen per Fenster jeden Namen klein -- "vorhersagbar". Fuer die ZEICHEN war das richtig (Leerzeichen, Klammern, Umlaute haben in einer Adresse nichts verloren), fuer die SCHREIBWEISE war es nie noetig: checkPath erlaubt [A-Za-z0-9] seit jeher, und in einer URL ist ein Grossbuchstabe kein Problem. Also bleibt die Schreibweise jetzt stehen. Umlaute werden weiter ersetzt, nun in beiden Formen -- sonst wuerde aus "Gruen.png" ein "gr-n.png", dieselbe stille Verstuemmelung eine Ebene tiefer. Die ENDUNG bleibt klein: daran haengt nur der Dateityp, und ".PNG" waere eine Adresse, die niemand so tippt. Dazu 109 vorhandene Bilder umbenannt (ueber moveFile, damit Vorschau und WebP mitwandern; jede Umbenennung steht im Ereignisprotokoll). Vorher: 0 Kollisionen im Trockenlauf. Nachher gemessen: WEAPON_COMBATPISTOL 200, und 156 von 226 Items haben ein exakt passendes Bild statt 47. EIGENER FEHLER, DER DAS VERZOEGERT HAT: mein erster Abgleich verglich beide Seiten kleingeschrieben und hat damit genau den Unterschied wegnormalisiert, auf den es ankam -- ich meldete 56 leere Felder statt 174. Eine Pruefung, die das Falsche misst, ist schlimmer als keine. Co-Authored-By: Claude Opus 5 --- fehlende-item-bilder.txt | 62 ++++++++++++++++++++++++++++++++++++++++ server/src/storage.ts | 36 +++++++++++++++++++---- 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 fehlende-item-bilder.txt diff --git a/fehlende-item-bilder.txt b/fehlende-item-bilder.txt new file mode 100644 index 0000000..2da08ed --- /dev/null +++ b/fehlende-item-bilder.txt @@ -0,0 +1,62 @@ +# Items ohne Bild -- gemessen am 22.08.2026 +# Abgleich: 226 Item-Namen aus den FiveM-Resourcen gegen 3685 Bilder in media/items + +## Name passt zu keiner Datei (49) +at_compensator +at_scope_macro +at_skin_ballas +at_skin_blagueurs +at_skin_bodyguard +at_skin_boom +at_skin_brushstroke +at_skin_bulletholes +at_skin_burgershot +at_skin_camo +at_skin_cluckinbell +at_skin_diamond +at_skin_dollar +at_skin_fatalincursion +at_skin_festive +at_skin_geometric +at_skin_hate +at_skin_king +at_skin_leopard +at_skin_love +at_skin_luchalibre +at_skin_luxe +at_skin_metal +at_skin_patriotic +at_skin_pearl +at_skin_perseus +at_skin_pimp +at_skin_player +at_skin_security +at_skin_sessanta +at_skin_skull +at_skin_splatter +at_skin_tiedye +at_skin_trippy +at_skin_vagos +at_skin_vip +at_skin_wall +at_skin_wood +at_skin_woodland +at_skin_zebra +clothing +compact_camera +photo +photo_camera +weapon_battlerifle +weapon_paintball2 +weapon_snowlauncher +weapon_tacticalrifle +weapon_teargas + +## client.image zeigt auf eine Datei, die es nicht gibt (7) +hospital_ticket -> hospital_ticket.png +phone_blue -> phone_blue.png +phone_gold -> phone_gold.png +phone_lilac -> phone_lilac.png +phone_red -> phone_red.png +phone_sim -> phone_sim.png +phone_white -> phone_white.png diff --git a/server/src/storage.ts b/server/src/storage.ts index 63fc069..5287dbc 100644 --- a/server/src/storage.ts +++ b/server/src/storage.ts @@ -135,21 +135,47 @@ export function safeFilename(name: string, eindeutig?: string): string { const roh = punkt > 0 ? name.slice(0, punkt) : name const endung = punkt > 0 ? name.slice(punkt + 1) : '' + // DIE SCHREIBWEISE BLEIBT, seit dem 22.08.2026. + // + // Hier stand `.toLowerCase()` mit der Begruendung "vorhersagbar". Das war + // fuer die Zeichen richtig und fuer die GROSSSCHREIBUNG falsch, und es hat + // etwas kaputtgemacht, das niemand mit dem Hochladen in Verbindung brachte: + // + // ox_inventory fragt Item-Bilder unter dem EXAKTEN Item-Namen ab. Seine + // Waffen heissen WEAPON_COMBATPISTOL. Der Ordner lag auf einem + // Linux-Wirt, dort ist Gross- und Kleinschreibung ein Unterschied -- + // also 404, also leeres Feld im Inventar. Gemessen am 22.08.2026: + // 109 von 226 Items betroffen, und ox_inventory liefert seine eigenen + // Bilder genau deshalb GROSS aus (113 von 198). + // + // Der Grund fuer das Zaehmen bleibt richtig -- Leerzeichen, Klammern und + // Umlaute haben in einer Adresse nichts verloren. Nur die Schreibweise + // gehoerte nie dazu: `checkPath` erlaubt `[A-Za-z0-9]` seit jeher, und in + // einer URL ist ein Grossbuchstabe kein Problem. + // + // Umlaute werden weiterhin ersetzt, jetzt in beiden Schreibweisen -- sonst + // wuerde aus "Gruen.png" ein "gr-n.png", und das waere dieselbe stille + // Verstuemmelung eine Ebene tiefer. const zaehmen = (s: string) => s - .toLowerCase() - // Umlaute NICHT einfach wegwerfen: "grün" wuerde sonst zu "grn". .replace(/ä/g, 'ae') + .replace(/Ä/g, 'Ae') .replace(/ö/g, 'oe') + .replace(/Ö/g, 'Oe') .replace(/ü/g, 'ue') + .replace(/Ü/g, 'Ue') .replace(/ß/g, 'ss') - .replace(/[^a-z0-9._-]+/g, '-') + .replace(/[^A-Za-z0-9._-]+/g, '-') .replace(/-{2,}/g, '-') - .replace(/^[^a-z0-9]+/, '') + .replace(/^[^A-Za-z0-9]+/, '') .replace(/[-.]+$/, '') const stamm = zaehmen(roh) - const ende = zaehmen(endung) + // DIE ENDUNG BLEIBT KLEIN. Am Stamm haengt die Bedeutung -- an der Endung + // haengt nur der Dateityp, und die schreibt alle Welt klein. Wer + // "Bild.PNG" hochlaedt, will kein zweites Format, sondern ein PNG; ein + // ".PNG" waere eine Adresse, die niemand so tippt. + const ende = zaehmen(endung).toLowerCase() // Bleibt nichts uebrig — etwa bei einem rein kyrillischen Namen —, ist das // kein Fehlerfall fuer den Aufrufer: er bekommt einen erzeugten Namen und