diff --git a/Libraries/Core/Helpers/ModHelper.cs b/Libraries/Core/Helpers/ModHelper.cs new file mode 100644 index 00000000..a4a8f900 --- /dev/null +++ b/Libraries/Core/Helpers/ModHelper.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using Core.Utils; +using SptCommon.Annotations; + +namespace Core.Helpers +{ + [Injectable] + public class ModHelper + { + private readonly FileUtil _fileUtil; + private readonly JsonUtil _jsonUtil; + + public ModHelper( + FileUtil fileUtil, + JsonUtil jsonUtil) + { + _fileUtil = fileUtil; + _jsonUtil = jsonUtil; + } + + public string GetAbsolutePathToModFolder(Assembly modAssembly) + { + // The full path to the mod folder + return Path.GetDirectoryName(modAssembly.Location); + } + + public T GetFileFromModFolder(string pathToFile, string fileName) + { + // Read the content of the config file as a string + var rawContent = _fileUtil.ReadFile(Path.Combine(pathToFile, fileName)); + + // Take the string above and deserialise it into a config file with a type (defined between the diamond brackets) + return _jsonUtil.Deserialize(rawContent); + } + } +} diff --git a/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderHelper.cs b/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderHelper.cs index c2f52a49..6fdc1824 100644 --- a/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderHelper.cs +++ b/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderHelper.cs @@ -3,6 +3,7 @@ using Core.Models.Eft.Common.Tables; using Core.Models.Spt.Config; using Core.Models.Spt.Server; using Core.Utils; +using Core.Utils.Cloners; namespace _13._1AddTraderWithDynamicAssorts { @@ -34,18 +35,14 @@ namespace _13._1AddTraderWithDynamicAssorts * @param tables database * @param jsonUtil json utility class */ - public void AddTraderToDb(TraderBase traderDetailsToAdd, DatabaseTables tables, JsonUtil jsonUtil, object assortJson) + public void AddTraderToDb(TraderBase traderDetailsToAdd, DatabaseTables tables, ICloner cloner, TraderAssort assort) { // Create trader data ready to add to database var traderDataToAdd = new Trader { - Assort = - jsonUtil.Deserialize( - jsonUtil.Serialize(assortJson)), // Deserialise/serialise creates a copy of the json - Base = - jsonUtil.Deserialize( - jsonUtil.Serialize(traderDetailsToAdd)), // Deserialise/serialise creates a copy of the json - QuestAssort = new Dictionary> // questassort is empty as trader has no assorts unlocked by quests + Assort = cloner.Clone(assort), + Base = cloner.Clone(traderDetailsToAdd), + QuestAssort = new Dictionary> // quest assort is empty as trader has no assorts unlocked by quests { { "Started", new Dictionary() }, { "Success", new Dictionary() }, diff --git a/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderWithDynamicAssorts.cs b/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderWithDynamicAssorts.cs index 382a1bec..35dcd9e9 100644 --- a/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderWithDynamicAssorts.cs +++ b/ModExamples/13.1AddTraderWithDynamicAssorts/AddTraderWithDynamicAssorts.cs @@ -1,4 +1,6 @@ -using Core.Models.Eft.Common.Tables; +using Core.Helpers; +using System.Reflection; +using Core.Models.Eft.Common.Tables; using Core.Models.Enums; using Core.Models.External; using Core.Models.Spt.Config; @@ -7,7 +9,9 @@ using Core.Routers; using Core.Servers; using Core.Services; using Core.Utils; +using Core.Utils.Cloners; using SptCommon.Annotations; +using Path = System.IO.Path; namespace _13._1AddTraderWithDynamicAssorts; @@ -15,12 +19,14 @@ namespace _13._1AddTraderWithDynamicAssorts; public class AddTraderWithDynamicAssorts : IPostDBLoadMod { private readonly ISptLogger _logger; + private readonly ModHelper _modHelper; private readonly HashUtil _hashUtil; private readonly JsonUtil _jsonUtil; private readonly FileUtil _fileUtil; private readonly DatabaseService _databaseService; private readonly ImageRouter _imageRouter; private readonly ConfigServer _configServer; + private readonly ICloner _cloner; private readonly TraderConfig _traderConfig; private readonly RagfairConfig _ragfairConfig; @@ -29,20 +35,24 @@ public class AddTraderWithDynamicAssorts : IPostDBLoadMod public AddTraderWithDynamicAssorts( ISptLogger logger, + ModHelper modHelper, HashUtil hashUtil, JsonUtil jsonUtil, FileUtil fileUtil, DatabaseService databaseService, ImageRouter imageRouter, - ConfigServer configServer) + ConfigServer configServer, + ICloner cloner ) { _logger = logger; + _modHelper = modHelper; _hashUtil = hashUtil; _jsonUtil = jsonUtil; _fileUtil = fileUtil; _databaseService = databaseService; _imageRouter = imageRouter; _configServer = configServer; + _cloner = cloner; _traderConfig = _configServer.GetConfig(); _ragfairConfig = _configServer.GetConfig(); @@ -50,15 +60,14 @@ public class AddTraderWithDynamicAssorts : IPostDBLoadMod public void PostDBLoad() { - var modPath = _fileUtil.GetModPath(_modName); - var traderImagePath = $"{modPath}/db/cat.jpg"; + var pathToMod = _modHelper.GetAbsolutePathToModFolder(Assembly.GetExecutingAssembly()); - var baseJson = _fileUtil.ReadFile($"{modPath}/db/base.json"); - var traderBase = _jsonUtil.Deserialize(baseJson); + var traderImagePath = Path.Combine(pathToMod, "db/cat.jpg"); + var traderBase = _modHelper.GetFileFromModFolder(pathToMod, "db/base.json"); // Create helper class and use it to register our traders image/icon + set its stock refresh time var addTraderHelper = new AddTraderHelper(); - _imageRouter.AddRoute(traderBase.Avatar.Replace(".jpg", ""), System.IO.Path.GetFullPath(traderImagePath)); + _imageRouter.AddRoute(traderBase.Avatar.Replace(".jpg", ""), traderImagePath); addTraderHelper.SetTraderUpdateTime(_traderConfig, traderBase, 3600, 4000); // Add trader to flea market @@ -70,8 +79,8 @@ public class AddTraderWithDynamicAssorts : IPostDBLoadMod addTraderHelper.AddTraderToDb( traderBase, _databaseService.GetTables(), - _jsonUtil, - new TraderAssort() {Items = new List(), BarterScheme = new Dictionary>>(), LoyalLevelItems = new Dictionary()}); + _cloner, + new TraderAssort {Items = [], BarterScheme = new Dictionary>>(), LoyalLevelItems = new Dictionary()}); _logger.Success("added trader base"); var fluentAssortCreator = new FluentTraderAssortCreator(_logger, _hashUtil); diff --git a/ModExamples/13AddTraderWithAssortJson/AddTraderHelper.cs b/ModExamples/13AddTraderWithAssortJson/AddTraderHelper.cs index 5ebab46b..842d021f 100644 --- a/ModExamples/13AddTraderWithAssortJson/AddTraderHelper.cs +++ b/ModExamples/13AddTraderWithAssortJson/AddTraderHelper.cs @@ -3,6 +3,7 @@ using Core.Models.Eft.Common.Tables; using Core.Models.Spt.Config; using Core.Models.Spt.Server; using Core.Utils; +using Core.Utils.Cloners; namespace _13AddTraderWithAssortJson { @@ -34,17 +35,13 @@ namespace _13AddTraderWithAssortJson * @param tables database * @param jsonUtil json utility class */ - public void AddTraderToDb(TraderBase traderDetailsToAdd, DatabaseTables tables, JsonUtil jsonUtil, object assortJson) + public void AddTraderToDb(TraderBase traderDetailsToAdd, DatabaseTables tables, ICloner cloner, TraderAssort assortJson) { // Create trader data ready to add to database var traderDataToAdd = new Trader { - Assort = - jsonUtil.Deserialize( - jsonUtil.Serialize(assortJson)), // Deserialise/serialise creates a copy of the json - Base = - jsonUtil.Deserialize( - jsonUtil.Serialize(traderDetailsToAdd)), // Deserialise/serialise creates a copy of the json + Assort = cloner.Clone(assortJson), // Clone the data before saving it so we dont mess up any references + Base = cloner.Clone(traderDetailsToAdd), QuestAssort = new Dictionary> // questassort is empty as trader has no assorts unlocked by quests { { "Started", new Dictionary() }, diff --git a/ModExamples/13AddTraderWithAssortJson/AddTraderWithAssortJson.cs b/ModExamples/13AddTraderWithAssortJson/AddTraderWithAssortJson.cs index 886e720f..2f611957 100644 --- a/ModExamples/13AddTraderWithAssortJson/AddTraderWithAssortJson.cs +++ b/ModExamples/13AddTraderWithAssortJson/AddTraderWithAssortJson.cs @@ -1,12 +1,15 @@ -using Core.Models.Eft.Common.Tables; +using Core.Helpers; +using System.Reflection; +using Core.Models.Eft.Common.Tables; using Core.Models.External; using Core.Models.Spt.Config; using Core.Models.Utils; using Core.Routers; using Core.Servers; using Core.Services; -using Core.Utils; +using Core.Utils.Cloners; using SptCommon.Annotations; +using Path = System.IO.Path; namespace _13AddTraderWithAssortJson; @@ -14,28 +17,28 @@ namespace _13AddTraderWithAssortJson; public class AddTraderWithAssortJson : IPostDBLoadMod { private readonly ISptLogger _logger; - private readonly JsonUtil _jsonUtil; - private readonly FileUtil _fileUtil; + private readonly ModHelper _modHelper; private readonly DatabaseService _databaseService; private readonly ImageRouter _imageRouter; private readonly ConfigServer _configServer; + private readonly ICloner _cloner; private readonly TraderConfig _traderConfig; private readonly RagfairConfig _ragfairConfig; public AddTraderWithAssortJson( ISptLogger logger, - JsonUtil jsonUtil, - FileUtil fileUtil, + ModHelper modHelper, DatabaseService databaseService, ImageRouter imageRouter, - ConfigServer configServer) + ConfigServer configServer, + ICloner cloner) { _logger = logger; - _jsonUtil = jsonUtil; - _fileUtil = fileUtil; + _modHelper = modHelper; _databaseService = databaseService; _imageRouter = imageRouter; _configServer = configServer; + _cloner = cloner; _traderConfig = _configServer.GetConfig(); _ragfairConfig = _configServer.GetConfig(); @@ -43,17 +46,16 @@ public class AddTraderWithAssortJson : IPostDBLoadMod public void PostDBLoad() { - var traderImagePath = "./db/cat.jpg"; - - var baseJson = _fileUtil.ReadFile("./db/base.json"); - var traderBase = _jsonUtil.Deserialize(baseJson); + var pathToMod = _modHelper.GetAbsolutePathToModFolder(Assembly.GetExecutingAssembly()); - var assortJson = _fileUtil.ReadFile("./db/assort.json"); - var assort = _jsonUtil.Deserialize(assortJson); + var traderImagePath = Path.Combine(pathToMod, "db/cat.jpg"); + var traderBase = _modHelper.GetFileFromModFolder(pathToMod, "db/base.json"); + + var assort = _modHelper.GetFileFromModFolder(pathToMod, "db/assort.json"); // Create helper class and use it to register our traders image/icon + set its stock refresh time var addTraderHelper = new AddTraderHelper(); - _imageRouter.AddRoute(traderBase.Avatar.Replace(".jpg", ""), System.IO.Path.GetFullPath(traderImagePath)); + _imageRouter.AddRoute(traderBase.Avatar.Replace(".jpg", ""), traderImagePath); addTraderHelper.SetTraderUpdateTime(_traderConfig, traderBase, 3600, 4000); // Add trader to flea market @@ -72,8 +74,8 @@ public class AddTraderWithAssortJson : IPostDBLoadMod addTraderHelper.AddTraderToDb( traderBase, _databaseService.GetTables(), - _jsonUtil, - assortJson); + _cloner, + assort); addTraderHelper.AddTraderToLocales( traderBase, diff --git a/ModExamples/4ReadCustomJson5Config/ReadJson5Config.cs b/ModExamples/4ReadCustomJson5Config/ReadJson5Config.cs index 7f550a6a..fb5a5e0e 100644 --- a/ModExamples/4ReadCustomJson5Config/ReadJson5Config.cs +++ b/ModExamples/4ReadCustomJson5Config/ReadJson5Config.cs @@ -1,6 +1,7 @@ -using Core.Models.External; +using Core.Helpers; +using System.Reflection; +using Core.Models.External; using Core.Models.Utils; -using Core.Utils; using SptCommon.Annotations; namespace _4ReadCustomJson5Config @@ -9,28 +10,24 @@ namespace _4ReadCustomJson5Config public class ReadJson5Config: IPreSptLoadMod { private readonly ISptLogger _logger; - private readonly FileUtil _fileUtil; - private readonly JsonUtil _jsonUtil; + private readonly ModHelper _modHelper; public ReadJson5Config( ISptLogger logger, - FileUtil fileUtil, - JsonUtil jsonUtil) + ModHelper modHelper) { _logger = logger; - _fileUtil = fileUtil; - _jsonUtil = jsonUtil; + _modHelper = modHelper; } public void PreSptLoad() { - // Read the content of the config file into a string - var rawContent = _fileUtil.ReadFile("config.json5"); + var pathToMod = _modHelper.GetAbsolutePathToModFolder(Assembly.GetExecutingAssembly()); - // Take the string above and deserialise it into a config file with a type (defined between the diamond brackets) - var config = _jsonUtil.Deserialize(rawContent); + // TODO - fix/implement + var json5Config = _modHelper.GetFileFromModFolder(pathToMod, "config.json5"); - _logger.Success($"Read property: 'ExampleProperty' from config with value: {config.ExampleProperty}"); + _logger.Success($"Read property: 'ExampleProperty' from config with value: {json5Config.ExampleProperty}"); } } diff --git a/ModExamples/5ReadCustomJsonConfig/ReadJsonConfig.cs b/ModExamples/5ReadCustomJsonConfig/ReadJsonConfig.cs index 7b16729c..746e3834 100644 --- a/ModExamples/5ReadCustomJsonConfig/ReadJsonConfig.cs +++ b/ModExamples/5ReadCustomJsonConfig/ReadJsonConfig.cs @@ -1,4 +1,6 @@ -using Core.Models.External; +using System.Reflection; +using Core.Helpers; +using Core.Models.External; using Core.Models.Utils; using Core.Utils; using SptCommon.Annotations; @@ -9,26 +11,23 @@ namespace _5ReadCustomJsonConfig public class ReadJsonConfig : IPreSptLoadMod { private readonly ISptLogger _logger; - private readonly FileUtil _fileUtil; - private readonly JsonUtil _jsonUtil; + private readonly ModHelper _modHelper; public ReadJsonConfig( ISptLogger logger, - FileUtil fileUtil, - JsonUtil jsonUtil) + ModHelper modHelper) { _logger = logger; - _fileUtil = fileUtil; - _jsonUtil = jsonUtil; + _modHelper = modHelper; } public void PreSptLoad() { - // Read the content of the config file into a string - var rawContent = _fileUtil.ReadFile("config.json"); + // This will get us the full path to the mod, e.g. C:\spt\user\mods\5ReadCustomJsonConfig-0.0.1 + var pathToMod = _modHelper.GetAbsolutePathToModFolder(Assembly.GetExecutingAssembly()); - // Take the string above and deserialise it into a config file with a type (defined between the diamond brackets) - var config = _jsonUtil.Deserialize(rawContent); + // We give the path to the mod folder and the file we want to get, giving us the config, supply the files 'type' between the diamond brackets + var config = _modHelper.GetFileFromModFolder(pathToMod, "config.json"); _logger.Success($"Read property: 'ExampleProperty' from config with value: {config.ExampleProperty}"); } diff --git a/ModExamples/7UseMultipleClasses/SecondClass.cs b/ModExamples/7UseMultipleClasses/SecondClass.cs index e3c8440b..4cdbb5cb 100644 --- a/ModExamples/7UseMultipleClasses/SecondClass.cs +++ b/ModExamples/7UseMultipleClasses/SecondClass.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace _7UseMultipleClasses { diff --git a/ModExamples/TempReferences/Core.dll b/ModExamples/TempReferences/Core.dll index 7a59d266..a92a944d 100644 Binary files a/ModExamples/TempReferences/Core.dll and b/ModExamples/TempReferences/Core.dll differ diff --git a/ModExamples/TempReferences/SptCommon.dll b/ModExamples/TempReferences/SptCommon.dll index 4651fa1c..8ca856c4 100644 Binary files a/ModExamples/TempReferences/SptCommon.dll and b/ModExamples/TempReferences/SptCommon.dll differ diff --git a/ModExamples/TempReferences/SptDependencyInjection.dll b/ModExamples/TempReferences/SptDependencyInjection.dll index 067e4093..d5b647fe 100644 Binary files a/ModExamples/TempReferences/SptDependencyInjection.dll and b/ModExamples/TempReferences/SptDependencyInjection.dll differ