BL Coding How to get the MetaData of your submodule in a savegame?

Users who are viewing this thread

Captain_Octavius

Sergeant Knight
WB
When a user loads a savegame, I want to detect which version of my submodule was active when that savegame was made. This way I can conditionally run some update/maintenance code.

There is a GetModuleVersion method in the class MetaDataExtensions, but it needs a MetaData object as a parameter and I don't know how to get it. I've seen many classes that use the following method + attribute to get the MetaData object, but if I add it to my submodule or behaviour class it doesn't seem to run:

C#:
        [LoadInitializationCallback]
        private void OnLoad(MetaData metaData)

Does anyone else have a clue? I could patch an existing class to get it but that's ugly.
 
Well i'm still working on it so my answer might be incomplete but will give you what i found so you can work on a solution too.

First you can get the name of all the active modules with Campaign.Current.SandBoxManager.ModuleManager.ModuleNames, but this is not really what you want.
Then you have the TaleWorlds.MountAndBlade.Module object that stores a few interresting methods on the submodules loaded.
TaleWorlds.MountAndBlade.Module.CurrentModule.SubModules gives you an enumerable of the submodule types that are directly loaded from the submodule.xml file from the mods.
There is also a ModuleInfo class and a SubModuleInfo class that contains all the meta datas you are looking for. I currently can't get one particular module's info, but as you might simply want to iterate them, you might be able to use them more easily than i do.
 
Upvote 0

Captain_Octavius

Sergeant Knight
WB
Now we're getting somewhere, thanks for that! That loops through all of them though, after looking at that function this does the trick for me and should be much more efficient:

ModuleInfo moduleinfo = new ModuleInfo();
moduleinfo.Load("PartyAIOverhaulCommands");
MessageBox.Show(moduleinfo.Version.ToString());
 
Upvote 0

Captain_Octavius

Sergeant Knight
WB
Actually, that only gets me the current version of the module, but my code already knows that. What I'm after is the version of the module that was stored in the savegame, so I can compare the current vs previous version. We know those are stored in the savegame because the game displays them in the loading menu.
 
Upvote 0

Captain_Octavius

Sergeant Knight
WB
I followed the load game code and figured out where that metadata is stored. It's in CampaignGameManager but the field is set as private without a public getter. So the only course of action I know is to use Harmony's Traverse utility to access that private field. This code works:


C#:
CampaignGameManager manager = CampaignGameManager.Current as CampaignGameManager;

if (manager != null)

{

    LoadResult loadResult = Traverse.Create(manager).Field("_loadedGameResult").GetValue<LoadResult>();

    ApplicationVersion version = loadResult.MetaData.GetModuleVersion("Party AI Overhaul and Commands");

}


You have to specify the Name as defined in your SubModule.xml in GetModuleVersion(). ApplicationVersion has Major/Minor/Revision int getters to make version comparison easy.
 
Upvote 0
That's really weird if it have no getter at all. Should really be reported as a bug to my opinion cause being able to check if a mod is uptodate before loading a savegame is really the basis of modding.
Isn't it possible to get with the SyncData method before loading something?
 
Upvote 0
Top Bottom