Add HTTPS support (#101)

* Initial work on adding https support

* Updated logging

* More logging

* Added support for a certificate password

Replaced method used for getting path to cert

* Reduce duplication of logic in program.cs

* Cleanup of `HttpServer`

* More https stuff

* https

* Fixed remote IP stuff

* Fixed non-local request logging

* Updated assets

* Replaced `singleplayer/bossconvert` to `singleplayer/bosstypes`

* Updated map loot

* Asset update

* Stop storing a bots inventory and other values to save memory

---------

Co-authored-by: Chomp <dev@dev.sp-tarkov.com>
Co-authored-by: clodan <clodan@clodan.com>
This commit is contained in:
Chomp
2025-02-20 12:27:55 +00:00
committed by GitHub
parent 6dc59a4be7
commit 5a5e18f568
62 changed files with 35395 additions and 35405 deletions
+1 -1
View File
@@ -314,7 +314,7 @@ public class BotController(
_botGenerationCacheService.StoreBots(cacheKey, [botToCache]);
// Store bot details in cache so post-raid PMC messages can use data
_matchBotDetailsCacheService.CacheBot(botToCache);
_matchBotDetailsCacheService.CacheBot(_cloner.Clone(botToCache));
// The client expects the Side for PMCs to be `Savage`
// We do this here so it's after we cache the bot in the match details lookup, as when you die, they will have the right side
+2 -2
View File
@@ -42,7 +42,7 @@ public class HttpServerHelper(ConfigServer configServer)
*/
public string GetBackendUrl()
{
return $"http://{BuildUrl()}";
return $"https://{BuildUrl()}";
}
/**
@@ -50,7 +50,7 @@ public class HttpServerHelper(ConfigServer configServer)
*/
public string GetWebsocketUrl()
{
return $"ws://{BuildUrl()}";
return $"wss://{BuildUrl()}";
}
public void SendTextJson(HttpResponse resp, object output)
@@ -68,4 +68,11 @@ public record HttpConfig : BaseConfig
get;
set;
}
[JsonPropertyName("certificatePassword")]
public string? CertificatePassword
{
get;
set;
}
}
@@ -42,7 +42,7 @@ public class InraidStaticRouter : StaticRouter
) => inraidCallbacks.GetTraitorScavHostileChance(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/bossconvert",
"/singleplayer/bosstypes",
(
url,
info,
+128 -26
View File
@@ -1,8 +1,14 @@
using Core.Context;
using System.Net;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Core.Context;
using Core.Models.Spt.Config;
using Core.Models.Utils;
using Core.Servers.Http;
using Core.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Primitives;
using SptCommon.Annotations;
@@ -19,37 +25,134 @@ public class HttpServer(
)
{
private readonly HttpConfig _httpConfig = _configServer.GetConfig<HttpConfig>();
private bool started;
private bool _started;
public void Load(WebApplicationBuilder? builder)
{
builder?.WebHost.UseKestrel();
//builder.Services.AddControllers();
// At the end
var app = builder?.Build();
if (builder is null)
{
throw new Exception("WebApplicationBuilder is null in HttpServer.Load()");
}
builder.Services.AddHttpsRedirection(conf =>
{
conf.HttpsPort = _httpConfig.Port;
});
builder.WebHost.ConfigureKestrel(
options =>
{
const string certFileName = "certificate.pfx";
var certificate = LoadCertificate(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, certFileName, _httpConfig.CertificatePassword));
if (certificate == null)
{
// Generate self-signed certificate
certificate = GenerateSelfSignedCertificate("localhost");
SaveCertificate(certificate, certFileName); // Save cert
// enable web socket
app?.UseWebSockets(new WebSocketOptions
_logger.Success($"Generated and stored self-signed certificate ({certFileName}) in {AppDomain.CurrentDomain.BaseDirectory}");
}
options.ListenAnyIP(_httpConfig.Port, listenOptions =>
{
listenOptions.UseHttps(opts =>
{
opts.SslProtocols = SslProtocols.Tls12;
opts.AllowAnyClientCertificate();
opts.ServerCertificate = certificate;
opts.ClientCertificateMode = ClientCertificateMode.NoCertificate;
});
});
});
var app = builder.Build();
app.UseHttpsRedirection();
if (app is null)
{
throw new Exception("WebApplication is null in HttpServer.Load()");
}
// Enable web socket
app.UseWebSockets(new WebSocketOptions
{
// Every minute a heartbeat is sent to keep the connection alive.
KeepAliveInterval = TimeSpan.FromSeconds(60)
});
app?.Use(
(HttpContext req, RequestDelegate _) =>
{
return Task.Factory.StartNew(async () => await HandleFallback(req));
}
);
started = true;
if (app is null)
{
throw new Exception("Application context is null in HttpServer.Load()");
}
app.MapFallback(HandleFallback);
_started = true;
_applicationContext.AddValue(ContextVariableType.WEB_APPLICATION, app);
}
/// <summary>
/// Get a certificate from provided path and return
/// </summary>
/// <param name="pfxPath">Path to pfx file</param>
/// <param name="certPassword">Optional password for certificate</param>
/// <returns>X509Certificate2</returns>
private X509Certificate2? LoadCertificate(string pfxPath, string? certPassword = null)
{
if (File.Exists(pfxPath))
{
try
{
//TODO: use this
//return X509CertificateLoader.LoadCertificateFromFile(pfxPath);
return string.IsNullOrEmpty(certPassword)
? new X509Certificate2(pfxPath)
: new X509Certificate2(pfxPath, certPassword);
}
catch (Exception ex)
{
_logger.Error($"Error loading certificate from path: {pfxPath} error: {ex.Message}");
return null;
}
}
return null;
}
/// <summary>
/// Generate and return a self-signed certificate
/// </summary>
/// <param name="subjectName">e.g. localhost</param>
/// <returns>X509Certificate2</returns>
private X509Certificate2 GenerateSelfSignedCertificate(string subjectName)
{
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddIpAddress(new IPAddress(new byte[] { 127, 0, 0, 1 }));
sanBuilder.AddDnsName("localhost");
sanBuilder.AddDnsName(Environment.MachineName);
var distinguishedName = new X500DistinguishedName($"CN={subjectName}");
using var rsa = RSA.Create(2048);
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(sanBuilder.Build());
return request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(3650)));
}
/// <summary>
/// Save a certificate as a file to disk
/// </summary>
/// <param name="certificate">Certificate to save</param>
/// <param name="pfxPath">Path to destination</param>
private void SaveCertificate(X509Certificate2 certificate, string pfxPath)
{
try
{
File.WriteAllBytes(pfxPath, certificate.Export(X509ContentType.Pfx));
}
catch (Exception ex)
{
_logger.Error($"Error saving certificate: {ex.Message}");
}
}
private async Task HandleFallback(HttpContext context)
{
if (context.WebSockets.IsWebSocketRequest)
@@ -78,7 +181,7 @@ public class HttpServer(
? realIp.Value.First()
: forwardedFor.HasValue
? forwardedFor.Value.First()!.Split(",")[0].Trim()
: context.Connection.RemoteIpAddress!.ToString();
: context.Connection.RemoteIpAddress!.ToString().Split(":")[3];
if (_httpConfig.LogRequests)
{
@@ -93,11 +196,10 @@ public class HttpServer(
{
_logger.Info(
_localisationService.GetText(
"client_request_ip",
new Dictionary<string, string>
"client_request_ip", new
{
{ "ip", clientIp },
{ "url", context.Request.Path.Value }
ip = clientIp,
url = context.Request.Path.Value
}
)
);
@@ -136,11 +238,11 @@ public class HttpServer(
public bool IsStarted()
{
return started;
return _started;
}
public string ListeningUrl()
{
return $"http://{_httpConfig.Ip}:{_httpConfig.Port}";
return $"https://{_httpConfig.Ip}:{_httpConfig.Port}";
}
}
@@ -21,6 +21,10 @@ public class MatchBotDetailsCacheService(
return;
}
botToCache.Inventory = null;
botToCache.Skills = null;
botToCache.Stats = null;
var key = $"{botToCache.Info.Nickname.Trim()}{botToCache.Info.Side}";
_botDetailsCache.TryAdd(key, botToCache);
}
+1 -1
View File
@@ -90,7 +90,7 @@ public class App
if (_httpServer.IsStarted())
{
_logger.Success(_localisationService.GetText("started_webserver_success", _httpServer.ListeningUrl()));
_logger.Success(_localisationService.GetText("websocket-started", _httpServer.ListeningUrl().Replace("http://", "ws://")));
_logger.Success(_localisationService.GetText("websocket-started", _httpServer.ListeningUrl().Replace("https://", "wss://")));
}
_logger.Success(GetRandomisedStartMessage());
+21 -28
View File
@@ -22,28 +22,28 @@
"survey": {
"locale": {
"en": {
"question_1": "How off-topic is general chat on the SPT discord?",
"question_1_answer_1": "Not at all",
"question_1_answer_2": "A little",
"question_1_answer_3": "Sometimes",
"question_1_answer_4": "Somewhat often",
"question_1_answer_5": "Quite often",
"question_1_answer_6": "Most of the time",
"question_1_answer_7": "Almost always",
"question_1_answer_8": "Always",
"question_1_answer_9": "NOT OFF TOPIC ENOUGH",
"question_1_answer_10": "I LIVE TO MAKE GENERAL CHAT OFF TOPIC",
"question_1_answer_11": "I am posting gifs to general chat as we speak",
"question_2": "When you download a mod from the hub do you read the readme/mod description?",
"question_2_answer_1": "What's a description",
"question_2_answer_2": "I can't read",
"question_2_answer_3": "I am illiterate",
"question_2_answer_4": "I am too busy making general chat off-topic to read",
"question_2_answer_5": "YOU WILL NEVER MAKE ME READ TEXT I WILL ASK IN GENERAL CHAT INSTEAD",
"question_1": "An update to a popular mod that makes the game more realistic has been released, which of the following actions on discord will you do?",
"question_1_answer_1": "Ignore the changelog",
"question_1_answer_2": "Ignore the readme",
"question_1_answer_3": "Ask in general chat why the guns dont shoot",
"question_1_answer_4": "Argue with general chat when they tell you to read the readme",
"question_1_answer_5": "Install as many mods as you can at the same time and get mad when everything breaks",
"question_1_answer_6": "Inform general chat of your displeasure and get mad when they laugh at you",
"question_1_answer_7": "Tag staff to inform them of your displeasure of a mod you don't like being released",
"question_1_answer_8": "DM the author informing them of your displeasure at their mods existence",
"question_1_answer_9": "DM the author and inform them you are going to sue them",
"question_1_answer_10": "Stalk the author and create dozens of hub accounts to message them",
"question_2": "You want to download an older version of SPT but you have been informed old versions cannot be downloaded, what do you do?",
"question_2_answer_1": "Get mad",
"question_2_answer_2": "Get REAL mad and voice your opinion in every possible chat you can",
"question_2_answer_3": "Travel around various discords informing anyone who listens what bad people SPT are",
"question_2_answer_4": "Create dozens of alt accounts to DM staff and inform them of your displeasure",
"question_2_answer_5": "Ask when the old SPT verison is coming back every day for weeks",
"title": "Feedback survey",
"time": "About 1 minute",
"description": "This is the first SPT survey! Your survey doesn't get sent anywhere, its just for modders to see how it works and maybe make use of.",
"farewell": "I told you at the start the survey doesn't get sent anywhere and yet you still completed it, curious."
"description": "This was the second SPT survey, what a valuable use of 20 minutes that was.",
"farewell": "You knew the first survey didnt do anything yet you still submitted the second one, you're quite an odd one."
}
},
"survey": {
@@ -125,12 +125,6 @@
"questionId": 0,
"sortIndex": 1,
"localeKey": "question_1_answer_10"
},
{
"id": 10,
"questionId": 0,
"sortIndex": 1,
"localeKey": "question_1_answer_11"
}
]
},
@@ -197,8 +191,7 @@
"6723fd51c5924c57ce0ca01f": true
}
},
"createNewProfileTypesBlacklist": [],
"achievementProfileIdBlacklist": []
"createNewProfileTypesBlacklist": []
},
"customWatermarkLocaleKeys": []
}
+2 -1
View File
@@ -5,5 +5,6 @@
"backendPort": 6969,
"webSocketPingDelayMs": 90000,
"logRequests": true,
"serverImagePathOverride": {}
"serverImagePathOverride": {},
"certificatePassword": ""
}
+431 -442
View File
@@ -1,445 +1,434 @@
{
"addCustomBotWavesToMaps": true,
"addOpenZonesToAllMaps": true,
"allowDuplicateItemsInStaticContainers": true,
"botTypeLimits": {
"Bigmap": [
{
"max": 4,
"min": 2,
"type": "marksman"
}
],
"TarkovStreets": [
{
"max": 4,
"min": 2,
"type": "marksman"
}
],
"Woods": [
{
"max": 5,
"min": 2,
"type": "marksman"
}
]
},
"containerRandomisationSettings": {
"containerGroupMaxSizeMultiplier": 1,
"containerGroupMinSizeMultiplier": 1,
"containerTypesToNotRandomise": [
"5d6fd45b86f774317075ed43",
"5909d89086f77472591234a0",
"578f87b7245977356274f2cd",
"5909d76c86f77471e53d2adf",
"578f8782245977354405a1e3",
"5d6fe50986f77449d97f7463",
"578f879c24597735401e6bc6",
"578f8782245977354405a1e3",
"5d6fd13186f77424ad2a8c69"
],
"enabled": true,
"maps": {
"bigmap": true,
"factory4_day": true,
"factory4_night": true,
"interchange": true,
"laboratory": true,
"lighthouse": true,
"rezervbase": true,
"sandbox": true,
"shoreline": true,
"tarkovstreets": true,
"woods": true
}
},
"customWaves": {
"boss": {},
"normal": {}
},
"enableBotTypeLimits": true,
"equipmentLootSettings": {
"modSpawnChancePercent": {
"back_plate": 100,
"front_plate": 100,
"left_side_plate": 25,
"mod_equipment": 5,
"mod_equipment_000": 5,
"mod_equipment_001": 5,
"mod_equipment_002": 5,
"mod_mount": 5,
"mod_nvg": 5,
"right_side_plate": 25
}
},
"fitLootIntoContainerAttempts": 3,
"forcedLootSingleSpawnById": {
"bigmap": [
"5ac620eb86f7743a8e6e0da0",
"5939e5a786f77461f11c0098",
"64e74a3d4d49d23b2c39d319",
"6614230055afee107f05e998",
"66b22630a6b4e5ec7c02cdb7",
"675f80d4fe1b59cf490d3527",
"67499d0eeca8acb2d2061639",
"675f7acc4076a741a3061566",
"675f80d4fe1b59cf490d3527",
"675f7f224076a741a3061568",
"675f7b168d28a25ec7007dbb"
],
"factory4_day": [
"591093bb86f7747caa7bb2ee",
"66c0b39ca1f68fcc1d0c0cc3",
"66a0e523e749756c920d02d0",
"593a87af86f774122f54a951"
],
"factory4_night": [
"591093bb86f7747caa7bb2ee",
"66c0b39ca1f68fcc1d0c0cc3",
"66a0e523e749756c920d02d0",
"593a87af86f774122f54a951"
],
"interchange": [
"64e74a5ac2b4f829615ec336",
"667a8ef464eea5fdef0db135"
],
"laboratory": [
"6398a4cfb5992f573c6562b3",
"64e74a44c2b4f829615ec334",
"6711039f9e648049e50b3307",
"6707cef3571b50abc703b64f",
"6707cd70aab679420007e018",
"6707cc67cc1667e49e0f7232",
"6707cf827d279daad80fa95f"
],
"lighthouse": [
"6331bb0d1aa9f42b804997a6",
"6398a0861c712b1e1d4dadf1",
"6399f54b0a36db13c823ad21",
"64e74a64aac4cd0a7264ecdf",
"661666458c2aa9cb1602503b"
],
"rezervbase": [
"64e74a4baac4cd0a7264ecdd",
"6398a072e301557ae24cec92",
"67499b3eeca8acb2d2061636",
"67499b9b909d2013670a5029"
],
"sandbox": [
"6575a6ca8778e96ded05a802",
"6582bd252b50c61c565828e2"
],
"shoreline": [
"64e74a534d49d23b2c39d31b",
"661421c7c1f2f548c50ee649",
"6614217b6d9d5abcad0ff098",
"661423200d240a5f5d0f679b",
"6707d1f9571b50abc703b651",
"66760b3deb51b08bd40c2b08",
"67499adbeca8acb2d2061634",
"6614238e0d240a5f5d0f679d",
"666073159916667083033cb9"
],
"tarkovstreets": [
"638df4cc7b560b03794a18d2",
"638cbc68a63f1b49be6a3010",
"638e0057ab150a5f56238960",
"63927b29c115f907b14700b9",
"638dfc803083a019d447768e",
"638e9d5536b3b72c944e2fc7",
"6393262086e646067c176aa2",
"63989ced706b793c7d60cfef",
"63a39e1d234195315d4020bd",
"64e74a35aac4cd0a7264ecdb",
"64e74a186393886f74114a96",
"64e74a1faac4cd0a7264ecd9",
"64e73909cd54ef0580746af3",
"64e74a2fc2b4f829615ec332",
"64e74a274d49d23b2c39d317",
"64f09c02b63b74469b6c149f",
"64f07f7726cfa02c506f8ac0",
"64f69b4267e11a7c6206e010",
"64f5b4f71a5f313cb144c06c",
"657acb2ac900be5902191ac9",
"6582dbf0b8d7830efc45016f",
"66687bc89111279d600b5062"
]
},
"looseLootBlacklist": {},
"looseLootMultiplier": {
"bigmap": 2.5,
"develop": 1,
"factory4_day": 3.5,
"factory4_night": 3.5,
"hideout": 0,
"interchange": 2.8,
"laboratory": 2.8,
"lighthouse": 2.8,
"privatearea": 1,
"rezervbase": 2.9,
"sandbox": 2.8,
"sandbox_high": 2.8,
"shoreline": 3.7,
"suburbs": 1,
"tarkovstreets": 3,
"terminal": 1,
"town": 0,
"woods": 1.9
},
"magazineLootHasAmmoChancePercent": 50,
"minFillLooseMagazinePercent": 50,
"minFillStaticMagazinePercent": 50,
"nonMaps": [
"base",
"develop",
"hideout",
"privatearea",
"suburbs",
"terminal",
"town"
],
"openZones": {},
"reserveRaiderSpawnChanceOverrides": {
"nonTriggered": 80,
"triggered": 90
},
"rogueLighthouseSpawnTimeSettings": {
"enabled": false,
"waitTimeSeconds": 120
},
"scavRaidTimeSettings": {
"maps": {
"bigmap": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 1,
"25": 2,
"30": 4,
"35": 4,
"40": 4,
"45": 4,
"50": 4,
"60": 2,
"70": 2
}
},
"default": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 50,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"10": 1,
"20": 2,
"30": 5,
"40": 5,
"50": 5,
"60": 2,
"70": 1
}
},
"factory4_day": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"25": 3,
"30": 5,
"40": 5,
"5": 2,
"50": 5,
"60": 2,
"65": 2
}
},
"factory4_night": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 75,
"reductionPercentWeights": {
"20": 4,
"30": 3,
"40": 3,
"60": 2,
"65": 2
}
},
"interchange": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 5,
"25": 5,
"30": 5,
"35": 5,
"40": 5,
"50": 5,
"55": 2
}
},
"laboratory": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 2
}
},
"lighthouse": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 2,
"25": 2,
"30": 4,
"40": 4,
"50": 4,
"60": 2
}
},
"rezervbase": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 3,
"40": 4,
"50": 4,
"60": 2
}
},
"sandbox": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 1,
"65": 1
}
},
"sandbox_high": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 1,
"65": 1
}
},
"shoreline": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 2,
"25": 3,
"30": 5,
"35": 5,
"40": 5,
"50": 5,
"60": 2,
"65": 1
}
},
"tarkovstreets": {
"adjustWaves": true,
"minDynamicLootPercent": 70,
"minStaticLootPercent": 60,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 4,
"40": 5,
"50": 4,
"60": 3
}
},
"woods": {
"adjustWaves": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reduceLootByPercent": true,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 1,
"65": 1
}
}
"looseLootMultiplier": {
"bigmap": 2.5,
"develop": 1,
"factory4_day": 3.5,
"factory4_night": 3.5,
"interchange": 2.8,
"laboratory": 2.8,
"rezervbase": 2.9,
"shoreline": 3.7,
"woods": 1.9,
"hideout": 0,
"lighthouse": 2.8,
"privatearea": 1,
"suburbs": 1,
"tarkovstreets": 3,
"terminal": 1,
"sandbox": 2.8,
"sandbox_high": 2.8,
"town": 0
},
"settings": {
"trainArrivalDelayObservedSeconds": 90
}
},
"staticLootMultiplier": {
"bigmap": 1,
"develop": 1,
"factory4_day": 1,
"factory4_night": 1,
"hideout": 0,
"interchange": 1,
"laboratory": 1,
"lighthouse": 1,
"privatearea": 1,
"rezervbase": 1,
"sandbox": 1,
"sandbox_high": 1,
"shoreline": 1,
"suburbs": 1,
"tarkovstreets": 1,
"terminal": 1,
"town": 1,
"woods": 1
},
"staticMagazineLootHasAmmoChancePercent": 0,
"tplsToStripChildItemsFrom": [
"63a8970d7108f713591149f5",
"63a897c6b1ff6e29734fcc95",
"63a898a328e385334e0640a5",
"634959225289190e5e773b3b"
]
"staticLootMultiplier": {
"bigmap": 1,
"develop": 1,
"factory4_day": 1,
"factory4_night": 1,
"interchange": 1,
"laboratory": 1,
"rezervbase": 1,
"shoreline": 1,
"woods": 1,
"hideout": 0,
"lighthouse": 1,
"privatearea": 1,
"suburbs": 1,
"tarkovstreets": 1,
"terminal": 1,
"sandbox": 1,
"sandbox_high": 1,
"town": 1
},
"customWaves": {
"boss": {},
"normal": {}
},
"openZones": {},
"forcedLootSingleSpawnById": {
"bigmap": [
"5ac620eb86f7743a8e6e0da0",
"5939e5a786f77461f11c0098",
"64e74a3d4d49d23b2c39d319",
"6614230055afee107f05e998",
"66b22630a6b4e5ec7c02cdb7",
"675f80d4fe1b59cf490d3527",
"67499d0eeca8acb2d2061639",
"675f7acc4076a741a3061566",
"675f80d4fe1b59cf490d3527",
"675f7f224076a741a3061568",
"675f7b168d28a25ec7007dbb"
],
"interchange": [
"64e74a5ac2b4f829615ec336",
"667a8ef464eea5fdef0db135"
],
"lighthouse": [
"6331bb0d1aa9f42b804997a6",
"6398a0861c712b1e1d4dadf1",
"6399f54b0a36db13c823ad21",
"64e74a64aac4cd0a7264ecdf",
"661666458c2aa9cb1602503b"
],
"rezervbase": [
"64e74a4baac4cd0a7264ecdd",
"6398a072e301557ae24cec92",
"67499b3eeca8acb2d2061636",
"67499b9b909d2013670a5029"
],
"shoreline": [
"64e74a534d49d23b2c39d31b",
"661421c7c1f2f548c50ee649",
"6614217b6d9d5abcad0ff098",
"661423200d240a5f5d0f679b",
"6707d1f9571b50abc703b651",
"66760b3deb51b08bd40c2b08",
"67499adbeca8acb2d2061634",
"6614238e0d240a5f5d0f679d",
"666073159916667083033cb9"
],
"tarkovstreets": [
"638df4cc7b560b03794a18d2",
"638cbc68a63f1b49be6a3010",
"638e0057ab150a5f56238960",
"63927b29c115f907b14700b9",
"638dfc803083a019d447768e",
"638e9d5536b3b72c944e2fc7",
"6393262086e646067c176aa2",
"63989ced706b793c7d60cfef",
"63a39e1d234195315d4020bd",
"64e74a35aac4cd0a7264ecdb",
"64e74a186393886f74114a96",
"64e74a1faac4cd0a7264ecd9",
"64e73909cd54ef0580746af3",
"64e74a2fc2b4f829615ec332",
"64e74a274d49d23b2c39d317",
"64f09c02b63b74469b6c149f",
"64f07f7726cfa02c506f8ac0",
"64f69b4267e11a7c6206e010",
"64f5b4f71a5f313cb144c06c",
"657acb2ac900be5902191ac9",
"6582dbf0b8d7830efc45016f",
"66687bc89111279d600b5062"
],
"laboratory": [
"6398a4cfb5992f573c6562b3",
"64e74a44c2b4f829615ec334",
"6711039f9e648049e50b3307",
"6707cef3571b50abc703b64f",
"6707cd70aab679420007e018",
"6707cc67cc1667e49e0f7232",
"6707cf827d279daad80fa95f"
],
"sandbox": ["6575a6ca8778e96ded05a802", "6582bd252b50c61c565828e2"],
"factory4_day": [
"591093bb86f7747caa7bb2ee",
"66c0b39ca1f68fcc1d0c0cc3",
"66a0e523e749756c920d02d0",
"593a87af86f774122f54a951"
],
"factory4_night": [
"591093bb86f7747caa7bb2ee",
"66c0b39ca1f68fcc1d0c0cc3",
"66a0e523e749756c920d02d0",
"593a87af86f774122f54a951"
]
},
"rogueLighthouseSpawnTimeSettings": {
"enabled": false,
"waitTimeSeconds": 120
},
"fitLootIntoContainerAttempts": 3,
"addOpenZonesToAllMaps": true,
"addCustomBotWavesToMaps": true,
"enableBotTypeLimits": true,
"botTypeLimits": {
"TarkovStreets": [
{
"type": "marksman",
"min": 2,
"max": 4
}
],
"Woods": [
{
"type": "marksman",
"min": 2,
"max": 5
}
],
"Bigmap": [
{
"type": "marksman",
"min": 2,
"max": 4
}
]
},
"containerRandomisationSettings": {
"enabled": true,
"maps": {
"tarkovstreets": true,
"factory4_day": true,
"factory4_night": true,
"bigmap": true,
"woods": true,
"shoreline": true,
"interchange": true,
"lighthouse": true,
"laboratory": true,
"rezervbase": true,
"sandbox": true
},
"containerTypesToNotRandomise": [
"5d6fd45b86f774317075ed43",
"5909d89086f77472591234a0",
"578f87b7245977356274f2cd",
"5909d76c86f77471e53d2adf",
"578f8782245977354405a1e3",
"5d6fe50986f77449d97f7463",
"578f879c24597735401e6bc6",
"578f8782245977354405a1e3",
"5d6fd13186f77424ad2a8c69"
],
"containerGroupMinSizeMultiplier": 1,
"containerGroupMaxSizeMultiplier": 1
},
"minFillLooseMagazinePercent": 50,
"minFillStaticMagazinePercent": 50,
"allowDuplicateItemsInStaticContainers": true,
"magazineLootHasAmmoChancePercent": 50,
"staticMagazineLootHasAmmoChancePercent": 0,
"looseLootBlacklist": {},
"scavRaidTimeSettings": {
"settings": {
"trainArrivalDelayObservedSeconds": 90
},
"maps": {
"bigmap": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 1,
"25": 2,
"30": 4,
"35": 4,
"40": 4,
"45": 4,
"50": 4,
"60": 2,
"70": 2
},
"adjustWaves": true
},
"factory4_day": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"5": 2,
"20": 3,
"25": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 2,
"65": 2
},
"adjustWaves": true
},
"factory4_night": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 75,
"reductionPercentWeights": {
"20": 4,
"30": 3,
"40": 3,
"60": 2,
"65": 2
},
"adjustWaves": true
},
"interchange": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 5,
"25": 5,
"30": 5,
"35": 5,
"40": 5,
"50": 5,
"55": 2
},
"adjustWaves": true
},
"rezervbase": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 3,
"40": 4,
"50": 4,
"60": 2
},
"adjustWaves": true
},
"laboratory": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 2
},
"adjustWaves": true
},
"lighthouse": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 2,
"25": 2,
"30": 4,
"40": 4,
"50": 4,
"60": 2
},
"adjustWaves": true
},
"shoreline": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 2,
"25": 3,
"30": 5,
"35": 5,
"40": 5,
"50": 5,
"60": 2,
"65": 1
},
"adjustWaves": true
},
"tarkovstreets": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 70,
"minStaticLootPercent": 60,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 4,
"40": 5,
"50": 4,
"60": 3
},
"adjustWaves": true
},
"woods": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 1,
"65": 1
},
"adjustWaves": true
},
"sandbox": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 1,
"65": 1
},
"adjustWaves": true
},
"sandbox_high": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 40,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"20": 3,
"30": 5,
"40": 5,
"50": 5,
"60": 1,
"65": 1
},
"adjustWaves": true
},
"default": {
"reduceLootByPercent": true,
"minDynamicLootPercent": 50,
"minStaticLootPercent": 50,
"reducedChancePercent": 95,
"reductionPercentWeights": {
"10": 1,
"20": 2,
"30": 5,
"40": 5,
"50": 5,
"60": 2,
"70": 1
},
"adjustWaves": true
}
}
},
"equipmentLootSettings": {
"modSpawnChancePercent": {
"mod_nvg": 5,
"front_plate": 100,
"back_plate": 100,
"left_side_plate": 25,
"right_side_plate": 25,
"mod_equipment_000": 5,
"mod_equipment_001": 5,
"mod_equipment_002": 5,
"mod_mount": 5,
"mod_equipment": 5
}
},
"reserveRaiderSpawnChanceOverrides": {
"nonTriggered": 80,
"triggered": 90
},
"tplsToStripChildItemsFrom": [
"63a8970d7108f713591149f5",
"63a897c6b1ff6e29734fcc95",
"63a898a328e385334e0640a5",
"634959225289190e5e773b3b"
],
"nonMaps": ["base", "develop", "hideout", "privatearea", "suburbs", "terminal", "town"]
}
File diff suppressed because it is too large Load Diff
@@ -222,7 +222,7 @@
"levels": [1, 10, 20, 30, 40, 50, 60],
"experience": [1000, 2000, 8000, 13000, 19000, 24000, 30000],
"roubles": [11000, 20000, 32000, 45000, 58000, 70000, 82000],
"gpCoins": [3, 3, 6, 6, 8, 8, 10],
"gpCoins": [2, 3, 6, 6, 8, 8, 10],
"items": [2, 4, 5, 5, 5, 5, 5],
"reputation": [0.01, 0.01, 0.02, 0.02, 0.03, 0.03, 0.03],
"rewardSpread": 0.5,
@@ -438,7 +438,7 @@
},
"allowBossItems": false,
"useRewardItemBlacklist": true,
"blockSeasonalItemsOutOfSeason": true
"blockSeasonalItemsOutOfSeason": true
},
"btrDeliveryExpireHours": 240,
"playerRepMin": -7,
@@ -2966,7 +2966,8 @@
"5e023e6e34d52a55c3304f71": 10,
"5e023e88277cce2b522ff2b1": 5,
"5efb0c1bd79ff02a1f5e68d9": 3,
"6769b8e3c1a1466c850658a8": 3
"6769b8e3c1a1466c850658a8": 3,
"6768c25aa7b238f14a08d3f6": 2
},
"Caliber762x54R": {
"560d61e84bdc2da74d8b4571": 90,
@@ -2958,7 +2958,8 @@
"5e023e6e34d52a55c3304f71": 10,
"5e023e88277cce2b522ff2b1": 5,
"5efb0c1bd79ff02a1f5e68d9": 3,
"6769b8e3c1a1466c850658a8": 3
"6769b8e3c1a1466c850658a8": 3,
"6768c25aa7b238f14a08d3f6": 2
},
"Caliber762x54R": {
"560d61e84bdc2da74d8b4571": 90,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -18024,7 +18024,7 @@
"StrengthBuffSprintSpeedInc": "Increases movement and sprint speed by [{0:0.#%}]",
"StrengthBuffThrowDistanceInc": "Increases throw distance by [{0:0.#%}]",
"StrengthDescription": "Increasing strength allows you to jump higher, sprint faster, hit harder, throw farther, and carry more weight.",
"StrengthLevelingUpDescription": "The Strength skill is improved by sprinting with the overweight status effect, throwing grenades, using melee weapons, and by working out in the Hideout gym.",
"StrengthLevelingUpDescription": "The Strength skill is improved by moving around with the overweight status effect, throwing grenades, using melee weapons, and by working out in the Hideout gym.",
"StressBerserk": "Berserk mode access",
"StressPainChance": "Reduces pain shock chance by [{0:0.#%}]",
"StressResistance": "Stress Resistance",
@@ -18024,7 +18024,7 @@
"StrengthBuffSprintSpeedInc": "Increases movement and sprint speed by [{0:0%}]",
"StrengthBuffThrowDistanceInc": "Increases throw distance by [{0:0%}]",
"StrengthDescription": "Az erő növelésével magasabbra ugorhatsz, gyorsabban futhatsz, nagyobbat üthetsz, messzebbre dobhatsz, és ezen felül, nagyobb súlyt cipelhetsz.",
"StrengthLevelingUpDescription": "The Strength skill is improved by sprinting with the overweight status effect, throwing grenades, using melee weapons, and by working out in the Hideout gym.",
"StrengthLevelingUpDescription": "The Strength skill is improved by moving around with the overweight status effect, throwing grenades, using melee weapons, and by working out in the Hideout gym.",
"StressBerserk": "Berserk mód feloldása",
"StressPainChance": "Reduces pain shock chance by [{0:0%}]",
"StressResistance": "Stressz-tűrés",
@@ -18024,7 +18024,7 @@
"StrengthBuffSprintSpeedInc": "Увеличивает скорость ходьбы и спринта на [{0:0.#%}]",
"StrengthBuffThrowDistanceInc": "Увеличивает силу броска гранат на [{0:0.#%}]",
"StrengthDescription": "Увеличение силы позволит прыгать выше и бегать быстрее, больнее бить и дальше бросать, и, что немаловажно - больше нести.",
"StrengthLevelingUpDescription": "Навык силы улучшается во время бега со статус-эффектом перегрузки, бросков гранат, использования холодного оружия, тренировок в тренажёрном зале Убежища.",
"StrengthLevelingUpDescription": "Навык силы улучшается во время перемещения со статус-эффектом перегрузки, бросков гранат, использования холодного оружия, тренировок в тренажёрном зале Убежища.",
"StressBerserk": "Доступен режим берсерка",
"StressPainChance": "Уменьшает шанс получить болевой эффект на [{0:0.#%}]",
"StressResistance": "Стрессоустойчивость",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -624,7 +624,7 @@
{
"Id": "5696686a4bdc2da3298b456a",
"ParentId": "5b5f78b786f77447ed5636af",
"Price": 136
"Price": 131
},
{
"Id": "572b7adb24597762ae139821",
@@ -1954,7 +1954,7 @@
{
"Id": "569668774bdc2da2298b4568",
"ParentId": "5b5f78b786f77447ed5636af",
"Price": 140
"Price": 134
},
{
"Id": "574eb85c245977648157eec3",
@@ -4059,7 +4059,7 @@
{
"Id": "59faff1d86f7746c51718c9c",
"ParentId": "5b47574386f77428ca22b2f1",
"Price": 1460419
"Price": 1397826
},
{
"Id": "5aa66a9be5b5b0214e506e89",
File diff suppressed because it is too large Load Diff
@@ -1356,6 +1356,7 @@
{
"_id": "678fb0f586f7d451620c4214",
"_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c4212",
"slotId": "cartridges",
"upd": {
@@ -1384,6 +1385,7 @@
{
"_id": "678fb0f586f7d451620c4217",
"_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c4215",
"slotId": "cartridges",
"upd": {
@@ -2044,6 +2046,7 @@
{
"_id": "678fb0f586f7d451620c4086",
"_tpl": "56dff2ced2720bb4668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4084",
"slotId": "cartridges",
"upd": {
@@ -2072,6 +2075,7 @@
{
"_id": "678fb0f586f7d451620c4089",
"_tpl": "56dff2ced2720bb4668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4087",
"slotId": "cartridges",
"upd": {
@@ -20637,6 +20641,7 @@
{
"_id": "678fb0f586f7d451620c49c2",
"_tpl": "5d6e68c4a4b9361b93413f79",
"location": 1,
"parentId": "678fb0f586f7d451620c49c0",
"slotId": "cartridges",
"upd": {
@@ -24001,6 +24006,7 @@
{
"_id": "678fb0f586f7d451620c3946",
"_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c3944",
"slotId": "cartridges",
"upd": {
@@ -24029,6 +24035,7 @@
{
"_id": "678fb0f586f7d451620c3949",
"_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c3947",
"slotId": "cartridges",
"upd": {
@@ -40949,6 +40956,7 @@
{
"_id": "678fb0f586f7d451620c3c06",
"_tpl": "59e690b686f7746c9f75e848",
"location": 1,
"parentId": "678fb0f586f7d451620c3c04",
"slotId": "cartridges",
"upd": {
@@ -40977,6 +40985,7 @@
{
"_id": "678fb0f586f7d451620c3c09",
"_tpl": "59e690b686f7746c9f75e848",
"location": 1,
"parentId": "678fb0f586f7d451620c3c07",
"slotId": "cartridges",
"upd": {
@@ -41005,6 +41014,7 @@
{
"_id": "678fb0f586f7d451620c3c0c",
"_tpl": "59e690b686f7746c9f75e848",
"location": 1,
"parentId": "678fb0f586f7d451620c3c0a",
"slotId": "cartridges",
"upd": {
@@ -44964,6 +44974,7 @@
{
"_id": "678fb0f586f7d451620c3cd0",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cce",
"slotId": "cartridges",
"upd": {
@@ -44989,6 +45000,7 @@
{
"_id": "678fb0f586f7d451620c3cd3",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cd1",
"slotId": "cartridges",
"upd": {
@@ -45014,6 +45026,7 @@
{
"_id": "678fb0f586f7d451620c3cd6",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cd4",
"slotId": "cartridges",
"upd": {
@@ -45039,6 +45052,7 @@
{
"_id": "678fb0f586f7d451620c3cd9",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cd7",
"slotId": "cartridges",
"upd": {
@@ -57700,6 +57714,7 @@
{
"_id": "678fb0f586f7d451620c4a2d",
"_tpl": "56dff061d2720bb5668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4a2b",
"slotId": "cartridges",
"upd": {
@@ -58447,6 +58462,7 @@
{
"_id": "678fb0f586f7d451620c4880",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c487e",
"slotId": "cartridges",
"upd": {
@@ -58475,6 +58491,7 @@
{
"_id": "678fb0f586f7d451620c4883",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c4881",
"slotId": "cartridges",
"upd": {
@@ -58503,6 +58520,7 @@
{
"_id": "678fb0f586f7d451620c4886",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c4884",
"slotId": "cartridges",
"upd": {
@@ -58531,6 +58549,7 @@
{
"_id": "678fb0f586f7d451620c4889",
"_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c4887",
"slotId": "cartridges",
"upd": {
@@ -61606,6 +61625,7 @@
{
"_id": "678fb0f586f7d451620c4019",
"_tpl": "56dff026d2720bb8668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4017",
"slotId": "cartridges",
"upd": {
@@ -65016,6 +65036,7 @@
{
"_id": "678fb0f586f7d451620c3a5d",
"_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c3a5b",
"slotId": "cartridges",
"upd": {
@@ -65044,6 +65065,7 @@
{
"_id": "678fb0f586f7d451620c3a60",
"_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c3a5e",
"slotId": "cartridges",
"upd": {
@@ -82731,6 +82753,7 @@
{
"_id": "678fb0f586f7d451620c4b6a",
"_tpl": "54527ac44bdc2d36668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4b68",
"slotId": "cartridges",
"upd": {
@@ -94241,7 +94264,8 @@
"65290f395ae2ae97b80fdf2d",
"644674a13d52156624001fbc",
"645e0c6b3b381ede770e1cc9",
"651450ce0e00edc794068371"
"651450ce0e00edc794068371",
"676176d362e0497044079f4c"
],
"weaponCaliber": [],
"weaponModsExclusive": [],
@@ -95236,7 +95260,6 @@
"index": 0,
"parentId": "",
"status": [
2,
4
],
"target": "5ac346cf86f7741d63233a02",
@@ -111383,7 +111406,9 @@
"544a5caa4bdc2d1a388b4568",
"5ab8dab586f77441cd04f2a2",
"59e7643b86f7742cbf2c109a",
"572b7adb24597762ae139821"
"572b7adb24597762ae139821",
"674da107c512807d1a0e7436",
"674da9cf0cb4bcde7103c07b"
],
"traderId": "5ac3b934156ae10c4430e83c",
"value": 250,
@@ -117791,7 +117816,9 @@
"5a7828548dc32e5a9c28b516",
"5e848cc2988a8701445df1e8",
"5a38e6bac4a2826c6e06d79b",
"60db29ce99594040e04c4a27"
"60db29ce99594040e04c4a27",
"66ffa9b66e19cc902401c5e8",
"67124dcfa3541f2a1f0e788b"
],
"weaponCaliber": [],
"weaponModsExclusive": [],
@@ -144666,6 +144693,7 @@
{
"_id": "679fb456e5533f2c2d0e72d5",
"_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "679fb456e5533f2c2d0e72d3",
"slotId": "cartridges",
"upd": {
@@ -144694,6 +144722,7 @@
{
"_id": "679fb456e5533f2c2d0e72d8",
"_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "679fb456e5533f2c2d0e72d6",
"slotId": "cartridges",
"upd": {
+9 -6
View File
@@ -1,8 +1,7 @@
using System.Runtime;
using Core.Context;
using Core.Helpers;
using Core.Models.External;
using Core.Models.Spt.Config;
using Core.Servers;
using Core.Utils;
using Serilog;
using Serilog.Events;
@@ -53,14 +52,18 @@ public static class Program
// Get the Built app and run it
var app = serviceProvider.GetService<App>();
app?.Run().Wait();
// RUn garbage collection now server is ready to start
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true, true);
var httpConfig = serviceProvider.GetService<ConfigServer>()?.GetConfig<HttpConfig>();
// When we application gets started by the HttpServer it will add into the AppContext the WebApplication
var httpServerHelper = serviceProvider.GetService<HttpServerHelper>();
// When the application is started by the HttpServer it will be added into the AppContext of the WebApplication
// object, which we can use here to start the webapp.
if (httpConfig != null)
if (httpServerHelper != null)
{
appContext?.GetLatestValue(ContextVariableType.WEB_APPLICATION)?.GetValue<WebApplication>().Run($"http://{httpConfig.Ip}:{httpConfig.Port}");
appContext?.GetLatestValue(ContextVariableType.WEB_APPLICATION)?.GetValue<WebApplication>().Run(httpServerHelper.GetBackendUrl());
}
}
catch (Exception ex)