Merge branch 'develop'

This commit is contained in:
Refringe
2025-03-07 19:07:05 -05:00
1468 changed files with 168020 additions and 138513 deletions
+143 -4
View File
@@ -1,11 +1,150 @@
# editorconfig.org
# top-most EditorConfig file
root = true
# Default settings:
# A newline ending every file
# Use 4 spaces as indentation
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 4
[*.md]
trim_trailing_whitespace = true
[*.json]
ij_formatter_enabled = false
# C# files
[*.cs]
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# ReSharper properties
resharper_wrap_object_and_collection_initializer_style = chop_always
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current
# Modifier preferences
csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:suggestion
# avoid this. unless absolutely necessary
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_property = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_event = false
# Types: use keywords instead of BCL types, and permit var only when the type is clear
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
# Code style defaults
csharp_using_directive_placement = outside_namespace:error
dotnet_sort_system_directives_first = true
csharp_prefer_braces = true:warning
csharp_preserve_single_line_blocks = false
csharp_preserve_single_line_statements = false
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_simple_using_statement = false:none
csharp_style_prefer_switch_expression = true:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_inferred_tuple_names = false:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = false:suggestion
dotnet_style_prefer_auto_properties = false:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
csharp_prefer_simple_default_expression = true:suggestion
# Expression-bodied members
csharp_style_expression_bodied_methods = false:warning
csharp_style_expression_bodied_constructors = false:warning
csharp_style_expression_bodied_operators = false:warning
csharp_style_expression_bodied_properties = false:warning
csharp_style_expression_bodied_indexers = false:warning
csharp_style_expression_bodied_accessors = false:warning
csharp_style_expression_bodied_lambdas = false:warning
csharp_style_expression_bodied_local_functions = false:warning
# Pattern matching
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
# Null checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Other features
csharp_style_prefer_index_operator = false:none
csharp_style_prefer_range_operator = false:none
csharp_style_pattern_local_over_anonymous_function = false:none
# Space preferences
csharp_space_after_cast = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_square_brackets = false
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
indent_size = 2
[*.{csproj,vbproj,proj,nativeproj,locproj}]
charset = utf-8
+3 -2
View File
@@ -2,8 +2,9 @@ name: Build
on:
push:
branches:
- main
branches: ["main"]
pull_request:
branches: ["*"]
jobs:
build:
+2 -2
View File
@@ -1,8 +1,8 @@
name: Tests
on:
#push:
# branches: ["main"]
push:
branches: ["main"]
pull_request:
branches: ["*"]
+2
View File
@@ -423,3 +423,5 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
launchSettings.json
+24
View File
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\Build.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0"/>
<ProjectReference Include="..\Libraries\SPTarkov.Server.Core\SPTarkov.Server.Core.csproj" />
<ProjectReference Include="..\Libraries\SPTarkov.Server.Assets\SPTarkov.Server.Assets.csproj" />
<ProjectReference Include="..\Libraries\SPTarkov.Common\SPTarkov.Common.csproj" />
<ProjectReference Include="..\Libraries\SPTarkov.DI\SPTarkov.DI.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
+50
View File
@@ -0,0 +1,50 @@
using BenchmarkDotNet.Attributes;
using Benchmarks.Mock;
using SPTarkov.Server.Core.Models.Spt.Templates;
using SPTarkov.Server.Core.Utils;
using SPTarkov.Server.Core.Utils.Cloners;
namespace Benchmarks;
[SimpleJob(warmupCount: 10, iterationCount: 10)]
[MemoryDiagnoser]
public class ClonerBenchmarks
{
private Templates? _templates;
private ICloner _jsonCloner;
private ICloner _reflectionsCloner;
private ICloner _fastCloner;
[GlobalSetup]
public void Setup()
{
var jsonUtil = new JsonUtil();
var importer = new ImporterUtil(new MockLogger<ImporterUtil>(), new FileUtil(new MockLogger<FileUtil>()),
jsonUtil);
var loadTask = importer.LoadRecursiveAsync<Templates>("./Assets/database/templates/");
loadTask.Wait();
_templates = loadTask.Result;
_jsonCloner = new JsonCloner(jsonUtil);
_reflectionsCloner = new ReflectionsCloner(new MockLogger<ReflectionsCloner>());
_fastCloner = new SPTarkov.Server.Core.Utils.Cloners.FastCloner();
}
[Benchmark]
public void JsonCloner()
{
_jsonCloner.Clone(_templates);
}
[Benchmark]
public void ReflectionsCloner()
{
_reflectionsCloner.Clone(_templates);
}
[Benchmark(Baseline = true)]
public void FastCloner()
{
_fastCloner.Clone(_templates);
}
}
+68
View File
@@ -0,0 +1,68 @@
using SPTarkov.Server.Core.Models.Logging;
using SPTarkov.Server.Core.Models.Spt.Logging;
using SPTarkov.Server.Core.Models.Utils;
namespace Benchmarks.Mock;
public class MockLogger<T> : ISptLogger<T>
{
public void LogWithColor(string data, LogTextColor? textColor = null, LogBackgroundColor? backgroundColor = null, Exception? ex = null)
{
throw new NotImplementedException();
}
public void Success(string data, Exception? ex = null)
{
Console.WriteLine(data);
}
public void Error(string data, Exception? ex = null)
{
Console.WriteLine(data);
}
public void Warning(string data, Exception? ex = null)
{
Console.WriteLine(data);
}
public void Info(string data, Exception? ex = null)
{
Console.WriteLine(data);
}
public void Debug(string data, Exception? ex = null)
{
Console.WriteLine(data);
}
public void Critical(string data, Exception? ex = null)
{
Console.WriteLine(data);
}
public void WriteToLogFile(string body, LogLevel level = LogLevel.Info)
{
throw new NotImplementedException();
}
public bool IsLogEnabled(LogLevel level)
{
return false;
}
public void LogWithColor(
string data,
Exception? ex = null,
LogTextColor? textColor = null,
LogBackgroundColor? backgroundColor = null
)
{
Console.WriteLine(data);
}
public void WriteToLogFile(object body)
{
Console.WriteLine(body);
}
}
+12
View File
@@ -0,0 +1,12 @@
using BenchmarkDotNet.Running;
namespace Benchmarks;
public class Program
{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<ClonerBenchmarks>();
Console.WriteLine(summary);
}
}
+11
View File
@@ -0,0 +1,11 @@
<Project>
<PropertyGroup>
<Version>4.0.0-prerelease2</Version>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<RepositoryType>Git</RepositoryType>
</PropertyGroup>
</Project>
-29
View File
@@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Libraries\Core\Core.csproj">
<Private>false</Private>
<CopyLocal>false</CopyLocal>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</ProjectReference>
<ProjectReference Include="..\Libraries\SptDependencyInjection\SptDependencyInjection.csproj">
<Private>false</Private>
<CopyLocal>false</CopyLocal>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</ProjectReference>
<ProjectReference Include="..\SptCommon\SptCommon.csproj">
<Private>false</Private>
<CopyLocal>false</CopyLocal>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</ProjectReference>
</ItemGroup>
</Project>
-75
View File
@@ -1,75 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Enums;
using Core.Models.Spt.Config;
using Core.Servers;
namespace ExampleMods.Mods;
[Injectable]
public class EditConfigs
{
private readonly ConfigServer _configServer;
private readonly BotConfig _botConfig;
private readonly HideoutConfig _hideoutConfig;
private readonly WeatherConfig _weatherConfig;
private readonly AirdropConfig _airdropConfig;
private readonly PmcChatResponse _pmcChatResponseConfig;
private readonly QuestConfig _questConfig;
private readonly PmcConfig _pmcConfig;
// We access configs via ConfigServer
public EditConfigs(
ConfigServer configServer)
{
_configServer = configServer;
// 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>();
Run();
}
public void Run()
{
// Let's edit the weather config to make the season 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 if you have an unheard profile
_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"];
var assaultConversionSettings = factory4DayConversionSettings["assault"];
assaultConversionSettings.Min = 100;
assaultConversionSettings.Max = 100;
}
}
-189
View File
@@ -1,189 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Eft.Hideout;
using Core.Models.Enums;
using Core.Models.Utils;
using Core.Services;
namespace ExampleMods.Mods;
[Injectable]
public class EditDatabaseValues
{
private readonly DatabaseService _databaseService;
public EditDatabaseValues(
DatabaseService databaseService)
{
_databaseService = databaseService;
Run();
}
public void Run()
{
// 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 to
EditScavSettings();
// Lets edit Customs
EditCustoms();
}
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;
}
}
-41
View File
@@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SptCommon.Annotations;
using Core.Models.Logging;
using Core.Models.Utils;
namespace ExampleMods.Mods;
[Injectable]
public class Logging
{
private readonly ISptLogger<Logging> _logger;
// Constructor - Inject a 'ISptLogger' with your mods Class in 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;
// Not 100% necessary but let's split our code out into a method to make it easier to read
Run();
}
public void Run()
{
// 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");
}
}
@@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
</Project>
@@ -1,33 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Utils;
using Core.Servers;
using Core.Services;
using Core.Utils;
namespace ExampleMods.Mods.Override;
[Injectable(InjectableTypeOverride = typeof(Watermark))]
public class WatermarkOverride(
ISptLogger<Watermark> _logger,
ConfigServer _configServer,
LocalisationService _localisationService,
WatermarkLocale _watermarkLocale
) : Watermark(
_logger,
_configServer,
_localisationService,
_watermarkLocale
) // was testing overriding with primary constructors, works fine from what i can see
{
public override void Initialize()
{
_logger.Success("This is a watermark mod override!");
base.Initialize();
}
// public override string GetVersionTag(bool withEftVersion = false)
// {
// // _logger.Success("asdasdasda");
// return base.GetVersionTag(withEftVersion);
// }
}
@@ -1,37 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.Models.Eft.Common;
using Core.Utils;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(AchievementCallbacks))]
public class AchievementCallbacks(
AchievementController _achievementController,
HttpResponseUtil _httpResponseUtil
)
{
/// <summary>
/// Handle client/achievement/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetAchievements(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_achievementController.GetAchievements(sessionID));
}
/// <summary>
/// Handle client/achievement/statistic
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string Statistic(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_achievementController.GetAchievementStatics(sessionID));
}
}
@@ -1,79 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.Models.Eft.Builds;
using Core.Models.Eft.Common;
using Core.Models.Eft.PresetBuild;
using Core.Utils;
namespace Core.Callbacks;
[Injectable]
public class BuildsCallbacks(
HttpResponseUtil _httpResponseUtil,
BuildController _buildController
)
{
/// <summary>
/// Handle client/builds/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetBuilds(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_buildController.GetUserBuilds(sessionID));
}
/// <summary>
/// Handle client/builds/magazine/save
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string CreateMagazineTemplate(string url, SetMagazineRequest info, string sessionID)
{
_buildController.CreateMagazineTemplate(sessionID, info);
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/builds/weapon/save
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SetWeapon(string url, PresetBuildActionRequestData info, string sessionID)
{
_buildController.SaveWeaponBuild(sessionID, info);
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/builds/equipment/save
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SetEquipment(string url, PresetBuildActionRequestData info, string sessionID)
{
_buildController.SaveEquipmentBuild(sessionID, info);
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/builds/delete
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string DeleteBuild(string url, RemoveBuildRequestData info, string sessionID)
{
_buildController.RemoveBuild(sessionID, info);
return _httpResponseUtil.NullResponse();
}
}
@@ -1,30 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Eft.Common;
using Core.Utils;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(BundleCallbacks))]
public class BundleCallbacks(
HttpResponseUtil _httpResponseUtil
// BundleLoader _bundleLoader,
)
{
/// <summary>
/// Handle singleplayer/bundles
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetBundles(string url, EmptyRequestData info, string sessionID)
{
// return _httpResponseUtil.NoBody(_bundleLoader.GetBundles());
return _httpResponseUtil.NoBody(new List<object>());
}
public string GetBundle(string url, object info, string sessionID)
{
return "BUNDLE";
}
}
@@ -1,92 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Customization;
using Core.Models.Eft.ItemEvent;
using Core.Servers;
using Core.Utils;
namespace Core.Callbacks;
[Injectable]
public class CustomizationCallbacks(
CustomizationController _customizationController,
SaveServer _saveServer,
HttpResponseUtil _httpResponseUtil
)
{
/// <summary>
/// Handle client/trading/customization/storage
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetCustomisationUnlocks(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_saveServer.GetProfile(sessionID).CustomisationUnlocks);
}
/// <summary>
/// Handle client/trading/customization
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetTraderSuits(string url, EmptyRequestData info, string sessionID)
{
var splitUrl = url.Split('/');
var traderId = splitUrl[^3];
return _httpResponseUtil.GetBody(_customizationController.GetTraderSuits(traderId, sessionID));
}
/// <summary>
/// Handle CustomizationBuy event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public ItemEventRouterResponse BuyCustomisation(PmcData pmcData, BuyClothingRequestData info, string sessionID)
{
return _customizationController.BuyCustomisation(pmcData, info, sessionID);
}
/// <summary>
/// Handle client/hideout/customization/offer/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetHideoutCustomisation(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_customizationController.GetHideoutCustomisation(sessionID, info));
}
/// <summary>
/// Handle client/customization/storage
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetStorage(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_customizationController.GetCustomisationStorage(sessionID, info));
}
/// <summary>
/// Handle CustomizationSet
/// </summary>
/// <param name="pmcData"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public ItemEventRouterResponse SetCustomisation(PmcData pmcData, CustomizationSetRequest info, string sessionID)
{
return _customizationController.SetCustomisation(sessionID, info, pmcData);
}
}
@@ -1,329 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.DI;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Dialog;
using Core.Utils;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(OnUpdate), TypePriority = OnUpdateOrder.DialogueCallbacks)]
[Injectable(InjectableTypeOverride = typeof(DialogueCallbacks))]
public class DialogueCallbacks(
HashUtil _hashUtil,
TimeUtil _timeUtil,
HttpResponseUtil _httpResponseUtil,
DialogueController _dialogueController
)
: OnUpdate
{
/// <summary>
/// Handle client/friend/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetFriendList(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.GetFriendList(sessionID));
}
/// <summary>
/// Handle client/chatServer/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetChatServerList(string url, GetChatServerListRequestData info, string sessionID)
{
var chatServer = new List<ChatServer>
{
new()
{
Id = _hashUtil.Generate(),
RegistrationId = 20,
DateTime = _timeUtil.GetTimeStamp(),
IsDeveloper = true,
Regions = ["EUR"],
VersionId = "bgkidft87ddd",
Ip = "",
Port = 0,
Chats = [new Chat { Id = "0", Members = 0 }]
}
};
return _httpResponseUtil.GetBody(chatServer);
}
/// <summary>
/// Handle client/mail/dialog/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetMailDialogList(string url, GetMailDialogListRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.GenerateDialogueList(sessionID), 0, null, false);
}
/// <summary>
/// Handle client/mail/dialog/view
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetMailDialogView(string url, GetMailDialogViewRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.GenerateDialogueView(info, sessionID), 0, null, false);
}
/// <summary>
/// Handle client/mail/dialog/info
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetMailDialogInfo(string url, GetMailDialogInfoRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.GetDialogueInfo(info.DialogId, sessionID));
}
/// <summary>
/// Handle client/mail/dialog/remove
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string RemoveDialog(string url, RemoveDialogRequestData info, string sessionID)
{
_dialogueController.RemoveDialogue(info.DialogId, sessionID);
return _httpResponseUtil.EmptyArrayResponse();
}
/// <summary>
/// Handle client/mail/dialog/pin
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string PinDialog(string url, PinDialogRequestData info, string sessionID)
{
_dialogueController.SetDialoguePin(info.DialogId, true, sessionID);
return _httpResponseUtil.EmptyArrayResponse();
}
/// <summary>
/// Handle client/mail/dialog/unpin
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string UnpinDialog(string url, PinDialogRequestData info, string sessionID)
{
_dialogueController.SetDialoguePin(info.DialogId, false, sessionID);
return _httpResponseUtil.EmptyArrayResponse();
}
/// <summary>
/// Handle client/mail/dialog/read
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SetRead(string url, SetDialogReadRequestData info, string sessionID)
{
_dialogueController.SetRead(info.Dialogs, sessionID);
return _httpResponseUtil.EmptyArrayResponse();
}
/// <summary>
/// Handle client/mail/dialog/getAllAttachments
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetAllAttachments(string url, GetAllAttachmentsRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.GetAllAttachments(info.DialogId, sessionID));
}
/// <summary>
/// Handle client/mail/msg/send
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SendMessage(string url, SendMessageRequest info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.SendMessage(sessionID, info));
}
/// <summary>
/// Handle client/friend/request/list/outbox
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string ListOutbox(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.EmptyArrayResponse();
}
/// <summary>
/// Handle client/friend/request/list/inbox
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string ListInbox(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.EmptyArrayResponse();
}
/// <summary>
/// Handle client/friend/request/send
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SendFriendRequest(string url, FriendRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_dialogueController.SendFriendRequest(sessionID, info));
}
/// <summary>
/// Handle client/friend/request/accept-all
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string AcceptAllFriendRequests(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/friend/request/accept
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string AcceptFriendRequest(string url, AcceptFriendRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(true);
}
/// <summary>
/// Handle client/friend/request/decline
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string DeclineFriendRequest(string url, DeclineFriendRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(true);
}
/// <summary>
/// Handle client/friend/request/cancel
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string CancelFriendRequest(string url, CancelFriendRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(true);
}
/// <summary>
/// Handle client/friend/delete
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string DeleteFriend(string url, DeleteFriendRequest info, string sessionID)
{
_dialogueController.DeleteFriend(sessionID, info);
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/friend/ignore/set
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string IgnoreFriend(string url, UIDRequestData info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/friend/ignore/remove
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string UnIgnoreFriend(string url, UIDRequestData info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
public string ClearMail(string url, ClearMailMessageRequest info, string sessionID)
{
return _httpResponseUtil.EmptyArrayResponse();
}
public string CreateGroupMail(string url, CreateGroupMailRequest info, string sessionID)
{
return _httpResponseUtil.EmptyArrayResponse();
}
public string ChangeMailGroupOwner(string url, ChangeGroupMailOwnerRequest info, string sessionID)
{
return "Not Implemented!"; // Not implemented in Node
}
public string AddUserToMail(string url, AddUserGroupMailRequest info, string sessionID)
{
return "Not Implemented!"; // Not implemented in Node
}
public string RemoveUserFromMail(string url, RemoveUserGroupMailRequest info, string sessionID)
{
return "Not Implemented!"; // Not implemented in Node
}
public bool OnUpdate(long timeSinceLastRun)
{
_dialogueController.Update();
return true;
}
public string GetRoute()
{
return "spt-dialogue";
}
}
-217
View File
@@ -1,217 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.DI;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Game;
using Core.Servers;
using Core.Utils;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(OnLoad), TypePriority = OnLoadOrder.GameCallbacks)]
[Injectable(InjectableTypeOverride = typeof(GameCallbacks))]
public class GameCallbacks(
HttpResponseUtil _httpResponseUtil,
Watermark _watermark,
SaveServer _saveServer,
GameController _gameController,
TimeUtil _timeUtil
) : OnLoad
{
public Task OnLoad()
{
_gameController.Load();
return Task.CompletedTask;
}
public string GetRoute()
{
return "spt-game";
}
/// <summary>
/// Handle client/game/version/validate
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string VersionValidate(string url, VersionValidateRequestData info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/game/start
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GameStart(string url, EmptyRequestData info, string sessionID)
{
var startTimestampSec = _timeUtil.GetTimeStamp();
_gameController.GameStart(url, info, sessionID, startTimestampSec);
return _httpResponseUtil.GetBody(new GameStartResponse() { UtcTime = startTimestampSec });
}
/// <summary>
/// Handle client/game/logout
/// Save profiles on game close
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GameLogout(string url, EmptyRequestData info, string sessionID)
{
_saveServer.Save();
return _httpResponseUtil.GetBody(new GameLogoutResponseData() { Status = "ok" });
}
/// <summary>
/// Handle client/game/config
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetGameConfig(string url, GameEmptyCrcRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetGameConfig(sessionID));
}
/// <summary>
/// Handle client/game/mode
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetGameMode(string url, GameModeRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetGameMode(sessionID, info));
}
/// <summary>
/// Handle client/server/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetServer(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetServer(sessionID));
}
/// <summary>
/// Handle client/match/group/current
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetCurrentGroup(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetCurrentGroup(sessionID));
}
/// <summary>
/// Handle client/checkVersion
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string ValidateGameVersion(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetValidGameVersion(sessionID));
}
/// <summary>
/// Handle client/game/keepalive
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GameKeepalive(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetKeepAlive(sessionID));
}
/// <summary>
/// Handle singleplayer/settings/version
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetVersion(string url, EmptyRequestData info, string sessionID)
{
// change to be a proper type
return _httpResponseUtil.NoBody(new { Version = _watermark.GetInGameVersionLabel() });
}
/// <summary>
/// Handle /client/report/send & /client/reports/lobby/send
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string ReportNickname(string url, UIDRequestData info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle singleplayer/settings/getRaidTime
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetRaidTime(string url, GetRaidTimeRequest info, string sessionID)
{
return _httpResponseUtil.NoBody(_gameController.GetRaidTime(sessionID, info));
}
/// <summary>
/// Handle /client/survey
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetSurvey(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_gameController.GetSurvey(sessionID));
}
/// <summary>
/// Handle client/survey/view
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string GetSurveyView(string url, SendSurveyOpinionRequest info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
/// <summary>
/// Handle client/survey/opinion
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SendSurveyOpinion(string url, SendSurveyOpinionRequest info, string sessionID)
{
return _httpResponseUtil.NullResponse();
}
}
@@ -1,20 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.DI;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(OnLoad), TypePriority = OnLoadOrder.HandbookCallbacks)]
public class HandbookCallbacks(HandBookController _handBookController) : OnLoad
{
public Task OnLoad()
{
_handBookController.Load();
return Task.CompletedTask;
}
public string GetRoute()
{
return "spt-handbook";
}
}
-47
View File
@@ -1,47 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.Models.Eft.Common;
using Core.Models.Eft.ItemEvent;
using Core.Models.Eft.Notes;
namespace Core.Callbacks;
[Injectable]
public class NoteCallbacks(NoteController _noteController)
{
/// <summary>
/// Handle AddNote event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public ItemEventRouterResponse AddNote(PmcData pmcData, NoteActionData info, string sessionID)
{
return _noteController.AddNote(pmcData, info, sessionID);
}
/// <summary>
/// Handle EditNote event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public ItemEventRouterResponse EditNote(PmcData pmcData, NoteActionData info, string sessionID)
{
return _noteController.EditNote(pmcData, info, sessionID);
}
/// <summary>
/// Handle DeleteNote event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public ItemEventRouterResponse DeleteNote(PmcData pmcData, NoteActionData info, string sessionID)
{
return _noteController.DeleteNote(pmcData, info, sessionID);
}
}
@@ -1,51 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Notifier;
using Core.Utils;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(NotifierCallbacks))]
public class NotifierCallbacks(
HttpResponseUtil _httpResponseUtil,
NotifierController _notifierController
)
{
/// <summary>
/// Handle client/notifier/channel/create
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string CreateNotifierChannel(string url, EmptyRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(_notifierController.GetChannel(sessionID));
}
/// <summary>
/// Handle client/game/profile/select
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string SelectProfile(string url, UIDRequestData info, string sessionID)
{
return _httpResponseUtil.GetBody(new SelectProfileResponse { Status = "ok" });
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="sessionID"></param>
/// <returns></returns>
public string Notify(string url, object info, string sessionID)
{
return "NOTIFY";
}
}
@@ -1,20 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.DI;
namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(OnLoad), TypePriority = OnLoadOrder.PresetCallbacks)]
public class PresetCallbacks(PresetController _presetController) : OnLoad
{
public Task OnLoad()
{
_presetController.Initialize();
return Task.CompletedTask;
}
public string GetRoute()
{
return "spt-presets";
}
}
@@ -1,151 +0,0 @@
using SptCommon.Annotations;
using Core.Controllers;
using Core.Helpers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Launcher;
using Core.Models.Eft.Profile;
using Core.Utils;
namespace Core.Callbacks;
[Injectable]
public class ProfileCallbacks(
HttpResponseUtil _httpResponse,
TimeUtil _timeUtil,
ProfileController _profileController,
ProfileHelper _profileHelper
)
{
/**
* Handle client/game/profile/create
*/
public string CreateProfile(string url, ProfileCreateRequestData info, string sessionID)
{
var id = _profileController.CreateProfile(info, sessionID);
return _httpResponse.GetBody(new CreateProfileResponse { UserId = id });
}
/**
* Handle client/game/profile/list
* Get the complete player profile (scav + pmc character)
*/
public string GetProfileData(string url, EmptyRequestData info, string sessionID)
{
return _httpResponse.GetBody(_profileController.GetCompleteProfile(sessionID));
}
/**
* Handle client/game/profile/savage/regenerate
* Handle the creation of a scav profile for player
* Occurs post-raid and when profile first created immediately after character details are confirmed by player
* @param url
* @param info empty
* @param sessionID Session id
* @returns Profile object
*/
public string RegenerateScav(string url, EmptyRequestData info, string sessionID)
{
return _httpResponse.GetBody(new List<PmcData> { _profileController.GeneratePlayerScav(sessionID) });
}
/**
* Handle client/game/profile/voice/change event
*/
public string ChangeVoice(string url, ProfileChangeVoiceRequestData info, string sessionID)
{
_profileController.ChangeVoice(info, sessionID);
return _httpResponse.NullResponse();
}
/**
* Handle client/game/profile/nickname/change event
* Client allows player to adjust their profile name
*/
public string ChangeNickname(string url, ProfileChangeNicknameRequestData info, string sessionID)
{
var output = _profileController.ChangeNickname(info, sessionID);
return output switch
{
"taken" => _httpResponse.GetBody<object?>(null, 255, "The nickname is already in use"),
"tooshort" => _httpResponse.GetBody<object?>(null, 1, "The nickname is too short"),
_ => _httpResponse.GetBody<object>(new { status = 0, nicknamechangedate = _timeUtil.GetTimeStamp() })
};
}
/**
* Handle client/game/profile/nickname/validate
*/
public string ValidateNickname(string url, ValidateNicknameRequestData info, string sessionID)
{
var output = _profileController.ValidateNickname(info, sessionID);
return output switch
{
"taken" => _httpResponse.GetBody<object?>(null, 255, "225 - "),
"tooshort" => _httpResponse.GetBody<object?>(null, 256, "256 - "),
_ => _httpResponse.GetBody(new { status = "ok" })
};
}
/**
* Handle client/game/profile/nickname/reserved
*/
public string GetReservedNickname(string url, EmptyRequestData info, string sessionID)
{
var fullProfile = _profileHelper.GetFullProfile(sessionID);
if (fullProfile?.ProfileInfo?.Username is not null) return _httpResponse.GetBody(fullProfile?.ProfileInfo?.Username);
return _httpResponse.GetBody("SPTarkov");
}
/**
* Handle client/profile/status
* Called when creating a character when choosing a character face/voice
*/
public string GetProfileStatus(string url, EmptyRequestData info, string sessionID)
{
return _httpResponse.GetBody(_profileController.GetProfileStatus(sessionID));
}
/**
* Handle client/profile/view
* Called when viewing another players profile
*/
public string GetOtherProfile(string url, GetOtherProfileRequest request, string sessionID)
{
return _httpResponse.GetBody(_profileController.GetOtherProfile(sessionID, request));
}
/**
* Handle client/profile/settings
*/
public string GetProfileSettings(string url, GetProfileSettingsRequest info, string sessionID)
{
return _httpResponse.GetBody(_profileController.SetChosenProfileIcon(sessionID, info));
}
/**
* Handle client/game/profile/search
*/
public string SearchProfiles(string url, SearchProfilesRequestData info, string sessionID)
{
return _httpResponse.GetBody(_profileController.SearchProfiles(info, sessionID));
}
/**
* Handle launcher/profile/info
*/
public string GetMiniProfile(string url, GetMiniProfileRequestData info, string sessionID)
{
return _httpResponse.NoBody(_profileController.GetMiniProfile(sessionID));
}
/**
* Handle /launcher/profiles
*/
public string GetAllMiniProfiles(string url, EmptyRequestData info, string sessionID)
{
return _httpResponse.NoBody(_profileController.GetMiniProfiles());
}
}
@@ -1,23 +0,0 @@
namespace Core.Context;
public enum ContextVariableType
{
/** Logged in users session id */
SESSION_ID = 0,
/** Currently acive raid information */
RAID_CONFIGURATION = 1,
/** SessionID + Timestamp when client first connected, has _ between values */
CLIENT_START_TIMESTAMP = 2,
/** When player is loading into map and loot is requested */
REGISTER_PLAYER_REQUEST = 3,
RAID_ADJUSTMENTS = 4,
/** Data returned from client request object from endLocalRaid() */
TRANSIT_INFO = 5,
APP_BUILDER = 6,
LOADED_MOD_ASSEMBLIES = 7,
WEB_APPLICATION = 8
}
@@ -1,34 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Eft.Profile;
using Core.Services;
namespace Core.Controllers;
[Injectable]
public class AchievementController(
DatabaseService _databaseService
)
{
public GetAchievementsResponse GetAchievements(string sessionID)
{
return new GetAchievementsResponse
{
Elements = _databaseService.GetAchievements()
};
}
public CompletedAchievementsResponse GetAchievementStatics(string sessionID)
{
var achievements = _databaseService.GetAchievements();
var stats = new Dictionary<string, int>();
foreach (var achievement in achievements)
if (achievement.Id != null)
stats.Add(achievement.Id, 0);
return new CompletedAchievementsResponse
{
Elements = stats
};
}
}
-431
View File
@@ -1,431 +0,0 @@
using SptCommon.Annotations;
using Core.Context;
using Core.Generators;
using Core.Helpers;
using Core.Models.Common;
using Core.Models.Eft.Bot;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Match;
using Core.Models.Spt.Bots;
using Core.Models.Spt.Config;
using Core.Models.Utils;
using Core.Servers;
using Core.Services;
using Core.Utils;
using Core.Utils.Cloners;
using SptCommon.Extensions;
using LogLevel = Core.Models.Spt.Logging.LogLevel;
using System.Diagnostics;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;
namespace Core.Controllers;
[Injectable]
public class BotController(
ISptLogger<BotController> _logger,
DatabaseService _databaseService,
BotGenerator _botGenerator,
BotHelper _botHelper,
BotDifficultyHelper _botDifficultyHelper,
WeightedRandomHelper _weightedRandomHelper,
BotGenerationCacheService _botGenerationCacheService,
// MatchBotDeatilsCacheService _matchBotDeatilsCacheService,
LocalisationService _localisationService,
SeasonalEventService _seasonalEventService,
MatchBotDetailsCacheService _matchBotDetailsCacheService,
ProfileHelper _profileHelper,
ConfigServer _configServer,
ApplicationContext _applicationContext,
RandomUtil _randomUtil,
ICloner _cloner
)
{
private readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
private readonly PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
public int? GetBotPresetGenerationLimit(string type)
{
var typeInLower = type.ToLower();
var value = (int?)typeof(PresetBatch).GetProperties()
.First(p => p.Name.ToLower() == (typeInLower == "assaultgroup" ? "assault" : typeInLower))
.GetValue(_botConfig.PresetBatch);
if (value != null) return value;
_logger.Warning(_localisationService.GetText("bot-bot_preset_count_value_missing", type));
return 30;
}
public Dictionary<string, object> GetBotCoreDifficulty()
{
return _databaseService.GetBots().Core!;
}
public DifficultyCategories GetBotDifficulty(string type, string diffLevel, GetRaidConfigurationRequestData? raidConfig, bool ignoreRaidSettings = false)
{
var difficulty = diffLevel.ToLower();
if (!(raidConfig != null || ignoreRaidSettings)) _logger.Error(_localisationService.GetText("bot-missing_application_context", "RAID_CONFIGURATION"));
// Check value chosen in pre-raid difficulty dropdown
// If value is not 'asonline', change requested difficulty to be what was chosen in dropdown
var botDifficultyDropDownValue = raidConfig?.WavesSettings?.BotDifficulty?.ToString().ToLower() ?? "asonline";
if (botDifficultyDropDownValue != "asonline") difficulty = _botDifficultyHelper.ConvertBotDifficultyDropdownToBotDifficulty(botDifficultyDropDownValue);
var botDb = _databaseService.GetBots();
return _botDifficultyHelper.GetBotDifficultySettings(type, difficulty, botDb);
}
public Dictionary<string, Dictionary<string, DifficultyCategories>> GetAllBotDifficulties()
{
var result = new Dictionary<string, Dictionary<string, DifficultyCategories>>();
var botTypesDb = _databaseService.GetBots().Types;
//Get all bot types as sting array
var botTypes = Enum.GetValues<WildSpawnType>().Select(item => item.ToString()).ToList();
foreach (var botType in botTypes)
{
if (botTypesDb is null) continue;
// If bot is usec/bear, swap to different name
var botTypeLower = _botHelper.IsBotPmc(botType)
? _botHelper.GetPmcSideByRole(botType).ToLower()
: botType.ToLower();
BotType? botDetails = null;
// Get details from db
if (!botTypesDb.TryGetValue(botTypeLower, out botDetails))
{
// No bot of this type found, copy details from assault
result[botTypeLower] = result["assault"];
if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to find bot: {botTypeLower} in db, copying 'assault'");
continue;
}
if (botDetails?.BotDifficulty is null)
{
// Bot has no difficulty values, skip
_logger.Warning($"Unable to find bot: {botTypeLower} difficulty values in db, skipping");
continue;
}
var botNameKey = botType.ToLower();
foreach (var (difficultyName, _) in botDetails.BotDifficulty)
{
// Bot doesn't exist in result, add
if (!result.ContainsKey(botNameKey)) result.TryAdd(botNameKey, new Dictionary<string, DifficultyCategories>());
// Store all difficulty values in dict keyed by difficulty type e.g. easy/normal/impossible
result[botNameKey].Add(difficultyName, GetBotDifficulty(botNameKey, difficultyName, null, true));
}
}
return result;
}
public List<BotBase> Generate(string sessionId, GenerateBotsRequestData info)
{
var pmcProfile = _profileHelper.GetPmcProfile(sessionId);
// Use this opportunity to create and cache bots for later retrieval
var multipleBotTypesRequested = info.Conditions?.Count > 1;
return multipleBotTypesRequested
? GenerateMultipleBotsAndCache(info, pmcProfile, sessionId)
: ReturnSingleBotFromCache(sessionId, info);
}
private List<BotBase> GenerateMultipleBotsAndCache(GenerateBotsRequestData request, PmcData? pmcProfile, string sessionId)
{
var raidSettings = GetMostRecentRaidSettings();
var allPmcsHaveSameNameAsPlayer = _randomUtil.GetChance100(
_pmcConfig.AllPMCsHavePlayerNameWithRandomPrefixChance
);
var stopwatch = Stopwatch.StartNew();
var tasks = new List<Task>();
// Map conditions to promises for bot generation
foreach (var condition in request.Conditions ?? [])
tasks.Add(
Task.Factory.StartNew(
() =>
{
var botGenerationDetails = GetBotGenerationDetailsForWave(
condition,
pmcProfile,
allPmcsHaveSameNameAsPlayer,
raidSettings,
_botConfig.PresetBatch!.GetValueOrDefault(condition.Role, 15),
_botHelper.IsBotPmc(condition.Role)
);
// Generate bots for the current condition
GenerateWithBotDetails(condition, botGenerationDetails, sessionId);
}
)
);
Task.WaitAll(tasks.ToArray());
stopwatch.Stop();
if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache");
return [];
}
private void GenerateWithBotDetails(GenerateCondition condition, BotGenerationDetails botGenerationDetails, string sessionId)
{
var isEventBot = condition.Role?.ToLower().Contains("event");
if (isEventBot ?? false)
{
// Add eventRole data + reassign role property to be base type
botGenerationDetails.EventRole = condition.Role;
botGenerationDetails.Role = _seasonalEventService.GetBaseRoleForEventBot(
botGenerationDetails.EventRole
);
}
// Create a compound key to store bots in cache against
var cacheKey = _botGenerationCacheService.CreateCacheKey(
botGenerationDetails.EventRole ?? botGenerationDetails.Role,
botGenerationDetails.BotDifficulty
);
// Get number of bots we have in cache
var botCacheCount = _botGenerationCacheService.GetCachedBotCount(cacheKey);
if (botCacheCount >= botGenerationDetails.BotCountToGenerate)
{
if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Cache already has sufficient {cacheKey} bots: {botCacheCount}");
return;
}
// We're below desired count, add bots to cache
var botsToGenerate = botGenerationDetails.BotCountToGenerate - botCacheCount;
var progressWriter = new ProgressWriter(botGenerationDetails.BotCountToGenerate.GetValueOrDefault(30));
if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Generating {botsToGenerate} bots for cacheKey: {cacheKey}");
for (var i = 0; i < botsToGenerate; i++)
try
{
var detailsClone = _cloner.Clone(botGenerationDetails);
GenerateSingleBotAndStoreInCache(detailsClone, sessionId, cacheKey);
progressWriter.Increment();
}
catch (Exception e)
{
_logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message}");
}
if (_logger.IsLogEnabled(LogLevel.Debug))
_logger.Debug(
$"Generated {botGenerationDetails.BotCountToGenerate} {botGenerationDetails.Role}" +
$"({botGenerationDetails.EventRole ?? botGenerationDetails.Role ?? ""}) {botGenerationDetails.BotDifficulty}bots"
);
}
private List<BotBase> ReturnSingleBotFromCache(string sessionId, GenerateBotsRequestData request)
{
var pmcProfile = _profileHelper.GetPmcProfile(sessionId);
var requestedBot = request.Conditions?.FirstOrDefault();
var raidSettings = GetMostRecentRaidSettings();
// Create generation request for when cache is empty
var condition = new GenerateCondition
{
Role = requestedBot?.Role,
Limit = 5,
Difficulty = requestedBot?.Difficulty
};
var botGenerationDetails = GetBotGenerationDetailsForWave(
condition,
pmcProfile,
false,
raidSettings,
_botConfig.PresetBatch?.GetByJsonProp<int>(requestedBot?.Role ?? string.Empty),
_botHelper.IsBotPmc(requestedBot?.Role)
);
// Event bots need special actions to occur, set data up for them
var isEventBot = requestedBot?.Role?.ToLower().Contains("event");
if (isEventBot ?? false)
{
// Add eventRole data + reassign role property
botGenerationDetails.EventRole = requestedBot?.Role;
botGenerationDetails.Role = _seasonalEventService.GetBaseRoleForEventBot(
botGenerationDetails.EventRole
);
}
// Does non pmc bot have a chance of being converted into a pmc
var convertIntoPmcChanceMinMax = GetPmcConversionMinMaxForLocation(
requestedBot?.Role,
raidSettings?.Location
);
if (convertIntoPmcChanceMinMax is not null && !botGenerationDetails.IsPmc.GetValueOrDefault(false))
{
// Bot has % chance to become pmc and isnt one pmc already
var convertToPmc = _botHelper.RollChanceToBePmc(convertIntoPmcChanceMinMax);
if (convertToPmc)
{
// Update requirements
botGenerationDetails.IsPmc = true;
botGenerationDetails.Role = _botHelper.GetRandomizedPmcRole();
botGenerationDetails.Side = _botHelper.GetPmcSideByRole(botGenerationDetails.Role);
botGenerationDetails.BotDifficulty = GetPmcDifficulty(requestedBot?.Difficulty);
botGenerationDetails.BotCountToGenerate = _botConfig.PresetBatch?.GetByJsonProp<int>(botGenerationDetails.Role);
}
}
// Only convert to boss when not already converted to PMC & Boss Convert is enabled
var bossConvertEnabled = _botConfig.AssaultToBossConversion.BossConvertEnabled;
var bossConvertMinMax = _botConfig.AssaultToBossConversion.BossConvertMinMax;
var bossesToConvertToWeights = _botConfig.AssaultToBossConversion.BossesToConvertToWeights;
if (bossConvertEnabled && botGenerationDetails.IsPmc is not null && !botGenerationDetails.IsPmc.Value)
{
var bossConvertPercent = bossConvertMinMax.GetByJsonProp<MinMax>(requestedBot?.Role?.ToLower() ?? string.Empty);
if (bossConvertPercent is not null)
// Roll a percentage check if we should convert scav to boss
if (_randomUtil.GetChance100(_randomUtil.GetDouble(bossConvertPercent.Min!.Value, bossConvertPercent.Max!.Value)))
UpdateBotGenerationDetailsToRandomBoss(botGenerationDetails, bossesToConvertToWeights);
}
// Create a compound key to store bots in cache against
var cacheKey = _botGenerationCacheService.CreateCacheKey(
botGenerationDetails.EventRole ?? botGenerationDetails.Role,
botGenerationDetails.BotDifficulty
);
// Check cache for bot using above key
if (!_botGenerationCacheService.CacheHasBotWithKey(cacheKey))
{
// No bot in cache, generate new and store in cache
GenerateSingleBotAndStoreInCache(botGenerationDetails, sessionId, cacheKey);
if (_logger.IsLogEnabled(LogLevel.Debug))
_logger.Debug(
$"Generated {botGenerationDetails.BotCountToGenerate} " +
$"{botGenerationDetails.Role} ({botGenerationDetails.EventRole ?? ""}) {botGenerationDetails.BotDifficulty} bots"
);
}
var desiredBot = _botGenerationCacheService.GetBot(cacheKey);
_botGenerationCacheService.StoreUsedBot(desiredBot);
return [desiredBot];
}
private void GenerateSingleBotAndStoreInCache(BotGenerationDetails? botGenerationDetails, string sessionId, string cacheKey)
{
var botToCache = _botGenerator.PrepareAndGenerateBot(sessionId, botGenerationDetails);
_botGenerationCacheService.StoreBots(cacheKey, [botToCache]);
// Store bot details in cache so post-raid PMC messages can use data
_matchBotDetailsCacheService.CacheBot(botToCache);
}
private void UpdateBotGenerationDetailsToRandomBoss(BotGenerationDetails botGenerationDetails, Dictionary<string, double> bossesToConvertToWeights)
{
// Seems Actual bosses have the same Brain issues like PMC gaining Boss Brains We can't use all bosses
botGenerationDetails.Role = _weightedRandomHelper.GetWeightedValue(bossesToConvertToWeights);
// Bosses are only ever 'normal'
botGenerationDetails.BotDifficulty = "normal";
botGenerationDetails.BotCountToGenerate = _botConfig.PresetBatch?.GetByJsonProp<int>(botGenerationDetails.Role);
}
private string? GetPmcDifficulty(string? requestedBotDifficulty)
{
var difficulty = _pmcConfig.Difficulty.ToLower();
return difficulty switch
{
"asonline" => requestedBotDifficulty,
"random" => _botDifficultyHelper.ChooseRandomDifficulty(),
_ => _pmcConfig.Difficulty
};
}
private MinMax? GetPmcConversionMinMaxForLocation(string? requestedBotRole, string? location)
{
return _pmcConfig.ConvertIntoPmcChance!.TryGetValue(location?.ToLower() ?? "", out var mapSpecificConversionValues)
? mapSpecificConversionValues.GetByJsonProp<MinMax>(requestedBotRole?.ToLower())
: _pmcConfig.ConvertIntoPmcChance.GetValueOrDefault("default")?.GetValueOrDefault(requestedBotRole);
}
private GetRaidConfigurationRequestData? GetMostRecentRaidSettings()
{
var raidSettings = _applicationContext
.GetLatestValue(ContextVariableType.RAID_CONFIGURATION)
?.GetValue<GetRaidConfigurationRequestData>();
if (raidSettings is null) _logger.Warning(_localisationService.GetText("bot-unable_to_load_raid_settings_from_appcontext"));
return raidSettings;
}
private MinMax? GetPmcLevelRangeForMap(string? location)
{
return _pmcConfig.LocationSpecificPmcLevelOverride!.GetValueOrDefault(location?.ToLower() ?? "", null);
}
private BotGenerationDetails GetBotGenerationDetailsForWave(
GenerateCondition condition,
PmcData? pmcProfile,
bool allPmcsHaveSameNameAsPlayer,
GetRaidConfigurationRequestData? raidSettings,
int? botCountToGenerate,
bool generateAsPmc)
{
return new BotGenerationDetails
{
IsPmc = generateAsPmc,
Side = generateAsPmc ? _botHelper.GetPmcSideByRole(condition.Role ?? string.Empty) : "Savage",
Role = condition.Role,
PlayerLevel = pmcProfile?.Info?.Level,
PlayerName = pmcProfile?.Info?.Nickname,
BotRelativeLevelDeltaMax = _pmcConfig.BotRelativeLevelDeltaMax,
BotRelativeLevelDeltaMin = _pmcConfig.BotRelativeLevelDeltaMin,
BotCountToGenerate = botCountToGenerate,
BotDifficulty = condition.Difficulty,
LocationSpecificPmcLevelOverride = GetPmcLevelRangeForMap(raidSettings?.Location), // Min/max levels for PMCs to generate within
IsPlayerScav = false,
AllPmcsHaveSameNameAsPlayer = allPmcsHaveSameNameAsPlayer
};
}
public int GetBotCap(string location)
{
var botCap = _botConfig.MaxBotCap.FirstOrDefault(x => x.Key.ToLower() == location.ToLower());
if (location == "default")
_logger.Warning(
_localisationService.GetText("bot-no_bot_cap_found_for_location", location.ToLower())
);
return botCap.Value;
}
public AiBotBrainTypes GetAiBotBrainTypes()
{
return new AiBotBrainTypes
{
PmcType = _pmcConfig.PmcType,
Assault = _botConfig.AssaultBrainType,
PlayerScav = _botConfig.PlayerScavBrainType
};
}
}
public record AiBotBrainTypes
{
[JsonPropertyName("pmc")]
public Dictionary<string, Dictionary<string, Dictionary<string, double>>> PmcType { get; set; }
[JsonPropertyName("assault")]
public Dictionary<string, Dictionary<string, int>> Assault { get; set; }
[JsonPropertyName("playerScav")]
public Dictionary<string, Dictionary<string, int>> PlayerScav { get; set; }
}
@@ -1,211 +0,0 @@
using SptCommon.Annotations;
using Core.Helpers;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Launcher;
using Core.Models.Eft.Profile;
using Core.Models.Spt.Config;
using Core.Models.Spt.Mod;
using Core.Models.Utils;
using Core.Servers;
using Core.Services;
using Core.Utils;
using SptCommon.Extensions;
using Info = Core.Models.Eft.Profile.Info;
namespace Core.Controllers;
[Injectable]
public class LauncherController(
ISptLogger<LauncherController> _logger,
HashUtil _hashUtil,
TimeUtil _timeUtil,
RandomUtil _randomUtil,
SaveServer _saveServer,
HttpServerHelper _httpServerHelper,
ProfileHelper _profileHelper,
DatabaseService _databaseService,
LocalisationService _localisationService,
ConfigServer _configServer
)
{
protected CoreConfig _coreConfig = _configServer.GetConfig<CoreConfig>();
public ConnectResponse Connect()
{
// Get all possible profile types + filter out any that are blacklisted
var profiles = typeof(ProfileTemplates).GetProperties()
.Where(p => p.CanWrite)
.Select(p => p.GetJsonName())
.Where(profileName => !_coreConfig.Features.CreateNewProfileTypesBlacklist.Contains(profileName))
.ToList();
return new ConnectResponse()
{
BackendUrl = _httpServerHelper.GetBackendUrl(),
Name = _coreConfig.ServerName,
Editions = profiles,
ProfileDescriptions = GetProfileDescriptions()
};
}
/**
* Get descriptive text for each of the profile edtions a player can choose, keyed by profile.json profile type e.g. "Edge Of Darkness"
* @returns Dictionary of profile types with related descriptive text
*/
protected Dictionary<string, string> GetProfileDescriptions()
{
var result = new Dictionary<string, string>();
var dbProfiles = _databaseService.GetProfiles();
foreach (var templatesProperty in typeof(ProfileTemplates).GetProperties().Where(p => p.CanWrite))
{
var propertyValue = templatesProperty.GetValue(dbProfiles);
if (propertyValue == null)
{
_logger.Warning(_localisationService.GetText("launcher-missing_property", templatesProperty));
continue;
}
var casterPropertyValue = propertyValue as ProfileSides;
result[templatesProperty.GetJsonName()] = _localisationService.GetText(casterPropertyValue?.DescriptionLocaleKey!);
}
return result;
}
public Info? Find(string? sessionId)
{
return sessionId is not null && _saveServer.GetProfiles().TryGetValue(sessionId, out var profile) ? profile.ProfileInfo : null;
}
public string? Login(LoginRequestData? info)
{
foreach (var kvp in _saveServer.GetProfiles())
{
var account = _saveServer.GetProfile(kvp.Key).ProfileInfo;
if (info?.Username == account?.Username) return kvp.Key;
}
return null;
}
public string Register(RegisterData info)
{
foreach (var kvp in _saveServer.GetProfiles())
if (info.Username == _saveServer.GetProfile(kvp.Key).ProfileInfo?.Username)
return "";
return CreateAccount(info);
}
protected string CreateAccount(RegisterData info)
{
var profileId = GenerateProfileId();
var scavId = GenerateProfileId();
var newProfileDetails = new Info
{
ProfileId = profileId,
ScavengerId = scavId,
Aid = _hashUtil.GenerateAccountId(),
Username = info.Username,
Password = info.Password,
IsWiped = true,
Edition = info.Edition
};
_saveServer.CreateProfile(newProfileDetails);
_saveServer.LoadProfile(profileId);
_saveServer.SaveProfile(profileId);
return profileId;
}
protected string GenerateProfileId()
{
var timestamp = _timeUtil.GetTimeStamp();
return FormatID(timestamp, timestamp * _randomUtil.GetInt(1, 1000000));
}
protected string FormatID(long timeStamp, long counter)
{
var timeStampStr = Convert.ToString(timeStamp, 16).PadLeft(8, '0');
var counterStr = Convert.ToString(counter, 16).PadLeft(16, '0');
return timeStampStr.ToLower() + counterStr.ToLower();
}
public string? ChangeUsername(ChangeRequestData info)
{
var sessionID = Login(info);
if (!string.IsNullOrEmpty(sessionID)) _saveServer.GetProfile(sessionID).ProfileInfo!.Username = info.Change;
return sessionID;
}
public string? ChangePassword(ChangeRequestData info)
{
var sessionID = Login(info);
if (!string.IsNullOrEmpty(sessionID)) _saveServer.GetProfile(sessionID).ProfileInfo!.Password = info.Change;
return sessionID;
}
/**
* Handle launcher requesting profile be wiped
* @param info IRegisterData
* @returns Session id
*/
public string? Wipe(RegisterData info)
{
if (!_coreConfig.AllowProfileWipe) return null;
var sessionID = Login(info);
if (!string.IsNullOrEmpty(sessionID))
{
var profileInfo = _saveServer.GetProfile(sessionID).ProfileInfo;
profileInfo!.Edition = info.Edition;
profileInfo.IsWiped = true;
}
return sessionID;
}
public string GetCompatibleTarkovVersion()
{
return _coreConfig.CompatibleTarkovVersion;
}
/**
* Get the mods the server has currently loaded
* @returns Dictionary of mod name and mod details
*/
public Dictionary<string, PackageJsonData> GetLoadedServerMods()
{
_logger.Error("NOT IMPLEMENTED - _preSptModLoader GetLoadedServerMods()");
return new Dictionary<string, PackageJsonData>();
// TODO => return this.preSptModLoader.getImportedModDetails();
}
/**
* Get the mods a profile has ever loaded into game with
* @param sessionId Player id
* @returns Array of mod details
*/
public List<ModDetails> GetServerModsProfileUsed(string sessionId)
{
// var profile = _profileHelper.GetFullProfile(sessionId);
_logger.Error("NOT IMPLEMENTED - _preSptModLoader GetServerModsProfileUsed()");
/* TODO => modding
if (profile?.spt?.mods) {
return this.preSptModLoader.GetProfileModsGroupedByModName(profile?.spt?.mods);
}
*/
return [];
}
}
@@ -1,67 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Eft.Common;
using Core.Models.Eft.ItemEvent;
using Core.Models.Eft.Notes;
using Core.Routers;
namespace Core.Controllers;
[Injectable]
public class NoteController(
EventOutputHolder _eventOutputHolder
)
{
/// <summary>
///
/// </summary>
/// <param name="pmcData"></param>
/// <param name="body"></param>
/// <param name="sessionId"></param>
/// <returns></returns>
public ItemEventRouterResponse AddNote(
PmcData pmcData,
NoteActionData body,
string sessionId)
{
var newNote = new Note { Time = body.Note.Time, Text = body.Note.Text };
pmcData.Notes.DataNotes.Add(newNote);
return _eventOutputHolder.GetOutput(sessionId);
}
/// <summary>
///
/// </summary>
/// <param name="pmcData"></param>
/// <param name="body"></param>
/// <param name="sessionId"></param>
/// <returns></returns>
public ItemEventRouterResponse EditNote(
PmcData pmcData,
NoteActionData body,
string sessionId)
{
var noteToEdit = pmcData.Notes.DataNotes[body.Index!.Value];
noteToEdit.Time = body.Note.Time;
noteToEdit.Text = body.Note.Text;
return _eventOutputHolder.GetOutput(sessionId);
}
/// <summary>
///
/// </summary>
/// <param name="pmcData"></param>
/// <param name="body"></param>
/// <param name="sessionId"></param>
/// <returns></returns>
public ItemEventRouterResponse DeleteNote(
PmcData pmcData,
NoteActionData body,
string sessionId)
{
pmcData.Notes?.DataNotes?.RemoveAt(body.Index!.Value);
return _eventOutputHolder.GetOutput(sessionId);
}
}
@@ -1,95 +0,0 @@
using SptCommon.Annotations;
using Core.Helpers;
using Core.Models.Eft.Notifier;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Core.Services;
using System.Diagnostics.Tracing;
namespace Core.Controllers;
[Injectable]
public class NotifierController(
HttpServerHelper _httpServerHelper,
NotifierHelper _notifierHelper
)
{
/// <summary>
/// Resolve an array of session notifications.
///
/// If no notifications are currently queued then intermittently check for new notifications until either
/// one or more appear or when a timeout expires.
/// If no notifications are available after the timeout, use a default message.
/// </summary>
/// <param name="sessionId"></param>
public async Task NotifyAsync(string sessionId)
{
// TODO: Finish implementation of the NotifyAsync method
//
//return new Promise((resolve) => {
// // keep track of our timeout
// let counter = 0;
// /**
// * Check for notifications, resolve if any, otherwise poll
// * intermittently for a period of time.
// */
// var checkNotifications = () => {
// /**
// * If there are no pending messages we should either check again later
// * or timeout now with a default response.
// */
// if (!_notificationService.Has(sessionID)) {
// // have we exceeded timeout? if so reply with default ping message
// if (counter > _timeout) {
// return resolve([_notifierHelper.getDefaultNotification()]);
// }
// // check again
// setTimeout(checkNotifications, _pollInterval);
// // update our timeout counter
// counter += _pollInterval;
// return;
// }
// /**
// * Maintaining array reference is not necessary, so we can just copy and reinitialize
// */
// var messages = _notificationService.Get(sessionID);
// _notificationService.UpdateMessageOnQueue(sessionID, []);
// resolve(messages);
//};
// immediately check
// checkNotifications();
//});
}
/// <summary>
/// Handle client/notifier/channel/create
/// </summary>
/// <param name="sessionId"></param>
/// <returns></returns>
public NotifierChannel GetChannel(string sessionId)
{
return new NotifierChannel
{
Server = _httpServerHelper.BuildUrl(),
ChannelId = sessionId,
Url = "",
NotifierServer = GetServer(sessionId),
WebSocket = _notifierHelper.GetWebSocketServer(sessionId)
};
}
/// <summary>
///
/// </summary>
/// <param name="sessionId"></param>
/// <returns></returns>
public string GetServer(string sessionId)
{
return $"{_httpServerHelper.GetBackendUrl()}/notifierServer/get/{sessionId}";
}
}
@@ -1,228 +0,0 @@
using System.Text.Json;
using SptCommon.Annotations;
using Core.Helpers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Inventory;
using Core.Models.Eft.Prestige;
using Core.Models.Eft.Profile;
using Core.Models.Enums;
using Core.Models.Utils;
using Core.Routers;
using Core.Servers;
using Core.Services;
using Core.Utils;
using Core.Utils.Cloners;
using SptCommon.Extensions;
namespace Core.Controllers;
[Injectable]
public class PrestigeController(
ISptLogger<PrestigeController> _logger,
TimeUtil _timeUtil,
InventoryHelper _inventoryHelper,
ProfileHelper _profileHelper,
EventOutputHolder _eventOutputHolder,
CreateProfileService _createProfileService,
DatabaseService _databaseService,
SaveServer _saveServer,
ICloner _cloner
)
{
protected double _prestigePercentage = 0.05;
/// <summary>
/// Handle /client/prestige/list
/// </summary>
/// <param name="sessionId"></param>
/// <param name="info"></param>
/// <returns></returns>
public Prestige GetPrestige(
string sessionId,
EmptyRequestData info)
{
return _databaseService.GetTemplates().Prestige;
}
/// <summary>
/// <para>Handle /client/prestige/obtain</para>
/// Going to Prestige 1 grants the below
/// <list type="bullet">
/// <item>5% of skills should be transfered over</item>
/// <item>5% of mastering should be transfered over</item>
/// <item>Earned achievements should be transfered over</item>
/// <item>Profile stats should be transfered over</item>
/// <item>Prestige progress should be transfered over</item>
/// <item>Items and rewards for Prestige 1</item>
/// </list>
/// Going to Prestige 2 grants the below
/// <list type="bullet">
/// <item>10% of skills should be transfered over</item>
/// <item>10% of mastering should be transfered over</item>
/// <item>Earned achievements should be transfered over</item>
/// <item>Profile stats should be transfered over</item>
/// <item>Prestige progress should be transfered over</item>
/// <item>Items and rewards for Prestige 2</item>
/// </list>
/// Each time reseting the below
/// <list type="bullet">
/// <item>Trader standing</item>
/// <item>Task progress</item>
/// <item>Character level</item>
/// <item>Stash</item>
/// <item>Hideout progress</item>
/// </list>
/// </summary>
/// <returns></returns>
public void ObtainPrestige(
string sessionId,
ObtainPrestigeRequestList request)
{
// Clone existing profile, create a new one
var prePrestigeProfileClone = _cloner.Clone(_profileHelper.GetFullProfile(sessionId));
var prePrestigePmc = prePrestigeProfileClone.CharacterData.PmcData;
var createRequest = new ProfileCreateRequestData
{
Side = prePrestigePmc.Info.Side,
Nickname = prePrestigePmc.Info.Nickname,
HeadId = prePrestigePmc.Customization.Head,
VoiceId = _databaseService.GetTemplates()
.Customization.FirstOrDefault(
(customisation) => customisation.Value.Name == prePrestigePmc.Info.Voice
)
.Value.Id
};
// Reset profile
_createProfileService.CreateProfile(sessionId, createRequest);
// Get freshly reset profile ready for editing
var newProfile = _profileHelper.GetFullProfile(sessionId);
// set this here so we can use the prestigeLevel for further calcs
newProfile.CharacterData.PmcData.Info.PrestigeLevel = prePrestigePmc.Info.PrestigeLevel ?? 0;
newProfile.CharacterData.PmcData.Info.PrestigeLevel++;
// Copy skills to new profile
var commonSkillsToCopy = prePrestigePmc.Skills.Common;
foreach (var skillToCopy in commonSkillsToCopy)
{
// Set progress 5% of what it was * prestige level to get 5% or 10% for prestige 1 or 2 respectivly
skillToCopy.Progress = (skillToCopy.Progress.Value * _prestigePercentage) * newProfile.CharacterData.PmcData.Info.PrestigeLevel;
var existingSkill = newProfile.CharacterData.PmcData.Skills.Common.FirstOrDefault((skill) => skill.Id == skillToCopy.Id);
if (existingSkill is not null)
existingSkill.Progress = skillToCopy.Progress;
else
newProfile.CharacterData.PmcData.Skills.Common.Add(skillToCopy);
}
// Copy mastering to new profile
var masteringSkillsToCopy = prePrestigePmc.Skills.Mastering;
foreach (var skillToCopy in masteringSkillsToCopy)
{
// Set progress 5% of what it was * prestige level to get 5% or 10% for prestige 1 or 2 respectivly
skillToCopy.Progress = (skillToCopy.Progress.Value * _prestigePercentage) * newProfile.CharacterData.PmcData.Info.PrestigeLevel;
var existingSkill = newProfile.CharacterData.PmcData.Skills.Mastering.FirstOrDefault(
(skill) => skill.Id == skillToCopy.Id
);
if (existingSkill is not null)
existingSkill.Progress = skillToCopy.Progress;
else
newProfile.CharacterData.PmcData.Skills.Mastering.Add(skillToCopy);
}
// Add existing completed achievements and new one for prestige
newProfile.CharacterData.PmcData.Achievements = prePrestigeProfileClone.CharacterData.PmcData.Achievements; // this *should* only contain completed ones
// Add "Prestigious" achievement
if (!newProfile.CharacterData.PmcData.Achievements.ContainsKey("676091c0f457869a94017a23"))
newProfile.CharacterData.PmcData.Achievements.Add("676091c0f457869a94017a23", _timeUtil.GetTimeStamp());
// TODO: is there one for second prestige
// Add existing Stats to profile
newProfile.CharacterData.PmcData.Stats = prePrestigePmc.Stats;
// Assumes Prestige data is in descending order
var indexOfPrestigeObtained = newProfile.CharacterData.PmcData.Info.PrestigeLevel ?? 0; // Index starts at 0
var currentPrestigeData = _databaseService.GetTemplates().Prestige.Elements[indexOfPrestigeObtained];
var prestigeRewards = currentPrestigeData.Rewards;
AddPrestigeRewardsToProfile(sessionId, newProfile, prestigeRewards);
// Flag profile as having achieved this prestige level
newProfile.CharacterData.PmcData.Prestige[currentPrestigeData.Id] = _timeUtil.GetTimeStamp();
if (request is not null)
// Copy transferred items
foreach (var transferRequest in request)
{
var item = prePrestigePmc.Inventory.Items.FirstOrDefault((item) => item.Id == transferRequest.Id);
var addItemRequest = new AddItemDirectRequest
{
ItemWithModsToAdd = [item],
FoundInRaid = item.Upd?.SpawnedInSession,
UseSortingTable = false,
Callback = null
};
_inventoryHelper.AddItemToStash(
sessionId,
addItemRequest,
newProfile.CharacterData.PmcData,
_eventOutputHolder.GetOutput(sessionId)
);
}
// Force save of above changes to disk
_saveServer.SaveProfile(sessionId);
}
private void AddPrestigeRewardsToProfile(string sessionId, SptProfile newProfile, IEnumerable<Reward> rewards)
{
foreach (var reward in rewards)
switch (reward.Type)
{
case RewardType.CustomizationDirect:
{
_profileHelper.AddHideoutCustomisationUnlock(newProfile, reward, CustomisationSource.PRESTIGE);
break;
}
case RewardType.Skill:
if (Enum.TryParse(reward.Target, out SkillTypes result))
_profileHelper.AddSkillPointsToPlayer(
newProfile.CharacterData.PmcData,
result,
((JsonElement)reward.Value).ToObject<double>()
);
else
_logger.Error($"Unable to parse reward Target to Enum: {reward.Target}");
break;
case RewardType.Item:
{
var addItemRequest = new AddItemDirectRequest
{
ItemWithModsToAdd = reward.Items,
FoundInRaid = reward.Items.FirstOrDefault()?.Upd?.SpawnedInSession,
UseSortingTable = false,
Callback = null
};
_inventoryHelper.AddItemToStash(
sessionId,
addItemRequest,
newProfile.CharacterData.PmcData,
_eventOutputHolder.GetOutput(sessionId)
);
break;
}
case RewardType.ExtraDailyQuest:
{
_logger.Info("additional quests will be added when generating repeatables");
break;
}
default:
_logger.Error($"Unhandled prestige reward type: {reward.Type}");
break;
}
}
}
-14
View File
@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SptDependencyInjection\SptDependencyInjection.csproj" />
</ItemGroup>
</Project>
-7
View File
@@ -1,7 +0,0 @@
namespace Core.DI;
public interface OnLoad
{
Task OnLoad();
string GetRoute();
}
@@ -1,8 +0,0 @@
namespace Core.Generators.WeaponGen;
public interface IInventoryMagGen
{
public abstract int GetPriority();
public abstract bool CanHandleInventoryMagGen(InventoryMagGen inventoryMagGen);
public abstract void Process(InventoryMagGen inventoryMagGen);
}
-201
View File
@@ -1,201 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
using Core.Models.Utils;
using Core.Servers;
using Core.Services;
using Core.Utils;
namespace Core.Helpers;
[Injectable]
public class BotHelper(
ISptLogger<BotHelper> _logger,
DatabaseService _databaseService,
RandomUtil _randomUtil,
ConfigServer _configServer
)
{
protected BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
protected PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
protected List<string?> _pmcNames = ["usec", "bear", "pmc", "pmcbear", "pmcusec"];
/// <summary>
/// Get a template object for the specified botRole from bots.types db
/// </summary>
/// <param name="role">botRole to get template for</param>
/// <returns>BotType object</returns>
public BotType? GetBotTemplate(string role)
{
if (!_databaseService.GetBots().Types.TryGetValue(role?.ToLower(), out var bot))
{
_logger.Error($"Unable to get bot of type: {role} from DB");
return null;
}
return bot;
}
/// <summary>
/// Is the passed in bot role a PMC (usec/bear/pmc)
/// </summary>
/// <param name="botRole">bot role to check</param>
/// <returns>true if is pmc</returns>
public bool IsBotPmc(string? botRole)
{
return _pmcNames.Contains(botRole?.ToLower());
}
public bool IsBotBoss(string botRole)
{
return _botConfig.Bosses.Any(x => string.Equals(x, botRole, StringComparison.CurrentCultureIgnoreCase));
}
public bool IsBotFollower(string botRole)
{
return botRole?.ToLower().StartsWith("follower") ?? false;
}
public bool IsBotZombie(string botRole)
{
return botRole?.ToLower().StartsWith("infected") ?? false;
}
/// <summary>
/// Add a bot to the FRIENDLY_BOT_TYPES list
/// </summary>
/// <param name="difficultySettings">bot settings to alter</param>
/// <param name="typeToAdd">bot type to add to friendly list</param>
public void AddBotToFriendlyList(DifficultyCategories difficultySettings, string typeToAdd)
{
var friendlyBotTypesKey = "FRIENDLY_BOT_TYPES";
// Null guard
if (difficultySettings.Mind[friendlyBotTypesKey] is null) difficultySettings.Mind[friendlyBotTypesKey] = new List<string>();
((List<string>)difficultySettings.Mind[friendlyBotTypesKey]).Add(typeToAdd);
}
/// <summary>
/// Add a bot to the REVENGE_BOT_TYPES list
/// </summary>
/// <param name="difficultySettings">bot settings to alter</param>
/// <param name="typesToAdd">bot type to add to revenge list</param>
public void AddBotToRevengeList(DifficultyCategories difficultySettings, string[] typesToAdd)
{
var revengePropKey = "REVENGE_BOT_TYPES";
// Nothing to add
if (typesToAdd is null) return;
// Null guard
if (difficultySettings.Mind[revengePropKey] is null) difficultySettings.Mind[revengePropKey] = new List<string>();
var revengeArray = (List<string>)difficultySettings.Mind[revengePropKey];
foreach (var botTypeToAdd in typesToAdd)
if (!revengeArray.Contains(botTypeToAdd))
revengeArray.Add(botTypeToAdd);
}
public bool RollChanceToBePmc(MinMax botConvertMinMax)
{
return _randomUtil.GetChance100(_randomUtil.GetDouble(botConvertMinMax.Min.Value, botConvertMinMax.Max.Value));
}
protected Dictionary<string, MinMax> GetPmcConversionValuesForLocation(string location)
{
var result = _pmcConfig.ConvertIntoPmcChance[location.ToLower()];
if (result is null) _pmcConfig.ConvertIntoPmcChance = new Dictionary<string, Dictionary<string, MinMax>>();
return result;
}
/// <summary>
/// is the provided role a PMC, case-agnostic
/// </summary>
/// <param name="botRole">Role to check</param>
/// <returns>True if role is PMC</returns>
public bool BotRoleIsPmc(string botRole)
{
List<string> ListToCheck = [_pmcConfig.UsecType.ToLower(), _pmcConfig.BearType.ToLower()];
return ListToCheck.Contains(
botRole.ToLower()
);
}
/// <summary>
/// Get randomization settings for bot from config/bot.json
/// </summary>
/// <param name="botLevel">level of bot</param>
/// <param name="botEquipConfig">bot equipment json</param>
/// <returns>RandomisationDetails</returns>
public RandomisationDetails GetBotRandomizationDetails(int botLevel, EquipmentFilters botEquipConfig)
{
// No randomisation details found, skip
if (botEquipConfig is null || botEquipConfig.Randomisation is null) return null;
return botEquipConfig.Randomisation.FirstOrDefault(
(randDetails) => botLevel >= randDetails.LevelRange.Min && botLevel <= randDetails.LevelRange.Max
);
}
/// <summary>
/// Choose between pmcBEAR and pmcUSEC at random based on the % defined in pmcConfig.isUsec
/// </summary>
/// <returns>pmc role</returns>
public string GetRandomizedPmcRole()
{
return _randomUtil.GetChance100(_pmcConfig.IsUsec) ? _pmcConfig.UsecType : _pmcConfig.BearType;
}
/// <summary>
/// Get the corresponding side when pmcBEAR or pmcUSEC is passed in
/// </summary>
/// <param name="botRole">role to get side for</param>
/// <returns>side (usec/bear)</returns>
public string GetPmcSideByRole(string botRole)
{
if (_pmcConfig.BearType.ToLower() == botRole.ToLower())
return "Bear";
if (_pmcConfig.UsecType.ToLower() == botRole.ToLower())
return "Usec";
return GetRandomizedPmcSide();
}
/// <summary>
/// Get a randomized PMC side based on bot config value 'isUsec'
/// </summary>
/// <returns>pmc side as string</returns>
protected string GetRandomizedPmcSide()
{
return _randomUtil.GetChance100(_pmcConfig.IsUsec) ? "Usec" : "Bear";
}
/// <summary>
/// Get a name from a PMC that fits the desired length
/// </summary>
/// <param name="maxLength">Max length of name, inclusive</param>
/// <param name="side">OPTIONAL - what side PMC to get name from (usec/bear)</param>
/// <returns>name of PMC</returns>
public string GetPmcNicknameOfMaxLength(int maxLength, string side = null)
{
var randomType = side is not null ? side : _randomUtil.GetInt(0, 1) == 0 ? "usec" : "bear";
var allNames = _databaseService.GetBots().Types[randomType.ToLower()].FirstNames;
var filteredNames = allNames.Where((name) => name.Length <= maxLength);
if (filteredNames.Count() == 0)
{
_logger.Warning(
$"Unable to filter: {randomType} PMC names to only those under: {maxLength}, none found that match that criteria, selecting from entire name pool instead`,\n"
);
return _randomUtil.GetStringCollectionValue(allNames);
}
return _randomUtil.GetStringCollectionValue(filteredNames);
}
}
@@ -1,22 +0,0 @@
using SptCommon.Annotations;
namespace Core.Helpers.Dialogue.Commando.SptCommands.GiveCommand;
[Injectable]
public class SavedCommand
{
public SavedCommand()
{
}
public SavedCommand(int quantity, List<string> potentialItemNames, string locale)
{
Quantity = quantity;
PotentialItemNames = potentialItemNames;
Locale = locale;
}
public int Quantity { get; set; }
public List<string> PotentialItemNames { get; set; }
public string Locale { get; set; }
}
@@ -1,13 +0,0 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Profile;
namespace Core.Helpers.Dialogue.SPTFriend.Commands;
public interface IChatMessageHandler
{
// Lower = More priority
int GetPriority();
public abstract bool CanHandle(string message);
public abstract void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender);
}
@@ -1,8 +0,0 @@
using SptCommon.Annotations;
namespace Core.Helpers;
[Injectable]
public class GameEventHelper
{
}
@@ -1,121 +0,0 @@
using SptCommon.Annotations;
using Core.Models.Spt.Helper;
using Core.Models.Utils;
namespace Core.Helpers;
[Injectable]
public class WeightedRandomHelper(
ISptLogger<WeightedRandomHelper> _logger
)
{
/// <summary>
/// Choose an item from the passed in array based on the weightings of each
/// </summary>
/// <param name="values">Items and weights to use</param>
/// <returns>Chosen item from array</returns>
public T GetWeightedValue<T>(Dictionary<T, double> values) where T : notnull
{
var itemKeys = values.Keys.ToList();
var weights = values.Values.ToList();
var chosenItem = WeightedRandom<T>(itemKeys, weights);
return chosenItem.Item;
}
/// <summary>
/// Picks the random item based on its weight.
/// The items with higher weight will be picked more often (with a higher probability).
///
/// For example:
/// - items = ['banana', 'orange', 'apple']
/// - weights = [0, 0.2, 0.8]
/// - weightedRandom(items, weights) in 80% of cases will return 'apple', in 20% of cases will return
/// 'orange' and it will never return 'banana' (because probability of picking the banana is 0%)
///
/// </summary>
/// <param name="items">List of items</param>
/// <param name="weights">List of weights</param>
/// <returns>Dictionary with item and index</returns>
public WeightedRandomResult<T> WeightedRandom<T>(List<T> items, List<double> weights)
{
if (items.Count == 0) _logger.Error("Items must not be empty");
if (weights.Count == 0) _logger.Error("Item weights must not be empty");
if (items.Count != weights.Count) _logger.Error("Items and weight inputs must be of the same length");
// Preparing the cumulative weights list.
List<int> cumulativeWeights = [];
for (var i = 0; i < weights.Count; i++) cumulativeWeights.Add((int)weights[i] + (i > 0 ? cumulativeWeights[i - 1] : 0));
// Getting the random number in a range of [0...sum(weights)]
var maxCumulativeWeight = cumulativeWeights[cumulativeWeights.Count - 1];
var randomNumber = maxCumulativeWeight * new Random().NextDouble();
// Picking the random item based on its weight.
for (var itemIndex = 0; itemIndex < items.Count; itemIndex++)
if (cumulativeWeights[itemIndex] >= randomNumber)
return new WeightedRandomResult<T>()
{
Item = items[itemIndex],
Index = itemIndex
};
throw new InvalidOperationException("No item was picked.");
}
/// <summary>
/// Find the greated common divisor of all weights and use it on the passed in dictionary
/// </summary>
/// <param name="weightedDict">Values to reduce</param>
public void ReduceWeightValues(Dictionary<string, double> weightedDict)
{
// No values, nothing to reduce
if (weightedDict.Count == 0) return;
// Only one value, set to 1 and exit
if (weightedDict.Count == 1)
{
var kvp = weightedDict.FirstOrDefault();
weightedDict[kvp.Key] = 1;
return;
}
var weights = weightedDict.Values.ToList();
var commonDivisor = CommonDivisor(weights);
// No point in dividing by 1
if (commonDivisor == 1) return;
foreach (var kvp in weightedDict) weightedDict[kvp.Key] /= commonDivisor;
}
/**
* Get the common divisor between all values in the passed in list and returns it
*/
protected double CommonDivisor(List<double> numbers)
{
var result = numbers[0];
for (var i = 1; i < numbers.Count; i++) result = Gcd(result, numbers[i]);
return result;
}
protected double Gcd(double a, double b)
{
var x = a;
var y = b;
while (y != 0)
{
var temp = y;
y = x % y;
x = temp;
}
return x;
}
}
-26
View File
@@ -1,26 +0,0 @@
using SptCommon.Annotations;
using Core.DI;
using Core.Models.External;
using Core.Models.Utils;
namespace Core.Loaders;
[Injectable(InjectableTypeOverride = typeof(OnLoad), TypePriority = OnLoadOrder.PostDBModLoader)]
public class PostDBModLoader(
ISptLogger<PostDBModLoader> _logger,
IEnumerable<IPostDBLoadMod> _postDbLoadMods
) : OnLoad
{
public async Task OnLoad()
{
_logger.Info("Loading PostDBLoadMod...");
foreach (var postDbLoadMod in _postDbLoadMods) postDbLoadMod.PostDBLoad();
_logger.Info("Finished loading PostDBLoadMod...");
}
public string GetRoute()
{
return "spt-post-db-mods";
}
}
@@ -1,14 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Common;
public record IdWithCount
{
/** Id of stack to take money from */
[JsonPropertyName("id")]
public string? Id { get; set; }
/** Amount of money to take off player for treatment */
[JsonPropertyName("count")]
public double? Count { get; set; }
}
-25
View File
@@ -1,25 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Common;
public record MinMax
{
public MinMax(double min, double max)
{
Min = min;
Max = max;
}
public MinMax()
{
}
[JsonPropertyName("type")]
public string? Type { get; set; }
[JsonPropertyName("max")]
public double? Max { get; set; }
[JsonPropertyName("min")]
public double? Min { get; set; }
}
@@ -1,25 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Bot;
public record GenerateBotsRequestData : IRequestData
{
[JsonPropertyName("conditions")]
public List<GenerateCondition>? Conditions { get; set; }
}
public record GenerateCondition
{
/// <summary>
/// e.g. assault/pmcBot/bossKilla
/// </summary>
[JsonPropertyName("Role")]
public string? Role { get; set; }
[JsonPropertyName("Limit")]
public int Limit { get; set; }
[JsonPropertyName("Difficulty")]
public string? Difficulty { get; set; }
}
@@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Bot;
public record RandomisedBotLevelResult
{
[JsonPropertyName("level")]
public int? Level { get; set; }
[JsonPropertyName("exp")]
public int? Exp { get; set; }
}
@@ -1,26 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Profile;
using Core.Models.Utils;
namespace Core.Models.Eft.Builds;
public record SetMagazineRequest : IRequestData
{
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonPropertyName("Caliber")]
public string? Caliber { get; set; }
[JsonPropertyName("Items")]
public List<MagazineTemplateAmmoItem>? Items { get; set; }
[JsonPropertyName("TopCount")]
public int? TopCount { get; set; }
[JsonPropertyName("BottomCount")]
public int? BottomCount { get; set; }
}
@@ -1,7 +0,0 @@
using Core.Models.Utils;
namespace Core.Models.Eft.Common;
public record EmptyRequestData : IRequestData
{
}
File diff suppressed because it is too large Load Diff
@@ -1,202 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Tables;
using Core.Utils.Json;
namespace Core.Models.Eft.Common;
public record Location
{
/** Map meta-data */
[JsonPropertyName("base")]
public LocationBase? Base { get; set; }
/** Loose loot positions and item weights */
[JsonPropertyName("looseLoot")]
public LazyLoad<LooseLoot>? LooseLoot { get; set; }
/** Static loot item weights */
[JsonPropertyName("staticLoot")]
public LazyLoad<Dictionary<string, StaticLootDetails>>? StaticLoot { get; set; }
/** Static container positions and item weights */
[JsonPropertyName("staticContainers")]
public LazyLoad<StaticContainerDetails>? StaticContainers { get; set; }
[JsonPropertyName("staticAmmo")]
public Dictionary<string, List<StaticAmmoDetails>> StaticAmmo { get; set; }
/** All possible static containers on map + their assign groupings */
[JsonPropertyName("statics")]
public StaticContainer? Statics { get; set; }
/** All possible map extracts */
[JsonPropertyName("allExtracts")]
public Exit[] AllExtracts { get; set; }
}
public record StaticContainer
{
[JsonPropertyName("containersGroups")]
public Dictionary<string, ContainerMinMax>? ContainersGroups { get; set; }
[JsonPropertyName("containers")]
public Dictionary<string, ContainerData>? Containers { get; set; }
}
public record ContainerMinMax
{
[JsonPropertyName("minContainers")]
public int? MinContainers { get; set; }
[JsonPropertyName("maxContainers")]
public int? MaxContainers { get; set; }
[JsonPropertyName("current")]
public int? Current { get; set; }
[JsonPropertyName("chosenCount")]
public int? ChosenCount { get; set; }
}
public record ContainerData
{
[JsonPropertyName("groupId")]
public string? GroupId { get; set; }
}
public record StaticLootDetails
{
[JsonPropertyName("itemcountDistribution")]
public ItemCountDistribution[] ItemCountDistribution { get; set; }
[JsonPropertyName("itemDistribution")]
public ItemDistribution[] ItemDistribution { get; set; }
}
public record ItemCountDistribution
{
[JsonPropertyName("count")]
public int? Count { get; set; }
[JsonPropertyName("relativeProbability")]
public float? RelativeProbability { get; set; }
}
public record ItemDistribution
{
[JsonPropertyName("tpl")]
public string? Tpl { get; set; }
[JsonPropertyName("relativeProbability")]
public float? RelativeProbability { get; set; }
}
public record StaticPropsBase
{
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonPropertyName("IsContainer")]
public bool? IsContainer { get; set; }
[JsonPropertyName("useGravity")]
public bool? UseGravity { get; set; }
[JsonPropertyName("randomRotation")]
public bool? RandomRotation { get; set; }
[JsonPropertyName("Position")]
public XYZ? Position { get; set; }
[JsonPropertyName("Rotation")]
public XYZ? Rotation { get; set; }
[JsonPropertyName("IsGroupPosition")]
public bool? IsGroupPosition { get; set; }
[JsonPropertyName("IsAlwaysSpawn")]
public bool? IsAlwaysSpawn { get; set; }
[JsonPropertyName("GroupPositions")]
public GroupPosition[] GroupPositions { get; set; }
[JsonPropertyName("Root")]
public string? Root { get; set; }
[JsonPropertyName("Items")]
public Item[] Items { get; set; }
}
[Obsolete("use SpawnpointTemplate")]
public record StaticWeaponProps : StaticPropsBase
{
[JsonPropertyName("Items")]
public Item[] Items { get; set; }
}
public record StaticContainerDetails
{
[JsonPropertyName("staticWeapons")]
public List<SpawnpointTemplate> StaticWeapons { get; set; }
[JsonPropertyName("staticContainers")]
public List<StaticContainerData> StaticContainers { get; set; }
[JsonPropertyName("staticForced")]
public List<StaticForced> StaticForced { get; set; }
}
public record StaticForced
{
[JsonPropertyName("containerId")]
public string ContainerId { get; set; }
[JsonPropertyName("itemTpl")]
public string ItemTpl { get; set; }
}
public record StaticContainerData
{
[JsonPropertyName("probability")]
public float? Probability { get; set; }
[JsonPropertyName("template")]
public SpawnpointTemplate? Template { get; set; }
}
public record StaticAmmoDetails
{
[JsonPropertyName("tpl")]
public string? Tpl { get; set; }
[JsonPropertyName("relativeProbability")]
public float? RelativeProbability { get; set; }
}
public record StaticForcedProps
{
[JsonPropertyName("containerId")]
public string? ContainerId { get; set; }
[JsonPropertyName("itemTpl")]
public string? ItemTpl { get; set; }
}
[Obsolete("use SpawnpointTemplate")]
public record StaticContainerProps : StaticPropsBase
{
[JsonPropertyName("Items")]
public StaticItem[] Items { get; set; }
}
public record StaticItem
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("_tpl")]
public string? Tpl { get; set; }
[JsonPropertyName("upd")]
public Upd? Upd { get; set; }
}
File diff suppressed because it is too large Load Diff
@@ -1,106 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Tables;
namespace Core.Models.Eft.Common;
public record LooseLoot
{
[JsonPropertyName("spawnpointCount")]
public SpawnpointCount? SpawnpointCount { get; set; }
[JsonPropertyName("spawnpointsForced")]
public List<Spawnpoint>? SpawnpointsForced { get; set; }
[JsonPropertyName("spawnpoints")]
public List<Spawnpoint>? Spawnpoints { get; set; }
}
public record SpawnpointCount
{
[JsonPropertyName("mean")]
public double? Mean { get; set; }
[JsonPropertyName("std")]
public double? Std { get; set; }
}
public record SpawnpointTemplate
{
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonPropertyName("IsContainer")]
public bool? IsContainer { get; set; }
[JsonPropertyName("useGravity")]
public bool? UseGravity { get; set; }
[JsonPropertyName("randomRotation")]
public bool? RandomRotation { get; set; }
[JsonPropertyName("Position")]
public XYZ? Position { get; set; }
[JsonPropertyName("Rotation")]
public XYZ? Rotation { get; set; }
[JsonPropertyName("IsAlwaysSpawn")]
public bool? IsAlwaysSpawn { get; set; }
[JsonPropertyName("IsGroupPosition")]
public bool? IsGroupPosition { get; set; }
[JsonPropertyName("GroupPositions")]
public List<GroupPosition>? GroupPositions { get; set; }
[JsonPropertyName("Root")]
public string? Root { get; set; }
[JsonPropertyName("Items")]
public List<Item>? Items { get; set; }
}
public record GroupPosition
{
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonPropertyName("Weight")]
public double? Weight { get; set; }
[JsonPropertyName("Position")]
public XYZ? Position { get; set; }
[JsonPropertyName("Rotation")]
public XYZ? Rotation { get; set; }
}
public record Spawnpoint
{
[JsonPropertyName("locationId")]
public string? LocationId { get; set; }
[JsonPropertyName("probability")]
public double? Probability { get; set; }
[JsonPropertyName("template")]
public SpawnpointTemplate? Template { get; set; }
[JsonPropertyName("itemDistribution")]
public List<LooseLootItemDistribution>? ItemDistribution { get; set; }
}
public record LooseLootItemDistribution
{
[JsonPropertyName("composedKey")]
public ComposedKey? ComposedKey { get; set; }
[JsonPropertyName("relativeProbability")]
public double? RelativeProbability { get; set; }
}
public record ComposedKey
{
[JsonPropertyName("key")]
public string? Key { get; set; }
}
@@ -1,21 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common;
public record MetricsTableData
{
[JsonPropertyName("Keys")]
public List<int>? Keys { get; set; }
[JsonPropertyName("NetProcessingBins")]
public List<int>? NetProcessingBins { get; set; }
[JsonPropertyName("RenderBins")]
public List<int>? RenderBins { get; set; }
[JsonPropertyName("GameUpdateBins")]
public List<int>? GameUpdateBins { get; set; }
[JsonPropertyName("MemoryMeasureInterval")]
public int? MemoryMeasureInterval { get; set; }
}
@@ -1,30 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Tables;
using Core.Utils.Json.Converters;
namespace Core.Models.Eft.Common;
public record PmcData : BotBase
{
[JsonPropertyName("Prestige")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, long>? Prestige { get; set; }
public Dictionary<string, double>? CheckedMagazines { get; set; }
public object CheckedChambers { get; set; }
}
public record PostRaidPmcData : PmcData
{
}
public record PostRaidStats
{
[JsonPropertyName("Eft")]
public EftStats? Eft { get; set; }
/** Only found in profile we get from client post raid */
[JsonPropertyName("Arena")]
public EftStats? Arena { get; set; }
}
@@ -1,24 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Request;
public record BaseInteractionRequestData
{
[JsonPropertyName("Action")]
public string? Action { get; set; }
[JsonPropertyName("fromOwner")]
public OwnerInfo? FromOwner { get; set; }
[JsonPropertyName("toOwner")]
public OwnerInfo? ToOwner { get; set; }
}
public record OwnerInfo
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Common.Request;
public record UIDRequestData : IRequestData
{
[JsonPropertyName("uid")]
public string? Uid { get; set; }
}
@@ -1,69 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record Achievement
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("imageUrl")]
public string? ImageUrl { get; set; }
[JsonPropertyName("assetPath")]
public string? AssetPath { get; set; }
[JsonPropertyName("rewards")]
public List<Reward>? Rewards { get; set; }
[JsonPropertyName("conditions")]
public AchievementQuestConditionTypes? Conditions { get; set; }
[JsonPropertyName("instantComplete")]
public bool? InstantComplete { get; set; }
[JsonPropertyName("showNotificationsInGame")]
public bool? ShowNotificationsInGame { get; set; }
[JsonPropertyName("showProgress")]
public bool? ShowProgress { get; set; }
[JsonPropertyName("prefab")]
public string? Prefab { get; set; }
[JsonPropertyName("rarity")]
public string? Rarity { get; set; }
[JsonPropertyName("hidden")]
public bool? Hidden { get; set; }
[JsonPropertyName("showConditions")]
public bool? ShowConditions { get; set; }
[JsonPropertyName("progressBarEnabled")]
public bool? ProgressBarEnabled { get; set; }
[JsonPropertyName("side")]
public string? Side { get; set; }
[JsonPropertyName("index")]
public int? Index { get; set; }
}
public record AchievementQuestConditionTypes
{
[JsonPropertyName("started")]
public List<QuestCondition>? Started { get; set; }
[JsonPropertyName("availableForFinish")]
public List<QuestCondition>? AvailableForFinish { get; set; }
[JsonPropertyName("availableForStart")]
public List<QuestCondition>? AvailableForStart { get; set; }
[JsonPropertyName("success")]
public List<QuestCondition>? Success { get; set; }
[JsonPropertyName("fail")]
public List<QuestCondition>? Fail { get; set; }
}
@@ -1,811 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Notes;
using Core.Models.Eft.Ragfair;
using Core.Models.Enums;
using Core.Utils.Json;
using Core.Utils.Json.Converters;
namespace Core.Models.Eft.Common.Tables;
public record BotBase
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("aid")]
[JsonConverter(typeof(StringToNumberFactoryConverter))]
public int? Aid { get; set; }
/** SPT property - use to store player id - TODO - move to AID ( account id as guid of choice) */
[JsonPropertyName("sessionId")]
public string? SessionId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("savage")]
public string? Savage { get; set; }
[JsonPropertyName("karmaValue")]
public double? KarmaValue { get; set; }
[JsonPropertyName("Info")]
public Info? Info { get; set; }
[JsonPropertyName("Customization")]
public Customization? Customization { get; set; }
[JsonPropertyName("Health")]
public BotBaseHealth? Health { get; set; }
[JsonPropertyName("Inventory")]
public BotBaseInventory? Inventory { get; set; }
[JsonPropertyName("Skills")]
public Skills? Skills { get; set; }
[JsonPropertyName("Stats")]
public Stats? Stats { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("Encyclopedia")]
public Dictionary<string, bool>? Encyclopedia { get; set; }
[JsonPropertyName("TaskConditionCounters")]
public Dictionary<string, TaskConditionCounter>? TaskConditionCounters { get; set; }
[JsonPropertyName("InsuredItems")]
public List<InsuredItem>? InsuredItems { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("Hideout")]
public Hideout? Hideout { get; set; }
[JsonPropertyName("Quests")]
public List<QuestStatus>? Quests { get; set; }
[JsonPropertyName("TradersInfo")]
public Dictionary<string, TraderInfo>? TradersInfo { get; set; }
[JsonPropertyName("UnlockedInfo")]
public UnlockedInfo? UnlockedInfo { get; set; }
[JsonPropertyName("RagfairInfo")]
public RagfairInfo? RagfairInfo { get; set; }
/** Achievement id and timestamp */
[JsonPropertyName("Achievements")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, long>? Achievements { get; set; }
[JsonPropertyName("RepeatableQuests")]
public List<PmcDataRepeatableQuest>? RepeatableQuests { get; set; }
[JsonPropertyName("Bonuses")]
public List<Bonus>? Bonuses { get; set; }
[JsonPropertyName("Notes")]
public Notes? Notes { get; set; }
[JsonPropertyName("CarExtractCounts")]
public Dictionary<string, int>? CarExtractCounts { get; set; }
[JsonPropertyName("CoopExtractCounts")]
public Dictionary<string, int>? CoopExtractCounts { get; set; }
[JsonPropertyName("SurvivorClass")]
public SurvivorClass? SurvivorClass { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("WishList")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public DictionaryOrList<string, int>? WishList { get; set; }
[JsonPropertyName("moneyTransferLimitData")]
public MoneyTransferLimits? MoneyTransferLimitData { get; set; }
/** SPT specific property used during bot generation in raid */
[JsonPropertyName("sptIsPmc")]
public bool? IsPmc { get; set; }
}
public record MoneyTransferLimits
{
// Resets every 24 hours in live
/** TODO: Implement */
[JsonPropertyName("nextResetTime")]
public double? NextResetTime { get; set; }
[JsonPropertyName("remainingLimit")]
public double? RemainingLimit { get; set; }
[JsonPropertyName("totalLimit")]
public double? TotalLimit { get; set; }
[JsonPropertyName("resetInterval")]
public double? ResetInterval { get; set; }
}
public record TaskConditionCounter
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
[JsonPropertyName("value")]
public double? Value { get; set; }
/** Quest id */
[JsonPropertyName("sourceId")]
public string? SourceId { get; set; }
}
public record UnlockedInfo
{
[JsonPropertyName("unlockedProductionRecipe")]
public List<string>? UnlockedProductionRecipe { get; set; }
}
public record Info
{
public string? EntryPoint { get; set; }
public string? Nickname { get; set; }
public string? MainProfileNickname { get; set; }
public string? LowerNickname { get; set; }
public string? Side { get; set; }
public bool? SquadInviteRestriction { get; set; }
// Confirmed in client
public int? PrestigeLevel { get; set; }
public string? Voice { get; set; }
public int? Level { get; set; }
//Experience the bot has gained
// Confirmed in client
public int? Experience { get; set; }
public List<Ban>? Bans { get; set; }
public bool? BannedState { get; set; }
public long? BannedUntil { get; set; }
public bool? IsStreamerModeAvailable { get; set; }
// Confirmed in client
[JsonConverter(typeof(StringToNumberFactoryConverter))]
public int? RegistrationDate { get; set; }
public string? GameVersion { get; set; }
public MemberCategory? MemberCategory { get; set; }
public MemberCategory? SelectedMemberCategory { get; set; }
[JsonPropertyName("lockedMoveCommands")]
public bool? LockedMoveCommands { get; set; }
public double? SavageLockTime { get; set; }
public long? LastTimePlayedAsSavage { get; set; }
public BotInfoSettings? Settings { get; set; }
public List<object>? NeedWipeOptions { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("lastCompletedWipe")]
public LastCompleted? LastCompletedWipe { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("lastWipeTimestamp")]
public LastCompleted? LastWipeTimestamp { get; set; }
public double? AccountType { get; set; }
public long? NicknameChangeDate { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("lastCompletedEvent")]
public LastCompleted? LastCompletedEvent { get; set; }
[JsonPropertyName("isMigratedSkills")]
public bool? IsMigratedSkills { get; set; }
public double? GroupId { get; set; }
public double? TeamId { get; set; }
public bool? HasCoopExtension { get; set; }
public bool? HasPveGame { get; set; }
public string? Type { get; set; }
}
public record BotInfoSettings
{
public string? Role { get; set; }
public string? BotDifficulty { get; set; }
// Experience given for being killed
public int? Experience { get; set; }
public double? StandingForKill { get; set; }
public double? AggressorBonus { get; set; }
public bool? UseSimpleAnimator { get; set; }
}
public record Ban
{
[JsonPropertyName("banType")]
public BanType? BanType { get; set; }
[JsonPropertyName("dateTime")]
public long? DateTime { get; set; }
}
public enum BanType
{
CHAT = 0,
RAGFAIR = 1,
VOIP = 2,
TRADING = 3,
ONLINE = 4,
FRIENDS = 5,
CHANGE_NICKNAME = 6
}
public record Customization
{
public string? Head { get; set; }
public string? Body { get; set; }
public string? Feet { get; set; }
public string? Hands { get; set; }
public string? DogTag { get; set; }
}
public record BotBaseHealth
{
public CurrentMinMax? Hydration { get; set; }
public CurrentMinMax? Energy { get; set; }
public CurrentMinMax? Temperature { get; set; }
public CurrentMinMax? Poison { get; set; }
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
[JsonPropertyName("BodyParts")]
public Dictionary<string, BodyPartHealth>? BodyParts { get; set; }
public double? UpdateTime { get; set; }
public bool? Immortal { get; set; }
}
public record BodyPartHealth
{
public CurrentMinMax? Health { get; set; }
public Dictionary<string, BodyPartEffectProperties>? Effects { get; set; } // TODO: change key to DamageEffectType enum
}
public record BodyPartEffectProperties
{
// TODO: this was any, what actual type is it?
public object? ExtraData { get; set; }
public double? Time { get; set; }
}
public record CurrentMinMax
{
public double? Current { get; set; }
public double? Minimum { get; set; }
public double? Maximum { get; set; }
public double? OverDamageReceivedMultiplier { get; set; }
public double? EnvironmentDamageMultiplier { get; set; }
}
public record BotBaseInventory
{
[JsonPropertyName("items")]
public List<Item>? Items { get; set; }
[JsonPropertyName("equipment")]
public string? Equipment { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("stash")]
public string? Stash { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("sortingTable")]
public string? SortingTable { get; set; }
[JsonPropertyName("questRaidItems")]
public string? QuestRaidItems { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("questStashItems")]
public string? QuestStashItems { get; set; }
/** Key is hideout area enum numeric as string e.g. "24", value is area _id */
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("hideoutAreaStashes")]
public Dictionary<string, string>? HideoutAreaStashes { get; set; }
[JsonPropertyName("fastPanel")]
public Dictionary<string, string>? FastPanel { get; set; }
[JsonPropertyName("favoriteItems")]
public List<string>? FavoriteItems { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("hideoutCustomizationStashId")]
public string? HideoutCustomizationStashId { get; set; }
}
public record BaseJsonSkills
{
public List<Common>? Common { get; set; }
public List<Mastering>? Mastering { get; set; }
public double? Points { get; set; }
}
public record Skills
{
public List<BaseSkill>? Common { get; set; }
public List<BaseSkill>? Mastering { get; set; }
public double? Points { get; set; }
}
public record BaseSkill
{
public double? PointsEarnedDuringSession { get; set; }
public long? LastAccess { get; set; }
public string? Id { get; set; }
public double? Progress { get; set; }
[JsonPropertyName("max")]
public int? Max { get; set; }
[JsonPropertyName("min")]
public int? Min { get; set; }
}
public record Common : BaseSkill
{
}
public record Mastering : BaseSkill
{
}
public record Stats
{
public EftStats? Eft { get; set; }
}
public record EftStats
{
public List<string>? CarriedQuestItems { get; set; }
public List<Victim>? Victims { get; set; }
public double? TotalSessionExperience { get; set; }
public long? LastSessionDate { get; set; }
public SessionCounters? SessionCounters { get; set; }
public OverallCounters? OverallCounters { get; set; }
public float? SessionExperienceMult { get; set; }
public float? ExperienceBonusMult { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public Aggressor? Aggressor { get; set; }
public List<DroppedItem>? DroppedItems { get; set; }
public List<FoundInRaidItem>? FoundInRaidItems { get; set; }
public DamageHistory? DamageHistory { get; set; }
public DeathCause? DeathCause { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public LastPlayerState? LastPlayerState { get; set; }
public long? TotalInGameTime { get; set; }
public string? SurvivorClass { get; set; }
[JsonPropertyName("sptLastRaidFenceRepChange")]
public float? SptLastRaidFenceRepChange { get; set; }
}
public record DroppedItem
{
public string? QuestId { get; set; }
public string? ItemId { get; set; }
public string? ZoneId { get; set; }
}
public record FoundInRaidItem
{
public string? QuestId { get; set; }
public string? ItemId { get; set; }
}
public record Victim
{
public string? AccountId { get; set; }
public string? ProfileId { get; set; }
public string? Name { get; set; }
public string? Side { get; set; }
public string? BodyPart { get; set; }
public string? Time { get; set; }
public double? Distance { get; set; }
public double? Level { get; set; }
public string? Weapon { get; set; }
public double? PrestigeLevel { get; set; }
public string? ColliderType { get; set; }
public string? Role { get; set; }
public string? Location { get; set; }
[JsonExtensionData]
public Dictionary<string, object> OtherProperties { get; set; }
}
public record SessionCounters
{
public List<CounterKeyValue>? Items { get; set; }
}
public record OverallCounters
{
public List<CounterKeyValue>? Items { get; set; }
}
public record CounterKeyValue
{
public List<string>? Key { get; set; }
public double? Value { get; set; }
}
public record Aggressor
{
public double? PrestigeLevel { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? AccountId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? ProfileId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? MainProfileNickname { get; set; }
public string? Name { get; set; }
public string? Side { get; set; }
public string? BodyPart { get; set; }
public string? HeadSegment { get; set; }
public string? WeaponName { get; set; }
public string? Category { get; set; }
public string? ColliderType { get; set; }
public string? Role { get; set; }
[JsonExtensionData]
public Dictionary<string, object> OtherProperties { get; set; }
}
public record DamageHistory
{
public string? LethalDamagePart { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public DamageStats? LethalDamage { get; set; }
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public BodyPartsDamageHistory? BodyParts { get; set; }
}
public record BodyPartsDamageHistory
{
public List<DamageStats>? Head { get; set; }
public List<DamageStats>? Chest { get; set; }
public List<DamageStats>? Stomach { get; set; }
public List<DamageStats>? LeftArm { get; set; }
public List<DamageStats>? RightArm { get; set; }
public List<DamageStats>? LeftLeg { get; set; }
public List<DamageStats>? RightLeg { get; set; }
public List<DamageStats>? Common { get; set; }
}
public record DamageStats
{
public double? Amount { get; set; }
public string? Type { get; set; }
public string? SourceId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? OverDamageFrom { get; set; }
public bool? Blunt { get; set; }
public double? ImpactsCount { get; set; }
}
public record DeathCause
{
public string? DamageType { get; set; }
public string? Side { get; set; }
public string? Role { get; set; }
public string? WeaponId { get; set; }
}
public record LastPlayerState
{
public LastPlayerStateInfo? Info { get; set; }
public Dictionary<string, string>? Customization { get; set; }
// TODO: there is no definition on TS just any
public object? Equipment { get; set; }
}
public record LastPlayerStateInfo
{
public string? Nickname { get; set; }
public string? Side { get; set; }
public double? Level { get; set; }
public MemberCategory? MemberCategory { get; set; }
}
public record BackendCounter
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("qid")]
public string? QId { get; set; }
[JsonPropertyName("value")]
public double? Value { get; set; }
}
public record InsuredItem
{
/** Trader Id item was insured by */
[JsonPropertyName("tid")]
public string? TId { get; set; }
[JsonPropertyName("itemId")]
public string? ItemId { get; set; }
}
public record Hideout
{
public Dictionary<string, Production?>? Production { get; set; }
public List<BotHideoutArea>? Areas { get; set; }
public Dictionary<string, HideoutImprovement>? Improvements { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public HideoutCounters? HideoutCounters { get; set; }
public double? Seed { get; set; }
public Dictionary<string, string>? MannequinPoses { get; set; }
[JsonPropertyName("sptUpdateLastRunTimestamp")]
public long? SptUpdateLastRunTimestamp { get; set; }
public Dictionary<string, string>? Customization { get; set; }
}
public record HideoutCounters
{
[JsonPropertyName("fuelCounter")]
public double? FuelCounter { get; set; }
[JsonPropertyName("airFilterCounter")]
public double? AirFilterCounter { get; set; }
[JsonPropertyName("waterFilterCounter")]
public double? WaterFilterCounter { get; set; }
[JsonPropertyName("craftingTimeCounter")]
public double? CraftingTimeCounter { get; set; }
}
public record HideoutImprovement
{
[JsonPropertyName("completed")]
public bool? Completed { get; set; }
[JsonPropertyName("improveCompleteTimestamp")]
public long? ImproveCompleteTimestamp { get; set; }
}
public record Production // use this instead of productive and scavcase
{
public List<Item>? Products { get; set; }
/** Seconds passed of production */
public double? Progress { get; set; }
/** Is craft in some state of being worked on by client (crafting/ready to pick up) */
[JsonPropertyName("inProgress")]
public bool? InProgress { get; set; }
public long? StartTimestamp { get; set; }
public double? SkipTime { get; set; }
/** Seconds needed to fully craft */
public double? ProductionTime { get; set; }
public List<Item>? GivenItemsInStart { get; set; }
public bool? Interrupted { get; set; }
public string? Code { get; set; }
public bool? Decoded { get; set; }
public bool? AvailableForFinish { get; set; }
/** Used in hideout production.json */
public bool? needFuelForAllProductionTime { get; set; }
/** Used when sending data to client */
public bool? NeedFuelForAllProductionTime { get; set; }
[JsonPropertyName("sptIsScavCase")]
public bool? SptIsScavCase { get; set; }
/** Some crafts are always inProgress, but need to be reset, e.g. water collector */
[JsonPropertyName("sptIsComplete")]
public bool? SptIsComplete { get; set; }
/** Is the craft a Continuous, e.g bitcoins/water collector */
[JsonPropertyName("sptIsContinuous")]
public bool? SptIsContinuous { get; set; }
/** Stores a list of tools used in this craft and whether they're FiR, to give back once the craft is done */
[JsonPropertyName("sptRequiredTools")]
public List<Item>? SptRequiredTools { get; set; }
// Craft is cultist circle sacrifice
[JsonPropertyName("sptIsCultistCircle")]
public bool? SptIsCultistCircle { get; set; }
public string? RecipeId { get; set; }
}
public record BotHideoutArea
{
[JsonPropertyName("type")]
public HideoutAreas? Type { get; set; }
[JsonPropertyName("level")]
public double? Level { get; set; }
[JsonPropertyName("active")]
public bool? Active { get; set; }
[JsonPropertyName("passiveBonusesEnabled")]
public bool? PassiveBonusesEnabled { get; set; }
/** Must be integer */
[JsonPropertyName("completeTime")]
public double? CompleteTime { get; set; }
[JsonPropertyName("constructing")]
public bool? Constructing { get; set; }
[JsonPropertyName("slots")]
public List<HideoutSlot>? Slots { get; set; }
[JsonPropertyName("lastRecipe")]
public string? LastRecipe { get; set; }
}
public record HideoutSlot
{
/// <summary>
/// SPT specific value to keep track of what index this slot is (0,1,2,3 etc)
/// </summary>
[JsonPropertyName("locationIndex")]
public double? LocationIndex { get; set; }
[JsonPropertyName("item")]
public List<HideoutItem>? Items { get; set; }
}
public record LastCompleted
{
[JsonPropertyName("$oid")]
public string? OId { get; set; }
}
public record Notes
{
[JsonPropertyName("Notes")]
public List<Note>? DataNotes { get; set; }
}
public enum SurvivorClass
{
UNKNOWN = 0,
NEUTRALIZER = 1,
MARAUDER = 2,
PARAMEDIC = 3,
SURVIVOR = 4
}
public record Quests
{
[JsonPropertyName("qid")]
public string? QId { get; set; }
[JsonPropertyName("startTime")]
public long? StartTime { get; set; }
[JsonPropertyName("status")]
public QuestStatusEnum? Status { get; set; }
[JsonPropertyName("statusTimers")]
public Dictionary<QuestStatusEnum, long>? StatusTimers { get; set; }
/** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client */
[JsonPropertyName("completedConditions")]
public List<string>? CompletedConditions { get; set; }
[JsonPropertyName("availableAfter")]
public long? AvailableAfter { get; set; }
}
public record TraderInfo
{
[JsonPropertyName("loyaltyLevel")]
public int? LoyaltyLevel { get; set; }
[JsonPropertyName("salesSum")]
public double? SalesSum { get; set; }
[JsonPropertyName("standing")]
public double? Standing { get; set; }
[JsonPropertyName("nextResupply")]
public double? NextResupply { get; set; }
[JsonPropertyName("unlocked")]
public bool? Unlocked { get; set; }
[JsonPropertyName("disabled")]
public bool? Disabled { get; set; }
}
public record RagfairInfo
{
[JsonPropertyName("rating")]
public double? Rating { get; set; }
[JsonPropertyName("isRatingGrowing")]
public bool? IsRatingGrowing { get; set; }
[JsonPropertyName("offers")]
public List<RagfairOffer>? Offers { get; set; }
[JsonPropertyName("sellSum")]
public double? SellSum { get; set; }
[JsonPropertyName("notSellSum")]
public double? NotSellSum { get; set; }
}
public record Bonus
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("type")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public BonusType? Type { get; set; }
[JsonPropertyName("templateId")]
public string? TemplateId { get; set; }
[JsonPropertyName("passive")]
public bool? IsPassive { get; set; }
[JsonPropertyName("production")]
public bool? IsProduction { get; set; }
[JsonPropertyName("visible")]
public bool? IsVisible { get; set; }
[JsonPropertyName("value")]
public double? Value { get; set; }
[JsonPropertyName("icon")]
public string? Icon { get; set; }
[JsonPropertyName("filter")]
public List<string>? Filter { get; set; }
[JsonPropertyName("skillType")]
public BonusSkillType? SkillType { get; set; }
}
@@ -1,399 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record BotCore
{
[JsonPropertyName("SAVAGE_KILL_DIST")]
public double? SavageKillDistance { get; set; }
[JsonPropertyName("SOUND_DOOR_BREACH_METERS")]
public double? SoundDoorBreachMeters { get; set; }
[JsonPropertyName("SOUND_DOOR_OPEN_METERS")]
public double? SoundDoorOpenMeters { get; set; }
[JsonPropertyName("STEP_NOISE_DELTA")]
public double? StepNoiseDelta { get; set; }
[JsonPropertyName("JUMP_NOISE_DELTA")]
public double? JumpNoiseDelta { get; set; }
[JsonPropertyName("GUNSHOT_SPREAD")]
public double? GunshotSpread { get; set; }
[JsonPropertyName("GUNSHOT_SPREAD_SILENCE")]
public double? GunshotSpreadSilence { get; set; }
[JsonPropertyName("BASE_WALK_SPEREAD2")]
public double? BaseWalkSpread2 { get; set; }
[JsonPropertyName("MOVE_SPEED_COEF_MAX")]
public double? MoveSpeedCoefficientMax { get; set; }
[JsonPropertyName("SPEED_SERV_SOUND_COEF_A")]
public double? SpeedServiceSoundCoefficientA { get; set; }
[JsonPropertyName("SPEED_SERV_SOUND_COEF_B")]
public double? SpeedServiceSoundCoefficientB { get; set; }
[JsonPropertyName("G")]
public double? Gravity { get; set; }
[JsonPropertyName("STAY_COEF")]
public double? StayCoefficient { get; set; }
[JsonPropertyName("SIT_COEF")]
public double? SitCoefficient { get; set; }
[JsonPropertyName("LAY_COEF")]
public double? LayCoefficient { get; set; }
[JsonPropertyName("MAX_ITERATIONS")]
public double? MaxIterations { get; set; }
[JsonPropertyName("START_DIST_TO_COV")]
public double? StartDistanceToCover { get; set; }
[JsonPropertyName("MAX_DIST_TO_COV")]
public double? MaxDistanceToCover { get; set; }
[JsonPropertyName("STAY_HEIGHT")]
public double? StayHeight { get; set; }
[JsonPropertyName("CLOSE_POINTS")]
public double? ClosePoints { get; set; }
[JsonPropertyName("COUNT_TURNS")]
public double? CountTurns { get; set; }
[JsonPropertyName("SIMPLE_POINT_LIFE_TIME_SEC")]
public double? SimplePointLifetimeSeconds { get; set; }
[JsonPropertyName("DANGER_POINT_LIFE_TIME_SEC")]
public double? DangerPointLifetimeSeconds { get; set; }
[JsonPropertyName("DANGER_POWER")]
public double? DangerPower { get; set; }
[JsonPropertyName("COVER_DIST_CLOSE")]
public double? CoverDistanceClose { get; set; }
[JsonPropertyName("GOOD_DIST_TO_POINT")]
public double? GoodDistanceToPoint { get; set; }
[JsonPropertyName("COVER_TOOFAR_FROM_BOSS")]
public double? CoverTooFarFromBoss { get; set; }
[JsonPropertyName("COVER_TOOFAR_FROM_BOSS_SQRT")]
public double? CoverTooFarFromBossSqrt { get; set; }
[JsonPropertyName("MAX_Y_DIFF_TO_PROTECT")]
public double? MaxYDifferenceToProtect { get; set; }
[JsonPropertyName("FLARE_POWER")]
public double? FlarePower { get; set; }
[JsonPropertyName("MOVE_COEF")]
public double? MoveCoefficient { get; set; }
[JsonPropertyName("PRONE_POSE")]
public double? PronePose { get; set; }
[JsonPropertyName("LOWER_POSE")]
public double? LowerPose { get; set; }
[JsonPropertyName("MAX_POSE")]
public double? MaxPose { get; set; }
[JsonPropertyName("FLARE_TIME")]
public double? FlareTime { get; set; }
[JsonPropertyName("MAX_REQUESTS__PER_GROUP")]
public double? MaxRequestsPerGroup { get; set; }
[JsonPropertyName("UPDATE_GOAL_TIMER_SEC")]
public double? UpdateGoalTimerSeconds { get; set; }
[JsonPropertyName("DIST_NOT_TO_GROUP")]
public double? DistanceNotToGroup { get; set; }
[JsonPropertyName("DIST_NOT_TO_GROUP_SQR")]
public double? DistanceNotToGroupSquared { get; set; }
[JsonPropertyName("LAST_SEEN_POS_LIFETIME")]
public double? LastSeenPositionLifetime { get; set; }
[JsonPropertyName("DELTA_GRENADE_START_TIME")]
public double? DeltaGrenadeStartTime { get; set; }
[JsonPropertyName("DELTA_GRENADE_END_TIME")]
public double? DeltaGrenadeEndTime { get; set; }
[JsonPropertyName("DELTA_GRENADE_RUN_DIST")]
public double? DeltaGrenadeRunDistance { get; set; }
[JsonPropertyName("DELTA_GRENADE_RUN_DIST_SQRT")]
public double? DeltaGrenadeRunDistanceSqrt { get; set; }
[JsonPropertyName("PATROL_MIN_LIGHT_DIST")]
public double? PatrolMinimumLightDistance { get; set; }
[JsonPropertyName("HOLD_MIN_LIGHT_DIST")]
public double? HoldMinimumLightDistance { get; set; }
[JsonPropertyName("STANDART_BOT_PAUSE_DOOR")]
public double? StandardBotPauseDoor { get; set; }
[JsonPropertyName("ARMOR_CLASS_COEF")]
public double? ArmorClassCoefficient { get; set; }
[JsonPropertyName("SHOTGUN_POWER")]
public double? ShotgunPower { get; set; }
[JsonPropertyName("RIFLE_POWER")]
public double? RiflePower { get; set; }
[JsonPropertyName("PISTOL_POWER")]
public double? PistolPower { get; set; }
[JsonPropertyName("SMG_POWER")]
public double? SMGPower { get; set; }
[JsonPropertyName("SNIPE_POWER")]
public double? SniperPower { get; set; }
[JsonPropertyName("GESTUS_PERIOD_SEC")]
public double? GestusPeriodSeconds { get; set; }
[JsonPropertyName("GESTUS_AIMING_DELAY")]
public double? GestusAimingDelay { get; set; }
[JsonPropertyName("GESTUS_REQUEST_LIFETIME")]
public double? GestusRequestLifetime { get; set; }
[JsonPropertyName("GESTUS_FIRST_STAGE_MAX_TIME")]
public double? GestusFirstStageMaxTime { get; set; }
[JsonPropertyName("GESTUS_SECOND_STAGE_MAX_TIME")]
public double? GestusSecondStageMaxTime { get; set; }
[JsonPropertyName("GESTUS_MAX_ANSWERS")]
public double? GestusMaxAnswers { get; set; }
[JsonPropertyName("GESTUS_FUCK_TO_SHOOT")]
public double? GestusFuckToShoot { get; set; }
[JsonPropertyName("GESTUS_DIST_ANSWERS")]
public double? GestusDistanceAnswers { get; set; }
[JsonPropertyName("GESTUS_DIST_ANSWERS_SQRT")]
public double? GestusDistanceAnswersSqrt { get; set; }
[JsonPropertyName("GESTUS_ANYWAY_CHANCE")]
public double? GestusAnywayChance { get; set; }
[JsonPropertyName("TALK_DELAY")]
public double? TalkDelay { get; set; }
[JsonPropertyName("CAN_SHOOT_TO_HEAD")]
public bool? CanShootToHead { get; set; }
[JsonPropertyName("CAN_TILT")]
public bool? CanTilt { get; set; }
[JsonPropertyName("TILT_CHANCE")]
public double? TiltChance { get; set; }
[JsonPropertyName("MIN_BLOCK_DIST")]
public double? MinimumBlockDistance { get; set; }
[JsonPropertyName("MIN_BLOCK_TIME")]
public double? MinimumBlockTime { get; set; }
[JsonPropertyName("COVER_SECONDS_AFTER_LOSE_VISION")]
public double? CoverSecondsAfterLoseVision { get; set; }
[JsonPropertyName("MIN_ARG_COEF")]
public double? MinimumArgumentCoefficient { get; set; }
[JsonPropertyName("MAX_ARG_COEF")]
public double? MaximumArgumentCoefficient { get; set; }
[JsonPropertyName("DEAD_AGR_DIST")]
public double? DeadAgrDistance { get; set; }
[JsonPropertyName("MAX_DANGER_CARE_DIST_SQRT")]
public double? MaxDangerCareDistanceSqrt { get; set; }
[JsonPropertyName("MAX_DANGER_CARE_DIST")]
public double? MaxDangerCareDistance { get; set; }
[JsonPropertyName("MIN_MAX_PERSON_SEARCH")]
public double? MinimumMaximumPersonSearch { get; set; }
[JsonPropertyName("PERCENT_PERSON_SEARCH")]
public double? PercentPersonSearch { get; set; }
[JsonPropertyName("LOOK_ANYSIDE_BY_WALL_SEC_OF_ENEMY")]
public double? LookAnySideByWallSecondsOfEnemy { get; set; }
[JsonPropertyName("CLOSE_TO_WALL_ROTATE_BY_WALL_SQRT")]
public double? CloseToWallRotateByWallSqrt { get; set; }
[JsonPropertyName("SHOOT_TO_CHANGE_RND_PART_MIN")]
public double? ShootToChangeRandomPartMinimum { get; set; }
[JsonPropertyName("SHOOT_TO_CHANGE_RND_PART_MAX")]
public double? ShootToChangeRandomPartMaximum { get; set; }
[JsonPropertyName("SHOOT_TO_CHANGE_RND_PART_DELTA")]
public double? ShootToChangeRandomPartDelta { get; set; }
[JsonPropertyName("FORMUL_COEF_DELTA_DIST")]
public double? FormulaCoefficientDeltaDistance { get; set; }
[JsonPropertyName("FORMUL_COEF_DELTA_SHOOT")]
public double? FormulaCoefficientDeltaShoot { get; set; }
[JsonPropertyName("FORMUL_COEF_DELTA_FRIEND_COVER")]
public double? FormulaCoefficientDeltaFriendCover { get; set; }
[JsonPropertyName("SUSPETION_POINT_DIST_CHECK")]
public double? SuspicionPointDistanceCheck { get; set; }
[JsonPropertyName("MAX_BASE_REQUESTS_PER_PLAYER")]
public double? MaxBaseRequestsPerPlayer { get; set; }
[JsonPropertyName("MAX_HOLD_REQUESTS_PER_PLAYER")]
public double? MaxHoldRequestsPerPlayer { get; set; }
[JsonPropertyName("MAX_GO_TO_REQUESTS_PER_PLAYER")]
public double? MaxGoToRequestsPerPlayer { get; set; }
[JsonPropertyName("MAX_COME_WITH_ME_REQUESTS_PER_PLAYER")]
public double? MaxComeWithMeRequestsPerPlayer { get; set; }
[JsonPropertyName("CORE_POINT_MAX_VALUE")]
public double? CorePointMaxValue { get; set; }
[JsonPropertyName("CORE_POINTS_MAX")]
public double? CorePointsMax { get; set; }
[JsonPropertyName("CORE_POINTS_MIN")]
public double? CorePointsMin { get; set; }
[JsonPropertyName("BORN_POISTS_FREE_ONLY_FAREST_BOT")]
public bool? BornPointsFreeOnlyFarthestBot { get; set; }
[JsonPropertyName("BORN_POINSTS_FREE_ONLY_FAREST_PLAYER")]
public bool? BornPointsFreeOnlyFarthestPlayer { get; set; }
[JsonPropertyName("SCAV_GROUPS_TOGETHER")]
public bool? ScavGroupsTogether { get; set; }
[JsonPropertyName("LAY_DOWN_ANG_SHOOT")]
public double? LayDownAngleShoot { get; set; }
[JsonPropertyName("HOLD_REQUEST_TIME_SEC")]
public double? HoldRequestTimeSeconds { get; set; }
[JsonPropertyName("TRIGGERS_DOWN_TO_RUN_WHEN_MOVE")]
public double? TriggersDownToRunWhenMove { get; set; }
[JsonPropertyName("MIN_DIST_TO_RUN_WHILE_ATTACK_MOVING")]
public double? MinimumDistanceToRunWhileAttackingMoving { get; set; }
[JsonPropertyName("MIN_DIST_TO_RUN_WHILE_ATTACK_MOVING_OTHER_ENEMIS")]
public double? MinimumDistanceToRunWhileAttackingMovingOtherEnemies { get; set; }
[JsonPropertyName("MIN_DIST_TO_STOP_RUN")]
public double? MinimumDistanceToStopRunning { get; set; }
[JsonPropertyName("JUMP_SPREAD_DIST")]
public double? JumpSpreadDistance { get; set; }
[JsonPropertyName("LOOK_TIMES_TO_KILL")]
public double? LookTimesToKill { get; set; }
[JsonPropertyName("COME_INSIDE_TIMES")]
public double? ComeInsideTimes { get; set; }
[JsonPropertyName("TOTAL_TIME_KILL")]
public double? TotalTimeKill { get; set; }
[JsonPropertyName("TOTAL_TIME_KILL_AFTER_WARN")]
public double? TotalTimeKillAfterWarning { get; set; }
[JsonPropertyName("MOVING_AIM_COEF")]
public double? MovingAimCoefficient { get; set; }
[JsonPropertyName("VERTICAL_DIST_TO_IGNORE_SOUND")]
public double? VerticalDistanceToIgnoreSound { get; set; }
[JsonPropertyName("DEFENCE_LEVEL_SHIFT")]
public double? DefenseLevelShift { get; set; }
[JsonPropertyName("MIN_DIST_CLOSE_DEF")]
public double? MinimumDistanceCloseDefense { get; set; }
[JsonPropertyName("USE_ID_PRIOR_WHO_GO")]
public bool? UseIdPriorWhoGoes { get; set; }
[JsonPropertyName("SMOKE_GRENADE_RADIUS_COEF")]
public double? SmokeGrenadeRadiusCoefficient { get; set; }
[JsonPropertyName("GRENADE_PRECISION")]
public double? GrenadePrecision { get; set; }
[JsonPropertyName("MAX_WARNS_BEFORE_KILL")]
public double? MaxWarningsBeforeKill { get; set; }
[JsonPropertyName("CARE_ENEMY_ONLY_TIME")]
public double? CareEnemyOnlyTime { get; set; }
[JsonPropertyName("MIDDLE_POINT_COEF")]
public double? MiddlePointCoefficient { get; set; }
[JsonPropertyName("MAIN_TACTIC_ONLY_ATTACK")]
public bool? MainTacticOnlyAttack { get; set; }
[JsonPropertyName("LAST_DAMAGE_ACTIVE")]
public double? LastDamageActive { get; set; }
[JsonPropertyName("SHALL_DIE_IF_NOT_INITED")]
public bool? ShallDieIfNotInitialized { get; set; }
[JsonPropertyName("CHECK_BOT_INIT_TIME_SEC")]
public double? CheckBotInitializationTimeSeconds { get; set; }
[JsonPropertyName("WEAPON_ROOT_Y_OFFSET")]
public double? WeaponRootYOffset { get; set; }
[JsonPropertyName("DELTA_SUPRESS_DISTANCE_SQRT")]
public double? DeltaSuppressDistanceSqrt { get; set; }
[JsonPropertyName("DELTA_SUPRESS_DISTANCE")]
public double? DeltaSuppressDistance { get; set; }
[JsonPropertyName("WAVE_COEF_LOW")]
public double? WaveCoefficientLow { get; set; }
[JsonPropertyName("WAVE_COEF_MID")]
public double? WaveCoefficientMid { get; set; }
[JsonPropertyName("WAVE_COEF_HIGH")]
public double? WaveCoefficientHigh { get; set; }
[JsonPropertyName("WAVE_COEF_HORDE")]
public double? WaveCoefficientHorde { get; set; }
[JsonPropertyName("WAVE_ONLY_AS_ONLINE")]
public bool? WaveOnlyAsOnline { get; set; }
[JsonPropertyName("LOCAL_BOTS_COUNT")]
public double? LocalBotsCount { get; set; }
[JsonPropertyName("AXE_MAN_KILLS_END")]
public double? AxeManKillsEnd { get; set; }
}
@@ -1,422 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Common;
using Core.Models.Enums;
using Core.Utils.Json.Converters;
using SptCommon.Extensions;
namespace Core.Models.Eft.Common.Tables;
public record BotType
{
[JsonPropertyName("appearance")]
public Appearance? BotAppearance { get; set; }
[JsonPropertyName("chances")]
public Chances? BotChances { get; set; }
[JsonPropertyName("difficulty")]
public Dictionary<string, DifficultyCategories>? BotDifficulty { get; set; }
[JsonPropertyName("experience")]
public Experience? BotExperience { get; set; }
[JsonPropertyName("firstName")]
public List<string>? FirstNames { get; set; }
[JsonPropertyName("generation")]
public Generation? BotGeneration { get; set; }
[JsonPropertyName("health")]
public BotTypeHealth? BotHealth { get; set; }
[JsonPropertyName("inventory")]
public BotTypeInventory? BotInventory { get; set; }
[JsonPropertyName("lastName")]
public List<string>? LastNames { get; set; }
[JsonPropertyName("skills")]
public BotDbSkills? BotSkills { get; set; }
}
public record Appearance
{
[JsonPropertyName("body")]
public Dictionary<string, double>? Body { get; set; }
[JsonPropertyName("feet")]
public Dictionary<string, double>? Feet { get; set; }
[JsonPropertyName("hands")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, double>? Hands { get; set; }
[JsonPropertyName("head")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, double>? Head { get; set; }
[JsonPropertyName("voice")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, double>? Voice { get; set; }
}
public record Chances
{
[JsonPropertyName("equipment")]
public Dictionary<string, double>? EquipmentChances { get; set; }
[JsonPropertyName("weaponMods")]
public Dictionary<string, double>? WeaponModsChances { get; set; }
[JsonPropertyName("equipmentMods")]
public Dictionary<string, double>? EquipmentModsChances { get; set; }
[JsonPropertyName("mods")]
public Dictionary<string, double>? Mods { get; set; }
}
/* record removed in favor of Dictionary<string, double>
used to be used in:
Chances.WeaponModsChances
Chances.EquipmentModsChances
GenerateWeaponRequest.ModSpawnChances
public record ModsChances
{
[JsonPropertyName("mod_charge")]
public double? ModCharge { get; set; }
[JsonPropertyName("mod_bipod")]
public double? ModBipod { get; set; }
[JsonPropertyName("mod_barrel")]
public double? ModBarrel { get; set; }
[JsonPropertyName("mod_catch")]
public double? ModCatch { get; set; }
[JsonPropertyName("mod_gas_block")]
public double? ModGasBlock { get; set; }
[JsonPropertyName("mod_hammer")]
public double? ModHammer { get; set; }
[JsonPropertyName("mod_equipment")]
public double? ModEquipment { get; set; }
[JsonPropertyName("mod_equipment_000")]
public double? ModEquipment000 { get; set; }
[JsonPropertyName("mod_equipment_001")]
public double? ModEquipment001 { get; set; }
[JsonPropertyName("mod_equipment_002")]
public double? ModEquipment002 { get; set; }
[JsonPropertyName("mod_flashlight")]
public double? ModFlashlight { get; set; }
[JsonPropertyName("mod_foregrip")]
public double? ModForegrip { get; set; }
[JsonPropertyName("mod_launcher")]
public double? ModLauncher { get; set; }
[JsonPropertyName("mod_magazine")]
public double? ModMagazine { get; set; }
[JsonPropertyName("mod_mount")]
public double? ModMount { get; set; }
[JsonPropertyName("mod_mount_000")]
public double? ModMount000 { get; set; }
[JsonPropertyName("mod_mount_001")]
public double? ModMount001 { get; set; }
[JsonPropertyName("mod_muzzle")]
public double? ModMuzzle { get; set; }
[JsonPropertyName("mod_nvg")]
public double? ModNvg { get; set; }
[JsonPropertyName("mod_pistol_grip")]
public double? ModPistolGrip { get; set; }
[JsonPropertyName("mod_reciever")]
public double? ModReceiver { get; set; }
[JsonPropertyName("mod_scope")]
public double? ModScope { get; set; }
[JsonPropertyName("mod_scope_000")]
public double? ModScope000 { get; set; }
[JsonPropertyName("mod_scope_001")]
public double? ModScope001 { get; set; }
[JsonPropertyName("mod_scope_002")]
public double? ModScope002 { get; set; }
[JsonPropertyName("mod_scope_003")]
public double? ModScope003 { get; set; }
[JsonPropertyName("mod_sight_front")]
public double? ModSightFront { get; set; }
[JsonPropertyName("mod_sight_rear")]
public double? ModSightRear { get; set; }
[JsonPropertyName("mod_stock")]
public double? ModStock { get; set; }
[JsonPropertyName("mod_stock_000")]
public double? ModStock000 { get; set; }
[JsonPropertyName("mod_stock_002")]
public double? ModStock002 { get; set; }
[JsonPropertyName("mod_stock_akms")]
public double? ModStockAkms { get; set; }
[JsonPropertyName("mod_tactical")]
public double? ModTactical { get; set; }
[JsonPropertyName("mod_tactical_000")]
public double? ModTactical000 { get; set; }
[JsonPropertyName("mod_tactical_001")]
public double? ModTactical001 { get; set; }
[JsonPropertyName("mod_tactical_002")]
public double? ModTactical002 { get; set; }
[JsonPropertyName("mod_tactical_2")]
public double? ModTactical2 { get; set; }
[JsonPropertyName("mod_tactical_003")]
public double? ModTactical003 { get; set; }
[JsonPropertyName("mod_handguard")]
public double? ModHandguard { get; set; }
[JsonPropertyName("back_plate")]
public double? BackPlate { get; set; }
[JsonPropertyName("front_plate")]
public double? FrontPlate { get; set; }
[JsonPropertyName("left_side_plate")]
public double? LeftSidePlate { get; set; }
[JsonPropertyName("right_side_plate")]
public double? RightSidePlate { get; set; }
[JsonPropertyName("mod_mount_002")]
public double? ModMount002 { get; set; }
[JsonPropertyName("mod_mount_003")]
public double? ModMount003 { get; set; }
[JsonPropertyName("mod_mount_004")]
public double? ModMount004 { get; set; }
[JsonPropertyName("mod_mount_005")]
public double? ModMount005 { get; set; }
[JsonPropertyName("mod_mount_006")]
public double? ModMount006 { get; set; }
[JsonPropertyName("mod_muzzle_000")]
public double? ModMuzzle000 { get; set; }
[JsonPropertyName("mod_muzzle_001")]
public double? ModMuzzle001 { get; set; }
[JsonPropertyName("mod_pistol_grip_akms")]
public double? ModPistolGripAkms { get; set; }
[JsonPropertyName("mod_pistolgrip")]
public double? ModPistol_Grip { get; set; }
}
*/
public record Difficulties
{
[JsonPropertyName("easy")]
public DifficultyCategories? Easy { get; set; }
[JsonPropertyName("normal")]
public DifficultyCategories? Normal { get; set; }
[JsonPropertyName("hard")]
public DifficultyCategories? Hard { get; set; }
[JsonPropertyName("impossible")]
public DifficultyCategories? Impossible { get; set; }
}
public record DifficultyCategories
{
public Dictionary<string, object>? Aiming { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Boss { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Change { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Core { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Cover { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Grenade { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Hearing { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Lay { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Look { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Mind { get; set; } // TODO: string | number | boolean | string[]
public Dictionary<string, object>? Move { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Patrol { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Scattering { get; set; } // TODO: string | number | boolean
public Dictionary<string, object>? Shoot { get; set; } // TODO: string | number | boolean
}
public record Experience
{
/** key = bot difficulty */
[JsonPropertyName("aggressorBonus")]
public Dictionary<string, double>? AggressorBonus { get; set; }
[JsonPropertyName("level")]
public MinMax? Level { get; set; }
/** key = bot difficulty */
[JsonPropertyName("reward")]
public Dictionary<string, MinMax>? Reward { get; set; }
/** key = bot difficulty */
[JsonPropertyName("standingForKill")]
public Dictionary<string, double>? StandingForKill { get; set; }
[JsonPropertyName("useSimpleAnimator")]
public bool? UseSimpleAnimator { get; set; }
}
public record Generation
{
[JsonPropertyName("items")]
public GenerationWeightingItems? Items { get; set; }
}
public record GenerationData
{
/** key: number of items, value: weighting */
[JsonPropertyName("weights")]
public Dictionary<double, double>? Weights { get; set; }
/** Array of item tpls */
[JsonPropertyName("whitelist")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, double>? Whitelist { get; set; }
}
public record GenerationWeightingItems
{
[JsonPropertyName("grenades")]
public GenerationData Grenades { get; set; }
[JsonPropertyName("healing")]
public GenerationData Healing { get; set; }
[JsonPropertyName("drugs")]
public GenerationData Drugs { get; set; }
[JsonPropertyName("food")]
public GenerationData Food { get; set; }
[JsonPropertyName("drink")]
public GenerationData Drink { get; set; }
[JsonPropertyName("currency")]
public GenerationData Currency { get; set; }
[JsonPropertyName("stims")]
public GenerationData Stims { get; set; }
[JsonPropertyName("backpackLoot")]
public GenerationData BackpackLoot { get; set; }
[JsonPropertyName("pocketLoot")]
public GenerationData PocketLoot { get; set; }
[JsonPropertyName("vestLoot")]
public GenerationData VestLoot { get; set; }
[JsonPropertyName("magazines")]
public GenerationData Magazines { get; set; }
[JsonPropertyName("specialItems")]
public GenerationData SpecialItems { get; set; }
[JsonPropertyName("looseLoot")]
public GenerationData LooseLoot { get; set; }
}
public record BotTypeHealth
{
public List<BodyPart>? BodyParts { get; set; }
public MinMax? Energy { get; set; }
public MinMax? Hydration { get; set; }
public MinMax? Temperature { get; set; }
}
public record BodyPart
{
public MinMax? Chest { get; set; }
public MinMax? Head { get; set; }
public MinMax? LeftArm { get; set; }
public MinMax? LeftLeg { get; set; }
public MinMax? RightArm { get; set; }
public MinMax? RightLeg { get; set; }
public MinMax? Stomach { get; set; }
}
public record BotTypeInventory
{
[JsonPropertyName("equipment")]
public Dictionary<EquipmentSlots, Dictionary<string, double>>? Equipment { get; set; }
public GlobalAmmo? Ammo { get; set; }
[JsonPropertyName("items")]
public ItemPools? Items { get; set; }
[JsonPropertyName("mods")]
public GlobalMods? Mods { get; set; }
}
public record Equipment
{
public Dictionary<string, double>? ArmBand { get; set; }
public Dictionary<string, double>? ArmorVest { get; set; }
public Dictionary<string, double>? Backpack { get; set; }
public Dictionary<string, double>? Earpiece { get; set; }
public Dictionary<string, double>? Eyewear { get; set; }
public Dictionary<string, double>? FaceCover { get; set; }
public Dictionary<string, double>? FirstPrimaryWeapon { get; set; }
public Dictionary<string, double>? Headwear { get; set; }
public Dictionary<string, double>? Holster { get; set; }
public Dictionary<string, double>? Pockets { get; set; }
public Dictionary<string, double>? Scabbard { get; set; }
public Dictionary<string, double>? SecondPrimaryWeapon { get; set; }
public Dictionary<string, double>? SecuredContainer { get; set; }
public Dictionary<string, double>? TacticalVest { get; set; }
}
public record ItemPools
{
public Dictionary<string, double>? Backpack { get; set; }
public Dictionary<string, double>? Pockets { get; set; }
public Dictionary<string, double>? SecuredContainer { get; set; }
public Dictionary<string, double>? SpecialLoot { get; set; }
public Dictionary<string, double>? TacticalVest { get; set; }
}
public record BotDbSkills
{
public Dictionary<string, MinMax>? Common { get; set; }
public Dictionary<string, MinMax>? Mastering { get; set; }
}
@@ -1,96 +0,0 @@
namespace Core.Models.Eft.Common.Tables;
using System.Text.Json.Serialization;
public record CustomizationItem
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("_name")]
public string? Name { get; set; }
[JsonPropertyName("_parent")]
public string? Parent { get; set; }
[JsonPropertyName("_type")]
public string? Type { get; set; }
[JsonPropertyName("_props")]
public CustomizationProps? Properties { get; set; }
[JsonPropertyName("_proto")]
public string? Proto { get; set; }
}
public class CustomizationProps
{
[JsonPropertyName("Prefab")]
public object? Prefab { get; set; } // Prefab object or string
[JsonPropertyName("WatchPrefab")]
public Prefab? WatchPrefab { get; set; }
[JsonPropertyName("WatchRotation")]
public XYZ? WatchRotation { get; set; }
[JsonPropertyName("WatchPosition")]
public XYZ? WatchPosition { get; set; }
[JsonPropertyName("IntegratedArmorVest")]
public bool? IntegratedArmorVest { get; set; }
[JsonPropertyName("MannequinPoseName")]
public string? MannequinPoseName { get; set; }
[JsonPropertyName("BodyPart")]
public string? BodyPart { get; set; }
[JsonPropertyName("Game")]
public List<string>? Game { get; set; }
[JsonPropertyName("Hands")]
public string? Hands { get; set; }
[JsonPropertyName("Feet")]
public string? Feet { get; set; }
[JsonPropertyName("Body")]
public string? Body { get; set; }
[JsonPropertyName("ProfileVersions")]
public List<string>? ProfileVersions { get; set; }
[JsonPropertyName("Side")]
public List<string>? Side { get; set; }
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonPropertyName("ShortName")]
public string? ShortName { get; set; }
[JsonPropertyName("Description")]
public string? Description { get; set; }
[JsonPropertyName("AvailableAsDefault")]
public bool? AvailableAsDefault { get; set; }
[JsonPropertyName("EnvironmentUIType")]
public string? EnvironmentUIType { get; set; }
[JsonPropertyName("Interaction")]
public string? Interaction { get; set; }
[JsonPropertyName("UsecTemplateId")]
public string? UsecTemplateId { get; set; }
[JsonPropertyName("BearTemplateId")]
public string? BearTemplateId { get; set; }
[JsonPropertyName("AssetPath")]
public Prefab? AssetPath { get; set; }
[JsonPropertyName("HideGarbage")]
public bool? HideGarbage { get; set; }
}
@@ -1,45 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record HandbookBase
{
[JsonPropertyName("Categories")]
public List<HandbookCategory>? Categories { get; set; }
[JsonPropertyName("Items")]
public List<HandbookItem>? Items { get; set; }
}
public record HandbookCategory
{
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonPropertyName("ParentId")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? ParentId { get; set; }
[JsonPropertyName("Icon")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? Icon { get; set; }
[JsonPropertyName("Color")]
public string? Color { get; set; }
[JsonPropertyName("Order")]
public string? Order { get; set; }
}
public record HandbookItem
{
[JsonPropertyName("Id")]
public string? Id { get; set; }
[JsonPropertyName("ParentId")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? ParentId { get; set; }
[JsonPropertyName("Price")]
public double? Price { get; set; }
}
@@ -1,324 +0,0 @@
using System.Text.Json.Serialization;
using Core.Utils.Json.Converters;
namespace Core.Models.Eft.Common.Tables;
public record Item
{
// MongoId
[JsonPropertyName("_id")]
public string? Id { get; set; }
// MongoId
[JsonPropertyName("_tpl")]
public string? Template { get; set; }
[JsonPropertyName("parentId")]
public string? ParentId { get; set; }
[JsonPropertyName("slotId")]
public string? SlotId { get; set; }
[JsonPropertyName("location")]
public object? Location { get; set; } // TODO: Can be IItemLocation or number
[JsonPropertyName("desc")]
public string? Desc { get; set; }
[JsonPropertyName("upd")]
public Upd? Upd { get; set; }
public HideoutItem ConvertToHideoutItem(Item item, double? count = null)
{
return new HideoutItem()
{
Id = item.Id,
Template = item.Template,
Upd = item.Upd,
Count = count
};
}
}
public record HideoutItem
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("_tpl")]
public string? Template { get; set; }
[JsonPropertyName("upd")]
public Upd? Upd { get; set; }
[JsonPropertyName("count")]
public double? Count { get; set; }
public Item ConvertToItem()
{
return new Item
{
Id = Id,
Template = Template,
Upd = Upd
};
}
}
public record ItemLocation
{
[JsonPropertyName("x")]
public int? X { get; set; }
[JsonPropertyName("y")]
public int? Y { get; set; }
[JsonPropertyName("r")]
public object? R { get; set; } // TODO: Can be string or number
[JsonPropertyName("isSearched")]
public bool? IsSearched { get; set; }
/** SPT property? */
[JsonPropertyName("rotation")]
public object? Rotation { get; set; } // TODO: Can be string or boolean
}
public record Upd
{
public UpdBuff? Buff { get; set; }
public double? OriginalStackObjectsCount { get; set; }
public UpdTogglable? Togglable { get; set; }
public UpdMap? Map { get; set; }
public UpdTag? Tag { get; set; }
/** SPT specific property, not made by BSG */
[JsonPropertyName("sptPresetId")]
public string? SptPresetId { get; set; }
public UpdFaceShield? FaceShield { get; set; }
[JsonConverter(typeof(StringToNumberFactoryConverter))]
public double? StackObjectsCount { get; set; } // TODO: LootDumpGen is outputting doubles, we can turn back to int once fixed
public bool? UnlimitedCount { get; set; }
public UpdRepairable? Repairable { get; set; }
public UpdRecodableComponent? RecodableComponent { get; set; }
public UpdFireMode? FireMode { get; set; }
public bool? SpawnedInSession { get; set; }
public UpdLight? Light { get; set; }
public UpdKey? Key { get; set; }
public UpdResource? Resource { get; set; }
public UpdSight? Sight { get; set; }
public UpdMedKit? MedKit { get; set; }
public UpdFoodDrink? FoodDrink { get; set; }
public UpdDogtag? Dogtag { get; set; }
public int? BuyRestrictionMax { get; set; }
public int? BuyRestrictionCurrent { get; set; }
public UpdFoldable? Foldable { get; set; }
public UpdSideEffect? SideEffect { get; set; }
public UpdRepairKit? RepairKit { get; set; }
public UpdCultistAmulet? CultistAmulet { get; set; }
public PinLockState? PinLockState { get; set; }
}
public enum PinLockState
{
Free,
Locked,
Pinned
}
public record UpdBuff
{
[JsonPropertyName("Rarity")]
public string? Rarity { get; set; }
[JsonPropertyName("BuffType")]
public string? BuffType { get; set; }
[JsonPropertyName("Value")]
public double? Value { get; set; }
[JsonPropertyName("ThresholdDurability")]
public double? ThresholdDurability { get; set; }
}
public record UpdTogglable
{
[JsonPropertyName("On")]
public bool? On { get; set; }
}
public record UpdMap
{
[JsonPropertyName("Markers")]
public List<MapMarker>? Markers { get; set; }
}
public record MapMarker
{
[JsonPropertyName("Type")]
public string? Type { get; set; }
[JsonPropertyName("X")]
public double? X { get; set; }
[JsonPropertyName("Y")]
public double? Y { get; set; }
[JsonPropertyName("Note")]
public string? Note { get; set; }
}
public record UpdTag
{
[JsonPropertyName("Color")]
public int? Color { get; set; }
[JsonPropertyName("Name")]
public string? Name { get; set; }
}
public record UpdFaceShield
{
[JsonPropertyName("Hits")]
public int? Hits { get; set; }
[JsonPropertyName("HitSeed")]
public int? HitSeed { get; set; }
}
public record UpdRepairable
{
[JsonPropertyName("Durability")]
public double? Durability { get; set; }
[JsonPropertyName("MaxDurability")]
public double? MaxDurability { get; set; }
}
public record UpdRecodableComponent
{
[JsonPropertyName("IsEncoded")]
public bool? IsEncoded { get; set; }
}
public record UpdMedKit
{
[JsonPropertyName("HpResource")]
public double? HpResource { get; set; }
}
public record UpdSight
{
[JsonPropertyName("ScopesCurrentCalibPointIndexes")]
public List<int>? ScopesCurrentCalibPointIndexes { get; set; }
[JsonPropertyName("ScopesSelectedModes")]
public List<int>? ScopesSelectedModes { get; set; }
[JsonPropertyName("SelectedScope")]
public int? SelectedScope { get; set; }
public double? ScopeZoomValue { get; set; }
}
public record UpdFoldable
{
[JsonPropertyName("Folded")]
public bool? Folded { get; set; }
}
public record UpdFireMode
{
[JsonPropertyName("FireMode")]
public string? FireMode { get; set; }
}
public record UpdFoodDrink
{
[JsonPropertyName("HpPercent")]
public double? HpPercent { get; set; }
}
public record UpdKey
{
// Checked in client
[JsonPropertyName("NumberOfUsages")]
public int? NumberOfUsages { get; set; }
}
public record UpdResource
{
[JsonPropertyName("Value")]
public double? Value { get; set; }
[JsonPropertyName("UnitsConsumed")]
public double? UnitsConsumed { get; set; }
}
public record UpdLight
{
[JsonPropertyName("IsActive")]
public bool? IsActive { get; set; }
[JsonPropertyName("SelectedMode")]
public int? SelectedMode { get; set; }
}
public record UpdDogtag
{
[JsonPropertyName("AccountId")]
public string? AccountId { get; set; }
[JsonPropertyName("ProfileId")]
public string? ProfileId { get; set; }
[JsonPropertyName("Nickname")]
public string? Nickname { get; set; }
[JsonPropertyName("Side")]
public object? Side { get; set; }
[JsonPropertyName("Level")]
public double? Level { get; set; }
[JsonPropertyName("Time")]
public string? Time { get; set; }
[JsonPropertyName("Status")]
public string? Status { get; set; }
[JsonPropertyName("KillerAccountId")]
public string? KillerAccountId { get; set; }
[JsonPropertyName("KillerProfileId")]
public string? KillerProfileId { get; set; }
[JsonPropertyName("KillerName")]
public string? KillerName { get; set; }
[JsonPropertyName("WeaponName")]
public string? WeaponName { get; set; }
public bool? CarriedByGroupMember { get; set; }
}
public record UpdSideEffect
{
[JsonPropertyName("Value")]
public double? Value { get; set; }
}
public record UpdRepairKit
{
[JsonPropertyName("Resource")]
public double? Resource { get; set; }
}
public record UpdCultistAmulet
{
[JsonPropertyName("NumberOfUsages")]
public double? NumberOfUsages { get; set; }
}
@@ -1,190 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
using Core.Utils.Json.Converters;
namespace Core.Models.Eft.Common.Tables;
public record LocationServices
{
[JsonPropertyName("TraderServerSettings")]
public TraderServerSettings? TraderServerSettings { get; set; }
[JsonPropertyName("BTRServerSettings")]
public BtrServerSettings? BtrServerSettings { get; set; }
}
public record TraderServerSettings
{
[JsonPropertyName("TraderServices")]
public TraderServices? TraderServices { get; set; }
}
public record TraderServices
{
[JsonPropertyName("ExUsecLoyalty")]
public TraderService? ExUsecLoyalty { get; set; }
[JsonPropertyName("ZryachiyAid")]
public TraderService? ZryachiyAid { get; set; }
[JsonPropertyName("CultistsAid")]
public TraderService? CultistsAid { get; set; }
[JsonPropertyName("PlayerTaxi")]
public TraderService? PlayerTaxi { get; set; }
[JsonPropertyName("BtrItemsDelivery")]
public TraderService? BtrItemsDelivery { get; set; }
[JsonPropertyName("BtrBotCover")]
public TraderService? BtrBotCover { get; set; }
[JsonPropertyName("TransitItemsDelivery")]
public TraderService? TransitItemsDelivery { get; set; }
}
public record TraderService
{
[JsonPropertyName("TraderId")]
public string? TraderId { get; set; }
[JsonPropertyName("TraderServiceType")]
public TraderServiceType? TraderServiceType { get; set; }
[JsonPropertyName("Requirements")]
public ServiceRequirements? Requirements { get; set; }
[JsonPropertyName("ServiceItemCost")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public Dictionary<string, ServiceItemCostDetails>? ServiceItemCost { get; set; }
[JsonPropertyName("UniqueItems")]
public List<string>? UniqueItems { get; set; }
}
public record ServiceRequirements
{
[JsonPropertyName("CompletedQuests")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public List<CompletedQuest>? CompletedQuests { get; set; }
[JsonPropertyName("Standings")]
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public Dictionary<string, StandingRequirement>? Standings { get; set; }
}
public record CompletedQuest
{
[JsonPropertyName("QuestId")]
public string? QuestId { get; set; }
}
public record StandingRequirement
{
[JsonPropertyName("Value")]
public double? Value { get; set; }
}
public record ServiceItemCostDetails
{
[JsonPropertyName("Count")]
public int? Count { get; set; }
}
public record BtrServerSettings
{
[JsonPropertyName("ChanceSpawn")]
public double? ChanceSpawn { get; set; }
[JsonPropertyName("SpawnPeriod")]
public XYZ? SpawnPeriod { get; set; }
[JsonPropertyName("MoveSpeed")]
public float? MoveSpeed { get; set; }
[JsonPropertyName("ReadyToDepartureTime")]
public float? ReadyToDepartureTime { get; set; }
[JsonPropertyName("CheckTurnDistanceTime")]
public float? CheckTurnDistanceTime { get; set; }
[JsonPropertyName("TurnCheckSensitivity")]
public float? TurnCheckSensitivity { get; set; }
[JsonPropertyName("DecreaseSpeedOnTurnLimit")]
public double? DecreaseSpeedOnTurnLimit { get; set; }
[JsonPropertyName("EndSplineDecelerationDistance")]
public double? EndSplineDecelerationDistance { get; set; }
[JsonPropertyName("AccelerationSpeed")]
public double? AccelerationSpeed { get; set; }
[JsonPropertyName("DecelerationSpeed")]
public double? DecelerationSpeed { get; set; }
[JsonPropertyName("PauseDurationRange")]
public XYZ? PauseDurationRange { get; set; }
[JsonPropertyName("BodySwingReturnSpeed")]
public float? BodySwingReturnSpeed { get; set; }
[JsonPropertyName("BodySwingDamping")]
public float? BodySwingDamping { get; set; }
[JsonPropertyName("BodySwingIntensity")]
public float? BodySwingIntensity { get; set; }
[JsonPropertyName("ServerMapBTRSettings")]
public Dictionary<string, ServerMapBtrsettings>? ServerMapBTRSettings { get; set; }
}
public record ServerMapBtrsettings
{
[JsonPropertyName("MapID")]
public string? MapID { get; set; }
[JsonPropertyName("ChanceSpawn")]
public double? ChanceSpawn { get; set; }
[JsonPropertyName("SpawnPeriod")]
public XYZ? SpawnPeriod { get; set; }
[JsonPropertyName("MoveSpeed")]
public float? MoveSpeed { get; set; }
[JsonPropertyName("ReadyToDepartureTime")]
public float? ReadyToDepartureTime { get; set; }
[JsonPropertyName("CheckTurnDistanceTime")]
public float? CheckTurnDistanceTime { get; set; }
[JsonPropertyName("TurnCheckSensitivity")]
public float? TurnCheckSensitivity { get; set; }
[JsonPropertyName("DecreaseSpeedOnTurnLimit")]
public float? DecreaseSpeedOnTurnLimit { get; set; }
[JsonPropertyName("EndSplineDecelerationDistance")]
public float? EndSplineDecelerationDistance { get; set; }
[JsonPropertyName("AccelerationSpeed")]
public float? AccelerationSpeed { get; set; }
[JsonPropertyName("DecelerationSpeed")]
public float? DecelerationSpeed { get; set; }
[JsonPropertyName("PauseDurationRange")]
public XYZ? PauseDurationRange { get; set; }
[JsonPropertyName("BodySwingReturnSpeed")]
public float? BodySwingReturnSpeed { get; set; }
[JsonPropertyName("BodySwingDamping")]
public float? BodySwingDamping { get; set; }
[JsonPropertyName("BodySwingIntensity")]
public float? BodySwingIntensity { get; set; }
}
@@ -1,28 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record LocationsBase
{
[JsonPropertyName("locations")]
public Locations? Locations { get; set; }
[JsonPropertyName("paths")]
public List<Path>? Paths { get; set; }
}
public record Locations
{
// Add properties as necessary
}
public record Path
{
[JsonPropertyName("Source")]
public string? Source { get; set; }
[JsonPropertyName("Destination")]
public string? Destination { get; set; }
public bool? Event { get; set; }
}
@@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record LocationsGenerateAllResponse
{
[JsonPropertyName("locations")]
public Dictionary<string, LocationBase> Locations { get; set; }
[JsonPropertyName("paths")]
public List<Path>? Paths { get; set; }
}
@@ -1,30 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record Match
{
[JsonPropertyName("metrics")]
public Metrics? Metrics { get; set; }
}
public record Metrics
{
[JsonPropertyName("Keys")]
public List<int>? Keys { get; set; }
[JsonPropertyName("NetProcessingBins")]
public List<int>? NetProcessingBins { get; set; }
[JsonPropertyName("RenderBins")]
public List<int>? RenderBins { get; set; }
[JsonPropertyName("GameUpdateBins")]
public List<int>? GameUpdateBins { get; set; }
[JsonPropertyName("MemoryMeasureInterval")]
public int? MemoryMeasureInterval { get; set; }
[JsonPropertyName("PauseReasons")]
public List<int>? PauseReasons { get; set; }
}
@@ -1,75 +0,0 @@
namespace Core.Models.Eft.Common.Tables;
using System.Text.Json.Serialization;
public record Prestige
{
[JsonPropertyName("elements")]
public List<PrestigeElement>? Elements { get; set; }
}
public record PrestigeElement
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("conditions")]
public List<QuestCondition>? Conditions { get; set; }
[JsonPropertyName("rewards")]
public List<Reward>? Rewards { get; set; }
[JsonPropertyName("transferConfigs")]
public TransferConfigs? TransferConfigs { get; set; }
[JsonPropertyName("image")]
public string? Image { get; set; }
[JsonPropertyName("bigImage")]
public string? BigImage { get; set; }
}
public record TransferConfigs
{
[JsonPropertyName("stashConfig")]
public StashPrestigeConfig? StashConfig { get; set; }
[JsonPropertyName("skillConfig")]
public PrestigeSkillConfig? SkillConfig { get; set; }
[JsonPropertyName("masteringConfig")]
public PrestigeMasteringConfig? MasteringConfig { get; set; }
}
public record StashPrestigeConfig
{
[JsonPropertyName("xCellCount")]
public int? XCellCount { get; set; }
[JsonPropertyName("yCellCount")]
public int? YCellCount { get; set; }
[JsonPropertyName("filters")]
public StashPrestigeFilters? Filters { get; set; }
}
public record StashPrestigeFilters
{
[JsonPropertyName("includedItems")]
public List<string>? IncludedItems { get; set; }
[JsonPropertyName("excludedItems")]
public List<string>? ExcludedItems { get; set; }
}
public record PrestigeSkillConfig
{
[JsonPropertyName("transferMultiplier")]
public double? TransferMultiplier { get; set; }
}
public record PrestigeMasteringConfig
{
[JsonPropertyName("transferMultiplier")]
public double? TransferMultiplier { get; set; }
}
@@ -1,104 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Profile;
using SptCommon.Extensions;
namespace Core.Models.Eft.Common.Tables;
public record ProfileTemplates
{
[JsonPropertyName("Standard")]
public ProfileSides? Standard { get; set; }
[JsonPropertyName("Left Behind")]
public ProfileSides? LeftBehind { get; set; }
[JsonPropertyName("Prepare To Escape")]
public ProfileSides? PrepareToEscape { get; set; }
[JsonPropertyName("Edge Of Darkness")]
public ProfileSides? EdgeOfDarkness { get; set; }
[JsonPropertyName("Unheard")]
public ProfileSides? Unheard { get; set; }
[JsonPropertyName("Tournament")]
public ProfileSides? Tournament { get; set; }
[JsonPropertyName("SPT Developer")]
public ProfileSides? SPTDeveloper { get; set; }
[JsonPropertyName("SPT Easy start")]
public ProfileSides? SPTEasyStart { get; set; }
[JsonPropertyName("SPT Zero to hero")]
public ProfileSides? SPTZeroToHero { get; set; }
}
public record ProfileSides
{
[JsonPropertyName("descriptionLocaleKey")]
public string? DescriptionLocaleKey { get; set; }
[JsonPropertyName("usec")]
public TemplateSide? Usec { get; set; }
[JsonPropertyName("bear")]
public TemplateSide? Bear { get; set; }
}
public record TemplateSide
{
[JsonPropertyName("character")]
public PmcData? Character { get; set; }
[JsonPropertyName("suits")]
public List<string>? Suits { get; set; }
[JsonPropertyName("dialogues")]
public Dictionary<string, Dialogue>? Dialogues { get; set; }
[JsonPropertyName("userbuilds")]
public UserBuilds? UserBuilds { get; set; }
[JsonPropertyName("trader")]
public ProfileTraderTemplate? Trader { get; set; }
[JsonPropertyName("equipmentBuilds")]
public object? EquipmentBuilds { get; set; }
[JsonPropertyName("weaponbuilds")]
public object? WeaponBuilds { get; set; }
}
public record ProfileTraderTemplate
{
[JsonPropertyName("initialLoyaltyLevel")]
public Dictionary<string, int?>? InitialLoyaltyLevel { get; set; }
[JsonPropertyName("initialStanding")]
public Dictionary<string, double?>? InitialStanding { get; set; }
[JsonPropertyName("setQuestsAvailableForStart")]
public bool? SetQuestsAvailableForStart { get; set; }
[JsonPropertyName("setQuestsAvailableForFinish")]
public bool? SetQuestsAvailableForFinish { get; set; }
[JsonPropertyName("initialSalesSum")]
public int? InitialSalesSum { get; set; }
[JsonPropertyName("jaegerUnlocked")]
public bool? JaegerUnlocked { get; set; }
/** How many days is usage of the flea blocked for upon profile creation */
[JsonPropertyName("fleaBlockedDays")]
public int? FleaBlockedDays { get; set; }
/** What traders default to being locked on profile creation */
[JsonPropertyName("lockedByDefaultOverride")]
public List<string>? LockedByDefaultOverride { get; set; }
/** What traders should have their clothing unlocked/purchased on creation */
[JsonPropertyName("purchaseAllClothingByDefaultForTrader")]
public List<string>? PurchaseAllClothingByDefaultForTrader { get; set; }
}
@@ -1,498 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
using Core.Utils.Json;
using Core.Utils.Json.Converters;
using SptCommon.Extensions;
namespace Core.Models.Eft.Common.Tables;
public record Quest
{
/// <summary>
/// SPT addition - human readable quest name
/// </summary>
[JsonPropertyName("QuestName")]
public string? QuestName { get; set; }
/// <summary>
/// _id
/// </summary>
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("canShowNotificationsInGame")]
public bool? CanShowNotificationsInGame { get; set; }
[JsonPropertyName("conditions")]
public QuestConditionTypes? Conditions { get; set; }
[JsonPropertyName("description")]
public string? Description { get; set; }
[JsonPropertyName("failMessageText")]
public string? FailMessageText { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("note")]
public string? Note { get; set; }
[JsonPropertyName("traderId")]
public string? TraderId { get; set; }
[JsonPropertyName("location")]
public string? Location { get; set; }
[JsonPropertyName("image")]
public string? Image { get; set; }
[JsonPropertyName("type")] // can be string or QuestTypeEnum
[JsonConverter(typeof(JsonStringEnumConverter))]
public QuestTypeEnum? Type { get; set; }
[JsonPropertyName("isKey")]
public bool? IsKey { get; set; }
[JsonPropertyName("restartable")]
public bool? Restartable { get; set; }
[JsonPropertyName("instantComplete")]
public bool? InstantComplete { get; set; }
[JsonPropertyName("secretQuest")]
public bool? SecretQuest { get; set; }
[JsonPropertyName("startedMessageText")]
public string? StartedMessageText { get; set; }
[JsonPropertyName("successMessageText")]
public string? SuccessMessageText { get; set; }
[JsonPropertyName("acceptPlayerMessage")]
public string? AcceptPlayerMessage { get; set; }
[JsonPropertyName("declinePlayerMessage")]
public string? DeclinePlayerMessage { get; set; }
[JsonPropertyName("completePlayerMessage")]
public string? CompletePlayerMessage { get; set; }
[JsonPropertyName("templateId")]
public string? TemplateId { get; set; }
[JsonPropertyName("rewards")]
public QuestRewards? Rewards { get; set; }
/// <summary>
/// Becomes 'AppearStatus' inside client
/// </summary>
[JsonPropertyName("status")]
public object? Status { get; set; } // TODO: string | number
[JsonPropertyName("KeyQuest")]
public bool? KeyQuest { get; set; }
[JsonPropertyName("changeQuestMessageText")]
public string? ChangeQuestMessageText { get; set; }
/// <summary>
/// "Pmc" or "Scav"
/// </summary>
[JsonPropertyName("side")]
public string? Side { get; set; }
[JsonPropertyName("acceptanceAndFinishingSource")]
public string? AcceptanceAndFinishingSource { get; set; }
[JsonPropertyName("progressSource")]
public string? ProgressSource { get; set; }
[JsonPropertyName("rankingModes")]
public List<string>? RankingModes { get; set; }
[JsonPropertyName("gameModes")]
public List<string>? GameModes { get; set; }
[JsonPropertyName("arenaLocations")]
public List<string>? ArenaLocations { get; set; }
/// <summary>
/// Status of quest to player
/// </summary>
[JsonPropertyName("sptStatus")]
public QuestStatusEnum? SptStatus { get; set; }
[JsonPropertyName("questStatus")]
public QuestStatus? QuestStatus { get; set; }
[JsonPropertyName("changeCost")]
public List<object> ChangeCost { get; set; }
[JsonPropertyName("changeStandingCost")]
public double ChangeStandingCost { get; set; }
}
/// <summary>
/// Same as BotBase.Quests
/// </summary>
public record QuestStatus
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("uid")]
public string? Uid { get; set; }
[JsonPropertyName("qid")]
public string? QId { get; set; }
[JsonPropertyName("startTime")]
public double? StartTime { get; set; }
[JsonPropertyName("status")]
public QuestStatusEnum? Status { get; set; }
[JsonPropertyName("statusTimers")]
public Dictionary<QuestStatusEnum, double>? StatusTimers { get; set; }
[JsonPropertyName("completedConditions")]
public List<string>? CompletedConditions { get; set; }
[JsonPropertyName("availableAfter")]
public double? AvailableAfter { get; set; }
}
public record QuestConditionTypes
{
[JsonPropertyName("Started")]
public List<QuestCondition>? Started { get; set; }
[JsonPropertyName("AvailableForFinish")]
public List<QuestCondition>? AvailableForFinish { get; set; }
[JsonPropertyName("AvailableForStart")]
public List<QuestCondition>? AvailableForStart { get; set; }
[JsonPropertyName("Success")]
public List<QuestCondition>? Success { get; set; }
[JsonPropertyName("Fail")]
public List<QuestCondition>? Fail { get; set; }
}
public record QuestCondition
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("index")]
public int? Index { get; set; }
[JsonPropertyName("compareMethod")]
public string? CompareMethod { get; set; }
[JsonPropertyName("dynamicLocale")]
public bool? DynamicLocale { get; set; }
[JsonPropertyName("visibilityConditions")]
public List<VisibilityCondition>? VisibilityConditions { get; set; }
[JsonPropertyName("globalQuestCounterId")]
public string? GlobalQuestCounterId { get; set; }
[JsonPropertyName("parentId")]
public string? ParentId { get; set; }
/// <summary>
/// Can be: string[] or string
/// </summary>
[JsonPropertyName("target")]
[JsonConverter(typeof(ListOrTConverterFactory))]
public ListOrT<string>? Target { get; set; } // TODO: string[] | string
[JsonPropertyName("value")]
public object? Value { get; set; } // TODO: string | number
[JsonPropertyName("type")]
public object? Type { get; set; } // TODO: boolean | string
[JsonPropertyName("status")]
public List<QuestStatusEnum>? Status { get; set; }
[JsonPropertyName("availableAfter")]
public int? AvailableAfter { get; set; }
[JsonPropertyName("dispersion")]
public double? Dispersion { get; set; }
[JsonPropertyName("onlyFoundInRaid")]
public bool? OnlyFoundInRaid { get; set; }
[JsonPropertyName("oneSessionOnly")]
public bool? OneSessionOnly { get; set; }
[JsonPropertyName("isResetOnConditionFailed")]
public bool? IsResetOnConditionFailed { get; set; }
[JsonPropertyName("isNecessary")]
public bool? IsNecessary { get; set; }
[JsonPropertyName("doNotResetIfCounterCompleted")]
public bool? DoNotResetIfCounterCompleted { get; set; }
[JsonPropertyName("dogtagLevel")]
public object? DogtagLevel { get; set; } // TODO: number | string
[JsonPropertyName("traderId")]
public string? TraderId { get; set; }
[JsonPropertyName("maxDurability")]
public object? MaxDurability { get; set; } // TODO: number | string
[JsonPropertyName("minDurability")]
public object? MinDurability { get; set; } // TODO: number | string
[JsonPropertyName("counter")]
public QuestConditionCounter? Counter { get; set; }
[JsonPropertyName("plantTime")]
public double? PlantTime { get; set; }
[JsonPropertyName("zoneId")]
public string? ZoneId { get; set; }
[JsonPropertyName("countInRaid")]
public bool? CountInRaid { get; set; }
[JsonPropertyName("completeInSeconds")]
public double? CompleteInSeconds { get; set; }
[JsonPropertyName("isEncoded")]
public bool? IsEncoded { get; set; }
[JsonPropertyName("conditionType")]
public string? ConditionType { get; set; }
[JsonPropertyName("areaType")]
public HideoutAreas? AreaType { get; set; }
[JsonPropertyName("baseAccuracy")]
public ValueCompare? BaseAccuracy { get; set; }
[JsonPropertyName("containsItems")]
public List<string>? ContainsItems { get; set; }
[JsonPropertyName("durability")]
public ValueCompare? Durability { get; set; }
[JsonPropertyName("effectiveDistance")]
public ValueCompare? EffectiveDistance { get; set; }
[JsonPropertyName("emptyTacticalSlot")]
public ValueCompare? EmptyTacticalSlot { get; set; }
[JsonPropertyName("ergonomics")]
public ValueCompare? Ergonomics { get; set; }
[JsonPropertyName("height")]
public ValueCompare? Height { get; set; }
[JsonPropertyName("hasItemFromCategory")]
public List<string>? HasItemFromCategory { get; set; }
[JsonPropertyName("magazineCapacity")]
public ValueCompare? MagazineCapacity { get; set; }
[JsonPropertyName("muzzleVelocity")]
public ValueCompare? MuzzleVelocity { get; set; }
[JsonPropertyName("recoil")]
public ValueCompare? Recoil { get; set; }
[JsonPropertyName("weight")]
public ValueCompare? Weight { get; set; }
[JsonPropertyName("width")]
public ValueCompare? Width { get; set; }
}
public record QuestConditionCounter
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("conditions")]
public List<QuestConditionCounterCondition>? Conditions { get; set; }
}
public record QuestConditionCounterCondition
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("dynamicLocale")]
public bool? DynamicLocale { get; set; }
[JsonPropertyName("target")]
public object? Target { get; set; } // TODO: string[] | string
[JsonPropertyName("completeInSeconds")]
public int? CompleteInSeconds { get; set; }
[JsonPropertyName("energy")]
public ValueCompare? Energy { get; set; }
[JsonPropertyName("exitName")]
public string? ExitName { get; set; }
[JsonPropertyName("hydration")]
public ValueCompare? Hydration { get; set; }
[JsonPropertyName("time")]
public ValueCompare? Time { get; set; }
[JsonPropertyName("compareMethod")]
public string? CompareMethod { get; set; }
[JsonPropertyName("value")]
public object? Value { get; set; } // TODO: number | string
[JsonPropertyName("weapon")]
public List<string>? Weapon { get; set; }
[JsonPropertyName("distance")]
public CounterConditionDistance? Distance { get; set; }
[JsonPropertyName("equipmentInclusive")]
public List<List<string>>? EquipmentInclusive { get; set; }
[JsonPropertyName("weaponModsInclusive")]
public List<List<string>>? WeaponModsInclusive { get; set; }
[JsonPropertyName("weaponModsExclusive")]
public List<List<string>>? WeaponModsExclusive { get; set; }
[JsonPropertyName("enemyEquipmentInclusive")]
public List<List<string>>? EnemyEquipmentInclusive { get; set; }
[JsonPropertyName("enemyEquipmentExclusive")]
public List<List<string>>? EnemyEquipmentExclusive { get; set; }
[JsonPropertyName("weaponCaliber")]
public List<string>? WeaponCaliber { get; set; }
[JsonPropertyName("savageRole")]
public List<string>? SavageRole { get; set; }
[JsonPropertyName("status")]
public List<string>? Status { get; set; }
[JsonPropertyName("bodyPart")]
public List<string>? BodyPart { get; set; }
[JsonPropertyName("daytime")]
public DaytimeCounter? Daytime { get; set; }
[JsonPropertyName("conditionType")]
public string? ConditionType { get; set; }
[JsonPropertyName("enemyHealthEffects")]
public List<EnemyHealthEffect>? EnemyHealthEffects { get; set; }
[JsonPropertyName("resetOnSessionEnd")]
public bool? ResetOnSessionEnd { get; set; }
[JsonPropertyName("bodyPartsWithEffects")]
public List<EnemyHealthEffect>? BodyPartsWithEffects { get; set; }
[JsonPropertyName("IncludeNotEquippedItems")]
public bool? IncludeNotEquippedItems { get; set; }
[JsonPropertyName("equipmentExclusive")]
public List<List<string>>? EquipmentExclusive { get; set; }
[JsonPropertyName("zoneIds")]
public List<string>? Zones { get; set; }
}
public record EnemyHealthEffect
{
[JsonPropertyName("bodyParts")]
public List<string>? BodyParts { get; set; }
[JsonPropertyName("effects")]
public List<string>? Effects { get; set; }
}
public record ValueCompare
{
[JsonPropertyName("compareMethod")]
public string? CompareMethod { get; set; }
[JsonPropertyName("value")]
public double? Value { get; set; }
}
public record CounterConditionDistance
{
[JsonPropertyName("value")]
public double? Value { get; set; }
[JsonPropertyName("compareMethod")]
public string? CompareMethod { get; set; }
}
public record DaytimeCounter
{
[JsonPropertyName("from")]
public int? From { get; set; }
[JsonPropertyName("to")]
public int? To { get; set; }
}
public record VisibilityCondition
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("target")]
public string? Target { get; set; }
[JsonPropertyName("value")]
public int? Value { get; set; }
[JsonPropertyName("dynamicLocale")]
public bool? DynamicLocale { get; set; }
[JsonPropertyName("oneSessionOnly")]
public bool? OneSessionOnly { get; set; }
[JsonPropertyName("conditionType")]
public string? ConditionType { get; set; }
}
public record QuestRewards
{
[JsonPropertyName("AvailableForStart")]
public List<Reward>? AvailableForStart { get; set; }
[JsonPropertyName("AvailableForFinish")]
public List<Reward>? AvailableForFinish { get; set; }
[JsonPropertyName("Started")]
public List<Reward>? Started { get; set; }
[JsonPropertyName("Success")]
public List<Reward>? Success { get; set; }
[JsonPropertyName("Fail")]
public List<Reward>? Fail { get; set; }
[JsonPropertyName("FailRestartable")]
public List<Reward>? FailRestartable { get; set; }
[JsonPropertyName("Expired")]
public List<Reward>? Expired { get; set; }
}
@@ -1,234 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common.Tables;
public record RepeatableQuest : Quest
{
[JsonPropertyName("changeCost")]
public List<ChangeCost?>? ChangeCost { get; set; }
[JsonPropertyName("changeStandingCost")]
public int? ChangeStandingCost { get; set; }
[JsonPropertyName("sptRepatableGroupName")]
public string? SptRepatableGroupName { get; set; }
[JsonPropertyName("acceptanceAndFinishingSource")]
public string? AcceptanceAndFinishingSource { get; set; }
[JsonPropertyName("progressSource")]
public string? ProgressSource { get; set; }
[JsonPropertyName("rankingModes")]
public List<string?>? RankingModes { get; set; }
[JsonPropertyName("gameModes")]
public List<string>? GameModes { get; set; }
[JsonPropertyName("arenaLocations")]
public List<string>? ArenaLocations { get; set; }
[JsonPropertyName("questStatus")]
public RepeatableQuestStatus? QuestStatus { get; set; }
}
public record RepeatableQuestDatabase
{
[JsonPropertyName("templates")]
public RepeatableTemplates? Templates { get; set; }
[JsonPropertyName("rewards")]
public RewardOptions? Rewards { get; set; }
[JsonPropertyName("data")]
public Options? Data { get; set; }
[JsonPropertyName("samples")]
public List<SampleQuests?>? Samples { get; set; }
}
public record RepeatableQuestStatus
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("uid")]
public string? Uid { get; set; }
[JsonPropertyName("qid")]
public string? QId { get; set; }
[JsonPropertyName("startTime")]
public long? StartTime { get; set; }
[JsonPropertyName("status")]
public int? Status { get; set; }
[JsonPropertyName("statusTimers")]
public object? StatusTimers { get; set; } // Use object for any type
}
public record RepeatableTemplates
{
[JsonPropertyName("Elimination")]
public RepeatableQuest? Elimination { get; set; }
[JsonPropertyName("Completion")]
public RepeatableQuest? Completion { get; set; }
[JsonPropertyName("Exploration")]
public RepeatableQuest? Exploration { get; set; }
[JsonPropertyName("Pickup")]
public RepeatableQuest? Pickup { get; set; }
}
public record PmcDataRepeatableQuest
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("unavailableTime")]
public string? UnavailableTime { get; set; }
[JsonPropertyName("activeQuests")]
public List<RepeatableQuest>? ActiveQuests { get; set; }
[JsonPropertyName("inactiveQuests")]
public List<RepeatableQuest>? InactiveQuests { get; set; }
[JsonPropertyName("endTime")]
public long? EndTime { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("changeRequirement")]
public Dictionary<string?, ChangeRequirement?>? ChangeRequirement { get; set; }
[JsonPropertyName("freeChanges")]
public int? FreeChanges { get; set; }
[JsonPropertyName("freeChangesAvailable")]
public int? FreeChangesAvailable { get; set; }
}
public record ChangeRequirement
{
[JsonPropertyName("changeCost")]
public List<ChangeCost?>? ChangeCost { get; set; }
[JsonPropertyName("changeStandingCost")]
public double? ChangeStandingCost { get; set; }
}
public record ChangeCost
{
[JsonPropertyName("templateId")]
public string? TemplateId { get; set; }
[JsonPropertyName("count")]
public int? Count { get; set; }
}
// Config Options
public record RewardOptions
{
[JsonPropertyName("itemsBlacklist")]
public List<string>? ItemsBlacklist { get; set; }
}
public record Options
{
[JsonPropertyName("Completion")]
public CompletionFilter? Completion { get; set; }
}
public record CompletionFilter
{
[JsonPropertyName("itemsBlacklist")]
public List<ItemsBlacklist>? ItemsBlacklist { get; set; }
[JsonPropertyName("itemsWhitelist")]
public List<ItemsWhitelist>? ItemsWhitelist { get; set; }
}
public record ItemsBlacklist
{
[JsonPropertyName("minPlayerLevel")]
public int? MinPlayerLevel { get; set; }
[JsonPropertyName("itemIds")]
public List<string>? ItemIds { get; set; }
}
public record ItemsWhitelist
{
[JsonPropertyName("minPlayerLevel")]
public int? MinPlayerLevel { get; set; }
[JsonPropertyName("itemIds")]
public List<string>? ItemIds { get; set; }
}
public record SampleQuests
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("traderId")]
public string? TraderId { get; set; }
[JsonPropertyName("location")]
public string? Location { get; set; }
[JsonPropertyName("image")]
public string? Image { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
[JsonPropertyName("isKey")]
public bool? IsKey { get; set; }
[JsonPropertyName("restartable")]
public bool? Restartable { get; set; }
[JsonPropertyName("instantComplete")]
public bool? InstantComplete { get; set; }
[JsonPropertyName("secretQuest")]
public bool? SecretQuest { get; set; }
[JsonPropertyName("canShowNotificationsInGame")]
public bool? CanShowNotificationsInGame { get; set; }
[JsonPropertyName("rewards")]
public QuestRewards? Rewards { get; set; }
[JsonPropertyName("conditions")]
public QuestConditionTypes? Conditions { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("note")]
public string? Note { get; set; }
[JsonPropertyName("description")]
public string? Description { get; set; }
[JsonPropertyName("successMessageText")]
public string? SuccessMessageText { get; set; }
[JsonPropertyName("failMessageText")]
public string? FailMessageText { get; set; }
[JsonPropertyName("startedMessageText")]
public string? StartedMessageText { get; set; }
[JsonPropertyName("templateId")]
public string? TemplateId { get; set; }
}
@@ -1,60 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
namespace Core.Models.Eft.Common.Tables;
public record Reward
{
[JsonPropertyName("value")]
public object? Value { get; set; } // TODO: Can be either string or number
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("type")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public RewardType? Type { get; set; }
[JsonPropertyName("index")]
public int? Index { get; set; }
[JsonPropertyName("target")]
public string? Target { get; set; }
[JsonPropertyName("items")]
public List<Item>? Items { get; set; }
[JsonPropertyName("loyaltyLevel")]
public int? LoyaltyLevel { get; set; }
/** Hideout area id */
[JsonPropertyName("traderId")]
public object? TraderId { get; set; } // TODO: string | int
[JsonPropertyName("isEncoded")]
public bool? IsEncoded { get; set; }
[JsonPropertyName("unknown")]
public bool? Unknown { get; set; }
[JsonPropertyName("findInRaid")]
public bool? FindInRaid { get; set; }
[JsonPropertyName("gameMode")]
public List<string>? GameMode { get; set; }
/** Game editions whitelisted to get reward */
[JsonPropertyName("availableInGameEditions")]
public List<string>? AvailableInGameEditions { get; set; }
/** Game editions blacklisted from getting reward */
[JsonPropertyName("notAvailableInGameEditions")]
public List<string>? NotAvailableInGameEditions { get; set; }
// This is always Null atm in the achievements.json
[JsonPropertyName("illustrationConfig")]
public object? IllustrationConfig { get; set; }
[JsonPropertyName("isHidden")]
public bool? IsHidden { get; set; }
}
File diff suppressed because it is too large Load Diff
@@ -1,321 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
using Core.Models.Spt.Services;
using Core.Utils.Json.Converters;
namespace Core.Models.Eft.Common.Tables;
public record Trader
{
[JsonPropertyName("assort")]
public TraderAssort? Assort { get; set; }
[JsonPropertyName("base")]
public TraderBase? Base { get; set; }
[JsonPropertyName("dialogue")]
public Dictionary<string, List<string>?>? Dialogue { get; set; }
[JsonPropertyName("questassort")]
public Dictionary<string, Dictionary<string, string>>? QuestAssort { get; set; }
[JsonPropertyName("suits")]
public List<Suit>? Suits { get; set; }
[JsonPropertyName("services")]
public List<TraderServiceModel>? Services { get; set; }
}
public record TraderBase
{
[JsonPropertyName("refreshTraderRagfairOffers")]
public bool? RefreshTraderRagfairOffers { get; set; }
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("availableInRaid")]
public bool? AvailableInRaid { get; set; }
[JsonPropertyName("avatar")]
public string? Avatar { get; set; }
[JsonPropertyName("balance_dol")]
public decimal? BalanceDollar { get; set; }
[JsonPropertyName("balance_eur")]
public decimal? BalanceEuro { get; set; }
[JsonPropertyName("balance_rub")]
public decimal? BalanceRub { get; set; }
[JsonPropertyName("buyer_up")]
public bool? BuyerUp { get; set; }
[JsonPropertyName("currency")]
public CurrencyType? Currency { get; set; }
[JsonPropertyName("customization_seller")]
public bool? CustomizationSeller { get; set; }
[JsonPropertyName("discount")]
public decimal? Discount { get; set; }
[JsonPropertyName("discount_end")]
public decimal? DiscountEnd { get; set; }
[JsonPropertyName("gridHeight")]
public double? GridHeight { get; set; }
[JsonPropertyName("sell_modifier_for_prohibited_items")]
public int? ProhibitedItemsSellModifier { get; set; }
[JsonPropertyName("insurance")]
public TraderInsurance? Insurance { get; set; }
[JsonPropertyName("items_buy")]
public ItemBuyData? ItemsBuy { get; set; }
[JsonPropertyName("items_buy_prohibited")]
public ItemBuyData? ItemsBuyProhibited { get; set; }
[JsonPropertyName("isCanTransferItems")]
public bool? IsCanTransferItems { get; set; }
[JsonPropertyName("transferableItems")]
public ItemBuyData? TransferableItems { get; set; }
[JsonPropertyName("prohibitedTransferableItems")]
public ItemBuyData? ProhibitedTransferableItems { get; set; }
[JsonPropertyName("location")]
public string? Location { get; set; }
[JsonPropertyName("loyaltyLevels")]
public List<TraderLoyaltyLevel>? LoyaltyLevels { get; set; }
[JsonPropertyName("medic")]
public bool? Medic { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
// Confirmed in client
[JsonPropertyName("nextResupply")]
public int? NextResupply { get; set; }
[JsonPropertyName("nickname")]
public string? Nickname { get; set; }
[JsonPropertyName("repair")]
public TraderRepair? Repair { get; set; }
[JsonPropertyName("sell_category")]
public List<string>? SellCategory { get; set; }
[JsonPropertyName("surname")]
public string? Surname { get; set; }
[JsonPropertyName("unlockedByDefault")]
public bool? UnlockedByDefault { get; set; }
}
public record ItemBuyData
{
// MongoId
[JsonPropertyName("category")]
public List<string>? Category { get; set; }
// MongoId
[JsonPropertyName("id_list")]
public List<string>? IdList { get; set; }
}
public record TraderInsurance
{
[JsonPropertyName("availability")]
public bool? Availability { get; set; }
// MongoId
[JsonPropertyName("excluded_category")]
public List<string>? ExcludedCategory { get; set; }
// Confirmed in client
[JsonPropertyName("max_return_hour")]
public int? MaxReturnHour { get; set; }
[JsonPropertyName("max_storage_time")]
public double? MaxStorageTime { get; set; }
// Confirmed in client
[JsonPropertyName("min_payment")]
public int? MinPayment { get; set; }
// Confirmed in client
[JsonPropertyName("min_return_hour")]
public int? MinReturnHour { get; set; }
}
public record TraderLoyaltyLevel
{
[JsonPropertyName("buy_price_coef")]
public double? BuyPriceCoefficient { get; set; }
[JsonPropertyName("exchange_price_coef")]
public double? ExchangePriceCoefficient { get; set; }
[JsonPropertyName("heal_price_coef")]
public double? HealPriceCoefficient { get; set; }
[JsonPropertyName("insurance_price_coef")]
[JsonConverter(typeof(StringToNumberFactoryConverter))]
public double? InsurancePriceCoefficient { get; set; }
// Chceked on client
[JsonPropertyName("minLevel")]
public int? MinLevel { get; set; }
[JsonPropertyName("minSalesSum")]
public long? MinSalesSum { get; set; }
[JsonPropertyName("minStanding")]
public double? MinStanding { get; set; }
[JsonPropertyName("repair_price_coef")]
public double? RepairPriceCoefficient { get; set; }
}
public record TraderRepair
{
[JsonPropertyName("availability")]
public bool? Availability { get; set; }
[JsonPropertyName("currency")]
public string? Currency { get; set; }
[JsonPropertyName("currency_coefficient")]
public double? CurrencyCoefficient { get; set; }
[JsonPropertyName("excluded_category")]
public List<string>? ExcludedCategory { get; set; }
[JsonPropertyName("excluded_id_list")]
public List<string>? ExcludedIdList { get; set; } // Doesn't exist in client object
[JsonPropertyName("quality")]
[JsonConverter(typeof(StringToNumberFactoryConverter))]
public double? Quality { get; set; }
[JsonPropertyName("price_rate")]
public double? PriceRate { get; set; }
}
public record TraderAssort
{
[JsonPropertyName("nextResupply")]
public double? NextResupply { get; set; }
[JsonPropertyName("items")]
public List<Item>? Items { get; set; }
[JsonPropertyName("barter_scheme")]
public Dictionary<string, List<List<BarterScheme>>>? BarterScheme { get; set; }
[JsonPropertyName("loyal_level_items")]
public Dictionary<string, int>? LoyalLevelItems { get; set; }
}
public record BarterScheme
{
[JsonPropertyName("count")]
public double? Count { get; set; }
[JsonPropertyName("_tpl")]
public string? Template { get; set; }
[JsonPropertyName("onlyFunctional")]
public bool? OnlyFunctional { get; set; }
[JsonPropertyName("sptQuestLocked")]
public bool? SptQuestLocked { get; set; }
[JsonPropertyName("level")]
public int? Level { get; set; }
[JsonPropertyName("side")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public DogtagExchangeSide? Side { get; set; }
}
public record Suit
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("externalObtain")]
public bool? ExternalObtain { get; set; }
[JsonPropertyName("internalObtain")]
public bool? InternalObtain { get; set; }
[JsonPropertyName("isHiddenInPVE")]
public bool? IsHiddenInPVE { get; set; }
[JsonPropertyName("tid")]
public string? Tid { get; set; }
[JsonPropertyName("suiteId")]
public string? SuiteId { get; set; }
[JsonPropertyName("isActive")]
public bool? IsActive { get; set; }
[JsonPropertyName("requirements")]
public SuitRequirements? Requirements { get; set; }
}
public record SuitRequirements
{
[JsonPropertyName("achievementRequirements")]
public List<string>? AchievementRequirements { get; set; }
[JsonPropertyName("loyaltyLevel")]
public double? LoyaltyLevel { get; set; }
[JsonPropertyName("profileLevel")]
public double? ProfileLevel { get; set; }
// Checked in client
[JsonPropertyName("standing")]
public double? Standing { get; set; }
[JsonPropertyName("skillRequirements")]
public List<string>? SkillRequirements { get; set; }
[JsonPropertyName("questRequirements")]
public List<string>? QuestRequirements { get; set; }
[JsonPropertyName("itemRequirements")]
public List<ItemRequirement>? ItemRequirements { get; set; }
[JsonPropertyName("requiredTid")]
public string? RequiredTid { get; set; }
}
public record ItemRequirement
{
[JsonPropertyName("count")]
public double? Count { get; set; }
[JsonPropertyName("_tpl")]
public string? Tpl { get; set; }
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("onlyFunctional")]
public bool? OnlyFunctional { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
}
-12
View File
@@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common;
public record XY
{
[JsonPropertyName("x")]
public double? X { get; set; }
[JsonPropertyName("y")]
public double? Y { get; set; }
}
-15
View File
@@ -1,15 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Common;
public record XYZ
{
[JsonPropertyName("x")]
public double? X { get; set; }
[JsonPropertyName("y")]
public double? Y { get; set; }
[JsonPropertyName("z")]
public double? Z { get; set; }
}
@@ -1,25 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Customization;
public record BuyClothingRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("offer")]
public string? Offer { get; set; }
[JsonPropertyName("items")]
public List<PaymentItemForClothing>? Items { get; set; }
}
public record PaymentItemForClothing
{
[JsonPropertyName("del")]
public bool? Del { get; set; }
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("count")]
public int? Count { get; set; }
}
@@ -1,22 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Customization;
public record CustomizationSetRequest : InventoryBaseActionRequestData
{
[JsonPropertyName("customizations")]
public List<CustomizationSetOption>? Customizations { get; set; }
}
public record CustomizationSetOption
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
[JsonPropertyName("source")]
public string? Source { get; set; }
}
@@ -1,5 +0,0 @@
namespace Core.Models.Eft.Customization;
public record WearClothingRequestData
{
}
@@ -1,13 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record AddUserGroupMailRequest : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
[JsonPropertyName("uid")]
public string? Uid { get; set; }
}
@@ -1,13 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record ChangeGroupMailOwnerRequest : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
[JsonPropertyName("uid")]
public string? Uid { get; set; }
}
@@ -1,43 +0,0 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Dialog;
public record ChatServer
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("RegistrationId")]
public int? RegistrationId { get; set; }
[JsonPropertyName("VersionId")]
public string? VersionId { get; set; }
[JsonPropertyName("Ip")]
public string? Ip { get; set; }
[JsonPropertyName("Port")]
public int? Port { get; set; }
[JsonPropertyName("DateTime")]
public long? DateTime { get; set; }
[JsonPropertyName("Chats")]
public List<Chat>? Chats { get; set; }
[JsonPropertyName("Regions")]
public List<string>? Regions { get; set; }
/** Possibly removed */
[JsonPropertyName("IsDeveloper")]
public bool? IsDeveloper { get; set; }
}
public record Chat
{
[JsonPropertyName("_id")]
public string? Id { get; set; }
[JsonPropertyName("Members")]
public int? Members { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record ClearMailMessageRequest : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
}
@@ -1,13 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record CreateGroupMailRequest : IRequestData
{
[JsonPropertyName("Name")]
public string? Name { get; set; }
[JsonPropertyName("Users")]
public List<string>? Users { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record DeleteFriendRequest : IRequestData
{
[JsonPropertyName("friend_id")]
public string? FriendId { get; set; }
}
@@ -1,19 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record FriendRequestData : IRequestData
{
[JsonPropertyName("status")]
public int? Status { get; set; }
[JsonPropertyName("requestId")]
public string? RequestId { get; set; }
[JsonPropertyName("retryAfter")]
public int? RetryAfter { get; set; }
[JsonPropertyName("to")]
public string? To { get; set; }
}
@@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
namespace Core.Models.Eft.Dialog;
public record FriendRequestSendResponse
{
[JsonPropertyName("status")]
public BackendErrorCodes? Status { get; set; }
[JsonPropertyName("requestId")]
public string? RequestId { get; set; }
[JsonPropertyName("retryAfter")]
public int? RetryAfter { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record GetAllAttachmentsRequestData : IRequestData
{
[JsonPropertyName("dialogId")]
public string DialogId { get; set; }
}
@@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Profile;
namespace Core.Models.Eft.Dialog;
public record GetAllAttachmentsResponse
{
[JsonPropertyName("messages")]
public List<Message>? Messages { get; set; }
[JsonPropertyName("profiles")]
public List<object>? Profiles { get; set; } // Assuming 'any' translates to 'object'
[JsonPropertyName("hasMessagesWithRewards")]
public bool? HasMessagesWithRewards { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record GetChatServerListRequestData : IRequestData
{
[JsonPropertyName("VersionId")]
public string? VersionId { get; set; }
}
@@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Profile;
namespace Core.Models.Eft.Dialog;
public record GetFriendListDataResponse
{
[JsonPropertyName("Friends")]
public List<UserDialogInfo>? Friends { get; set; }
[JsonPropertyName("Ignore")]
public List<string>? Ignore { get; set; }
[JsonPropertyName("InIgnoreList")]
public List<string>? InIgnoreList { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record GetMailDialogInfoRequestData : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
}
@@ -1,13 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record GetMailDialogListRequestData : IRequestData
{
[JsonPropertyName("limit")]
public int? Limit { get; set; }
[JsonPropertyName("offset")]
public int? Offset { get; set; }
}
@@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record GetMailDialogViewRequestData : IRequestData
{
[JsonPropertyName("type")]
public MessageType? Type { get; set; }
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
[JsonPropertyName("limit")]
public int? Limit { get; set; }
[JsonPropertyName("time")]
public decimal? Time { get; set; } // decimal
}
@@ -1,16 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Profile;
namespace Core.Models.Eft.Dialog;
public record GetMailDialogViewResponseData
{
[JsonPropertyName("messages")]
public List<Message>? Messages { get; set; }
[JsonPropertyName("profiles")]
public List<UserDialogInfo>? Profiles { get; set; }
[JsonPropertyName("hasMessagesWithRewards")]
public bool? HasMessagesWithRewards { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record PinDialogRequestData : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record RemoveDialogRequestData : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
}
@@ -1,10 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record RemoveMailMessageRequest : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
}
@@ -1,13 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record RemoveUserGroupMailRequest : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
[JsonPropertyName("uid")]
public string? Uid { get; set; }
}
@@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
using Core.Models.Enums;
using Core.Models.Utils;
namespace Core.Models.Eft.Dialog;
public record SendMessageRequest : IRequestData
{
[JsonPropertyName("dialogId")]
public string? DialogId { get; set; }
[JsonPropertyName("type")]
public MessageType? Type { get; set; }
[JsonPropertyName("text")]
public string? Text { get; set; }
[JsonPropertyName("replyTo")]
public string? ReplyTo { get; set; }
}

Some files were not shown because too many files have changed in this diff Show More