Update Mods to be foldered/ own csproj/ ref dll

This commit is contained in:
CWX
2025-02-10 15:04:40 +00:00
parent ed54312f35
commit 7cd8ef9179
49 changed files with 361 additions and 121 deletions
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_10CustomRoute</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,46 @@
using Core.DI;
using Core.Models.Utils;
using Core.Utils;
using SptCommon.Annotations;
namespace _10CustomRoute;
// Flag our mod as a type of static router
[Injectable(InjectableTypeOverride = typeof(StaticRouter))]
public class CustomStaticRouter : StaticRouter
{
public CustomStaticRouter(
JsonUtil jsonUtil) : base(
jsonUtil,
// Add an array of routes we want to add
GetCustomRoutes()
)
{
}
private static List<RouteAction> GetCustomRoutes()
{
return
[
new RouteAction(
"/example/route/static",
(
url,
info,
sessionId,
output
) => HandleRoute(url, info as ExampleStaticRequestData, sessionId)
)
];
}
private static string HandleRoute(string url, ExampleStaticRequestData info, string sessionId)
{
// Stuff goes here
return string.Empty;
}
}
public class ExampleStaticRequestData : IRequestData
{
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "10CustomStaticRouter",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_11RegisterClassesInDI</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,76 @@
using Core.Models.External;
using Core.Models.Utils;
using SptCommon.Annotations;
namespace _11RegisterClassesInDI;
[Injectable]
public class Bundle : IPostDBLoadMod // Run after db has loaded
{
private readonly SingletonClassExample _singletonClassExample;
private readonly TransientClassExample _transientClassExample;
// We inject 2 classes (singleton and transient) we've made below
public Bundle(
SingletonClassExample singletonClassExample,
TransientClassExample transientClassExample)
{
_singletonClassExample = singletonClassExample;
_transientClassExample = transientClassExample;
}
public void PostDBLoad()
{
_singletonClassExample.IncrementCounterAndLog();
_singletonClassExample.IncrementCounterAndLog();
_singletonClassExample.IncrementCounterAndLog();
_transientClassExample.IncrementCounterAndLog();
_transientClassExample.IncrementCounterAndLog();
_transientClassExample.IncrementCounterAndLog();
}
}
// This class is registered as a singleton. This means ONE and only ONE instance
// of this class will ever exist.
[Injectable(InjectionType.Singleton)]
public class SingletonClassExample
{
private readonly ISptLogger<SingletonClassExample> _logger;
private int _counter;
public SingletonClassExample(
ISptLogger<SingletonClassExample> logger)
{
_logger = logger;
_counter = 0;
}
public void IncrementCounterAndLog()
{
_counter++;
_logger.Success($"{_counter}");
}
}
// This class is being registered as default or transient. This means that
// every time a class requests an instance of this type a new one will be created
[Injectable(InjectionType.Transient)] // [Injectable] is the same as doing this
public class TransientClassExample
{
private readonly ISptLogger<TransientClassExample> _logger;
private int _counter;
public TransientClassExample(
ISptLogger<TransientClassExample> logger)
{
_logger = logger;
_counter = 0;
}
public void IncrementCounterAndLog()
{
_counter++;
_logger.Success($"{_counter}");
}
}
@@ -0,0 +1,13 @@
{
"Name": "11RegisterClassesInDI",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
+22
View File
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_12Bundle</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
+24
View File
@@ -0,0 +1,24 @@
using Core.Loaders;
using Core.Models.External;
using SptCommon.Annotations;
namespace _12Bundle;
[Injectable]
public class Bundle : IPostDBLoadMod
{
private readonly BundleLoader _bundleLoader;
public Bundle(
BundleLoader bundleLoader)
{
_bundleLoader = bundleLoader;
}
public void PostDBLoad()
{
var modFolder = Directory.GetCurrentDirectory();
_bundleLoader.AddBundles(modFolder);
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"manifest": [
{
"key": "assets/content/weapons/usable_items/item_bottle/textures/client_assets.bundle",
"dependencyKeys": []
}
]
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "12Bundle",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": true,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
+23
View File
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_1Logging</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
+36
View File
@@ -0,0 +1,36 @@
using Core.Models.External;
using Core.Models.Logging;
using Core.Models.Utils;
using SptCommon.Annotations;
namespace _1Logging;
[Injectable]
public class Logging : IPostSptLoadMod // Using this interface means our mod will run AFTER SPT has finished loading
{
// Our logger we create in the constructor below
private readonly ISptLogger<Logging> _logger;
// Constructor - Inject a 'ISptLogger' with your mods Class inside the diamond brackets
public Logging(
ISptLogger<Logging> logger
)
{
// Save the logger we're injecting into a private variable that is scoped to this class (only this class has access to it)
_logger = logger;
}
public void PostSptLoad()
{
// We can access the logger to assigned in the constructor here
_logger.Success("This is a success message");
_logger.Warning("This is a warning message");
_logger.Error("This is an error message");
_logger.Info("This is an info message");
_logger.Critical("this is a critical message");
// Logging with colors requires you to 'pass' the text color and background color
_logger.LogWithColor("This is a message with custom colors", LogTextColor.Red, LogBackgroundColor.Black);
_logger.Debug("This is a debug message that gets written to the log file, not the console");
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "1Logging",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_2EditDatabase</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,196 @@
using Core.Models.Enums;
using Core.Models.External;
using Core.Models.Utils;
using Core.Services;
using SptCommon.Annotations;
namespace _2EditDatabase;
[Injectable]
public class EditDatabaseValues : IPostDBLoadMod // Using this interface means our mod will run AFTER the SPT database has finished loading but BEFORE SPT code has run
{
private readonly DatabaseService _databaseService;
private readonly ISptLogger<EditDatabaseValues> _logger;
// Our constructor
public EditDatabaseValues(
DatabaseService databaseService,
ISptLogger<EditDatabaseValues> logger
)
{
_databaseService = databaseService;
_logger = logger;
}
public void PostDBLoad()
{
// When SPT starts, it stores all the data found in (SPT_Data\Server\database) in memory
// We can use the '_databaseService' we injected to access this data, this includes files from EFT and SPT
// Lets edit some globals settings to make the game easier
EditGlobals();
// Lets edit the BTR to have the christmas tarcola skin
EditBtr();
// Let's edit the hideout so it's easier to upgrade the lavatory
EditHideout();
// Lets edit the default scav (assault.json) to have different settings
EditScavSettings();
// Lets edit Customs
EditCustoms();
_logger.Success("Finished Editing Database");
}
private void EditGlobals()
{
// Let's edit settings in the GLOBALS file (database/globals.json)
var globals = _databaseService.GetGlobals();
// Let's edit the scav cooldown to be 1 second
globals.Configuration.SavagePlayCooldown = 1;
// Now lets try editing the ragfair unlock level, lets get the ragfair settings first
var ragfairSettings = globals.Configuration.RagFair;
// Lets set the level you need to be to access flea to be 1
ragfairSettings.MinUserLevel = 1;
// Now lets increase the number of offers you can have listed at one time
// The max is stored in a list, different flea ratings give different offer amounts
// We loop over all the settings, setting all of them to be 20
foreach (var offerCountSettings in ragfairSettings.MaxActiveOfferCount)
{
offerCountSettings.Count = 20;
}
}
private void EditBtr()
{
// BTR setting can be found in the GLOBALS file too
var globals = _databaseService.GetGlobals();
// We get the BTR settings from globals first
var btrSettings = globals.Configuration.BTRSettings;
// Let's get the settings for woods specifically, we use 'tryGetValue' for this, the settings will be stored in 'woodsBtrSettings'
btrSettings.MapsConfigs.TryGetValue("Woods", out var woodsBtrSettings);
// Lets set the BTR to use the christmas skin
woodsBtrSettings.BtrSkin = "Tarcola";
}
private void EditHideout()
{
// Hideout data can be found in (SPT_Data\Server\database\hideout)
var hideout = _databaseService.GetHideout();
// We want the areas, they're stored in a list
var hideoutAreas = hideout.Areas;
// We find the toilet, we use 'firstOrDefault', if we cant find the lavatory, 'lavatoryArea' will be null
var lavatoryArea = hideoutAreas.FirstOrDefault(area => area.Type == HideoutAreas.LAVATORY);
// Now we have the toilet, we can find the requirements to craft, all data is stored by stage
var toiletStages = lavatoryArea.Stages;
// Stages are stored in a dictionary, a dictionary has a 'key' and a 'value'
// In this case, the 'key' is the upgrade stage, e.g. "1", or "2"
// We reference to each stage as a 'stageKvP' this means 'Key value Pair', every key has a value (key = stage number, value = data for that stage)
foreach (var stageKvP in toiletStages)
{
// while we're here, we can make the stages craft really fast (60 seconds)
stageKvP.Value.ConstructionTime = 60;
// Let's get the stage requirements, they're a list
var stageRequirements = stageKvP.Value.Requirements;
// We empty the requirements out, now it can be built straight away
stageRequirements.Clear();
}
}
private void EditScavSettings()
{
var bots = _databaseService.GetBots();
// Same as the above example, we use 'TryGetValue' to get the 'assault' bot (assault is the internal name for scavs)
bots.Types.TryGetValue("assault", out var assaultBot);
// Let's make the chance to get a good backpack really high
assaultBot.BotInventory.Equipment.TryGetValue(EquipmentSlots.Backpack, out var backPacks);
// We access the backpacks dictionary by key directly using square brackets, we use ItemTpl to get the items ID
// Alternately, we could have typed backPacks["59e763f286f7742ee57895da"] and done the same thing, ItemTpl makes it easier to read
backPacks[ItemTpl.BACKPACK_PILGRIM_TOURIST] = 999999;
// Now lets make them always have an M4A1
assaultBot.BotInventory.Equipment.TryGetValue(EquipmentSlots.FirstPrimaryWeapon, out var primaryWeapons);
// We edit the weight value (pick chance) that is already there to be massive, making the item more likely to be picked
primaryWeapons[ItemTpl.ASSAULTRIFLE_COLT_M4A1_556X45_ASSAULT_RIFLE] = 999999;
// Now lets make them always have the first name of Gary
// We start by removing all the existing names
assaultBot.FirstNames.Clear();
// We add the new name Gary, very menacing
assaultBot.FirstNames.Add("Gary");
}
private void EditCustoms()
{
// Let's get all the maps (called locations)
var locations = _databaseService.GetLocations();
// Customs is called 'bigmap' in eft
var customs = locations.Bigmap;
// Lets get the exits and make them all 100% chance to appear
var exits = customs.Base.Exits;
// They're stored as a list so we can loop over them
foreach (var exit in exits)
{
// I can't remember which one is used, you'd assume ChancePVE is used in pve, but this is BSG we're dealing with
// So we set both
exit.Chance = 100;
exit.ChancePVE = 100;
}
// Lets try editing the airdrops on customs to be better
var airdropSettings = customs.Base.AirdropParameters;
// They're stored in an array but there's only one bunch of settings, it means we have to get the first item from the list,
// An alternate way to access the first item is done by using square brackets with the 'index' of the item we want,
// indexes start at 0 so we want to type "[0]" to access the first item in the list,
var actualAirdropSettings = airdropSettings.First();
// Make it spawn 100%
actualAirdropSettings.PlaneAirdropChance = 1; // Number between 0 and 1
// Make it spawn as early as start of raid
actualAirdropSettings.PlaneAirdropStartMin = 1;
// Let's make bosses spawn 100% of the time
// We get all the bosses, they're stored in a list
var bosses = customs.Base.BossLocationSpawn;
// Let's get Reshala, we use "FirstOrDefault" and look for the first boss with the name "bossBully"
var reshala = bosses.FirstOrDefault(boss => boss.BossName == "bossBully");
// Set him to 100%
reshala.BossChance = 100;
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "2EditDatabase",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_3EditSptConfig</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
+86
View File
@@ -0,0 +1,86 @@
using Core.Models.Enums;
using Core.Models.External;
using Core.Models.Spt.Config;
using Core.Models.Utils;
using Core.Servers;
using SptCommon.Annotations;
namespace _3EditSptConfig;
[Injectable]
public class EditConfigs : IPostDBLoadMod
{
private readonly AirdropConfig _airdropConfig;
private readonly BotConfig _botConfig;
private readonly ConfigServer _configServer;
private readonly HideoutConfig _hideoutConfig;
private readonly ISptLogger<EditConfigs> _logger;
private readonly PmcChatResponse _pmcChatResponseConfig;
private readonly PmcConfig _pmcConfig;
private readonly QuestConfig _questConfig;
private readonly WeatherConfig _weatherConfig;
// We access configs via ConfigServer
public EditConfigs(
ConfigServer configServer,
ISptLogger<EditConfigs> logger
)
{
_configServer = configServer;
_logger = logger;
// We get the bot config by calling GetConfig and passing the configs 'type' within the diamond brackets
_botConfig = _configServer.GetConfig<BotConfig>();
_hideoutConfig = _configServer.GetConfig<HideoutConfig>();
_weatherConfig = _configServer.GetConfig<WeatherConfig>();
_airdropConfig = _configServer.GetConfig<AirdropConfig>();
_pmcChatResponseConfig = _configServer.GetConfig<PmcChatResponse>();
_questConfig = _configServer.GetConfig<QuestConfig>();
_pmcConfig = _configServer.GetConfig<PmcConfig>();
}
public void PostDBLoad()
{
// Let's edit the weather config to force the season to winter
_weatherConfig.OverrideSeason = Season.WINTER;
// Let's edit the hideout config to Make all crafts take 60 seconds
_hideoutConfig.OverrideCraftTimeSeconds = 60;
// Let's edit the hideout config to Make all upgrades take 60 seconds
_hideoutConfig.OverrideBuildTimeSeconds = 60;
// Let's edit the airdrop config to Make weapon/armor drops REALLY common
_airdropConfig.AirdropTypeWeightings[SptAirdropTypeEnum.weaponArmor] = 999;
// Let's edit the airdrop config to Make weapon/armor drops always have 3 sealed weapon crates
var weaponCrateMinMax = _airdropConfig.Loot["weaponArmor"].WeaponCrateCount;
weaponCrateMinMax.Min = 3;
weaponCrateMinMax.Max = 3;
// Let's make PMCs always mail you when they kill you
_pmcChatResponseConfig.Killer.ResponseChancePercent = 100;
// Let's make quest rewards sent to you via mail last for over a week for unheard profiles
_questConfig.MailRedeemTimeHours["unheard_edition"] = 168;
// Let's make the interchange bot cap huge
_botConfig.MaxBotCap["interchange"] = 50;
// Let's disable loot on scavs
_botConfig.DisableLootOnBotTypes.Add("assault");
// Let's make the conversion rate of scavs to pmcs 100% on factory day
var factory4DayConversionSettings = _pmcConfig.ConvertIntoPmcChance["factory4_day"];
// We get assault bot settings for factory day
var assaultConversionSettings = factory4DayConversionSettings["assault"];
// Set min and max to 100%
assaultConversionSettings.Min = 100;
assaultConversionSettings.Max = 100;
_logger.Success("Finished Editing Configs");
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "3EditSptConfig",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_4ReadCustomJson5Config</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,42 @@
using Core.Models.External;
using Core.Models.Utils;
using Core.Utils;
using SptCommon.Annotations;
namespace _4ReadCustomJson5Config
{
[Injectable]
public class ReadJson5Config: IPreSptLoadMod
{
private readonly ISptLogger<ReadJson5Config> _logger;
private readonly FileUtil _fileUtil;
private readonly JsonUtil _jsonUtil;
public ReadJson5Config(
ISptLogger<ReadJson5Config> logger,
FileUtil fileUtil,
JsonUtil jsonUtil)
{
_logger = logger;
_fileUtil = fileUtil;
_jsonUtil = jsonUtil;
}
public void PreSptLoad()
{
// Read the content of the config file into a string
var rawContent = _fileUtil.ReadFile("config.json5");
// Take the string above and deserialise it into a config file with a type (defined between the diamond brackets)
var config = _jsonUtil.Deserialize<ModConfig>(rawContent);
_logger.Success($"Read property: 'ExampleProperty' from config with value: {config.ExampleProperty}");
}
}
// This class should represent your config structure
public class ModConfig
{
public string ExampleProperty { get; set; }
}
}
@@ -0,0 +1,4 @@
{
// Comment goes here, wow
"ExampleProperty": "boop"
}
@@ -0,0 +1,13 @@
{
"Name": "4ReadCustomJson5Config",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_5ReadCustomJsonConfig</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,45 @@
using Core.Models.External;
using Core.Models.Utils;
using Core.Utils;
using SptCommon.Annotations;
namespace _5ReadCustomJsonConfig
{
[Injectable]
public class ReadJsonConfig : IPreSptLoadMod
{
private readonly ISptLogger<ReadJsonConfig> _logger;
private readonly FileUtil _fileUtil;
private readonly JsonUtil _jsonUtil;
public ReadJsonConfig(
ISptLogger<ReadJsonConfig> logger,
FileUtil fileUtil,
JsonUtil jsonUtil)
{
_logger = logger;
_fileUtil = fileUtil;
_jsonUtil = jsonUtil;
}
public void PreSptLoad()
{
// Read the content of the config file into a string
var rawContent = _fileUtil.ReadFile("config.json");
// Take the string above and deserialise it into a config file with a type (defined between the diamond brackets)
var config = _jsonUtil.Deserialize<ModConfig>(rawContent);
_logger.Success($"Read property: 'ExampleProperty' from config with value: {config.ExampleProperty}");
}
}
// This class should represent your config structure
public class ModConfig
{
public string ExampleProperty
{
get; set;
}
}
}
@@ -0,0 +1,3 @@
{
"ExampleProperty": "boop"
}
@@ -0,0 +1,13 @@
{
"Name": "5ReadCustomConfig",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_6OverrideMethod</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,29 @@
using Core.Models.Utils;
using Core.Servers;
using Core.Services;
using Core.Utils;
using SptCommon.Annotations;
namespace _6OverrideMethod
{
[Injectable(InjectableTypeOverride = typeof(Watermark))]
public class OverrideMethod: Watermark
{
public OverrideMethod(
ISptLogger<Watermark> logger, // The logger needs to use the same type as the overriden type (in this case, Watermark)
ConfigServer configServer,
LocalisationService localisationService,
WatermarkLocale watermarkLocale)
: base(logger, configServer, localisationService, watermarkLocale) // You must provide the parameters the overridden type requires
{ }
public override void Initialize()
{
// We add a log message to the init method
_logger.Success("This is a watermark mod override!");
// This runs the original method (optional)
base.Initialize();
}
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "6OverrideMethod",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_7UseMultipleClasses</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _7UseMultipleClasses
{
public class SecondClass
{
public string GetText()
{
return "test text";
}
}
}
@@ -0,0 +1,31 @@
using Core.Models.External;
using Core.Models.Utils;
namespace _7UseMultipleClasses
{
/// <summary>
/// Having multiple classes can make keeping your code maintainable easier, you can split related code into their own class
/// </summary>
public class UseMultipleClasses : IPostDBLoadMod
{
private readonly ISptLogger<UseMultipleClasses> _logger;
public UseMultipleClasses(
ISptLogger<UseMultipleClasses> logger)
{
this._logger = logger;
}
public void PostDBLoad()
{
// We create an instance of the other class
var otherClass = new SecondClass();
// We call the "GetText" method that exists in the other class
var text = otherClass.GetText();
// Log the result to the server console
_logger.Info($"The SecondClass returned the text: {text}");
}
}
}
@@ -0,0 +1,13 @@
{
"Name": "7UseMultipleClasses",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
+22
View File
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_8OnLoad</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
+33
View File
@@ -0,0 +1,33 @@
using Core.DI;
using Core.Models.Utils;
using SptCommon.Annotations;
namespace _8OnLoad
{
// Flag class as being OnLoad and give it a load priority, check `OnLoadOrder` for list of possible choices
[Injectable(InjectableTypeOverride = typeof(IOnLoad), TypePriority = OnLoadOrder.PostSptDatabase)] // Can also give an int value for fine-grained control
[Injectable(InjectableTypeOverride = typeof(OnLoadExample))]
public class OnLoadExample : IOnLoad // Must implement the IOnLoad interface
{
private readonly ISptLogger<OnLoadExample> _logger;
public OnLoadExample(
ISptLogger<OnLoadExample> logger)
{
_logger = logger;
}
public Task OnLoad()
{
// Can do work here
_logger.Success($"Mod loaded after database!");
return Task.CompletedTask;
}
public string GetRoute()
{
return "mod-load-example";
}
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "8OnLoadExample",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
+22
View File
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>_9OnUpdate</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Change to Nuget Package -->
<ItemGroup>
<Reference Include="Core">
<HintPath>..\TempReferences\Core.dll</HintPath>
</Reference>
<Reference Include="SptCommon">
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
</Reference>
<Reference Include="SptDependencyInjection">
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
+33
View File
@@ -0,0 +1,33 @@
using Core.DI;
using Core.Models.Utils;
using SptCommon.Annotations;
namespace _9OnUpdate
{
// Flag class as being OnLoad and give it a load priority, check `OnLoadOrder` for list of possible choices
[Injectable(InjectableTypeOverride = typeof(IOnUpdate), TypePriority = OnUpdateOrder.PostSptUpdate)] // Can also give it an int value for more fine-grained control
[Injectable(InjectableTypeOverride = typeof(OnUpdateExample))]
public class OnUpdateExample : IOnUpdate // Must implement the IOnUpdate interface
{
private readonly ISptLogger<OnUpdateExample> _logger;
public OnUpdateExample(
ISptLogger<OnUpdateExample> logger)
{
_logger = logger;
}
public bool OnUpdate(long timeSinceLastRun)
{
// Can do work here
_logger.Success($"Mod running update after SPT updates have run!");
return true; // Return true for a success, false for failure
}
public string GetRoute()
{
return "mod-update-example";
}
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "9OnUpdateExample",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
+82
View File
@@ -0,0 +1,82 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "1Logging", "1Logging\1Logging.csproj", "{98270ED7-04C7-4F90-91B1-820C672CE123}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2EditDatabase", "2EditDatabase\2EditDatabase.csproj", "{42BF3751-D744-4373-B5CC-704A0CCA0106}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "3EditSptConfig", "3EditSptConfig\3EditSptConfig.csproj", "{CE1A0F24-D1CB-4E12-8462-13641A7FB964}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "4ReadCustomJson5Config", "4ReadCustomJson5Config\4ReadCustomJson5Config.csproj", "{CEFCC99D-C0C7-4894-93D9-3B6F3BAFD92F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "5ReadCustomJsonConfig", "5ReadCustomJsonConfig\5ReadCustomJsonConfig.csproj", "{00CE855D-299F-4700-84C2-0567060593DF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "6OverrideMethod", "6OverrideMethod\6OverrideMethod.csproj", "{494C6DB5-EAD2-4DCA-871A-34675D2452DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "7UseMultipleClasses", "7UseMultipleClasses\7UseMultipleClasses.csproj", "{B6DE92DC-7ADB-4E5E-BECF-68C829D7CBCA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "8OnLoad", "8OnLoad\8OnLoad.csproj", "{556E07A1-E399-4761-89C0-AC74E6A20BA1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "9OnUpdate", "9OnUpdate\9OnUpdate.csproj", "{113E9B1C-25E4-4DB3-9724-A48684A40B91}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "10CustomRoute", "10CustomRoute\10CustomRoute.csproj", "{4AF609A6-91C8-48CC-8D4B-9454864C98E2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "11RegisterClassesInDI", "11RegisterClassesInDI\11RegisterClassesInDI.csproj", "{5B705F9E-7F4F-491A-8215-30EE5B5D77B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "12Bundle", "12Bundle\12Bundle.csproj", "{FE769EA8-4F31-4426-90A3-A1EFA8A43D6E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{98270ED7-04C7-4F90-91B1-820C672CE123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98270ED7-04C7-4F90-91B1-820C672CE123}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98270ED7-04C7-4F90-91B1-820C672CE123}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98270ED7-04C7-4F90-91B1-820C672CE123}.Release|Any CPU.Build.0 = Release|Any CPU
{42BF3751-D744-4373-B5CC-704A0CCA0106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42BF3751-D744-4373-B5CC-704A0CCA0106}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42BF3751-D744-4373-B5CC-704A0CCA0106}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42BF3751-D744-4373-B5CC-704A0CCA0106}.Release|Any CPU.Build.0 = Release|Any CPU
{CE1A0F24-D1CB-4E12-8462-13641A7FB964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE1A0F24-D1CB-4E12-8462-13641A7FB964}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE1A0F24-D1CB-4E12-8462-13641A7FB964}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE1A0F24-D1CB-4E12-8462-13641A7FB964}.Release|Any CPU.Build.0 = Release|Any CPU
{CEFCC99D-C0C7-4894-93D9-3B6F3BAFD92F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CEFCC99D-C0C7-4894-93D9-3B6F3BAFD92F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CEFCC99D-C0C7-4894-93D9-3B6F3BAFD92F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CEFCC99D-C0C7-4894-93D9-3B6F3BAFD92F}.Release|Any CPU.Build.0 = Release|Any CPU
{00CE855D-299F-4700-84C2-0567060593DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00CE855D-299F-4700-84C2-0567060593DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00CE855D-299F-4700-84C2-0567060593DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00CE855D-299F-4700-84C2-0567060593DF}.Release|Any CPU.Build.0 = Release|Any CPU
{494C6DB5-EAD2-4DCA-871A-34675D2452DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{494C6DB5-EAD2-4DCA-871A-34675D2452DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{494C6DB5-EAD2-4DCA-871A-34675D2452DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{494C6DB5-EAD2-4DCA-871A-34675D2452DE}.Release|Any CPU.Build.0 = Release|Any CPU
{B6DE92DC-7ADB-4E5E-BECF-68C829D7CBCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6DE92DC-7ADB-4E5E-BECF-68C829D7CBCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6DE92DC-7ADB-4E5E-BECF-68C829D7CBCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6DE92DC-7ADB-4E5E-BECF-68C829D7CBCA}.Release|Any CPU.Build.0 = Release|Any CPU
{556E07A1-E399-4761-89C0-AC74E6A20BA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{556E07A1-E399-4761-89C0-AC74E6A20BA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{556E07A1-E399-4761-89C0-AC74E6A20BA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{556E07A1-E399-4761-89C0-AC74E6A20BA1}.Release|Any CPU.Build.0 = Release|Any CPU
{113E9B1C-25E4-4DB3-9724-A48684A40B91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{113E9B1C-25E4-4DB3-9724-A48684A40B91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{113E9B1C-25E4-4DB3-9724-A48684A40B91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{113E9B1C-25E4-4DB3-9724-A48684A40B91}.Release|Any CPU.Build.0 = Release|Any CPU
{4AF609A6-91C8-48CC-8D4B-9454864C98E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AF609A6-91C8-48CC-8D4B-9454864C98E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AF609A6-91C8-48CC-8D4B-9454864C98E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AF609A6-91C8-48CC-8D4B-9454864C98E2}.Release|Any CPU.Build.0 = Release|Any CPU
{5B705F9E-7F4F-491A-8215-30EE5B5D77B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B705F9E-7F4F-491A-8215-30EE5B5D77B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B705F9E-7F4F-491A-8215-30EE5B5D77B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B705F9E-7F4F-491A-8215-30EE5B5D77B0}.Release|Any CPU.Build.0 = Release|Any CPU
{FE769EA8-4F31-4426-90A3-A1EFA8A43D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE769EA8-4F31-4426-90A3-A1EFA8A43D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE769EA8-4F31-4426-90A3-A1EFA8A43D6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE769EA8-4F31-4426-90A3-A1EFA8A43D6E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Binary file not shown.
Binary file not shown.