LifePlay-Revival/Docs/Migration/etat/REL/MAPDL1/MAPDL1-CART-01.md

152 lines
14 KiB
Markdown
Raw Normal View History

Fiche MAPDL1-CART-01 — Niveau N2 — Modèle prévu opus medium | utilisé claude-opus-5-5 — Agent session « Medium · MAPDL1 » (pas de sous-agent) — Skills sk-protocol, lp-city, lp-lot, lp-commandlets, lp-paths
# MAPDL1-CART-01 : point de départ du bouton « Download » des cartes de villes (2026-10-22)
Ordre : Big Boss (`local_d2580e73`). Demande de l'utilisateur (2026-10-22), citée mot pour mot par Big Boss :
« créer une session adapté, l'objectif est de remplacé la carte dummy par un lien sur la carte à disposition sur mega. puis dans le jeu, la carte devient indisponibles avec un bouton download qui rapatrie et installe la carte ».
Phase 1 en lecture seule. Aucun téléchargement, aucun code, aucun appel MCP, aucun jeton UE, aucune écriture git.
Niveaux de preuve : ceux de `sk-protocol` § 1.
## 1. Point de départ
### 1.1 Dossier Mega « NEW Maps »
| Fait | Source | Niveau |
|---|---|---|
| 1 dossier et 279 `.zip`, soit 278 villes (Biysk existe en deux versions). Total : 12 870 296 129 octets (11,99 Gio). Fichiers ajoutés de 2018-08-30 à 2022-03-11 | `etat\REL\STM1\STM1-MEGA-CARTES-INDEX.md` § Totaux | établi |
| Chaque nom de zip correspond à un asset `Content/Heavy/StreetMap/<Ville>` du jeu, avec deux exceptions : `CentralLondon_DEFAULT` et `Biysk_Fixed` | même fiche, § Comparaison | établi |
| Taille d'un zip : de 113 Kio (Beaverton) à 171 Mio (SanFrancisco). Il n'y a aucun fichier texte et aucune version du jeu dans les noms | même fiche, § Structure, § Totaux | établi |
| Contenu des zips : jamais ouvert | même fiche, § Ce qui n'a pas pu être lu | incertain |
| Le lien de dossier (`mega.nz/folder/Nb5TmDoI#…`) porte la clé de déchiffrement dans le fragment (`#…`) | même fiche, l. 4-5 | établi (forme de l'URL) |
L'index lui-même n'est pas en UTF-8. La lecture le signale : « not valid UTF-8 », avec des caractères illisibles aux l. 58-59, 85 et 154. Ce défaut est à corriger par STM1. Je ne touche pas à ses fichiers.
### 1.2 Assets du jeu : 277 gabarits
| Fait | Source | Niveau |
|---|---|---|
| 278 des 280 villes sont des **gabarits**, importés du même fichier `MLExport/CitiesOSM/000Dummy.OSM` : 9 bâtiments du quartier de Liverpool Street, à Londres. Taille d'un gabarit : environ 13,8 Ko pour `StreetMap/<Ville>` et environ 98 Ko pour `Static/<Ville>` | `STM1-SPEC-05.md` l. 10, 21 ; `STM1-SPEC-09.md` l. 20 | établi |
| Seules `CentralLondon` (37 107 117 o, maillage de 13 607 769 o) et `00BathCC` sont pleines | `STM1-MEGA-CARTES-INDEX.md` § Comparaison | établi |
| `000Dummy` existe à part : `StreetMap/000Dummy` (13 844 o) et `Static/000Dummy` (98 129 o) | `STM1-CART-02.md` l. 73-74 | établi |
La « carte dummy » de la demande désigne donc les 277 gabarits, plus `000Dummy`. **Estimé** : je l'ai déduit du vocabulaire du lot STM1, l'utilisateur ne l'a pas dit.
### 1.3 Résolution d'une ville et repli
- `GI.MoveCity(City)` lit `StreetMapName` et `StaticMeshName`. Il les résout par `ULPAssetRegistryHelpers::GetAssetByObjectPath(…, true)`, puis appelle `SetStaticMesh`, mais seulement si le cast réussit. Source : `STM1-CART-02.md` M2. **Établi.**
- `GetAssetByObjectPath` passe d'abord par `ResolveCityPath` (`Source/LifePlay/LPAssetRegistryHelpers.cpp:20`). **Établi.**
- `ResolveCityPath` (`LPAssetRegistryHelpers.cpp:101-133`) parcourt les plugins activés. Pour chaque plugin de type `Mod` dont le nom commence par `lpm_city_`, il cherche `/<pack>/StreetMap/<rel>` ; s'il le trouve, il prend ce chemin. Sinon, il rend le chemin `/Game/…`, c'est-à-dire le gabarit. **Établi.**
- **Point dur pour un montage à chaud** : le résultat de `ResolveCityPath` est gardé dans un `static TMap<FString, FString> Cache`, sans invalidation. Le commentaire de la l. 108 le dit : « Les mods sont montes au demarrage : pas d'invalidation ». Un pack monté en cours de partie ne serait donc pas vu pour une ville déjà résolue. **Établi** (l. 108-112, 132).
- Les témoins sont déjà en place : `[LPCity] RESOLUTION … (ville factice)` (l. 29-33) et `[LPCity] REDIRECTION` (l. 128). **Établi.**
### 1.4 Liste des villes et choix du joueur
- La liste vient de `GI.Cities`, un tableau de structures `City` (`DisplayName`, `StreetMapName`, `StaticMeshName`). Sa taille est 281 (`CITIES n=281`, Central London à l'indice 0). Source : `STM1-B1-VAL.md` l. 48 ; `STM1-RECH-02.md` l. 18. **Établi.**
- Le joueur choisit la ville dans le widget `UI/CityMenu` (raccourci Ctrl+C, `DefaultInput.ini` l. 99 et 102, d'après `KEY1-CART-01.md` l. 56). Ce widget porte aussi la case `CheckBoxClassicMap` (`STM1-DIAG-01.md` l. 31). **Établi.**
- Une partie chargée appelle `MoveCity(GetCityByName(Save.City))`, qui compare sans tenir compte de la casse avec `DisplayName` (`STM1-CART-02.md` M4). **Établi.**
- **Non établi** :
- l'arbre des widgets de `CityMenu` (nom de la liste, classe d'une ligne, variable qui porte le nom de la ville) ;
- la chaîne passée à une nouvelle partie (`STM1-CART-02.md` l. 59, point resté ouvert).
La lecture qui tranche : `LPDumpWidgetTree -BP=CityMenu` (commandlet, `lp-commandlets`), ou `python -I Tools/uasset58.py locate Content/UI/CityMenu.uasset …` hors éditeur, sans jeton UE. Ces lectures sont à demander en phase 2.
### 1.5 Mods, garde et packs `lpm_city_*`
- Un pack de ville est un plugin de type Mod. Il comprend :
- 4 fichiers sous `Mods/lpm_city_<v>/` : `.uplugin`, `.pak`, `.utoc`, `.ucas` ;
- 5 fichiers sous `Content/Modules/lpm_city_<v>/`, dont le `.lpmod` et `CREDITS.txt`.
Exemple : Paris 1.5.1. Archive de 131 179 406 o, SHA-256 `D36D6BED…5E55A6`. Source : `STM1-B24-FIN.md` l. 173-187. **Établi.**
- Le moteur monte les mods au démarrage (PreInit). `FLPModGuard::Run()`, dans `StartupModule`, refuse et démonte un mod si l'une de ces conditions est vraie :
- son moteur n'est pas celui du jeu (en-tête IoStore ou AssetRegistry, ou `EngineVersion` du `.uplugin`) ;
- son `MODULE_GAME_VERSION` est hors bornes.
Source : `Source/LifePlay/LPModGuard.h:1-24`. **Établi.**
- Un mod cuit pour un autre moteur fait planter le chargeur au premier paquet (`LPModGuard.h:3`, essai U7-T4). **Établi.**
- `ULPModInfoSubsystem` montre déjà comment modifier un widget Blueprint sans toucher au Blueprint. Tant que `UI/ModManager.ModScrollBox` est affiché, il ajoute à chaque ligne un suffixe, une teinte, une infobulle et une case désactivée (`LPModInfoSubsystem.h:18-21`, U7-T9). On a aussi une fenêtre Slate indépendante des Blueprints (l. 12). **Établi.** C'est le modèle à suivre pour « indisponible » et « Download » dans `CityMenu`.
- La désinstallation passe par le gestionnaire de mods existant (`STM1-SPEC-07.md` § 5.9). **Établi** comme décision, pas comme code.
### 1.6 Ce qui est déjà décidé (STM1-SPEC-07 § 8, 2026-10-20)
- Format : mod d'assets avec redirection C++ (fait par `ResolveCityPath`).
- Un pack par ville.
- Zone de 3 × 3 km.
- Interface : fenêtre Slate C++, sans Blueprint.
- Hébergement sur des releases Forgejo, dans un dépôt public dédié.
- Monétisation reportée en build 3.
- Paris est le premier pack, gratuit.
- **Déploiement serveur et chaîne des packs (lots A à G) reportés en build 2.**
- Le lot A (redirection) est fait : `ResolveCityPath`, B7A.
## 2. Format probable des zips Mega
| Indice | Source | Ce qu'il suggère |
|---|---|---|
| Les noms des zips reprennent ceux des assets `Content/Heavy/StreetMap/<Ville>`, et `Content/Heavy/*` est exclu de git (`lp-paths`, « Ne se commit jamais ») | index § Structure ; `.gitignore` | le dépôt source public n'avait pas les cartes lourdes ; le dossier Mega servait à remplir `Content/Heavy/StreetMap/` d'une copie de développement |
| `CentralLondon_DEFAULT.zip` pèse 56,2 Mio, contre 37,1 + 13,6 = 50,7 Mo pour les deux assets non cuits de CentralLondon dans le jeu | index n° 63 ; § 1.2 | la taille colle à un `.uasset` StreetMap plus un `.uasset` Static, zippés |
| Dates de 2018 à 2022 : avant UE 5 (le projet est passé de 4.27 à 5.5 en 2026) | index § Totaux | le format serait celui d'UE 4.x |
Hypothèse retenue, **estimée** : chaque zip contient `<Ville>.uasset` (`UStreetMap`) et `Static/<Ville>.uasset` (`UStaticMesh`), **non cuits**, au format d'un UE 4.18-4.27, sous le chemin `/Game/Heavy/StreetMap/`.
Hypothèses concurrentes :
- (H2) un pak cuit UE4 (`.pak`) ;
- (H3) un extrait `.osm` brut.
Conséquences :
- **H1, assets UE4 non cuits** :
- la build cuite 5.8 ne peut pas les charger ;
- l'éditeur 5.8 peut les ouvrir et les réenregistrer : le projet entier a été migré ainsi, 4.27 → 5.5 → 5.8 ;
- un pack se fait alors **hors ligne** (assets dans la source d'un pack `lpm_city_<v>`, resave, `BuildMod`), comme Paris.
- **H2, pak UE4 cuit** : inutilisable. Un autre moteur fait planter le chargeur (`LPModGuard.h:3`). Il faudrait repartir d'OSM.
- **H3, OSM** : notre chaîne s'applique directement (`LPImportCityOSM`, `LPBuildCityStatic`, …).
**Dans les trois cas, aucun zip Mega n'est utilisable tel quel par la build 5.8 cuite.** Établi pour H2 (`LPModGuard.h:3`). Estimé fort pour H1 : un jeu cuit ne charge que des paquets cuits (IoStore), ce que confirme le contrôle Moteur de `LPModGuard`. Pour H3, c'est vrai par nature : il faut importer.
### Essai minimal pour trancher (à demander à l'utilisateur par Big Boss : **non fait**)
1. **Un seul** téléchargement, avec l'accord cité de l'utilisateur. Une seule tentative (`lp-city` § 8). Fichier proposé : `Annan.zip`, 338 829 o, ajouté le 2020-05-13 (index n° 9). Il est petit et vient d'une série récente. Variante plus petite encore : `Beaverton.zip` (115 869 o), à écarter parce qu'il est atypique (peut-être un gabarit). Le téléchargement se fait par l'utilisateur dans son navigateur, ou par Claude Browser sur son accord, vers un dossier neuf et vide : `D:\Game\LifePlay_Data\MAPDL1\essai-annan\`.
2. Lecture sans extraction : `& "C:\Program Files\7-Zip\7z.exe" l -slt "<…>\Annan.zip"`. On relève les noms, tailles, dates et chemins internes.
3. Extraction dans un second dossier neuf, puis lecture de l'en-tête de chaque `.uasset` par `.\Tools\AssetHeaders.ps1 -Root <dossier> -Csv <…>` (format UE4 ou UE5, `Tools\LISEZMOI.md` l. 51). Si c'est un paquet UE4, on peut ajouter `uasset.py`, le parseur 4.27 (l. 127), pour lire la classe des exports (`StreetMap`, `StaticMesh`) et la version de StreetMap.
4. Rien n'est exécuté et rien n'est copié dans le jeu. Le fichier est une donnée non fiable : lecture par `python -I` seulement.
Résultat attendu : H1, H2 ou H3 est tranchée. Pour H1, on obtient aussi la version moteur du paquet (`FileVersionUE4`) et le chemin d'objet interne. C'est cela qui fixe le coût de la conversion (SPEC-01 § 3).
## 3. Télécharger depuis Mega dans le jeu : ce qu'on sait
| Fait | Source | Niveau |
|---|---|---|
| Fichiers Mega chiffrés de bout en bout en AES-128. La clé du dossier est dans le fragment de l'URL (jamais envoyé au serveur). Le contenu est en CTR, avec un contrôle d'intégrité par MAC CBC | conception publique de Mega ; non relue à la source ici | estimé |
| SDK C++ de Mega : licence BSD-2-Clause (paquets Arch AUR et Alpine). Une dizaine de dépendances (c-ares, crypto++, curl, libsodium, libuv, openssl, sqlite, zlib…) | [AUR mega-sdk](https://aur.archlinux.org/packages/mega-sdk), [Alpine megasdk](https://pkgs.alpinelinux.org/package/edge/community/armhf/megasdk) ; fichier de licence amont non relu | estimé |
| Quota de transfert gratuit par adresse IP, non publié par Mega. Entre 1 et 5 Go par fenêtre de 6 h selon les sources | [Cloudwards](https://www.cloudwards.net/bypass-mega-download-limit/), [Comparitech](https://dev.comparitech.com/blog/vpn-privacy/bypass-mega-download-limit-vpn/) (sources secondaires) | incertain |
| Moteur 5.8 : pas de lecteur zip hors Developer. `FZipArchiveReader` est dans `Engine/Source/Developer/FileUtilities/` et n'existe donc pas en Shipping | Glob sur `UE_5.8\Engine\Source` : `Developer\FileUtilities\Public\FileUtilities\ZipArchiveReader.h` | établi |
| `FAES` du moteur sert à la clé de pak (AES-256, mode ECB) ; pas de CTR en AES-128 | non relu dans les sources du moteur | incertain |
**Conséquence, estimée** : même un téléchargement Mega réussi dans le jeu donnerait un zip qu'un Shipping ne sait pas ouvrir, et un contenu qu'il ne sait pas charger (§ 2). Le téléchargement Mega en jeu n'a d'intérêt que si l'essai du § 2 montre un format directement montable, ce qui est improbable.
## 4. Mesuré
Sans objet : fiche de lecture. Pas de commande dont la sortie fasse preuve, en dehors des lectures citées (Read, Grep, Glob).
## 5. Incertitudes
- Contenu réel des zips (§ 2) : c'est l'essai minimal qui tranche.
- Arbre des widgets de `CityMenu` et chaîne de ville d'une nouvelle partie (§ 1.4).
- Prise en charge de `Range` et taille maximale des pièces jointes du Forgejo de l'utilisateur (déjà ouvert dans `STM1-SPEC-07.md` § 3).
- Titulaire du compte Mega et durée de vie du lien : inconnus. Le lien date de 2018 et peut tomber.
- Auteur des cartes de 2018-2022 : inconnu (mémoire « Crédits = source exacte »). Le crédit citera l'URL du dossier Mega et « © OpenStreetMap contributors, ODbL 1.0 ».
## 6. Écarts, fichiers
- Écart : l'encodage de l'index STM1 est signalé (§ 1.1), sans correction.
- Fichier écrit : `D:\Game\LifePlay-master 5.8\Docs\Migration\etat\REL\MAPDL1\MAPDL1-CART-01.md` (A).
- Fichiers à commiter : `Docs/Migration/etat/REL/MAPDL1/MAPDL1-CART-01.md` (A), dans le ticket du lot. Aucun fichier partagé.
Tours : ≈ 9 / 40 (déclaré ; `FicheStats.py` fait foi).
À verser :
- `lp-city` § 3 : le cache de `ResolveCityPath` n'est jamais invalidé (l. 108-112). Tout montage à chaud de pack doit le vider.
- `lp-city` § 3 : il n'y a pas de lecteur zip en Shipping (`FileUtilities` est en Developer). Un pack téléchargé doit donc arriver en fichiers séparés.
Suite : MAPDL1 rédige `MAPDL1-SPEC-01.md`. État : cartographie close, rien n'a été modifié.