BattletechModders / BattleTechModLoader

A simple mod loader and injector for HBS's PC game BattleTech.
The Unlicense
48 stars 10 forks source link

BMIT.DataLibrary Incorporation Example #1

Closed brandonm4 closed 6 years ago

brandonm4 commented 6 years ago

An idea on how you could utilize the MetadataDatabase library I'm working on to autoload mechdefs, vehicledefs (and in the future pilots,events,etc) with BTML. Link to BMIT GitHub. You only need the BMIT.DataLibrary project from my repo. This is just a quick/dirty example, I'm sure there are better ways to incorporate but I hope you can get the basic idea of functionality from this example.

public static void Init()
{ 
... 
//Not sure if this is the right path, but need full path to metadatadatabase.db file. using your path to mods as example to base it on. 

var MDDPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(VersionManifestUtilities.MANIFEST_FILEPATH), @"......\BattleTech_Data\StreamingAssets\MDD\MetaDataDatabase.db"));

// TODO: load mods in the correct order 
using(var db = new BMIT.DataLibrary.MDData(MDDPath)) 
{ 
foreach (var modDef in modDefs)
 { 
    LoadMod(modDef, db); 
  } 
}
....
LoadMod(ModDef moddef, BMIT.DataLibrary.MDData db)
...

/*
Not sure where to put this UpdateUnitDefs call yet - wherever you read in the mechdef,vehicledef,etc and actually use them. I see you read them into a JObject in InferIDFromFileAndType and I see you add them to potentialAdditions. When a potentialAddition becomes an actual addition you would need to read in the def.json file as a JObject and call db.UnitDefsUpdate. 
*/

//Example - I know the mod structure is not quite this 
foreach(var mechdefpath in mod.mechdefspaths) 
{ 
    var jObj = Newtonsoft.Json.Linq.JObject.Parse(File.ReadAllText(mechdefpath )); 
    db.UnitDefsUpdate(jObj, UnitType.Mech); 
}

Potential Issues: Once the MetadataDatabase.db has been updated with a def, that def must exist in the VersionManifest.CSV list (or get loaded by BTML someway). If that def is removed, the MetadataDatabse.db must also have it's associated entries removed. Failure to do this will cause infinite/hanging loading screens. I will add def deletion functionality to the library, but it means the mod manager must be used to 'Uninstall' a mod, and not simply just delete it. Alternatively, some sanity check could be run on inititalization that cleans the db of any def that isn't found in the associated json files. Obviously removing a def from an active campaign will break it, if the player has the mech or the parts in his inventory or it's saved during a contract with one in play.

mpstark commented 6 years ago

DB/Savegame management will be an important part of the project as a whole as it evolves. Mods should be able to be installed and uninstalled without much impact to the end user. Thanks for the information and the link to your project.

Regarding licensing, ModTek is licensed under the UNLICENSE, which means it's released to the public domain. That also means that any included code will have to licensed like that, so I'll probably use your project as a jumping off platform to how the DB works and what needs to be done, and write separate code that actually does it or you'll have to 'release' the code to me in a pull request that acknowledges that you're agreeing to the license.

Also, as an observation, I don't think it's a very good idea to write raw SQL into your code -- instead, I would look up documentation on how to use a library (preferably the one that the game uses to write to the DB) that does it for me. Again, I haven't worked on this particular problem at all, so it might ultimately be needed.

brandonm4 commented 6 years ago

They are using Mono.Data.Sqlite, I'm using Microsoft.Data.Sqlite. Either will work similarly. If you check out the BattleTech.Data classes in Assembly_CSharp you'll see they are using SQL right in the code as well. As far as I know that's the only way to work with sqlite in .Net but there could be a wrapper out there that I'm not aware of. (Although even entity and such when you get to the lower layers you're still seeing sql, it's just a lot of it is autogenerated by the library for you).

I'm pretty open to licensing, I figured by putting it on GitHub it's open to the world anyway but I can look into setting a specific license for it.

ffaristocrat commented 6 years ago

Definitely have some kind of wrapper to escape data and mitigate SQL injection attacks. You definitely wouldn't want a mod to become a malware vector because BT assumes the database is safe to ingest naively.

mpstark commented 6 years ago

ModTek will end up using the game MDD extension methods, as provided by the game's assembly.