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]); _botGenerationCacheService.StoreBots(cacheKey, [botToCache]);
// Store bot details in cache so post-raid PMC messages can use data // 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` // 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 // 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() public string GetBackendUrl()
{ {
return $"http://{BuildUrl()}"; return $"https://{BuildUrl()}";
} }
/** /**
@@ -50,7 +50,7 @@ public class HttpServerHelper(ConfigServer configServer)
*/ */
public string GetWebsocketUrl() public string GetWebsocketUrl()
{ {
return $"ws://{BuildUrl()}"; return $"wss://{BuildUrl()}";
} }
public void SendTextJson(HttpResponse resp, object output) public void SendTextJson(HttpResponse resp, object output)
@@ -68,4 +68,11 @@ public record HttpConfig : BaseConfig
get; get;
set; set;
} }
[JsonPropertyName("certificatePassword")]
public string? CertificatePassword
{
get;
set;
}
} }
@@ -42,7 +42,7 @@ public class InraidStaticRouter : StaticRouter
) => inraidCallbacks.GetTraitorScavHostileChance(url, info as EmptyRequestData, sessionID) ) => inraidCallbacks.GetTraitorScavHostileChance(url, info as EmptyRequestData, sessionID)
), ),
new RouteAction( new RouteAction(
"/singleplayer/bossconvert", "/singleplayer/bosstypes",
( (
url, url,
info, 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.Spt.Config;
using Core.Models.Utils; using Core.Models.Utils;
using Core.Servers.Http; using Core.Servers.Http;
using Core.Services; using Core.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using SptCommon.Annotations; using SptCommon.Annotations;
@@ -19,37 +25,134 @@ public class HttpServer(
) )
{ {
private readonly HttpConfig _httpConfig = _configServer.GetConfig<HttpConfig>(); private readonly HttpConfig _httpConfig = _configServer.GetConfig<HttpConfig>();
private bool started; private bool _started;
public void Load(WebApplicationBuilder? builder) public void Load(WebApplicationBuilder? builder)
{ {
builder?.WebHost.UseKestrel(); if (builder is null)
//builder.Services.AddControllers(); {
// At the end throw new Exception("WebApplicationBuilder is null in HttpServer.Load()");
var app = builder?.Build(); }
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 _logger.Success($"Generated and stored self-signed certificate ({certFileName}) in {AppDomain.CurrentDomain.BaseDirectory}");
app?.UseWebSockets(new WebSocketOptions }
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. // Every minute a heartbeat is sent to keep the connection alive.
KeepAliveInterval = TimeSpan.FromSeconds(60) KeepAliveInterval = TimeSpan.FromSeconds(60)
}); });
app?.Use( app.MapFallback(HandleFallback);
(HttpContext req, RequestDelegate _) =>
{ _started = true;
return Task.Factory.StartNew(async () => await HandleFallback(req));
}
);
started = true;
if (app is null)
{
throw new Exception("Application context is null in HttpServer.Load()");
}
_applicationContext.AddValue(ContextVariableType.WEB_APPLICATION, app); _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) private async Task HandleFallback(HttpContext context)
{ {
if (context.WebSockets.IsWebSocketRequest) if (context.WebSockets.IsWebSocketRequest)
@@ -78,7 +181,7 @@ public class HttpServer(
? realIp.Value.First() ? realIp.Value.First()
: forwardedFor.HasValue : forwardedFor.HasValue
? forwardedFor.Value.First()!.Split(",")[0].Trim() ? forwardedFor.Value.First()!.Split(",")[0].Trim()
: context.Connection.RemoteIpAddress!.ToString(); : context.Connection.RemoteIpAddress!.ToString().Split(":")[3];
if (_httpConfig.LogRequests) if (_httpConfig.LogRequests)
{ {
@@ -93,11 +196,10 @@ public class HttpServer(
{ {
_logger.Info( _logger.Info(
_localisationService.GetText( _localisationService.GetText(
"client_request_ip", "client_request_ip", new
new Dictionary<string, string>
{ {
{ "ip", clientIp }, ip = clientIp,
{ "url", context.Request.Path.Value } url = context.Request.Path.Value
} }
) )
); );
@@ -136,11 +238,11 @@ public class HttpServer(
public bool IsStarted() public bool IsStarted()
{ {
return started; return _started;
} }
public string ListeningUrl() public string ListeningUrl()
{ {
return $"http://{_httpConfig.Ip}:{_httpConfig.Port}"; return $"https://{_httpConfig.Ip}:{_httpConfig.Port}";
} }
} }
@@ -21,6 +21,10 @@ public class MatchBotDetailsCacheService(
return; return;
} }
botToCache.Inventory = null;
botToCache.Skills = null;
botToCache.Stats = null;
var key = $"{botToCache.Info.Nickname.Trim()}{botToCache.Info.Side}"; var key = $"{botToCache.Info.Nickname.Trim()}{botToCache.Info.Side}";
_botDetailsCache.TryAdd(key, botToCache); _botDetailsCache.TryAdd(key, botToCache);
} }
+1 -1
View File
@@ -90,7 +90,7 @@ public class App
if (_httpServer.IsStarted()) if (_httpServer.IsStarted())
{ {
_logger.Success(_localisationService.GetText("started_webserver_success", _httpServer.ListeningUrl())); _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()); _logger.Success(GetRandomisedStartMessage());
+21 -28
View File
@@ -22,28 +22,28 @@
"survey": { "survey": {
"locale": { "locale": {
"en": { "en": {
"question_1": "How off-topic is general chat on the SPT discord?", "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": "Not at all", "question_1_answer_1": "Ignore the changelog",
"question_1_answer_2": "A little", "question_1_answer_2": "Ignore the readme",
"question_1_answer_3": "Sometimes", "question_1_answer_3": "Ask in general chat why the guns dont shoot",
"question_1_answer_4": "Somewhat often", "question_1_answer_4": "Argue with general chat when they tell you to read the readme",
"question_1_answer_5": "Quite often", "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": "Most of the time", "question_1_answer_6": "Inform general chat of your displeasure and get mad when they laugh at you",
"question_1_answer_7": "Almost always", "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": "Always", "question_1_answer_8": "DM the author informing them of your displeasure at their mods existence",
"question_1_answer_9": "NOT OFF TOPIC ENOUGH", "question_1_answer_9": "DM the author and inform them you are going to sue them",
"question_1_answer_10": "I LIVE TO MAKE GENERAL CHAT OFF TOPIC", "question_1_answer_10": "Stalk the author and create dozens of hub accounts to message them",
"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": "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": "What's a description", "question_2_answer_1": "Get mad",
"question_2_answer_2": "I can't read", "question_2_answer_2": "Get REAL mad and voice your opinion in every possible chat you can",
"question_2_answer_3": "I am illiterate", "question_2_answer_3": "Travel around various discords informing anyone who listens what bad people SPT are",
"question_2_answer_4": "I am too busy making general chat off-topic to read", "question_2_answer_4": "Create dozens of alt accounts to DM staff and inform them of your displeasure",
"question_2_answer_5": "YOU WILL NEVER MAKE ME READ TEXT I WILL ASK IN GENERAL CHAT INSTEAD", "question_2_answer_5": "Ask when the old SPT verison is coming back every day for weeks",
"title": "Feedback survey", "title": "Feedback survey",
"time": "About 1 minute", "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.", "description": "This was the second SPT survey, what a valuable use of 20 minutes that was.",
"farewell": "I told you at the start the survey doesn't get sent anywhere and yet you still completed it, curious." "farewell": "You knew the first survey didnt do anything yet you still submitted the second one, you're quite an odd one."
} }
}, },
"survey": { "survey": {
@@ -125,12 +125,6 @@
"questionId": 0, "questionId": 0,
"sortIndex": 1, "sortIndex": 1,
"localeKey": "question_1_answer_10" "localeKey": "question_1_answer_10"
},
{
"id": 10,
"questionId": 0,
"sortIndex": 1,
"localeKey": "question_1_answer_11"
} }
] ]
}, },
@@ -197,8 +191,7 @@
"6723fd51c5924c57ce0ca01f": true "6723fd51c5924c57ce0ca01f": true
} }
}, },
"createNewProfileTypesBlacklist": [], "createNewProfileTypesBlacklist": []
"achievementProfileIdBlacklist": []
}, },
"customWatermarkLocaleKeys": [] "customWatermarkLocaleKeys": []
} }
+2 -1
View File
@@ -5,5 +5,6 @@
"backendPort": 6969, "backendPort": 6969,
"webSocketPingDelayMs": 90000, "webSocketPingDelayMs": 90000,
"logRequests": true, "logRequests": true,
"serverImagePathOverride": {} "serverImagePathOverride": {},
"certificatePassword": ""
} }
+431 -442
View File
@@ -1,445 +1,434 @@
{ {
"addCustomBotWavesToMaps": true, "looseLootMultiplier": {
"addOpenZonesToAllMaps": true, "bigmap": 2.5,
"allowDuplicateItemsInStaticContainers": true, "develop": 1,
"botTypeLimits": { "factory4_day": 3.5,
"Bigmap": [ "factory4_night": 3.5,
{ "interchange": 2.8,
"max": 4, "laboratory": 2.8,
"min": 2, "rezervbase": 2.9,
"type": "marksman" "shoreline": 3.7,
} "woods": 1.9,
], "hideout": 0,
"TarkovStreets": [ "lighthouse": 2.8,
{ "privatearea": 1,
"max": 4, "suburbs": 1,
"min": 2, "tarkovstreets": 3,
"type": "marksman" "terminal": 1,
} "sandbox": 2.8,
], "sandbox_high": 2.8,
"Woods": [ "town": 0
{
"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
}
}
}, },
"settings": { "staticLootMultiplier": {
"trainArrivalDelayObservedSeconds": 90 "bigmap": 1,
} "develop": 1,
}, "factory4_day": 1,
"staticLootMultiplier": { "factory4_night": 1,
"bigmap": 1, "interchange": 1,
"develop": 1, "laboratory": 1,
"factory4_day": 1, "rezervbase": 1,
"factory4_night": 1, "shoreline": 1,
"hideout": 0, "woods": 1,
"interchange": 1, "hideout": 0,
"laboratory": 1, "lighthouse": 1,
"lighthouse": 1, "privatearea": 1,
"privatearea": 1, "suburbs": 1,
"rezervbase": 1, "tarkovstreets": 1,
"sandbox": 1, "terminal": 1,
"sandbox_high": 1, "sandbox": 1,
"shoreline": 1, "sandbox_high": 1,
"suburbs": 1, "town": 1
"tarkovstreets": 1, },
"terminal": 1, "customWaves": {
"town": 1, "boss": {},
"woods": 1 "normal": {}
}, },
"staticMagazineLootHasAmmoChancePercent": 0, "openZones": {},
"tplsToStripChildItemsFrom": [ "forcedLootSingleSpawnById": {
"63a8970d7108f713591149f5", "bigmap": [
"63a897c6b1ff6e29734fcc95", "5ac620eb86f7743a8e6e0da0",
"63a898a328e385334e0640a5", "5939e5a786f77461f11c0098",
"634959225289190e5e773b3b" "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], "levels": [1, 10, 20, 30, 40, 50, 60],
"experience": [1000, 2000, 8000, 13000, 19000, 24000, 30000], "experience": [1000, 2000, 8000, 13000, 19000, 24000, 30000],
"roubles": [11000, 20000, 32000, 45000, 58000, 70000, 82000], "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], "items": [2, 4, 5, 5, 5, 5, 5],
"reputation": [0.01, 0.01, 0.02, 0.02, 0.03, 0.03, 0.03], "reputation": [0.01, 0.01, 0.02, 0.02, 0.03, 0.03, 0.03],
"rewardSpread": 0.5, "rewardSpread": 0.5,
@@ -438,7 +438,7 @@
}, },
"allowBossItems": false, "allowBossItems": false,
"useRewardItemBlacklist": true, "useRewardItemBlacklist": true,
"blockSeasonalItemsOutOfSeason": true "blockSeasonalItemsOutOfSeason": true
}, },
"btrDeliveryExpireHours": 240, "btrDeliveryExpireHours": 240,
"playerRepMin": -7, "playerRepMin": -7,
@@ -2966,7 +2966,8 @@
"5e023e6e34d52a55c3304f71": 10, "5e023e6e34d52a55c3304f71": 10,
"5e023e88277cce2b522ff2b1": 5, "5e023e88277cce2b522ff2b1": 5,
"5efb0c1bd79ff02a1f5e68d9": 3, "5efb0c1bd79ff02a1f5e68d9": 3,
"6769b8e3c1a1466c850658a8": 3 "6769b8e3c1a1466c850658a8": 3,
"6768c25aa7b238f14a08d3f6": 2
}, },
"Caliber762x54R": { "Caliber762x54R": {
"560d61e84bdc2da74d8b4571": 90, "560d61e84bdc2da74d8b4571": 90,
@@ -2958,7 +2958,8 @@
"5e023e6e34d52a55c3304f71": 10, "5e023e6e34d52a55c3304f71": 10,
"5e023e88277cce2b522ff2b1": 5, "5e023e88277cce2b522ff2b1": 5,
"5efb0c1bd79ff02a1f5e68d9": 3, "5efb0c1bd79ff02a1f5e68d9": 3,
"6769b8e3c1a1466c850658a8": 3 "6769b8e3c1a1466c850658a8": 3,
"6768c25aa7b238f14a08d3f6": 2
}, },
"Caliber762x54R": { "Caliber762x54R": {
"560d61e84bdc2da74d8b4571": 90, "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.#%}]", "StrengthBuffSprintSpeedInc": "Increases movement and sprint speed by [{0:0.#%}]",
"StrengthBuffThrowDistanceInc": "Increases throw distance 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.", "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", "StressBerserk": "Berserk mode access",
"StressPainChance": "Reduces pain shock chance by [{0:0.#%}]", "StressPainChance": "Reduces pain shock chance by [{0:0.#%}]",
"StressResistance": "Stress Resistance", "StressResistance": "Stress Resistance",
@@ -18024,7 +18024,7 @@
"StrengthBuffSprintSpeedInc": "Increases movement and sprint speed by [{0:0%}]", "StrengthBuffSprintSpeedInc": "Increases movement and sprint speed by [{0:0%}]",
"StrengthBuffThrowDistanceInc": "Increases throw distance 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.", "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", "StressBerserk": "Berserk mód feloldása",
"StressPainChance": "Reduces pain shock chance by [{0:0%}]", "StressPainChance": "Reduces pain shock chance by [{0:0%}]",
"StressResistance": "Stressz-tűrés", "StressResistance": "Stressz-tűrés",
@@ -18024,7 +18024,7 @@
"StrengthBuffSprintSpeedInc": "Увеличивает скорость ходьбы и спринта на [{0:0.#%}]", "StrengthBuffSprintSpeedInc": "Увеличивает скорость ходьбы и спринта на [{0:0.#%}]",
"StrengthBuffThrowDistanceInc": "Увеличивает силу броска гранат на [{0:0.#%}]", "StrengthBuffThrowDistanceInc": "Увеличивает силу броска гранат на [{0:0.#%}]",
"StrengthDescription": "Увеличение силы позволит прыгать выше и бегать быстрее, больнее бить и дальше бросать, и, что немаловажно - больше нести.", "StrengthDescription": "Увеличение силы позволит прыгать выше и бегать быстрее, больнее бить и дальше бросать, и, что немаловажно - больше нести.",
"StrengthLevelingUpDescription": "Навык силы улучшается во время бега со статус-эффектом перегрузки, бросков гранат, использования холодного оружия, тренировок в тренажёрном зале Убежища.", "StrengthLevelingUpDescription": "Навык силы улучшается во время перемещения со статус-эффектом перегрузки, бросков гранат, использования холодного оружия, тренировок в тренажёрном зале Убежища.",
"StressBerserk": "Доступен режим берсерка", "StressBerserk": "Доступен режим берсерка",
"StressPainChance": "Уменьшает шанс получить болевой эффект на [{0:0.#%}]", "StressPainChance": "Уменьшает шанс получить болевой эффект на [{0:0.#%}]",
"StressResistance": "Стрессоустойчивость", "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", "Id": "5696686a4bdc2da3298b456a",
"ParentId": "5b5f78b786f77447ed5636af", "ParentId": "5b5f78b786f77447ed5636af",
"Price": 136 "Price": 131
}, },
{ {
"Id": "572b7adb24597762ae139821", "Id": "572b7adb24597762ae139821",
@@ -1954,7 +1954,7 @@
{ {
"Id": "569668774bdc2da2298b4568", "Id": "569668774bdc2da2298b4568",
"ParentId": "5b5f78b786f77447ed5636af", "ParentId": "5b5f78b786f77447ed5636af",
"Price": 140 "Price": 134
}, },
{ {
"Id": "574eb85c245977648157eec3", "Id": "574eb85c245977648157eec3",
@@ -4059,7 +4059,7 @@
{ {
"Id": "59faff1d86f7746c51718c9c", "Id": "59faff1d86f7746c51718c9c",
"ParentId": "5b47574386f77428ca22b2f1", "ParentId": "5b47574386f77428ca22b2f1",
"Price": 1460419 "Price": 1397826
}, },
{ {
"Id": "5aa66a9be5b5b0214e506e89", "Id": "5aa66a9be5b5b0214e506e89",
File diff suppressed because it is too large Load Diff
@@ -1356,6 +1356,7 @@
{ {
"_id": "678fb0f586f7d451620c4214", "_id": "678fb0f586f7d451620c4214",
"_tpl": "5d6e6806a4b936088465b17e", "_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c4212", "parentId": "678fb0f586f7d451620c4212",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -1384,6 +1385,7 @@
{ {
"_id": "678fb0f586f7d451620c4217", "_id": "678fb0f586f7d451620c4217",
"_tpl": "5d6e6806a4b936088465b17e", "_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c4215", "parentId": "678fb0f586f7d451620c4215",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -2044,6 +2046,7 @@
{ {
"_id": "678fb0f586f7d451620c4086", "_id": "678fb0f586f7d451620c4086",
"_tpl": "56dff2ced2720bb4668b4567", "_tpl": "56dff2ced2720bb4668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4084", "parentId": "678fb0f586f7d451620c4084",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -2072,6 +2075,7 @@
{ {
"_id": "678fb0f586f7d451620c4089", "_id": "678fb0f586f7d451620c4089",
"_tpl": "56dff2ced2720bb4668b4567", "_tpl": "56dff2ced2720bb4668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4087", "parentId": "678fb0f586f7d451620c4087",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -20637,6 +20641,7 @@
{ {
"_id": "678fb0f586f7d451620c49c2", "_id": "678fb0f586f7d451620c49c2",
"_tpl": "5d6e68c4a4b9361b93413f79", "_tpl": "5d6e68c4a4b9361b93413f79",
"location": 1,
"parentId": "678fb0f586f7d451620c49c0", "parentId": "678fb0f586f7d451620c49c0",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -24001,6 +24006,7 @@
{ {
"_id": "678fb0f586f7d451620c3946", "_id": "678fb0f586f7d451620c3946",
"_tpl": "5d6e6806a4b936088465b17e", "_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c3944", "parentId": "678fb0f586f7d451620c3944",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -24029,6 +24035,7 @@
{ {
"_id": "678fb0f586f7d451620c3949", "_id": "678fb0f586f7d451620c3949",
"_tpl": "5d6e6806a4b936088465b17e", "_tpl": "5d6e6806a4b936088465b17e",
"location": 1,
"parentId": "678fb0f586f7d451620c3947", "parentId": "678fb0f586f7d451620c3947",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -40949,6 +40956,7 @@
{ {
"_id": "678fb0f586f7d451620c3c06", "_id": "678fb0f586f7d451620c3c06",
"_tpl": "59e690b686f7746c9f75e848", "_tpl": "59e690b686f7746c9f75e848",
"location": 1,
"parentId": "678fb0f586f7d451620c3c04", "parentId": "678fb0f586f7d451620c3c04",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -40977,6 +40985,7 @@
{ {
"_id": "678fb0f586f7d451620c3c09", "_id": "678fb0f586f7d451620c3c09",
"_tpl": "59e690b686f7746c9f75e848", "_tpl": "59e690b686f7746c9f75e848",
"location": 1,
"parentId": "678fb0f586f7d451620c3c07", "parentId": "678fb0f586f7d451620c3c07",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -41005,6 +41014,7 @@
{ {
"_id": "678fb0f586f7d451620c3c0c", "_id": "678fb0f586f7d451620c3c0c",
"_tpl": "59e690b686f7746c9f75e848", "_tpl": "59e690b686f7746c9f75e848",
"location": 1,
"parentId": "678fb0f586f7d451620c3c0a", "parentId": "678fb0f586f7d451620c3c0a",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -44964,6 +44974,7 @@
{ {
"_id": "678fb0f586f7d451620c3cd0", "_id": "678fb0f586f7d451620c3cd0",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cce", "parentId": "678fb0f586f7d451620c3cce",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -44989,6 +45000,7 @@
{ {
"_id": "678fb0f586f7d451620c3cd3", "_id": "678fb0f586f7d451620c3cd3",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cd1", "parentId": "678fb0f586f7d451620c3cd1",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -45014,6 +45026,7 @@
{ {
"_id": "678fb0f586f7d451620c3cd6", "_id": "678fb0f586f7d451620c3cd6",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cd4", "parentId": "678fb0f586f7d451620c3cd4",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -45039,6 +45052,7 @@
{ {
"_id": "678fb0f586f7d451620c3cd9", "_id": "678fb0f586f7d451620c3cd9",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c3cd7", "parentId": "678fb0f586f7d451620c3cd7",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -57700,6 +57714,7 @@
{ {
"_id": "678fb0f586f7d451620c4a2d", "_id": "678fb0f586f7d451620c4a2d",
"_tpl": "56dff061d2720bb5668b4567", "_tpl": "56dff061d2720bb5668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4a2b", "parentId": "678fb0f586f7d451620c4a2b",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -58447,6 +58462,7 @@
{ {
"_id": "678fb0f586f7d451620c4880", "_id": "678fb0f586f7d451620c4880",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c487e", "parentId": "678fb0f586f7d451620c487e",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -58475,6 +58491,7 @@
{ {
"_id": "678fb0f586f7d451620c4883", "_id": "678fb0f586f7d451620c4883",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c4881", "parentId": "678fb0f586f7d451620c4881",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -58503,6 +58520,7 @@
{ {
"_id": "678fb0f586f7d451620c4886", "_id": "678fb0f586f7d451620c4886",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c4884", "parentId": "678fb0f586f7d451620c4884",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -58531,6 +58549,7 @@
{ {
"_id": "678fb0f586f7d451620c4889", "_id": "678fb0f586f7d451620c4889",
"_tpl": "5d6e68a8a4b9360b6c0d54e2", "_tpl": "5d6e68a8a4b9360b6c0d54e2",
"location": 1,
"parentId": "678fb0f586f7d451620c4887", "parentId": "678fb0f586f7d451620c4887",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -61606,6 +61625,7 @@
{ {
"_id": "678fb0f586f7d451620c4019", "_id": "678fb0f586f7d451620c4019",
"_tpl": "56dff026d2720bb8668b4567", "_tpl": "56dff026d2720bb8668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4017", "parentId": "678fb0f586f7d451620c4017",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -65016,6 +65036,7 @@
{ {
"_id": "678fb0f586f7d451620c3a5d", "_id": "678fb0f586f7d451620c3a5d",
"_tpl": "56dfef82d2720bbd668b4567", "_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c3a5b", "parentId": "678fb0f586f7d451620c3a5b",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -65044,6 +65065,7 @@
{ {
"_id": "678fb0f586f7d451620c3a60", "_id": "678fb0f586f7d451620c3a60",
"_tpl": "56dfef82d2720bbd668b4567", "_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c3a5e", "parentId": "678fb0f586f7d451620c3a5e",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -82731,6 +82753,7 @@
{ {
"_id": "678fb0f586f7d451620c4b6a", "_id": "678fb0f586f7d451620c4b6a",
"_tpl": "54527ac44bdc2d36668b4567", "_tpl": "54527ac44bdc2d36668b4567",
"location": 1,
"parentId": "678fb0f586f7d451620c4b68", "parentId": "678fb0f586f7d451620c4b68",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -94241,7 +94264,8 @@
"65290f395ae2ae97b80fdf2d", "65290f395ae2ae97b80fdf2d",
"644674a13d52156624001fbc", "644674a13d52156624001fbc",
"645e0c6b3b381ede770e1cc9", "645e0c6b3b381ede770e1cc9",
"651450ce0e00edc794068371" "651450ce0e00edc794068371",
"676176d362e0497044079f4c"
], ],
"weaponCaliber": [], "weaponCaliber": [],
"weaponModsExclusive": [], "weaponModsExclusive": [],
@@ -95236,7 +95260,6 @@
"index": 0, "index": 0,
"parentId": "", "parentId": "",
"status": [ "status": [
2,
4 4
], ],
"target": "5ac346cf86f7741d63233a02", "target": "5ac346cf86f7741d63233a02",
@@ -111383,7 +111406,9 @@
"544a5caa4bdc2d1a388b4568", "544a5caa4bdc2d1a388b4568",
"5ab8dab586f77441cd04f2a2", "5ab8dab586f77441cd04f2a2",
"59e7643b86f7742cbf2c109a", "59e7643b86f7742cbf2c109a",
"572b7adb24597762ae139821" "572b7adb24597762ae139821",
"674da107c512807d1a0e7436",
"674da9cf0cb4bcde7103c07b"
], ],
"traderId": "5ac3b934156ae10c4430e83c", "traderId": "5ac3b934156ae10c4430e83c",
"value": 250, "value": 250,
@@ -117791,7 +117816,9 @@
"5a7828548dc32e5a9c28b516", "5a7828548dc32e5a9c28b516",
"5e848cc2988a8701445df1e8", "5e848cc2988a8701445df1e8",
"5a38e6bac4a2826c6e06d79b", "5a38e6bac4a2826c6e06d79b",
"60db29ce99594040e04c4a27" "60db29ce99594040e04c4a27",
"66ffa9b66e19cc902401c5e8",
"67124dcfa3541f2a1f0e788b"
], ],
"weaponCaliber": [], "weaponCaliber": [],
"weaponModsExclusive": [], "weaponModsExclusive": [],
@@ -144666,6 +144693,7 @@
{ {
"_id": "679fb456e5533f2c2d0e72d5", "_id": "679fb456e5533f2c2d0e72d5",
"_tpl": "56dfef82d2720bbd668b4567", "_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "679fb456e5533f2c2d0e72d3", "parentId": "679fb456e5533f2c2d0e72d3",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
@@ -144694,6 +144722,7 @@
{ {
"_id": "679fb456e5533f2c2d0e72d8", "_id": "679fb456e5533f2c2d0e72d8",
"_tpl": "56dfef82d2720bbd668b4567", "_tpl": "56dfef82d2720bbd668b4567",
"location": 1,
"parentId": "679fb456e5533f2c2d0e72d6", "parentId": "679fb456e5533f2c2d0e72d6",
"slotId": "cartridges", "slotId": "cartridges",
"upd": { "upd": {
+9 -6
View File
@@ -1,8 +1,7 @@
using System.Runtime; using System.Runtime;
using Core.Context; using Core.Context;
using Core.Helpers;
using Core.Models.External; using Core.Models.External;
using Core.Models.Spt.Config;
using Core.Servers;
using Core.Utils; using Core.Utils;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
@@ -53,14 +52,18 @@ public static class Program
// Get the Built app and run it // Get the Built app and run it
var app = serviceProvider.GetService<App>(); var app = serviceProvider.GetService<App>();
app?.Run().Wait(); app?.Run().Wait();
// RUn garbage collection now server is ready to start
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true, true); 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. // 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) catch (Exception ex)