Skip to content

Commit

Permalink
Merge pull request #139 from BUTR/dev
Browse files Browse the repository at this point in the history
Release 1.1.2
  • Loading branch information
Aragas committed Jul 4, 2024
2 parents 7588454 + 7506a8d commit 7c143ea
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 38 deletions.
131 changes: 131 additions & 0 deletions assets/localization/FR/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageData id="Français" name="Français" subtitle_extension="fr" supported_iso="fr,fra,fr-fr,fr-be,fr-ca,fr-ch" under_development="false">
<strings>
<!-- BUTRLauncherModuleVM -->
<string id="kfMQEOFS" text="Le module est installé dans le dossier /Modules du jeu et sur le Steam Workshop !{NL}La version /Modules sera utilisée !"/>
<string id="aAYdk1zd" text="Le DLL est obfusqué !{NL}Il n'y a aucune garantie que le code est sûr !{NL}L'équipe de BUTR met en garde contre les conséquences possibles de l'exécution de code obfusqué !"/>

<!-- BUTRLauncherOptionsVM -->
<string id="z9WqFewN" text="DÉSACTIVÉ !"/>
<string id="44qrhQ6g" text="Redémarrage requis !"/>

<string id="zHo3tzQT" text="Débloquer les fichiers au démarrage"/>
<string id="sOInYH9V" text="Débloque automatiquement les fichiers .dll au démarrage"/>
<string id="LXlsSS8t" text="Corriger les problèmes courants"/>
<string id="J9VbkLW4" text="Corrige des problèmes tels que la présence de 0Harmony.dll dans le dossier /bin"/>
<string id="vUAqDj9H" text="Liste compacte des modules"/>
<string id="Qn1aPNQM" text="Réduit la taille du contenu de l'onglet Mods"/>
<string id="GUWbD65T" text="Désactiver la vérification de compatibilité binaire"/>
<string id="lmpQeQBS" text="Désactive la vérification de compatibilité des mods par le Launcher"/>
<string id="iD27wEq7" text="Masquer l'image aléatoire"/>
<string id="LaPvZjwC" text="Cacher l'image du Cavalier pour que le Launcher soit plus compact"/>
<string id="JT7QnJJA" text="Débloquer les fichiers"/>
<string id="VMIp4503" text="Débloque tous les fichiers .dll dans le dossier /Modules"/>
<string id="RDLKkiVk" text="Débloquer"/>
<string id="QJSBiZdJ" text="Tri expérimental"/>
<string id="HVhaqeb4" text="Utilise le nouvel algorithme de tri après la v1.12.x. Désactiver pour utiliser l'ancien algorithme"/>
<string id="1zt99vTt" text="Mode agrandi"/>
<string id="XUSDSpvf" text="Augmente la hauteur du Launcher"/>
<string id="IsR2rbnG" text="Restaurer la sauvegarde des options de jeu"/>
<string id="uKUsA3Sp" text="LauncherEx fait toujours une sauvegarde avant d'enregistrer pour la première fois. Cela restaurera les fichiers d'origine"/>
<string id="TLDgPay9" text="Restaurer"/>
<string id="5XzSM7RN" text="Restaurer la sauvegarde des options du moteur"/>
<string id="JusnHy6S" text="Active le redimensionnement DPI de Windows pour éliminer le flou des éléments de l'interface utilisateur"/>

<!-- BUTRLauncherSavesVM -->
<string id="JtelOsIW" text="Nom"/>
<string id="14WBFIS1" text="Version"/>
<string id="OJsGrGVi" text="Personnage"/>
<string id="JxpEEQdF" text="Niveau"/>
<string id="qkkTPycE" text="Jours"/>
<string id="aYWWDkKX" text="Créé le"/>

<!-- LauncherConfirmStartVMMixin -->
<string id="DzJmcvsP" text="Annuler"/>
<string id="epTxGUqT" text="Confirmer"/>

<!-- LauncherModsVMMixin -->
<string id="pZVVdI5d" text="L'ordre de chargement a été réorganisé avec l'algorithme par défaut !{NL}Raisons :{NL}{REASONS}"/>
<string id="sP1a61KE" text="Impossible de placer le module à la position souhaitée ! Placement au plus proche disponible !{NL}Raison :{NL}{REASONS}"/>
<string id="sLf3eIpH" text="Échec du tri de la liste des modules !"/>

<!-- LauncherVMMixin -->
<string id="yS5hbWCL" text="Options"/>
<string id="V66qoU6n" text="Launcher"/>
<string id="ro4RMgyt" text="Jeu"/>
<string id="q4rQuTgG" text="Moteur"/>
<string id="d5OjKcGE" text="Sauvegardes"/>
<string id="Aws9irMU" text="Importer l'ordre de chargement"/>
<string id="4wKr76gx" text="Importer l'ordre de chargement de la sauvegarde"/>
<string id="XdZGqnFW" text="Exporter l'ordre de charge actuel"/>
<string id="G55IdM6M" text="Exporter l'ordre de chargement de la sauvegarde"/>
<string id="MlYQ0uX7" text="Des instabilités pourraient survenir."/>
<string id="qvzptzrE" text="Souhaitez-vous continuer à charger la sauvegarde ?"/>
<string id="dDprK7Mz" text="ATTENTION"/>

<string id="Hk7FBBSa" text="Solo"/>
<string id="UOGhdUWE" text="Multijoueur"/>
<string id="VDTcZpPr" text="Compagnon Digital"/>
<string id="Tg0If68v" text="Actualités"/>
<string id="YGU9eXM0" text="Mods"/>
<string id="xYv4iv7C" text="JOUER"/>
<string id="6B3iZLqR" text="CONTINUER"/>
<string id="eUt6GKkQ" text="LANCER"/>

<!-- LauncherVMMixin -->
<string id="WJnTxf3v" text="Importation annulée !"/>
<string id="BjtJ4Lxw" text="Exportation annulée"/>
<string id="eohqbvHU" text="Liste importée avec succès !"/>
<string id="VwFQTk5z" text="Liste exportée avec succès !"/>

<!-- Issues -->
<string id="kxqLbSqe" text="(ID inconnu)"/>

<string id="izSm5f85" text="IDs des modules en double :{NL}{MODULEIDS}"/>
<string id="vCwH9226" text="Noms des modules en double :{NL}{MODULENAMES}"/>
<string id="GtDRbC3m" text="Modules manquants :{NL}{MODULES}"/>
<string id="BuMom4Jt" text="Versions de modules incompatibles :{NL}{MODULEVERSIONS}"/>

<string id="nYVWoomO" text="{MODULEID}. Requis {REQUIREDVERSION}. Installé {ACTUALVERSION}"/>
<string id="sd6M4KRd" text="Ordre de chargement :{NL}{LOADORDER}"/>
<string id="HvvA78sZ" text="Problèmes d'ordre de chargement :{NL}{LOADORDERISSUES}"/>

<string id="B64DbmWp" text="Fichier de sauvegarde introuvable !"/>
<string id="epU06HID" text="Échec de la lecture du fichier de sauvegarde !"/>

<string id="DKRNkst2" text="Ouvrir un fichier avec un ordre de chargement"/>
<string id="XSxlKweM" text="Enregistrer la liste de modules de Bannerlord"/>

<string id="hgew15HH" text="Continuer l'importation ?"/>

<string id="tqjPGPtP" text="LauncherEx a détecté 0Harmony.dll dans le dossier racine /bin du jeu !{NL}Cela pourrait causer des problèmes, souhaitez-vous le supprimer ?"/>

<string id="J3Uh6MV4" text="'{ID}' {VERSION} manquant dans la liste des modules"/>
<string id="3eQSr6wt" text="'{ID}' {VERSION} manquant"/>
<string id="U858vdQX" text="'{ID}' a une ou plusieurs dépendances manquantes !"/>
<string id="1LS8Z5DU" text="'{ID}' a des problèmes non résolus !"/>
<string id="Vjz9HQ41" text="Mauvaise version de '{ID}' &lt;= {VERSION}"/>
<string id="ZvnlL7VE" text="Mauvaise version de '{ID}' &lt;= [{VERSION}]"/>
<string id="EfNuH2bG" text="Mauvaise version de '{ID}' &gt;= [{VERSION}]"/>
<string id="zXDidmpQ" text="'{ID}' est incompatible avec ce module"/>
<string id="4KFwqKgG" text="Le module '{ID}' est à la fois requis et marqué comme incompatible"/>
<string id="9DRB6yXv" text="Le module '{ID}' est à la fois requis en tant que LoadBefore et LoadAfter"/>
<string id="RC1V9BbP" text="Dépendances circulaires. '{TARGETID}' et '{SOURCEID}' dépendent l'un de l'autre"/>
<string id="s3xbuejE" text="'{SOURCEID}' doit être chargé avant '{TARGETID}'"/>
<string id="2ALJB7z2" text="'{SOURCEID}' doit être chargé après '{TARGETID}'"/>

<!-- Dependency Constructor -->
<string id="8ldMJPhQ" text=" (optionnel)"/>
<string id="f9hYP7mk" text="Dépend de :"/>
<string id="eGJ387f7" text="Incompatible avec :"/>
<string id="eW76jyd7" text="Doit être chargé avant :"/>


<string id="HdnFwgVA" text="Basé sur les analyses de BUTR :{NL}{NL}Mise à jour non requise.{NL}Score de compatibilité {SCORE}%{NL}{NL}{CURRENTVERSION} est l'une des meilleures versions pour le jeu {GAMEVERSION}"/>
<string id="HdnFwgVB" text="Basé sur les analyses de BUTR :{NL}{NL}Score de compatibilité {SCORE}%{NL}{NL}Suggère de mettre à jour vers {RECOMMENDEDVERSION}.{NL}Score de compatibilité {RECOMMENDEDSCORE}%{NL}{NL}{RECOMMENDEDVERSION} a une meilleure compatibilité pour le jeu {GAMEVERSION} plutôt que {CURRENTVERSION} !"/>

<string id="q5quVWMI" text="Basculer tous les modules"/>
<string id="H5nMY4WU" text="Actualiser les modules"/>
<string id="zXWdahH9" text="Obtenir des recommandations de mise à jour{NL}Cliquer sur ce bouton enverra votre liste de modules au serveur de BUTR pour obtenir les scores de compatibilité et les versions recommandées.{NL}Ils sont basés sur les rapports de crash de ButterLib.{NL}{NL}(Nécessite une connexion Internet)"/>
</strings>
</LanguageData>
4 changes: 4 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
---------------------------------------------------------------------------------------------------
Version: 1.1.2
* Collection Load Order Tab was not updated correctly on Load Order Page changes
* Added French localization
---------------------------------------------------------------------------------------------------
Version: 1.1.1
* Fixed collection creation
---------------------------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "game-mount-and-blade-ii-bannerlord-butr",
"version": "1.1.1",
"version": "1.1.2",
"description": "A Vortex extension for Mount and Blade II: Bannerlord mod management.",
"author": "BUTR Team & Nexus Mods",
"license": "GPL-3.0+",
Expand Down
8 changes: 5 additions & 3 deletions src/blse/events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actions, types } from 'vortex-api';
import { findBLSEMod } from './utils';
import { hasSettingsInterfacePrimaryTool } from '../vortex';
import { hasPersistentBannerlordMods, hasSettingsInterfacePrimaryTool } from '../vortex';
import { GAME_ID } from '../common';

export const didDeployBLSE = (api: types.IExtensionApi): Promise<void> => {
Expand All @@ -12,7 +12,8 @@ export const didDeployBLSE = (api: types.IExtensionApi): Promise<void> => {

const primaryTool = state.settings.interface.primaryTool.mountandblade2bannerlord;

const blseMod = findBLSEMod(state);
const mods = hasPersistentBannerlordMods(state.persistent) ? state.persistent.mods.mountandblade2bannerlord : {};
const blseMod = findBLSEMod(mods);
if (blseMod && primaryTool === undefined) {
api.store?.dispatch(actions.setPrimaryTool(GAME_ID, 'blse-cli'));
}
Expand All @@ -38,7 +39,8 @@ export const didPurgeBLSE = (api: types.IExtensionApi): Promise<void> => {
return Promise.resolve();
}

const blseMod = findBLSEMod(state);
const mods = hasPersistentBannerlordMods(state.persistent) ? state.persistent.mods.mountandblade2bannerlord : {};
const blseMod = findBLSEMod(mods);
if (blseMod) {
api.store?.dispatch(actions.setPrimaryTool(GAME_ID, undefined!));
}
Expand Down
7 changes: 2 additions & 5 deletions src/blse/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { IFileInfo } from '@nexusmods/nexus-api/lib';
import { BLSE_MOD_ID, BLSE_URL, GAME_ID } from '../common';
import { hasPersistentBannerlordMods } from '../vortex';
import { LocalizationManager } from '../localization';
import { IBannerlordMod } from '../types';
import { IBannerlordMod, IBannerlordModStorage } from '../types';

export const isModActive = (profile: types.IProfile, mod: IBannerlordMod): boolean => {
return profile.modState[mod.id]?.enabled ?? false;
Expand All @@ -13,10 +13,7 @@ const isModBLSE = (mod: IBannerlordMod): boolean => {
return mod.type === `bannerlord-blse` || (mod.attributes?.modId === 1 && mod.attributes?.source === `nexus`);
};

export const findBLSEMod = (state: types.IState): IBannerlordMod | undefined => {
if (!hasPersistentBannerlordMods(state.persistent)) return undefined;

const mods = state.persistent.mods.mountandblade2bannerlord ?? {};
export const findBLSEMod = (mods: IBannerlordModStorage): IBannerlordMod | undefined => {
const blseMods: IBannerlordMod[] = Object.values(mods).filter((mod: IBannerlordMod) => isModBLSE(mod));

if (blseMods.length === 0) return undefined;
Expand Down
7 changes: 5 additions & 2 deletions src/blse/vortex.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { actions, selectors, types } from 'vortex-api';
import { deployBLSE, downloadBLSE, findBLSEDownload, findBLSEMod, isModActive } from './utils';
import { LocalizationManager } from '../localization';
import { hasPersistentBannerlordMods } from '../vortex';

const sendNotification = (
api: types.IExtensionApi,
Expand Down Expand Up @@ -31,7 +32,8 @@ export const recommendBLSE = (api: types.IExtensionApi): void => {

const profile: types.IProfile | undefined = selectors.activeProfile(state);

const blseMod = findBLSEMod(state);
const mods = hasPersistentBannerlordMods(state.persistent) ? state.persistent.mods.mountandblade2bannerlord : {};
const blseMod = findBLSEMod(mods);
if (blseMod) {
// Found but not enabled
const blseIsActive = isModActive(profile, blseMod);
Expand Down Expand Up @@ -84,7 +86,8 @@ export const forceInstallBLSE = async (api: types.IExtensionApi): Promise<void>

const profile: types.IProfile | undefined = selectors.activeProfile(state);

const blseMod = findBLSEMod(state);
const mods = hasPersistentBannerlordMods(state.persistent) ? state.persistent.mods.mountandblade2bannerlord : {};
const blseMod = findBLSEMod(mods);
if (blseMod) {
// Found but not enabled
const blseIsActive = isModActive(profile, blseMod);
Expand Down
7 changes: 3 additions & 4 deletions src/butr/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { types } from 'vortex-api';
import { IModAnalyzerRequestModule, IModAnalyzerRequestQuery, IModuleCompatibilityInfoCache } from './types';
import { ModAnalyzerProxy } from './modAnalyzerProxy';
import { versionToString, VortexLauncherManager } from '../launcher';

export const getCompatibilityScores = async (api: types.IExtensionApi): Promise<IModuleCompatibilityInfoCache> => {
const launcherManager = VortexLauncherManager.getInstance(api);

export const getCompatibilityScores = async (
launcherManager: VortexLauncherManager
): Promise<IModuleCompatibilityInfoCache> => {
const allModules = launcherManager.getAllModules();
const gameVersion = launcherManager.getGameVersionVortex();

Expand Down
19 changes: 7 additions & 12 deletions src/collections/generalData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { selectors, types } from 'vortex-api';
import { profile } from 'node:console';
import { ICollectionData, ICollectionDataWithGeneralData, ICollectionGeneralData } from './types';
import { genCollectionGeneralLoadOrder, parseCollectionGeneralLoadOrder } from './loadOrder';
import { CollectionParseError } from './errors';
Expand All @@ -7,25 +8,19 @@ import { hasPersistentBannerlordMods, hasPersistentLoadOrder } from '../vortex';
import { findBLSEMod, forceInstallBLSE, isModActive } from '../blse';
import { vortexToPersistence } from '../loadOrder';
import { VortexLauncherManager } from '../launcher';
import { IBannerlordMod, IBannerlordModStorage, VortexLoadOrderStorage } from '../types';

/**
* Assumes that the correct Game ID is active and that the profile is set up correctly.
*/
export const genCollectionGeneralData = (
api: types.IExtensionApi,
includedModIds: string[]
profile: types.IProfile,
loadOrder: VortexLoadOrderStorage,
includedMods: IBannerlordModStorage
): Promise<ICollectionGeneralData> => {
const state = api.getState();

const profile: types.IProfile | undefined = selectors.activeProfile(state);

const loadOrder = hasPersistentLoadOrder(state.persistent) ? state.persistent.loadOrder[profile.id] ?? [] : [];
const mods = hasPersistentBannerlordMods(state.persistent) ? state.persistent.mods.mountandblade2bannerlord : {};

const includedMods = Object.values(mods).filter((mod) => includedModIds.includes(mod.id));
const collectionLoadOrder = genCollectionGeneralLoadOrder(loadOrder, includedMods);
const collectionLoadOrder = genCollectionGeneralLoadOrder(loadOrder, Object.values(includedMods));

const blseMod = findBLSEMod(state);
const blseMod = findBLSEMod(includedMods);
const hasBLSE = blseMod !== undefined && isModActive(profile, blseMod);

return Promise.resolve({
Expand Down
29 changes: 25 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
SettingsProps,
} from './views';
import { BannerlordGame } from './game';
import { IAddedFiles } from './types';
import { IAddedFiles, IBannerlordModStorage } from './types';
import { reducer } from './react';
import { actionsSettings } from './settings';
import {
Expand All @@ -32,7 +32,13 @@ import { didDeployLoadOrder, gamemodeActivatedLoadOrder, LoadOrderManager } from
import { didDeployBLSE, didPurgeBLSE, getInstallPathBLSE, installBLSE, isModTypeBLSE, testBLSE } from './blse';
import { VortexLauncherManager } from './launcher';
import { gamemodeActivatedSave } from './save';
import { addedFilesEvent, getInstallPathModule, isModTypeModule } from './vortex';
import {
addedFilesEvent,
getInstallPathModule,
hasPersistentBannerlordMods,
hasPersistentLoadOrder,
isModTypeModule,
} from './vortex';
import { version } from '../package.json';

// TODO: Better dialogs with settings
Expand Down Expand Up @@ -64,11 +70,26 @@ const main = (context: types.IExtensionContext): boolean => {
if (hasContextWithCollectionFeature(context)) {
context.optional.registerCollectionFeature(
/*id:*/ `${GAME_ID}_load_order`,
/*generate:*/ async (gameId: string, includedMods: string[], _mod: types.IMod) => {
/*generate:*/ async (gameId: string, includedModIds: string[], _mod: types.IMod) => {
if (GAME_ID !== gameId) {
return {};
}
return await genCollectionGeneralData(context.api, includedMods);

const state = context.api.getState();
const profile: types.IProfile | undefined = selectors.activeProfile(state);
const loadOrder = hasPersistentLoadOrder(state.persistent) ? state.persistent.loadOrder[profile?.id] ?? [] : [];
const mods = hasPersistentBannerlordMods(state.persistent)
? state.persistent.mods.mountandblade2bannerlord
: {};

const includedMods = Object.values(mods)
.filter((mod) => includedModIds.includes(mod.id))
.reduce<IBannerlordModStorage>((map, obj) => {
map[obj.id] = obj;
return map;
}, {});

return await genCollectionGeneralData(profile, loadOrder, includedMods);
},
/*parse:*/ async (gameId: string, collection: ICollectionData, _mod: types.IMod) => {
if (GAME_ID !== gameId) {
Expand Down
14 changes: 9 additions & 5 deletions src/views/CollectionGeneralData/pages/GeneralDataPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { getCompatibilityScores, IModuleCompatibilityInfoCache } from '../../../
import { genCollectionGeneralData } from '../../../collections';
import { useLocalization } from '../../../localization';
import { hasPersistentBannerlordMods, hasPersistentLoadOrder } from '../../../vortex';
import { useLauncher } from '../../../launcher';

interface IFromState {
profile: types.IProfile | undefined;
loadOrder: VortexLoadOrderStorage;
mods: IBannerlordModStorage;
}
Expand All @@ -22,23 +24,24 @@ export const BannerlordGeneralDataPage = (props: BannerlordGeneralDataPageProps)
const [hasBLSE, setHasBLSE] = useState<boolean>(false);
const [persistentLoadOrder, setPersistentLoadOrder] = useState<PersistenceLoadOrderStorage>([]);

const { loadOrder, mods } = useSelector(mapState);
const { profile, loadOrder, mods } = useSelector(mapState);

const context = useContext(MainContext);
const launcherManager = useLauncher();

useEffect(() => {
async function setData(): Promise<void> {
const data = await genCollectionGeneralData(context.api, Object.keys(mods));
if (!profile) return;
const data = await genCollectionGeneralData(profile, loadOrder, mods);
setHasBLSE(data.hasBLSE);
setPersistentLoadOrder(data.suggestedLoadOrder);
}
setData().catch(() => {});
}, [context.api, mods]);
}, [profile, loadOrder, mods]);

const { localize: t } = useLocalization();

const refreshCompatibilityScores = (): void => {
getCompatibilityScores(context.api)
getCompatibilityScores(launcherManager)
.then((cache) => {
setCompatibilityInfoCache(cache);
})
Expand Down Expand Up @@ -90,6 +93,7 @@ const mapState = (state: types.IState): IFromState => {
const loadOrder = hasPersistentLoadOrder(state.persistent) ? state.persistent.loadOrder[profile?.id] ?? [] : [];
const mods = hasPersistentBannerlordMods(state.persistent) ? state.persistent.mods.mountandblade2bannerlord : {};
return {
profile,
loadOrder,
mods,
};
Expand Down
2 changes: 1 addition & 1 deletion src/views/Saves/components/RadioView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ export const RadioView = (props: RadioViewProps): JSX.Element => {
onChange={() => onChange(save)}
/>
) : (
<div />
<></>
);
};
Loading

0 comments on commit 7c143ea

Please sign in to comment.