Http server router refactor (#553)

* Add edge case for Reverse Proxies

* Cleanup HttpListener, remove unecessary MemoryStreams

* Handle with IPAddress instead of string

* Handle nullabiity of RouteAction, tighten typing on requests

* Cleanup HttpRouter

* Use tighter typing on Routers
This commit is contained in:
Jesse
2025-08-18 19:59:07 +02:00
committed by GitHub
parent 5985777533
commit 80f759a0da
39 changed files with 968 additions and 1237 deletions
@@ -62,7 +62,7 @@ public class GameCallbacks(
/// Handle client/game/config
/// </summary>
/// <returns></returns>
public ValueTask<string> GetGameConfig(string url, GameEmptyCrcRequestData info, MongoId sessionID)
public ValueTask<string> GetGameConfig(string url, EmptyRequestData info, MongoId sessionID)
{
return new ValueTask<string>(httpResponseUtil.GetBody(gameController.GetGameConfig(sessionID)));
}
+7 -4
View File
@@ -52,7 +52,7 @@ public abstract class StaticRouter(JsonUtil jsonUtil, IEnumerable<RouteAction> r
info = (IRequestData?)jsonUtil.Deserialize(body, type);
}
return await action.action(url, info, sessionId, output);
return await action.action(url, info ?? new EmptyRequestData(), sessionId, output);
}
protected override IEnumerable<HandledRoute> GetHandledRoutes()
@@ -73,7 +73,7 @@ public abstract class DynamicRouter(JsonUtil jsonUtil, IEnumerable<RouteAction>
info = (IRequestData?)jsonUtil.Deserialize(body, type);
}
return await action.action(url, info, sessionID, output);
return await action.action(url, info ?? new EmptyRequestData(), sessionID, output);
}
protected override IEnumerable<HandledRoute> GetHandledRoutes()
@@ -102,5 +102,8 @@ public abstract class SaveLoadRouter : Router
public record HandledRoute(string route, bool dynamic);
public record RouteAction(string url, Func<string, IRequestData?, MongoId, string?, ValueTask<object>> action, Type? bodyType = null);
//public action: (url: string, info: any, sessionID: string, output: string) => Promise<any>,
public record RouteAction(string url, Func<string, IRequestData, MongoId, string?, ValueTask<object>> action, Type? bodyType = null);
public record RouteAction<TRequest>(string url, Func<string, TRequest, MongoId, string?, ValueTask<string>> typedAction)
: RouteAction(url, async (url, info, sessionId, output) => await typedAction(url, (TRequest)info, sessionId, output), typeof(TRequest))
where TRequest : class;
@@ -7,33 +7,29 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class BotDynamicRouter : DynamicRouter
{
public BotDynamicRouter(JsonUtil jsonUtil, BotCallbacks botCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/singleplayer/settings/bot/limit/",
async (url, info, sessionID, output) => await botCallbacks.GetBotLimit(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/settings/bot/difficulty/",
async (url, info, sessionID, output) => await botCallbacks.GetBotDifficulty(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/settings/bot/difficulties",
async (url, info, sessionID, output) =>
await botCallbacks.GetAllBotDifficulties(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/settings/bot/maxCap",
async (url, info, sessionID, output) => await botCallbacks.GetBotCap(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/settings/bot/getBotBehaviours/",
async (url, info, sessionID, output) => await botCallbacks.GetBotBehaviours()
),
]
) { }
}
public class BotDynamicRouter(JsonUtil jsonUtil, BotCallbacks botCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/bot/limit/",
async (url, info, sessionID, output) => await botCallbacks.GetBotLimit(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/bot/difficulty/",
async (url, info, sessionID, output) => await botCallbacks.GetBotDifficulty(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/bot/difficulties",
async (url, info, sessionID, output) => await botCallbacks.GetAllBotDifficulties(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/bot/maxCap",
async (url, info, sessionID, output) => await botCallbacks.GetBotCap(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/bot/getBotBehaviours/",
async (url, info, sessionID, output) => await botCallbacks.GetBotBehaviours()
),
]
) { }
@@ -7,16 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class BundleDynamicRouter : DynamicRouter
{
public BundleDynamicRouter(JsonUtil jsonUtil, BundleCallbacks bundleCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/files/bundle",
async (url, info, sessionID, output) => await bundleCallbacks.GetBundle(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class BundleDynamicRouter(JsonUtil jsonUtil, BundleCallbacks bundleCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/files/bundle",
async (url, info, sessionID, output) => await bundleCallbacks.GetBundle(url, info, sessionID)
),
]
) { }
@@ -7,17 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class CustomizationDynamicRouter : DynamicRouter
{
public CustomizationDynamicRouter(JsonUtil jsonUtil, CustomizationCallbacks customizationCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/trading/customization/",
async (url, info, sessionID, output) =>
await customizationCallbacks.GetTraderSuits(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class CustomizationDynamicRouter(JsonUtil jsonUtil, CustomizationCallbacks customizationCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/trading/customization/",
async (url, info, sessionID, output) => await customizationCallbacks.GetTraderSuits(url, info, sessionID)
),
]
) { }
@@ -7,24 +7,21 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class DataDynamicRouter : DynamicRouter
{
public DataDynamicRouter(JsonUtil jsonUtil, DataCallbacks dataCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/menu/locale/",
async (url, info, sessionID, output) => await dataCallbacks.GetLocalesMenu(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/locale/",
async (url, info, sessionID, output) => await dataCallbacks.GetLocalesGlobal(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/items/prices/",
async (url, info, sessionID, output) => await dataCallbacks.GetItemPrices(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class DataDynamicRouter(JsonUtil jsonUtil, DataCallbacks dataCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/menu/locale/",
async (url, info, sessionID, output) => await dataCallbacks.GetLocalesMenu(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/locale/",
async (url, info, sessionID, output) => await dataCallbacks.GetLocalesGlobal(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/items/prices/",
async (url, info, sessionID, output) => await dataCallbacks.GetItemPrices(url, info, sessionID)
),
]
) { }
@@ -1,19 +1,17 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class HttpDynamicRouter : DynamicRouter
{
public HttpDynamicRouter(ImageRouter imageRouter, JsonUtil jsonUtil)
: base(
jsonUtil,
[
new RouteAction(".jpg", async (_, _, _, _) => await imageRouter.GetImage()),
new RouteAction(".png", async (_, _, _, _) => await imageRouter.GetImage()),
new RouteAction(".ico", async (_, _, _, _) => await imageRouter.GetImage()),
]
) { }
}
public class HttpDynamicRouter(ImageRouter imageRouter, JsonUtil jsonUtil)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(".jpg", async (_, _, _, _) => await imageRouter.GetImage()),
new RouteAction<EmptyRequestData>(".png", async (_, _, _, _) => await imageRouter.GetImage()),
new RouteAction<EmptyRequestData>(".ico", async (_, _, _, _) => await imageRouter.GetImage()),
]
) { }
@@ -7,21 +7,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class InraidDynamicRouter : DynamicRouter
public class InraidDynamicRouter(JsonUtil jsonUtil, InraidCallbacks inraidCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<RegisterPlayerRequestData>(
"/client/location/getLocalloot",
async (url, info, sessionID, output) => await inraidCallbacks.RegisterPlayer(url, info, sessionID)
),
]
)
{
public InraidDynamicRouter(JsonUtil jsonUtil, InraidCallbacks inraidCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/location/getLocalloot",
async (url, info, sessionID, output) =>
await inraidCallbacks.RegisterPlayer(url, info as RegisterPlayerRequestData, sessionID),
typeof(RegisterPlayerRequestData)
),
]
) { }
public override string GetTopLevelRoute()
{
return "spt-name";
@@ -5,11 +5,8 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class LocationDynamicRouter : DynamicRouter
public class LocationDynamicRouter(JsonUtil jsonUtil) : DynamicRouter(jsonUtil, [])
{
public LocationDynamicRouter(JsonUtil jsonUtil)
: base(jsonUtil, []) { }
public override string GetTopLevelRoute()
{
return "spt-loot";
@@ -1,27 +1,31 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Callbacks;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class NotifierDynamicRouter : DynamicRouter
{
public NotifierDynamicRouter(JsonUtil jsonUtil, NotifierCallbacks notifierCallbacks)
: base(
jsonUtil,
[
new RouteAction("/?last_id", async (url, info, sessionID, _) => await notifierCallbacks.Notify(url, info, sessionID)),
new RouteAction("/notifierServer", async (url, info, sessionID, _) => await notifierCallbacks.Notify(url, info, sessionID)),
new RouteAction(
"/push/notifier/get/",
async (url, info, sessionID, _) => await notifierCallbacks.GetNotifier(url, info, sessionID)
),
new RouteAction(
"/push/notifier/get/",
async (url, info, sessionID, _) => await notifierCallbacks.GetNotifier(url, info, sessionID)
),
]
) { }
}
public class NotifierDynamicRouter(JsonUtil jsonUtil, NotifierCallbacks notifierCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/?last_id",
async (url, info, sessionID, _) => await notifierCallbacks.Notify(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/notifierServer",
async (url, info, sessionID, _) => await notifierCallbacks.Notify(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/push/notifier/get/",
async (url, info, sessionID, _) => await notifierCallbacks.GetNotifier(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/push/notifier/get/",
async (url, info, sessionID, _) => await notifierCallbacks.GetNotifier(url, info, sessionID)
),
]
) { }
@@ -7,20 +7,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Dynamic;
[Injectable]
public class TraderDynamicRouter : DynamicRouter
{
public TraderDynamicRouter(JsonUtil jsonUtil, TraderCallbacks traderCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/trading/api/getTrader/",
async (url, info, sessionID, output) => await traderCallbacks.GetTrader(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/trading/api/getTraderAssort/",
async (url, info, sessionID, output) => await traderCallbacks.GetAssort(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class TraderDynamicRouter(JsonUtil jsonUtil, TraderCallbacks traderCallbacks)
: DynamicRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/trading/api/getTrader/",
async (url, info, sessionID, output) => await traderCallbacks.GetTrader(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/trading/api/getTraderAssort/",
async (url, info, sessionID, output) => await traderCallbacks.GetAssort(url, info, sessionID)
),
]
) { }
@@ -6,41 +6,16 @@ using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Routers;
[Injectable]
public class HttpRouter
public class HttpRouter(IEnumerable<StaticRouter> staticRouters, IEnumerable<DynamicRouter> dynamicRoutes)
{
protected readonly IEnumerable<DynamicRouter> _dynamicRoutes;
protected readonly IEnumerable<StaticRouter> _staticRouters;
public HttpRouter(IEnumerable<StaticRouter> staticRouters, IEnumerable<DynamicRouter> dynamicRoutes)
{
_staticRouters = staticRouters;
_dynamicRoutes = dynamicRoutes;
}
/*
protected groupBy<T>(list: T[], keyGetter: (t: T) => string): Map<string, T[]> {
const map: Map<string, T[]> = new Map();
for (const item of list) {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
}
return map;
}
*/
public async ValueTask<string?> GetResponse(HttpRequest req, MongoId sessionID, string? body)
{
var wrapper = new ResponseWrapper("");
var handled = await HandleRoute(req, sessionID, wrapper, _staticRouters, false, body);
var handled = await HandleRoute(req, sessionID, wrapper, staticRouters, false, body);
if (!handled)
{
await HandleRoute(req, sessionID, wrapper, _dynamicRoutes, true, body);
await HandleRoute(req, sessionID, wrapper, dynamicRoutes, true, body);
}
return wrapper.Output;
@@ -7,21 +7,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class AchievementStaticRouter : StaticRouter
{
public AchievementStaticRouter(JsonUtil jsonUtil, AchievementCallbacks achievementCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/achievement/list",
async (url, info, sessionID, output) =>
await achievementCallbacks.GetAchievements(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/achievement/statistic",
async (url, info, sessionID, output) => await achievementCallbacks.Statistic(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class AchievementStaticRouter(JsonUtil jsonUtil, AchievementCallbacks achievementCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/achievement/list",
async (url, info, sessionID, output) => await achievementCallbacks.GetAchievements(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/achievement/statistic",
async (url, info, sessionID, output) => await achievementCallbacks.Statistic(url, info, sessionID)
),
]
) { }
@@ -7,18 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class BotStaticRouter : StaticRouter
{
public BotStaticRouter(JsonUtil jsonUtil, BotCallbacks botCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/game/bot/generate",
async (url, info, sessionID, outout) =>
await botCallbacks.GenerateBots(url, info as GenerateBotsRequestData, sessionID),
typeof(GenerateBotsRequestData)
),
]
) { }
}
public class BotStaticRouter(JsonUtil jsonUtil, BotCallbacks botCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<GenerateBotsRequestData>(
"/client/game/bot/generate",
async (url, info, sessionID, outout) => await botCallbacks.GenerateBots(url, info, sessionID)
),
]
) { }
@@ -9,40 +9,29 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class BuildStaticRouter : StaticRouter
{
public BuildStaticRouter(JsonUtil jsonUtil, BuildsCallbacks buildsCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/builds/list",
async (url, info, sessionID, output) => await buildsCallbacks.GetBuilds(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/builds/magazine/save",
async (url, info, sessionID, output) =>
await buildsCallbacks.CreateMagazineTemplate(url, info as SetMagazineRequest, sessionID),
typeof(SetMagazineRequest)
),
new RouteAction(
"/client/builds/weapon/save",
async (url, info, sessionID, output) =>
await buildsCallbacks.SetWeapon(url, info as PresetBuildActionRequestData, sessionID),
typeof(PresetBuildActionRequestData)
),
new RouteAction(
"/client/builds/equipment/save",
async (url, info, sessionID, output) =>
await buildsCallbacks.SetEquipment(url, info as PresetBuildActionRequestData, sessionID),
typeof(PresetBuildActionRequestData)
),
new RouteAction(
"/client/builds/delete",
async (url, info, sessionID, output) =>
await buildsCallbacks.DeleteBuild(url, info as RemoveBuildRequestData, sessionID),
typeof(RemoveBuildRequestData)
),
]
) { }
}
public class BuildStaticRouter(JsonUtil jsonUtil, BuildsCallbacks buildsCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/builds/list",
async (url, info, sessionID, output) => await buildsCallbacks.GetBuilds(url, info, sessionID)
),
new RouteAction<SetMagazineRequest>(
"/client/builds/magazine/save",
async (url, info, sessionID, output) => await buildsCallbacks.CreateMagazineTemplate(url, info, sessionID)
),
new RouteAction<PresetBuildActionRequestData>(
"/client/builds/weapon/save",
async (url, info, sessionID, output) => await buildsCallbacks.SetWeapon(url, info, sessionID)
),
new RouteAction<PresetBuildActionRequestData>(
"/client/builds/equipment/save",
async (url, info, sessionID, output) => await buildsCallbacks.SetEquipment(url, info, sessionID)
),
new RouteAction<RemoveBuildRequestData>(
"/client/builds/delete",
async (url, info, sessionID, output) => await buildsCallbacks.DeleteBuild(url, info, sessionID)
),
]
) { }
@@ -7,16 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class BundleStaticRouter : StaticRouter
{
public BundleStaticRouter(JsonUtil jsonUtil, BundleCallbacks bundleCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/singleplayer/bundles",
async (url, info, sessionID, output) => await bundleCallbacks.GetBundles(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class BundleStaticRouter(JsonUtil jsonUtil, BundleCallbacks bundleCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/singleplayer/bundles",
async (url, info, sessionID, output) => await bundleCallbacks.GetBundles(url, info, sessionID)
),
]
) { }
@@ -1,28 +1,28 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Callbacks;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Spt.Logging;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class ClientLogStaticRouter : StaticRouter
{
public ClientLogStaticRouter(JsonUtil jsonUtil, ClientLogCallbacks clientLogCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/singleplayer/log",
async (url, info, sessionID, output) => await clientLogCallbacks.ClientLog(url, info as ClientLogRequest, sessionID),
typeof(ClientLogRequest)
),
new RouteAction("/singleplayer/release", async (url, info, sessionID, output) => await clientLogCallbacks.ReleaseNotes()),
new RouteAction(
"/singleplayer/enableBSGlogging",
async (url, info, sessionID, output) => await clientLogCallbacks.BsgLogging()
),
]
) { }
}
public class ClientLogStaticRouter(JsonUtil jsonUtil, ClientLogCallbacks clientLogCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<ClientLogRequest>(
"/singleplayer/log",
async (url, info, sessionID, output) => await clientLogCallbacks.ClientLog(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/release",
async (url, info, sessionID, output) => await clientLogCallbacks.ReleaseNotes()
),
new RouteAction<EmptyRequestData>(
"/singleplayer/enableBSGlogging",
async (url, info, sessionID, output) => await clientLogCallbacks.BsgLogging()
),
]
) { }
@@ -7,27 +7,21 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class CustomizationStaticRouter : StaticRouter
{
public CustomizationStaticRouter(JsonUtil jsonUtil, CustomizationCallbacks customizationCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/trading/customization/storage",
async (url, info, sessionID, output) =>
await customizationCallbacks.GetCustomisationUnlocks(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/hideout/customization/offer/list",
async (url, info, sessionID, output) =>
await customizationCallbacks.GetHideoutCustomisation(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/customization/storage",
async (url, info, sessionID, output) =>
await customizationCallbacks.GetStorage(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class CustomizationStaticRouter(JsonUtil jsonUtil, CustomizationCallbacks customizationCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/trading/customization/storage",
async (url, info, sessionID, output) => await customizationCallbacks.GetCustomisationUnlocks(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/hideout/customization/offer/list",
async (url, info, sessionID, output) => await customizationCallbacks.GetHideoutCustomisation(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/customization/storage",
async (url, info, sessionID, output) => await customizationCallbacks.GetStorage(url, info, sessionID)
),
]
) { }
@@ -7,60 +7,53 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class DataStaticRouter : StaticRouter
{
public DataStaticRouter(JsonUtil jsonUtil, DataCallbacks dataCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/settings",
async (url, info, sessionID, output) => await dataCallbacks.GetSettings(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/globals",
async (url, info, sessionID, output) => await dataCallbacks.GetGlobals(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/items",
async (url, info, sessionID, output) => await dataCallbacks.GetTemplateItems(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/handbook/templates",
async (url, info, sessionID, output) =>
await dataCallbacks.GetTemplateHandbook(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/customization",
async (url, info, sessionID, output) => await dataCallbacks.GetTemplateSuits(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/account/customization",
async (url, info, sessionID, output) =>
await dataCallbacks.GetTemplateCharacter(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/hideout/production/recipes",
async (url, info, sessionID, output) =>
await dataCallbacks.GetHideoutProduction(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/hideout/settings",
async (url, info, sessionID, output) => await dataCallbacks.GetHideoutSettings(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/hideout/areas",
async (url, info, sessionID, output) => await dataCallbacks.GetHideoutAreas(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/languages",
async (url, info, sessionID, output) =>
await dataCallbacks.GetLocalesLanguages(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/hideout/qte/list",
async (url, info, sessionID, output) => await dataCallbacks.GetQteList(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class DataStaticRouter(JsonUtil jsonUtil, DataCallbacks dataCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/settings",
async (url, info, sessionID, output) => await dataCallbacks.GetSettings(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/globals",
async (url, info, sessionID, output) => await dataCallbacks.GetGlobals(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/items",
async (url, info, sessionID, output) => await dataCallbacks.GetTemplateItems(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/handbook/templates",
async (url, info, sessionID, output) => await dataCallbacks.GetTemplateHandbook(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/customization",
async (url, info, sessionID, output) => await dataCallbacks.GetTemplateSuits(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/account/customization",
async (url, info, sessionID, output) => await dataCallbacks.GetTemplateCharacter(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/hideout/production/recipes",
async (url, info, sessionID, output) => await dataCallbacks.GetHideoutProduction(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/hideout/settings",
async (url, info, sessionID, output) => await dataCallbacks.GetHideoutSettings(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/hideout/areas",
async (url, info, sessionID, output) => await dataCallbacks.GetHideoutAreas(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/languages",
async (url, info, sessionID, output) => await dataCallbacks.GetLocalesLanguages(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/hideout/qte/list",
async (url, info, sessionID, output) => await dataCallbacks.GetQteList(url, info, sessionID)
),
]
) { }
@@ -9,157 +9,113 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class DialogStaticRouter : StaticRouter
{
public DialogStaticRouter(JsonUtil jsonUtil, DialogueCallbacks dialogueCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/chatServer/list",
async (url, info, sessionID, output) =>
await dialogueCallbacks.GetChatServerList(url, info as GetChatServerListRequestData, sessionID),
typeof(GetChatServerListRequestData)
),
new RouteAction(
"/client/mail/dialog/list",
async (url, info, sessionID, output) =>
await dialogueCallbacks.GetMailDialogList(url, info as GetMailDialogListRequestData, sessionID),
typeof(GetMailDialogListRequestData)
),
new RouteAction(
"/client/mail/dialog/view",
async (url, info, sessionID, output) =>
await dialogueCallbacks.GetMailDialogView(url, info as GetMailDialogViewRequestData, sessionID),
typeof(GetMailDialogViewRequestData)
),
new RouteAction(
"/client/mail/dialog/info",
async (url, info, sessionID, output) =>
await dialogueCallbacks.GetMailDialogInfo(url, info as GetMailDialogInfoRequestData, sessionID),
typeof(GetMailDialogInfoRequestData)
),
new RouteAction(
"/client/mail/dialog/remove",
async (url, info, sessionID, output) =>
await dialogueCallbacks.RemoveDialog(url, info as RemoveDialogRequestData, sessionID),
typeof(RemoveDialogRequestData)
),
new RouteAction(
"/client/mail/dialog/pin",
async (url, info, sessionID, output) => await dialogueCallbacks.PinDialog(url, info as PinDialogRequestData, sessionID),
typeof(PinDialogRequestData)
),
new RouteAction(
"/client/mail/dialog/unpin",
async (url, info, sessionID, output) =>
await dialogueCallbacks.UnpinDialog(url, info as PinDialogRequestData, sessionID),
typeof(PinDialogRequestData)
),
new RouteAction(
"/client/mail/dialog/read",
async (url, info, sessionID, output) =>
await dialogueCallbacks.SetRead(url, info as SetDialogReadRequestData, sessionID),
typeof(SetDialogReadRequestData)
),
new RouteAction(
"/client/mail/dialog/getAllAttachments",
async (url, info, sessionID, output) =>
await dialogueCallbacks.GetAllAttachments(url, info as GetAllAttachmentsRequestData, sessionID),
typeof(GetAllAttachmentsRequestData)
),
new RouteAction(
"/client/mail/msg/send",
async (url, info, sessionID, output) => await dialogueCallbacks.SendMessage(url, info as SendMessageRequest, sessionID),
typeof(SendMessageRequest)
),
new RouteAction(
"/client/mail/dialog/clear",
async (url, info, sessionID, output) =>
await dialogueCallbacks.ClearMail(url, info as ClearMailMessageRequest, sessionID),
typeof(ClearMailMessageRequest)
),
new RouteAction(
"/client/mail/dialog/group/create",
async (url, info, sessionID, output) =>
await dialogueCallbacks.CreateGroupMail(url, info as CreateGroupMailRequest, sessionID),
typeof(CreateGroupMailRequest)
),
new RouteAction(
"/client/mail/dialog/group/owner/change",
async (url, info, sessionID, output) =>
await dialogueCallbacks.ChangeMailGroupOwner(url, info as ChangeGroupMailOwnerRequest, sessionID),
typeof(ChangeGroupMailOwnerRequest)
),
new RouteAction(
"/client/mail/dialog/group/users/add",
async (url, info, sessionID, output) =>
await dialogueCallbacks.AddUserToMail(url, info as AddUserGroupMailRequest, sessionID),
typeof(AddUserGroupMailRequest)
),
new RouteAction(
"/client/mail/dialog/group/users/remove",
async (url, info, sessionID, output) =>
await dialogueCallbacks.RemoveUserFromMail(url, info as RemoveUserGroupMailRequest, sessionID),
typeof(RemoveUserGroupMailRequest)
),
new RouteAction(
"/client/friend/list",
async (url, info, sessionID, output) => await dialogueCallbacks.GetFriendList(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/friend/request/list/outbox",
async (url, info, sessionID, output) => await dialogueCallbacks.ListOutbox(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/friend/request/list/inbox",
async (url, info, sessionID, output) => await dialogueCallbacks.ListInbox(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/friend/request/send",
async (url, info, sessionID, output) =>
await dialogueCallbacks.SendFriendRequest(url, info as FriendRequestData, sessionID),
typeof(FriendRequestData)
),
new RouteAction(
"/client/friend/request/accept-all",
async (url, info, sessionID, output) =>
await dialogueCallbacks.AcceptAllFriendRequests(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/friend/request/accept",
async (url, info, sessionID, output) =>
await dialogueCallbacks.AcceptFriendRequest(url, info as AcceptFriendRequestData, sessionID),
typeof(AcceptFriendRequestData)
),
new RouteAction(
"/client/friend/request/decline",
async (url, info, sessionID, output) =>
await dialogueCallbacks.DeclineFriendRequest(url, info as DeclineFriendRequestData, sessionID),
typeof(DeclineFriendRequestData)
),
new RouteAction(
"/client/friend/request/cancel",
async (url, info, sessionID, output) =>
await dialogueCallbacks.CancelFriendRequest(url, info as CancelFriendRequestData, sessionID),
typeof(CancelFriendRequestData)
),
new RouteAction(
"/client/friend/delete",
async (url, info, sessionID, output) =>
await dialogueCallbacks.DeleteFriend(url, info as DeleteFriendRequest, sessionID),
typeof(DeleteFriendRequest)
),
new RouteAction(
"/client/friend/ignore/set",
async (url, info, sessionID, output) => await dialogueCallbacks.IgnoreFriend(url, info as UIDRequestData, sessionID),
typeof(UIDRequestData)
),
new RouteAction(
"/client/friend/ignore/remove",
async (url, info, sessionID, output) => await dialogueCallbacks.UnIgnoreFriend(url, info as UIDRequestData, sessionID),
typeof(UIDRequestData)
),
]
) { }
}
public class DialogStaticRouter(JsonUtil jsonUtil, DialogueCallbacks dialogueCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<GetChatServerListRequestData>(
"/client/chatServer/list",
async (url, info, sessionID, output) => await dialogueCallbacks.GetChatServerList(url, info, sessionID)
),
new RouteAction<GetMailDialogListRequestData>(
"/client/mail/dialog/list",
async (url, info, sessionID, output) => await dialogueCallbacks.GetMailDialogList(url, info, sessionID)
),
new RouteAction<GetMailDialogViewRequestData>(
"/client/mail/dialog/view",
async (url, info, sessionID, output) => await dialogueCallbacks.GetMailDialogView(url, info, sessionID)
),
new RouteAction<GetMailDialogInfoRequestData>(
"/client/mail/dialog/info",
async (url, info, sessionID, output) => await dialogueCallbacks.GetMailDialogInfo(url, info, sessionID)
),
new RouteAction<RemoveDialogRequestData>(
"/client/mail/dialog/remove",
async (url, info, sessionID, output) => await dialogueCallbacks.RemoveDialog(url, info, sessionID)
),
new RouteAction<PinDialogRequestData>(
"/client/mail/dialog/pin",
async (url, info, sessionID, output) => await dialogueCallbacks.PinDialog(url, info, sessionID)
),
new RouteAction<PinDialogRequestData>(
"/client/mail/dialog/unpin",
async (url, info, sessionID, output) => await dialogueCallbacks.UnpinDialog(url, info, sessionID)
),
new RouteAction<SetDialogReadRequestData>(
"/client/mail/dialog/read",
async (url, info, sessionID, output) => await dialogueCallbacks.SetRead(url, info, sessionID)
),
new RouteAction<GetAllAttachmentsRequestData>(
"/client/mail/dialog/getAllAttachments",
async (url, info, sessionID, output) => await dialogueCallbacks.GetAllAttachments(url, info, sessionID)
),
new RouteAction<SendMessageRequest>(
"/client/mail/msg/send",
async (url, info, sessionID, output) => await dialogueCallbacks.SendMessage(url, info, sessionID)
),
new RouteAction<ClearMailMessageRequest>(
"/client/mail/dialog/clear",
async (url, info, sessionID, output) => await dialogueCallbacks.ClearMail(url, info, sessionID)
),
new RouteAction<CreateGroupMailRequest>(
"/client/mail/dialog/group/create",
async (url, info, sessionID, output) => await dialogueCallbacks.CreateGroupMail(url, info, sessionID)
),
new RouteAction<ChangeGroupMailOwnerRequest>(
"/client/mail/dialog/group/owner/change",
async (url, info, sessionID, output) => await dialogueCallbacks.ChangeMailGroupOwner(url, info, sessionID)
),
new RouteAction<AddUserGroupMailRequest>(
"/client/mail/dialog/group/users/add",
async (url, info, sessionID, output) => await dialogueCallbacks.AddUserToMail(url, info, sessionID)
),
new RouteAction<RemoveUserGroupMailRequest>(
"/client/mail/dialog/group/users/remove",
async (url, info, sessionID, output) => await dialogueCallbacks.RemoveUserFromMail(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/friend/list",
async (url, info, sessionID, output) => await dialogueCallbacks.GetFriendList(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/friend/request/list/outbox",
async (url, info, sessionID, output) => await dialogueCallbacks.ListOutbox(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/friend/request/list/inbox",
async (url, info, sessionID, output) => await dialogueCallbacks.ListInbox(url, info, sessionID)
),
new RouteAction<FriendRequestData>(
"/client/friend/request/send",
async (url, info, sessionID, output) => await dialogueCallbacks.SendFriendRequest(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/friend/request/accept-all",
async (url, info, sessionID, output) => await dialogueCallbacks.AcceptAllFriendRequests(url, info, sessionID)
),
new RouteAction<AcceptFriendRequestData>(
"/client/friend/request/accept",
async (url, info, sessionID, output) => await dialogueCallbacks.AcceptFriendRequest(url, info, sessionID)
),
new RouteAction<DeclineFriendRequestData>(
"/client/friend/request/decline",
async (url, info, sessionID, output) => await dialogueCallbacks.DeclineFriendRequest(url, info, sessionID)
),
new RouteAction<CancelFriendRequestData>(
"/client/friend/request/cancel",
async (url, info, sessionID, output) => await dialogueCallbacks.CancelFriendRequest(url, info, sessionID)
),
new RouteAction<DeleteFriendRequest>(
"/client/friend/delete",
async (url, info, sessionID, output) => await dialogueCallbacks.DeleteFriend(url, info, sessionID)
),
new RouteAction<UIDRequestData>(
"/client/friend/ignore/set",
async (url, info, sessionID, output) => await dialogueCallbacks.IgnoreFriend(url, info, sessionID)
),
new RouteAction<UIDRequestData>(
"/client/friend/ignore/remove",
async (url, info, sessionID, output) => await dialogueCallbacks.UnIgnoreFriend(url, info, sessionID)
),
]
) { }
@@ -9,100 +9,81 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class GameStaticRouter : StaticRouter
{
public GameStaticRouter(JsonUtil jsonUtil, GameCallbacks gameCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/game/config",
async (url, info, sessionID, output) =>
await gameCallbacks.GetGameConfig(url, info as GameEmptyCrcRequestData, sessionID),
typeof(GameEmptyCrcRequestData)
),
new RouteAction(
"/client/putHWMetrics",
async (url, info, sessionID, output) => await gameCallbacks.PutHwMetrics(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/game/mode",
async (url, info, sessionID, output) => await gameCallbacks.GetGameMode(url, info as GameModeRequestData, sessionID),
typeof(GameModeRequestData)
),
new RouteAction(
"/client/server/list",
async (url, info, sessionID, output) => await gameCallbacks.GetServer(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/current",
async (url, info, sessionID, output) => await gameCallbacks.GetCurrentGroup(url, info as EmptyRequestData, sessionID),
typeof(GameModeRequestData)
),
new RouteAction(
"/client/game/version/validate",
async (url, info, sessionID, output) =>
await gameCallbacks.VersionValidate(url, info as VersionValidateRequestData, sessionID),
typeof(VersionValidateRequestData)
),
new RouteAction(
"/client/game/start",
async (url, info, sessionID, output) => await gameCallbacks.GameStart(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/game/logout",
async (url, info, sessionID, output) => await gameCallbacks.GameLogout(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/checkVersion",
async (url, info, sessionID, output) =>
await gameCallbacks.ValidateGameVersion(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/game/keepalive",
async (url, info, sessionID, output) => await gameCallbacks.GameKeepalive(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/settings/version",
async (url, info, sessionID, output) => await gameCallbacks.GetVersion(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/reports/lobby/send",
async (url, info, sessionID, output) => await gameCallbacks.ReportNickname(url, info as UIDRequestData, sessionID),
typeof(UIDRequestData)
),
new RouteAction(
"/client/report/send",
async (url, info, sessionID, output) => await gameCallbacks.ReportNickname(url, info as UIDRequestData, sessionID),
typeof(GameModeRequestData)
),
new RouteAction(
"/singleplayer/settings/getRaidTime",
async (url, info, sessionID, output) => await gameCallbacks.GetRaidTime(url, info as GetRaidTimeRequest, sessionID),
typeof(GetRaidTimeRequest)
),
new RouteAction(
"/client/survey",
async (url, info, sessionID, output) => await gameCallbacks.GetSurvey(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/survey/view",
async (url, info, sessionID, output) =>
await gameCallbacks.GetSurveyView(url, info as SendSurveyOpinionRequest, sessionID),
typeof(SendSurveyOpinionRequest)
),
new RouteAction(
"/client/survey/opinion",
async (url, info, sessionID, output) =>
await gameCallbacks.SendSurveyOpinion(url, info as SendSurveyOpinionRequest, sessionID),
typeof(SendSurveyOpinionRequest)
),
new RouteAction(
"/singleplayer/clientmods",
async (url, info, sessionID, output) =>
await gameCallbacks.ReceiveClientMods(url, info as SendClientModsRequest, sessionID),
typeof(SendClientModsRequest)
),
]
) { }
}
public class GameStaticRouter(JsonUtil jsonUtil, GameCallbacks gameCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/game/config",
async (url, info, sessionID, output) => await gameCallbacks.GetGameConfig(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/putHWMetrics",
async (url, info, sessionID, output) => await gameCallbacks.PutHwMetrics(url, info, sessionID)
),
new RouteAction<GameModeRequestData>(
"/client/game/mode",
async (url, info, sessionID, output) => await gameCallbacks.GetGameMode(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/server/list",
async (url, info, sessionID, output) => await gameCallbacks.GetServer(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/current",
async (url, info, sessionID, output) => await gameCallbacks.GetCurrentGroup(url, info, sessionID)
),
new RouteAction<VersionValidateRequestData>(
"/client/game/version/validate",
async (url, info, sessionID, output) => await gameCallbacks.VersionValidate(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/game/start",
async (url, info, sessionID, output) => await gameCallbacks.GameStart(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/game/logout",
async (url, info, sessionID, output) => await gameCallbacks.GameLogout(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/checkVersion",
async (url, info, sessionID, output) => await gameCallbacks.ValidateGameVersion(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/game/keepalive",
async (url, info, sessionID, output) => await gameCallbacks.GameKeepalive(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/version",
async (url, info, sessionID, output) => await gameCallbacks.GetVersion(url, info, sessionID)
),
new RouteAction<UIDRequestData>(
"/client/reports/lobby/send",
async (url, info, sessionID, output) => await gameCallbacks.ReportNickname(url, info, sessionID)
),
new RouteAction<UIDRequestData>(
"/client/report/send",
async (url, info, sessionID, output) => await gameCallbacks.ReportNickname(url, info, sessionID)
),
new RouteAction<GetRaidTimeRequest>(
"/singleplayer/settings/getRaidTime",
async (url, info, sessionID, output) => await gameCallbacks.GetRaidTime(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/survey",
async (url, info, sessionID, output) => await gameCallbacks.GetSurvey(url, info, sessionID)
),
new RouteAction<SendSurveyOpinionRequest>(
"/client/survey/view",
async (url, info, sessionID, output) => await gameCallbacks.GetSurveyView(url, info, sessionID)
),
new RouteAction<SendSurveyOpinionRequest>(
"/client/survey/opinion",
async (url, info, sessionID, output) => await gameCallbacks.SendSurveyOpinion(url, info, sessionID)
),
new RouteAction<SendClientModsRequest>(
"/singleplayer/clientmods",
async (url, info, sessionID, output) => await gameCallbacks.ReceiveClientMods(url, info, sessionID)
),
]
) { }
@@ -7,17 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class HealthStaticRouter : StaticRouter
{
public HealthStaticRouter(JsonUtil jsonUtil, HealthCallbacks healthCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/hideout/workout",
async (url, info, sessionID, output) => await healthCallbacks.HandleWorkoutEffects(url, info as WorkoutData, sessionID),
typeof(WorkoutData)
),
]
) { }
}
public class HealthStaticRouter(JsonUtil jsonUtil, HealthCallbacks healthCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<WorkoutData>(
"/client/hideout/workout",
async (url, info, sessionID, output) => await healthCallbacks.HandleWorkoutEffects(url, info, sessionID)
),
]
) { }
@@ -8,30 +8,25 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class InraidStaticRouter : StaticRouter
{
public InraidStaticRouter(InraidCallbacks inRaidCallbacks, JsonUtil jsonUtil)
: base(
jsonUtil,
[
new RouteAction(
"/raid/profile/scavsave",
async (url, info, sessionID, output) => await inRaidCallbacks.SaveProgress(url, info as ScavSaveRequestData, sessionID),
typeof(ScavSaveRequestData)
),
new RouteAction(
"/singleplayer/settings/raid/menu",
async (url, info, sessionID, output) => await inRaidCallbacks.GetRaidMenuSettings()
),
new RouteAction(
"/singleplayer/scav/traitorscavhostile",
async (url, info, sessionID, output) =>
await inRaidCallbacks.GetTraitorScavHostileChance(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/bosstypes",
async (url, info, sessionID, output) => await inRaidCallbacks.GetBossTypes(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class InraidStaticRouter(InraidCallbacks inRaidCallbacks, JsonUtil jsonUtil)
: StaticRouter(
jsonUtil,
[
new RouteAction<ScavSaveRequestData>(
"/raid/profile/scavsave",
async (url, info, sessionID, output) => await inRaidCallbacks.SaveProgress(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/settings/raid/menu",
async (url, info, sessionID, output) => await inRaidCallbacks.GetRaidMenuSettings()
),
new RouteAction<EmptyRequestData>(
"/singleplayer/scav/traitorscavhostile",
async (url, info, sessionID, output) => await inRaidCallbacks.GetTraitorScavHostileChance(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/bosstypes",
async (url, info, sessionID, output) => await inRaidCallbacks.GetBossTypes(url, info, sessionID)
),
]
) { }
@@ -7,18 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class InsuranceStaticRouter : StaticRouter
{
public InsuranceStaticRouter(JsonUtil jsonUtil, InsuranceCallbacks insuranceCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/insurance/items/list/cost",
async (url, info, sessionID, output) =>
await insuranceCallbacks.GetInsuranceCost(url, info as GetInsuranceCostRequestData, sessionID),
typeof(GetInsuranceCostRequestData)
),
]
) { }
}
public class InsuranceStaticRouter(JsonUtil jsonUtil, InsuranceCallbacks insuranceCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<GetInsuranceCostRequestData>(
"/client/insurance/items/list/cost",
async (url, info, sessionID, output) => await insuranceCallbacks.GetInsuranceCost(url, info, sessionID)
),
]
) { }
@@ -7,18 +7,13 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class ItemEventStaticRouter : StaticRouter
{
public ItemEventStaticRouter(JsonUtil jsonUtil, ItemEventCallbacks itemEventCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/game/profile/items/moving",
async (url, info, sessionID, output) =>
await itemEventCallbacks.HandleEvents(url, info as ItemEventRouterRequest, sessionID),
typeof(ItemEventRouterRequest)
),
]
) { }
}
public class ItemEventStaticRouter(JsonUtil jsonUtil, ItemEventCallbacks itemEventCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<ItemEventRouterRequest>(
"/client/game/profile/items/moving",
async (url, info, sessionID, output) => await itemEventCallbacks.HandleEvents(url, info, sessionID)
),
]
) { }
@@ -8,61 +8,55 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class LauncherStaticRouter : StaticRouter
{
public LauncherStaticRouter(LauncherCallbacks launcherCallbacks, JsonUtil jsonUtil)
: base(
jsonUtil,
[
new RouteAction("/launcher/ping", async (url, _, sessionID, _) => await launcherCallbacks.Ping(url, null, sessionID)),
new RouteAction("/launcher/server/connect", async (_, _, _, _) => await launcherCallbacks.Connect()),
new RouteAction(
"/launcher/profile/login",
async (url, info, sessionID, _) => await launcherCallbacks.Login(url, info as LoginRequestData, sessionID),
typeof(LoginRequestData)
),
new RouteAction(
"/launcher/profile/register",
async (url, info, sessionID, _) => await launcherCallbacks.Register(url, info as RegisterData, sessionID),
typeof(RegisterData)
),
new RouteAction(
"/launcher/profile/get",
async (url, info, sessionID, _) => await launcherCallbacks.Get(url, info as LoginRequestData, sessionID),
typeof(LoginRequestData)
),
new RouteAction(
"/launcher/profile/change/username",
async (url, info, sessionID, _) => await launcherCallbacks.ChangeUsername(url, info as ChangeRequestData, sessionID),
typeof(ChangeRequestData)
),
new RouteAction(
"/launcher/profile/change/password",
async (url, info, sessionID, _) => await launcherCallbacks.ChangePassword(url, info as ChangeRequestData, sessionID),
typeof(ChangeRequestData)
),
new RouteAction(
"/launcher/profile/change/wipe",
async (url, info, sessionID, _) => await launcherCallbacks.Wipe(url, info as RegisterData, sessionID),
typeof(RegisterData)
),
new RouteAction(
"/launcher/profile/remove",
async (url, info, sessionID, _) => await launcherCallbacks.RemoveProfile(url, info as RemoveProfileData, sessionID),
typeof(RemoveProfileData)
),
new RouteAction(
"/launcher/profile/compatibleTarkovVersion",
async (_, _, _, _) => await launcherCallbacks.GetCompatibleTarkovVersion()
),
new RouteAction("/launcher/server/version", async (_, _, _, _) => await launcherCallbacks.GetServerVersion()),
new RouteAction("/launcher/server/loadedServerMods", async (_, _, _, _) => await launcherCallbacks.GetLoadedServerMods()),
new RouteAction(
"/launcher/server/serverModsUsedByProfile",
async (url, info, sessionID, _) =>
await launcherCallbacks.GetServerModsProfileUsed(url, info as EmptyRequestData, sessionID),
typeof(EmptyRequestData)
),
]
) { }
}
public class LauncherStaticRouter(LauncherCallbacks launcherCallbacks, JsonUtil jsonUtil)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/launcher/ping",
async (url, info, sessionID, _) => await launcherCallbacks.Ping(url, info, sessionID)
),
new RouteAction<EmptyRequestData>("/launcher/server/connect", async (_, _, _, _) => await launcherCallbacks.Connect()),
new RouteAction<LoginRequestData>(
"/launcher/profile/login",
async (url, info, sessionID, _) => await launcherCallbacks.Login(url, info, sessionID)
),
new RouteAction<RegisterData>(
"/launcher/profile/register",
async (url, info, sessionID, _) => await launcherCallbacks.Register(url, info, sessionID)
),
new RouteAction<LoginRequestData>(
"/launcher/profile/get",
async (url, info, sessionID, _) => await launcherCallbacks.Get(url, info, sessionID)
),
new RouteAction<ChangeRequestData>(
"/launcher/profile/change/username",
async (url, info, sessionID, _) => await launcherCallbacks.ChangeUsername(url, info, sessionID)
),
new RouteAction<ChangeRequestData>(
"/launcher/profile/change/password",
async (url, info, sessionID, _) => await launcherCallbacks.ChangePassword(url, info, sessionID)
),
new RouteAction<RegisterData>(
"/launcher/profile/change/wipe",
async (url, info, sessionID, _) => await launcherCallbacks.Wipe(url, info, sessionID)
),
new RouteAction<RemoveProfileData>(
"/launcher/profile/remove",
async (url, info, sessionID, _) => await launcherCallbacks.RemoveProfile(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/launcher/profile/compatibleTarkovVersion",
async (_, _, _, _) => await launcherCallbacks.GetCompatibleTarkovVersion()
),
new RouteAction<EmptyRequestData>("/launcher/server/version", async (_, _, _, _) => await launcherCallbacks.GetServerVersion()),
new RouteAction<EmptyRequestData>(
"/launcher/server/loadedServerMods",
async (_, _, _, _) => await launcherCallbacks.GetLoadedServerMods()
),
new RouteAction<EmptyRequestData>(
"/launcher/server/serverModsUsedByProfile",
async (url, info, sessionID, _) => await launcherCallbacks.GetServerModsProfileUsed(url, info, sessionID)
),
]
) { }
@@ -1,44 +1,47 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Callbacks;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Launcher;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class LauncherV2StaticRouter : StaticRouter
{
public LauncherV2StaticRouter(LauncherV2Callbacks launcherV2Callbacks, JsonUtil jsonUtil)
: base(
jsonUtil,
[
new RouteAction("/launcher/v2/ping", async (url, _, sessionID, _) => await launcherV2Callbacks.Ping()),
new RouteAction("/launcher/v2/types", async (url, _, sessionID, _) => await launcherV2Callbacks.Types()),
new RouteAction(
"/launcher/v2/login",
async (url, info, sessionID, _) => await launcherV2Callbacks.Login(info as LoginRequestData),
typeof(LoginRequestData)
),
new RouteAction(
"/launcher/v2/register",
async (url, info, sessionID, _) => await launcherV2Callbacks.Register(info as RegisterData),
typeof(RegisterData)
),
new RouteAction(
"/launcher/v2/passwordChange",
async (url, info, sessionID, _) => await launcherV2Callbacks.PasswordChange(info as ChangeRequestData),
typeof(ChangeRequestData)
),
new RouteAction(
"/launcher/v2/remove",
async (url, info, sessionID, _) => await launcherV2Callbacks.Remove(info as LoginRequestData),
typeof(LoginRequestData)
),
new RouteAction("/launcher/v2/version", async (url, _, sessionID, _) => await launcherV2Callbacks.CompatibleVersion()),
new RouteAction("/launcher/v2/mods", async (url, _, sessionID, _) => await launcherV2Callbacks.Mods()),
new RouteAction("/launcher/v2/profiles", async (url, _, sessionID, _) => await launcherV2Callbacks.Profiles()),
new RouteAction("/launcher/v2/profile", async (url, _, sessionID, _) => await launcherV2Callbacks.Profile(sessionID)),
]
) { }
}
public class LauncherV2StaticRouter(LauncherV2Callbacks launcherV2Callbacks, JsonUtil jsonUtil)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>("/launcher/v2/ping", async (url, _, sessionID, _) => await launcherV2Callbacks.Ping()),
new RouteAction<EmptyRequestData>("/launcher/v2/types", async (url, _, sessionID, _) => await launcherV2Callbacks.Types()),
new RouteAction<LoginRequestData>(
"/launcher/v2/login",
async (url, info, sessionID, _) => await launcherV2Callbacks.Login(info)
),
new RouteAction<RegisterData>(
"/launcher/v2/register",
async (url, info, sessionID, _) => await launcherV2Callbacks.Register(info)
),
new RouteAction<ChangeRequestData>(
"/launcher/v2/passwordChange",
async (url, info, sessionID, _) => await launcherV2Callbacks.PasswordChange(info)
),
new RouteAction<LoginRequestData>(
"/launcher/v2/remove",
async (url, info, sessionID, _) => await launcherV2Callbacks.Remove(info)
),
new RouteAction<EmptyRequestData>(
"/launcher/v2/version",
async (url, _, sessionID, _) => await launcherV2Callbacks.CompatibleVersion()
),
new RouteAction<EmptyRequestData>("/launcher/v2/mods", async (url, _, sessionID, _) => await launcherV2Callbacks.Mods()),
new RouteAction<EmptyRequestData>(
"/launcher/v2/profiles",
async (url, _, sessionID, _) => await launcherV2Callbacks.Profiles()
),
new RouteAction<EmptyRequestData>(
"/launcher/v2/profile",
async (url, _, sessionID, _) => await launcherV2Callbacks.Profile(sessionID)
),
]
) { }
@@ -8,23 +8,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class LocationStaticRouter : StaticRouter
{
public LocationStaticRouter(JsonUtil jsonUtil, LocationCallbacks locationCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/locations",
async (url, info, sessionID, output) =>
await locationCallbacks.GetLocationData(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/airdrop/loot",
async (url, info, sessionID, output) =>
await locationCallbacks.GetAirdropLoot(url, info as GetAirdropLootRequest, sessionID),
typeof(GetAirdropLootRequest)
),
]
) { }
}
public class LocationStaticRouter(JsonUtil jsonUtil, LocationCallbacks locationCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/locations",
async (url, info, sessionID, output) => await locationCallbacks.GetLocationData(url, info, sessionID)
),
new RouteAction<GetAirdropLootRequest>(
"/client/airdrop/loot",
async (url, info, sessionID, output) => await locationCallbacks.GetAirdropLoot(url, info, sessionID)
),
]
) { }
@@ -9,154 +9,121 @@ using static SPTarkov.Server.Core.Services.MatchLocationService;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class MatchStaticRouter : StaticRouter
{
public MatchStaticRouter(JsonUtil jsonUtil, MatchCallbacks matchCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/match/available",
async (url, info, sessionID, output) => await matchCallbacks.ServerAvailable(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/updatePing",
async (url, info, sessionID, output) => await matchCallbacks.UpdatePing(url, info as UpdatePingRequestData, sessionID),
typeof(UpdatePingRequestData)
),
new RouteAction(
"/client/match/join",
async (url, info, sessionID, output) => await matchCallbacks.JoinMatch(url, info as MatchGroupJoinRequest, sessionID),
typeof(MatchGroupJoinRequest)
),
new RouteAction(
"/client/match/exit",
async (url, info, sessionID, output) => await matchCallbacks.ExitMatch(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/delete",
async (url, info, sessionID, output) => await matchCallbacks.DeleteGroup(url, info as DeleteGroupRequest, sessionID)
),
new RouteAction(
"/client/match/group/leave",
async (url, info, sessionID, output) => await matchCallbacks.LeaveGroup(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/status",
async (url, info, sessionID, output) =>
await matchCallbacks.GetGroupStatus(url, info as MatchGroupStatusRequest, sessionID),
typeof(MatchGroupStatusRequest)
),
new RouteAction(
"/client/match/group/start_game",
async (url, info, sessionID, output) =>
await matchCallbacks.StartGameAsGroupLeader(url, info as MatchGroupStartGameRequest, sessionID),
typeof(MatchGroupStartGameRequest)
),
new RouteAction(
"/client/match/group/exit_from_menu",
async (url, info, sessionID, output) => await matchCallbacks.ExitFromMenu(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/current",
async (url, info, sessionID, output) => await matchCallbacks.GroupCurrent(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/looking/start",
async (url, info, sessionID, output) => await matchCallbacks.StartGroupSearch(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/looking/stop",
async (url, info, sessionID, output) => await matchCallbacks.StopGroupSearch(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/invite/send",
async (url, info, sessionID, output) =>
await matchCallbacks.SendGroupInvite(url, info as MatchGroupInviteSendRequest, sessionID),
typeof(MatchGroupInviteSendRequest)
),
new RouteAction(
"/client/match/group/invite/accept",
async (url, info, sessionID, output) =>
await matchCallbacks.AcceptGroupInvite(url, info as RequestIdRequest, sessionID),
typeof(RequestIdRequest)
),
new RouteAction(
"/client/match/group/invite/decline",
async (url, info, sessionID, output) =>
await matchCallbacks.DeclineGroupInvite(url, info as RequestIdRequest, sessionID),
typeof(RequestIdRequest)
),
new RouteAction(
"/client/match/group/invite/cancel",
async (url, info, sessionID, output) =>
await matchCallbacks.CancelGroupInvite(url, info as RequestIdRequest, sessionID),
typeof(RequestIdRequest)
),
new RouteAction(
"/client/match/group/invite/cancel-all",
async (url, info, sessionID, output) =>
await matchCallbacks.CancelAllGroupInvite(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/transfer",
async (url, info, sessionID, output) =>
await matchCallbacks.TransferGroup(url, info as MatchGroupTransferRequest, sessionID),
typeof(MatchGroupTransferRequest)
),
new RouteAction(
"/client/match/group/raid/ready",
async (url, info, sessionID, output) => await matchCallbacks.RaidReady(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/match/group/raid/not-ready",
async (url, info, sessionID, output) => await matchCallbacks.NotRaidReady(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/putMetrics",
async (url, info, sessionID, output) => await matchCallbacks.PutMetrics(url, info as PutMetricsRequestData, sessionID),
typeof(PutMetricsRequestData)
),
new RouteAction(
"/client/analytics/event-disconnect",
async (url, info, sessionID, output) =>
await matchCallbacks.EventDisconnect(url, info as PutMetricsRequestData, sessionID),
typeof(PutMetricsRequestData)
),
new RouteAction(
"/client/getMetricsConfig",
async (url, info, sessionID, output) => await matchCallbacks.GetMetrics(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/raid/configuration",
async (url, info, sessionID, output) =>
await matchCallbacks.GetRaidConfiguration(url, info as GetRaidConfigurationRequestData, sessionID),
typeof(GetRaidConfigurationRequestData)
),
new RouteAction(
"/client/raid/configuration-by-profile",
async (url, info, sessionID, output) =>
await matchCallbacks.GetConfigurationByProfile(url, info as GetRaidConfigurationRequestData, sessionID),
typeof(GetRaidConfigurationRequestData)
),
new RouteAction(
"/client/match/group/player/remove",
async (url, info, sessionID, output) =>
await matchCallbacks.RemovePlayerFromGroup(url, info as MatchGroupPlayerRemoveRequest, sessionID),
typeof(MatchGroupPlayerRemoveRequest)
),
new RouteAction(
"/client/match/local/start",
async (url, info, sessionID, output) =>
await matchCallbacks.StartLocalRaid(url, info as StartLocalRaidRequestData, sessionID),
typeof(StartLocalRaidRequestData)
),
new RouteAction(
"/client/match/local/end",
async (url, info, sessionID, output) =>
await matchCallbacks.EndLocalRaid(url, info as EndLocalRaidRequestData, sessionID),
typeof(EndLocalRaidRequestData)
),
]
) { }
}
public class MatchStaticRouter(JsonUtil jsonUtil, MatchCallbacks matchCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/match/available",
async (url, info, sessionID, output) => await matchCallbacks.ServerAvailable(url, info, sessionID)
),
new RouteAction<UpdatePingRequestData>(
"/client/match/updatePing",
async (url, info, sessionID, output) => await matchCallbacks.UpdatePing(url, info, sessionID)
),
new RouteAction<MatchGroupJoinRequest>(
"/client/match/join",
async (url, info, sessionID, output) => await matchCallbacks.JoinMatch(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/exit",
async (url, info, sessionID, output) => await matchCallbacks.ExitMatch(url, info, sessionID)
),
new RouteAction<DeleteGroupRequest>(
"/client/match/group/delete",
async (url, info, sessionID, output) => await matchCallbacks.DeleteGroup(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/leave",
async (url, info, sessionID, output) => await matchCallbacks.LeaveGroup(url, info, sessionID)
),
new RouteAction<MatchGroupStatusRequest>(
"/client/match/group/status",
async (url, info, sessionID, output) => await matchCallbacks.GetGroupStatus(url, info, sessionID)
),
new RouteAction<MatchGroupStartGameRequest>(
"/client/match/group/start_game",
async (url, info, sessionID, output) => await matchCallbacks.StartGameAsGroupLeader(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/exit_from_menu",
async (url, info, sessionID, output) => await matchCallbacks.ExitFromMenu(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/current",
async (url, info, sessionID, output) => await matchCallbacks.GroupCurrent(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/looking/start",
async (url, info, sessionID, output) => await matchCallbacks.StartGroupSearch(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/looking/stop",
async (url, info, sessionID, output) => await matchCallbacks.StopGroupSearch(url, info, sessionID)
),
new RouteAction<MatchGroupInviteSendRequest>(
"/client/match/group/invite/send",
async (url, info, sessionID, output) => await matchCallbacks.SendGroupInvite(url, info, sessionID)
),
new RouteAction<RequestIdRequest>(
"/client/match/group/invite/accept",
async (url, info, sessionID, output) => await matchCallbacks.AcceptGroupInvite(url, info, sessionID)
),
new RouteAction<RequestIdRequest>(
"/client/match/group/invite/decline",
async (url, info, sessionID, output) => await matchCallbacks.DeclineGroupInvite(url, info, sessionID)
),
new RouteAction<RequestIdRequest>(
"/client/match/group/invite/cancel",
async (url, info, sessionID, output) => await matchCallbacks.CancelGroupInvite(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/invite/cancel-all",
async (url, info, sessionID, output) => await matchCallbacks.CancelAllGroupInvite(url, info, sessionID)
),
new RouteAction<MatchGroupTransferRequest>(
"/client/match/group/transfer",
async (url, info, sessionID, output) => await matchCallbacks.TransferGroup(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/raid/ready",
async (url, info, sessionID, output) => await matchCallbacks.RaidReady(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/match/group/raid/not-ready",
async (url, info, sessionID, output) => await matchCallbacks.NotRaidReady(url, info, sessionID)
),
new RouteAction<PutMetricsRequestData>(
"/client/putMetrics",
async (url, info, sessionID, output) => await matchCallbacks.PutMetrics(url, info, sessionID)
),
new RouteAction<PutMetricsRequestData>(
"/client/analytics/event-disconnect",
async (url, info, sessionID, output) => await matchCallbacks.EventDisconnect(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/getMetricsConfig",
async (url, info, sessionID, output) => await matchCallbacks.GetMetrics(url, info, sessionID)
),
new RouteAction<GetRaidConfigurationRequestData>(
"/client/raid/configuration",
async (url, info, sessionID, output) => await matchCallbacks.GetRaidConfiguration(url, info, sessionID)
),
new RouteAction<GetRaidConfigurationRequestData>(
"/client/raid/configuration-by-profile",
async (url, info, sessionID, output) => await matchCallbacks.GetConfigurationByProfile(url, info, sessionID)
),
new RouteAction<MatchGroupPlayerRemoveRequest>(
"/client/match/group/player/remove",
async (url, info, sessionID, output) => await matchCallbacks.RemovePlayerFromGroup(url, info, sessionID)
),
new RouteAction<StartLocalRaidRequestData>(
"/client/match/local/start",
async (url, info, sessionID, output) => await matchCallbacks.StartLocalRaid(url, info, sessionID)
),
new RouteAction<EndLocalRaidRequestData>(
"/client/match/local/end",
async (url, info, sessionID, output) => await matchCallbacks.EndLocalRaid(url, info, sessionID)
),
]
) { }
@@ -8,22 +8,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class NotifierStaticRouter : StaticRouter
{
public NotifierStaticRouter(JsonUtil jsonUtil, NotifierCallbacks notifierCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/notifier/channel/create",
async (url, info, sessionID, output) =>
await notifierCallbacks.CreateNotifierChannel(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/game/profile/select",
async (url, info, sessionID, output) => await notifierCallbacks.SelectProfile(url, info as UIDRequestData, sessionID),
typeof(UIDRequestData)
),
]
) { }
}
public class NotifierStaticRouter(JsonUtil jsonUtil, NotifierCallbacks notifierCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/notifier/channel/create",
async (url, info, sessionID, output) => await notifierCallbacks.CreateNotifierChannel(url, info, sessionID)
),
new RouteAction<UIDRequestData>(
"/client/game/profile/select",
async (url, info, sessionID, output) => await notifierCallbacks.SelectProfile(url, info, sessionID)
),
]
) { }
@@ -8,22 +8,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class PrestigeStaticRouter : StaticRouter
{
public PrestigeStaticRouter(JsonUtil jsonUtil, PrestigeCallbacks prestigeCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/prestige/list",
async (url, info, sessionID, output) => await prestigeCallbacks.GetPrestige(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/prestige/obtain",
async (url, info, sessionID, output) =>
await prestigeCallbacks.ObtainPrestige(url, info as ObtainPrestigeRequestList, sessionID),
typeof(ObtainPrestigeRequestList)
),
]
) { }
}
public class PrestigeStaticRouter(JsonUtil jsonUtil, PrestigeCallbacks prestigeCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/prestige/list",
async (url, info, sessionID, output) => await prestigeCallbacks.GetPrestige(url, info, sessionID)
),
new RouteAction<ObtainPrestigeRequestList>(
"/client/prestige/obtain",
async (url, info, sessionID, output) => await prestigeCallbacks.ObtainPrestige(url, info, sessionID)
),
]
) { }
@@ -9,83 +9,61 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class ProfileStaticRouter : StaticRouter
{
public ProfileStaticRouter(ProfileCallbacks profileCallbacks, JsonUtil jsonUtil)
: base(
jsonUtil,
[
new RouteAction(
"/client/game/profile/create",
async (url, info, sessionID, output) =>
await profileCallbacks.CreateProfile(url, info as ProfileCreateRequestData, sessionID),
typeof(ProfileCreateRequestData)
),
new RouteAction(
"/client/game/profile/list",
async (url, info, sessionID, output) => await profileCallbacks.GetProfileData(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/game/profile/savage/regenerate",
async (url, info, sessionID, output) => await profileCallbacks.RegenerateScav(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/game/profile/voice/change",
async (url, info, sessionID, output) =>
await profileCallbacks.ChangeVoice(url, info as ProfileChangeVoiceRequestData, sessionID),
typeof(ProfileChangeVoiceRequestData)
),
new RouteAction(
"/client/game/profile/nickname/change",
async (url, info, sessionID, output) =>
await profileCallbacks.ChangeNickname(url, info as ProfileChangeNicknameRequestData, sessionID),
typeof(ProfileChangeNicknameRequestData)
),
new RouteAction(
"/client/game/profile/nickname/validate",
async (url, info, sessionID, output) =>
await profileCallbacks.ValidateNickname(url, info as ValidateNicknameRequestData, sessionID),
typeof(ValidateNicknameRequestData)
),
new RouteAction(
"/client/game/profile/nickname/reserved",
async (url, info, sessionID, output) =>
await profileCallbacks.GetReservedNickname(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/profile/status",
async (url, info, sessionID, output) =>
await profileCallbacks.GetProfileStatus(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/profile/view",
async (url, info, sessionID, output) =>
await profileCallbacks.GetOtherProfile(url, info as GetOtherProfileRequest, sessionID),
typeof(GetOtherProfileRequest)
),
new RouteAction(
"/client/profile/settings",
async (url, info, sessionID, output) =>
await profileCallbacks.GetProfileSettings(url, info as GetProfileSettingsRequest, sessionID),
typeof(GetProfileSettingsRequest)
),
new RouteAction(
"/client/game/profile/search",
async (url, info, sessionID, output) =>
await profileCallbacks.SearchProfiles(url, info as SearchProfilesRequestData, sessionID),
typeof(SearchProfilesRequestData)
),
new RouteAction(
"/launcher/profile/info",
async (url, info, sessionID, output) =>
await profileCallbacks.GetMiniProfile(url, info as GetMiniProfileRequestData, sessionID),
typeof(GetMiniProfileRequestData)
),
new RouteAction(
"/launcher/profiles",
async (url, info, sessionID, output) =>
await profileCallbacks.GetAllMiniProfiles(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class ProfileStaticRouter(ProfileCallbacks profileCallbacks, JsonUtil jsonUtil)
: StaticRouter(
jsonUtil,
[
new RouteAction<ProfileCreateRequestData>(
"/client/game/profile/create",
async (url, info, sessionID, output) => await profileCallbacks.CreateProfile(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/game/profile/list",
async (url, info, sessionID, output) => await profileCallbacks.GetProfileData(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/game/profile/savage/regenerate",
async (url, info, sessionID, output) => await profileCallbacks.RegenerateScav(url, info, sessionID)
),
new RouteAction<ProfileChangeVoiceRequestData>(
"/client/game/profile/voice/change",
async (url, info, sessionID, output) => await profileCallbacks.ChangeVoice(url, info, sessionID)
),
new RouteAction<ProfileChangeNicknameRequestData>(
"/client/game/profile/nickname/change",
async (url, info, sessionID, output) => await profileCallbacks.ChangeNickname(url, info, sessionID)
),
new RouteAction<ValidateNicknameRequestData>(
"/client/game/profile/nickname/validate",
async (url, info, sessionID, output) => await profileCallbacks.ValidateNickname(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/game/profile/nickname/reserved",
async (url, info, sessionID, output) => await profileCallbacks.GetReservedNickname(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/profile/status",
async (url, info, sessionID, output) => await profileCallbacks.GetProfileStatus(url, info, sessionID)
),
new RouteAction<GetOtherProfileRequest>(
"/client/profile/view",
async (url, info, sessionID, output) => await profileCallbacks.GetOtherProfile(url, info, sessionID)
),
new RouteAction<GetProfileSettingsRequest>(
"/client/profile/settings",
async (url, info, sessionID, output) => await profileCallbacks.GetProfileSettings(url, info, sessionID)
),
new RouteAction<SearchProfilesRequestData>(
"/client/game/profile/search",
async (url, info, sessionID, output) => await profileCallbacks.SearchProfiles(url, info, sessionID)
),
new RouteAction<GetMiniProfileRequestData>(
"/launcher/profile/info",
async (url, info, sessionID, output) => await profileCallbacks.GetMiniProfile(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/launcher/profiles",
async (url, info, sessionID, output) => await profileCallbacks.GetAllMiniProfiles(url, info, sessionID)
),
]
) { }
@@ -8,21 +8,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class QuestStaticRouter : StaticRouter
{
public QuestStaticRouter(JsonUtil jsonUtil, QuestCallbacks questCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/quest/list",
async (url, info, sessionID, output) => await questCallbacks.ListQuests(url, info as ListQuestsRequestData, sessionID),
typeof(ListQuestsRequestData)
),
new RouteAction(
"/client/repeatalbeQuests/activityPeriods",
async (url, info, sessionID, output) => await questCallbacks.ActivityPeriods(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class QuestStaticRouter(JsonUtil jsonUtil, QuestCallbacks questCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<ListQuestsRequestData>(
"/client/quest/list",
async (url, info, sessionID, output) => await questCallbacks.ListQuests(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/repeatalbeQuests/activityPeriods",
async (url, info, sessionID, output) => await questCallbacks.ActivityPeriods(url, info, sessionID)
),
]
) { }
@@ -8,50 +8,37 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class RagfairStaticRouter : StaticRouter
{
public RagfairStaticRouter(JsonUtil jsonUtil, RagfairCallbacks ragfairCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/ragfair/search",
async (url, info, sessionID, output) => await ragfairCallbacks.Search(url, info as SearchRequestData, sessionID),
typeof(SearchRequestData)
),
new RouteAction(
"/client/ragfair/find",
async (url, info, sessionID, output) => await ragfairCallbacks.Search(url, info as SearchRequestData, sessionID),
typeof(SearchRequestData)
),
new RouteAction(
"/client/ragfair/itemMarketPrice",
async (url, info, sessionID, output) =>
await ragfairCallbacks.GetMarketPrice(url, info as GetMarketPriceRequestData, sessionID),
typeof(GetMarketPriceRequestData)
),
new RouteAction(
"/client/ragfair/offerfees",
async (url, info, sessionID, output) =>
await ragfairCallbacks.StorePlayerOfferTaxAmount(url, info as StorePlayerOfferTaxAmountRequestData, sessionID),
typeof(StorePlayerOfferTaxAmountRequestData)
),
new RouteAction(
"/client/reports/ragfair/send",
async (url, info, sessionID, output) =>
await ragfairCallbacks.SendReport(url, info as SendRagfairReportRequestData, sessionID),
typeof(SendRagfairReportRequestData)
),
new RouteAction(
"/client/items/prices",
async (url, info, sessionID, output) => await ragfairCallbacks.GetFleaPrices(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/ragfair/offer/findbyid",
async (url, info, sessionID, output) =>
await ragfairCallbacks.GetFleaOfferById(url, info as GetRagfairOfferByIdRequest, sessionID),
typeof(GetRagfairOfferByIdRequest)
),
]
) { }
}
public class RagfairStaticRouter(JsonUtil jsonUtil, RagfairCallbacks ragfairCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<SearchRequestData>(
"/client/ragfair/search",
async (url, info, sessionID, output) => await ragfairCallbacks.Search(url, info, sessionID)
),
new RouteAction<SearchRequestData>(
"/client/ragfair/find",
async (url, info, sessionID, output) => await ragfairCallbacks.Search(url, info, sessionID)
),
new RouteAction<GetMarketPriceRequestData>(
"/client/ragfair/itemMarketPrice",
async (url, info, sessionID, output) => await ragfairCallbacks.GetMarketPrice(url, info, sessionID)
),
new RouteAction<StorePlayerOfferTaxAmountRequestData>(
"/client/ragfair/offerfees",
async (url, info, sessionID, output) => await ragfairCallbacks.StorePlayerOfferTaxAmount(url, info, sessionID)
),
new RouteAction<SendRagfairReportRequestData>(
"/client/reports/ragfair/send",
async (url, info, sessionID, output) => await ragfairCallbacks.SendReport(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/items/prices",
async (url, info, sessionID, output) => await ragfairCallbacks.GetFleaPrices(url, info, sessionID)
),
new RouteAction<GetRagfairOfferByIdRequest>(
"/client/ragfair/offer/findbyid",
async (url, info, sessionID, output) => await ragfairCallbacks.GetFleaOfferById(url, info, sessionID)
),
]
) { }
@@ -7,22 +7,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class TraderStaticRouter : StaticRouter
{
public TraderStaticRouter(JsonUtil jsonUtil, TraderCallbacks traderCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/trading/api/traderSettings",
async (url, info, sessionID, output) =>
await traderCallbacks.GetTraderSettings(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/singleplayer/moddedTraders",
async (url, info, sessionID, output) =>
await traderCallbacks.GetModdedTraderData(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class TraderStaticRouter(JsonUtil jsonUtil, TraderCallbacks traderCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/trading/api/traderSettings",
async (url, info, sessionID, output) => await traderCallbacks.GetTraderSettings(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/singleplayer/moddedTraders",
async (url, info, sessionID, output) => await traderCallbacks.GetModdedTraderData(url, info, sessionID)
),
]
) { }
@@ -7,20 +7,17 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Routers.Static;
[Injectable]
public class WeatherStaticRouter : StaticRouter
{
public WeatherStaticRouter(JsonUtil jsonUtil, WeatherCallbacks weatherCallbacks)
: base(
jsonUtil,
[
new RouteAction(
"/client/weather",
async (url, info, sessionID, output) => await weatherCallbacks.GetWeather(url, info as EmptyRequestData, sessionID)
),
new RouteAction(
"/client/localGame/weather",
async (url, info, sessionID, output) => await weatherCallbacks.GetLocalWeather(url, info as EmptyRequestData, sessionID)
),
]
) { }
}
public class WeatherStaticRouter(JsonUtil jsonUtil, WeatherCallbacks weatherCallbacks)
: StaticRouter(
jsonUtil,
[
new RouteAction<EmptyRequestData>(
"/client/weather",
async (url, info, sessionID, output) => await weatherCallbacks.GetWeather(url, info, sessionID)
),
new RouteAction<EmptyRequestData>(
"/client/localGame/weather",
async (url, info, sessionID, output) => await weatherCallbacks.GetLocalWeather(url, info, sessionID)
),
]
) { }
@@ -25,14 +25,8 @@ public class SptHttpListener(
ServerLocalisationService serverLocalisationService
) : IHttpListener
{
// We want to read 1KB at a time, for most request this is already big enough
private const int BodyReadBufferSize = 1024 * 1;
private static readonly ImmutableHashSet<string> SupportedMethods = ["GET", "PUT", "POST"];
protected readonly HttpRouter _router = httpRouter;
protected readonly IEnumerable<ISerializer> _serializers = serializers;
public bool CanHandle(MongoId _, HttpRequest req)
{
return SupportedMethods.Contains(req.Method);
@@ -60,33 +54,16 @@ public class SptHttpListener(
var requestCompressed = req.Method == "PUT" || requestIsCompressed;
string body;
using MemoryStream bufferStream = new();
var buffer = new byte[BodyReadBufferSize];
int bytesRead;
while ((bytesRead = await req.Body.ReadAsync(buffer)) > 0)
{
await bufferStream.WriteAsync(buffer.AsMemory(0, bytesRead));
}
bufferStream.Position = 0;
if (requestCompressed)
{
await using var deflateStream = new ZLibStream(bufferStream, CompressionMode.Decompress);
await using var decompressedStream = new MemoryStream();
await deflateStream.CopyToAsync(decompressedStream);
decompressedStream.Position = 0;
using var reader = new StreamReader(decompressedStream, Encoding.UTF8);
await using var deflateStream = new ZLibStream(req.Body, CompressionMode.Decompress);
using var reader = new StreamReader(deflateStream, Encoding.UTF8);
body = await reader.ReadToEndAsync();
}
else
{
// No decompression needed, decode directly from the bufferStream's buffer
bufferStream.Position = 0;
using var reader = new StreamReader(bufferStream, Encoding.UTF8);
using var reader = new StreamReader(req.Body, Encoding.UTF8);
body = await reader.ReadToEndAsync();
}
@@ -139,7 +116,7 @@ public class SptHttpListener(
}
// Not debug, minority of requests need a serializer to do the job (IMAGE/BUNDLE/NOTIFY)
var serialiser = _serializers.FirstOrDefault(x => x.CanHandle(output));
var serialiser = serializers.FirstOrDefault(x => x.CanHandle(output));
if (serialiser != null)
{
await serialiser.Serialize(sessionID, req, resp, bodyInfo);
@@ -179,7 +156,7 @@ public class SptHttpListener(
public async ValueTask<string> GetResponse(MongoId sessionId, HttpRequest req, string? body)
{
var output = await _router.GetResponse(req, sessionId, body);
var output = await httpRouter.GetResponse(req, sessionId, body);
// Route doesn't exist or response is not properly set up
if (string.IsNullOrEmpty(output))
@@ -203,30 +180,23 @@ public class SptHttpListener(
resp.StatusCode = 200;
resp.ContentType = "application/json";
resp.Headers.Append("Set-Cookie", $"PHPSESSID={sessionID.ToString()}");
if (!string.IsNullOrEmpty(output))
{
await resp.WriteAsync(output);
}
await resp.StartAsync();
await resp.CompleteAsync();
}
public async Task SendZlibJson(HttpResponse resp, string? output, MongoId sessionID)
public async Task SendZlibJson(HttpResponse resp, string output, MongoId sessionID)
{
using (var ms = new MemoryStream())
resp.StatusCode = 200;
resp.ContentType = "application/json";
resp.Headers.Append("Set-Cookie", $"PHPSESSID={sessionID.ToString()}");
await using (var deflateStream = new ZLibStream(resp.Body, CompressionLevel.SmallestSize))
{
await using (var deflateStream = new ZLibStream(ms, CompressionLevel.SmallestSize))
{
await deflateStream.WriteAsync(Encoding.UTF8.GetBytes(output));
}
var bytes = ms.ToArray();
await resp.Body.WriteAsync(bytes);
await deflateStream.WriteAsync(Encoding.UTF8.GetBytes(output));
}
await resp.StartAsync();
await resp.CompleteAsync();
}
private record Response(string Method, string jsonData);
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using SPTarkov.Common.Extensions;
using System.Net;
using System.Net.Sockets;
using Microsoft.AspNetCore.Http;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Spt.Config;
@@ -20,7 +20,7 @@ public class HttpServer(
IEnumerable<IHttpListener> httpListeners
)
{
private readonly HttpConfig _httpConfig = configServer.GetConfig<HttpConfig>();
protected readonly HttpConfig HttpConfig = configServer.GetConfig<HttpConfig>();
public async Task HandleRequest(HttpContext context)
{
@@ -39,18 +39,16 @@ public class HttpServer(
profileActivityService.SetActivityTimestamp(sessionId);
}
// Extract header for original IP detection
var realIp = context.GetHeaderIfExists("x-real-ip");
var clientIp = GetClientIp(context, realIp);
var realIp = context.Connection.RemoteIpAddress ?? IPAddress.Parse("127.0.0.1");
if (_httpConfig.LogRequests)
if (HttpConfig.LogRequests)
{
LogRequest(context, clientIp, IsLocalRequest(clientIp));
LogRequest(context, realIp, IsPrivateOrLocalAddress(realIp));
}
try
{
var listener = httpListeners.FirstOrDefault(l => l.CanHandle(sessionId, context.Request));
var listener = httpListeners.FirstOrDefault(listener => listener.CanHandle(sessionId, context.Request));
if (listener != null)
{
@@ -76,7 +74,7 @@ public class HttpServer(
/// <param name="context">HttpContext of request</param>
/// <param name="clientIp">Ip of requester</param>
/// <param name="isLocalRequest">Is this local request</param>
protected void LogRequest(HttpContext context, string clientIp, bool isLocalRequest)
protected void LogRequest(HttpContext context, IPAddress clientIp, bool isLocalRequest)
{
if (isLocalRequest)
{
@@ -88,32 +86,50 @@ public class HttpServer(
}
}
protected static string GetClientIp(HttpContext context, StringValues? realIp)
{
if (realIp.HasValue)
{
return realIp.Value.First();
}
var forwardedFor = context.GetHeaderIfExists("x-forwarded-for");
return forwardedFor.HasValue
? forwardedFor.Value.First()!.Split(",")[0].Trim()
: context.Connection.RemoteIpAddress!.ToString().Split(":").Last();
}
/// <summary>
/// Check against hardcoded values that determine it's from a local address
/// </summary>
/// <param name="remoteAddress"> Address to check </param>
/// <returns> True if its local </returns>
protected bool IsLocalRequest(string? remoteAddress)
protected bool IsPrivateOrLocalAddress(IPAddress remoteAddress)
{
if (remoteAddress == null)
if (IPAddress.IsLoopback(remoteAddress))
{
return false;
return true;
}
return remoteAddress.StartsWith("127.0.0") || remoteAddress.StartsWith("192.168.") || remoteAddress.StartsWith("localhost");
if (remoteAddress.AddressFamily == AddressFamily.InterNetwork)
{
var bytes = remoteAddress.GetAddressBytes();
switch (bytes[0])
{
case 10:
return true; // 10.0.0.0/8 (private)
case 169:
return bytes[1] == 254; // 169.254.0.0/16 (APIPA/link-local)
case 172:
return bytes[1] >= 16 && bytes[1] <= 31; // 172.16.0.0/12 (private)
case 192:
return bytes[1] == 168; // 192.168.0.0/16 (private)
default:
return false;
}
}
if (remoteAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
if (remoteAddress.IsIPv6LinkLocal)
{
return true;
}
}
return false;
}
protected Dictionary<string, string> GetCookies(HttpRequest req)
@@ -130,6 +146,6 @@ public class HttpServer(
public string ListeningUrl()
{
return $"https://{_httpConfig.Ip}:{_httpConfig.Port}";
return $"https://{HttpConfig.Ip}:{HttpConfig.Port}";
}
}
+6
View File
@@ -3,6 +3,7 @@ using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Text;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using SPTarkov.Common.Semver;
using SPTarkov.Common.Semver.Implementations;
@@ -78,6 +79,11 @@ public static class Program
var loggerFinalizer = app.Services.GetService<ISptLogger<App>>()!;
try
{
// Handle edge cases where reverse proxies might pass X-Forwarded-For, use this as the actual IP address
app.UseForwardedHeaders(
new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }
);
SetConsoleOutputMode();
await app.RunAsync();