From 55a9571958133ad7603dda33c23cd5882447c23c Mon Sep 17 00:00:00 2001 From: neckfire Date: Tue, 14 Jul 2026 17:56:22 +0200 Subject: [PATCH] fix(matchmaking): deploy signal targets only the deploying player EnterMatchmakingMatch broadcast OnSquadMatchmakingSuccess to Clients.All, so one player deploying pulled every connected player into the match. Map each player to their SignalR connection (GetSignalRConnection tags the URL with uid; CycleHub records it via a SignalRConnectionRegistry) and send the deploy signal only to that connection (broadcast fallback if unmapped). Also enable m_automaticImportPlatformFriends (Steam friends). Co-Authored-By: Claude Opus 4.8 --- src/Prospect.Server.Api/Hubs/CycleHub.cs | 25 ++++++++++++++-- .../Hubs/SignalRConnectionRegistry.cs | 29 +++++++++++++++++++ .../Functions/EnterMatchmakingMatch.cs | 19 +++++++++--- .../Functions/GetSignalRConnection.cs | 9 +++++- .../Services/UserData/TitleDataDefault.cs | 4 +-- src/Prospect.Server.Api/Startup.cs | 1 + 6 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 src/Prospect.Server.Api/Hubs/SignalRConnectionRegistry.cs diff --git a/src/Prospect.Server.Api/Hubs/CycleHub.cs b/src/Prospect.Server.Api/Hubs/CycleHub.cs index ec5e2eb..0d91064 100644 --- a/src/Prospect.Server.Api/Hubs/CycleHub.cs +++ b/src/Prospect.Server.Api/Hubs/CycleHub.cs @@ -1,12 +1,31 @@ -using Microsoft.AspNetCore.SignalR; +using Microsoft.AspNetCore.SignalR; namespace Prospect.Server.Api.Hubs; public class CycleHub : Hub { + private readonly SignalRConnectionRegistry _registry; + + public CycleHub(SignalRConnectionRegistry registry) + { + _registry = registry; + } + public override async Task OnConnectedAsync() { - Console.WriteLine("Connected {0}", Context.ConnectionId); + // The client connects with the SignalR URL returned by GetSignalRConnection, which + // carries a `uid` query param — use it to map this connection to the player so + // server-initiated messages can target a single player instead of everyone. + var uid = Context.GetHttpContext()?.Request.Query["uid"].ToString(); + if (!string.IsNullOrEmpty(uid)) + _registry.Add(uid, Context.ConnectionId); + Console.WriteLine("Connected {0} (uid={1})", Context.ConnectionId, uid); await base.OnConnectedAsync(); } -} \ No newline at end of file + + public override async Task OnDisconnectedAsync(Exception? exception) + { + _registry.Remove(Context.ConnectionId); + await base.OnDisconnectedAsync(exception); + } +} diff --git a/src/Prospect.Server.Api/Hubs/SignalRConnectionRegistry.cs b/src/Prospect.Server.Api/Hubs/SignalRConnectionRegistry.cs new file mode 100644 index 0000000..3660841 --- /dev/null +++ b/src/Prospect.Server.Api/Hubs/SignalRConnectionRegistry.cs @@ -0,0 +1,29 @@ +using System.Collections.Concurrent; + +namespace Prospect.Server.Api.Hubs; + +// Maps players to their live SignalR connection so server-initiated messages (e.g. the +// matchmaking-success "travel to match" signal) can target a single player instead of being +// broadcast to everyone. The client's SignalR URL carries a `uid` query param (added by +// GetSignalRConnection); CycleHub records it on connect. +public class SignalRConnectionRegistry +{ + private readonly ConcurrentDictionary _userToConn = new(); + private readonly ConcurrentDictionary _connToUser = new(); + + public void Add(string userId, string connectionId) + { + if (string.IsNullOrEmpty(userId)) return; + _userToConn[userId] = connectionId; + _connToUser[connectionId] = userId; + } + + public void Remove(string connectionId) + { + if (_connToUser.TryRemove(connectionId, out var userId)) + _userToConn.TryRemove(userId, out _); + } + + public string? GetConnection(string userId) + => _userToConn.TryGetValue(userId, out var c) ? c : null; +} diff --git a/src/Prospect.Server.Api/Services/CloudScript/Functions/EnterMatchmakingMatch.cs b/src/Prospect.Server.Api/Services/CloudScript/Functions/EnterMatchmakingMatch.cs index 6625fd3..49f1016 100644 --- a/src/Prospect.Server.Api/Services/CloudScript/Functions/EnterMatchmakingMatch.cs +++ b/src/Prospect.Server.Api/Services/CloudScript/Functions/EnterMatchmakingMatch.cs @@ -24,13 +24,15 @@ public class EnterMatchmakingMatchFunction : ICloudScriptFunction _hubContext; private readonly UserDataService _userDataService; private readonly TitleDataService _titleDataService; + private readonly SignalRConnectionRegistry _registry; - public EnterMatchmakingMatchFunction(IHubContext hubContext, IHttpContextAccessor httpContextAccessor, UserDataService userDataService, TitleDataService titleDataService) + public EnterMatchmakingMatchFunction(IHubContext hubContext, IHttpContextAccessor httpContextAccessor, UserDataService userDataService, TitleDataService titleDataService, SignalRConnectionRegistry registry) { _httpContextAccessor = httpContextAccessor; _hubContext = hubContext; _userDataService = userDataService; _titleDataService = titleDataService; + _registry = registry; } public async Task ExecuteAsync(FYEnterMatchAzureFunction request) @@ -94,11 +96,20 @@ public class EnterMatchmakingMatchFunction : ICloudScriptFunction {Url}", remote, lan, url); + // Tag the connection with the player id so the hub can map connection -> user and + // target server messages (deploy signal) instead of broadcasting to everyone. + var userId = _httpContextAccessor.HttpContext?.User.FindAuthUserId(); + if (!string.IsNullOrEmpty(userId)) + url += (url.Contains('?') ? "&" : "?") + "uid=" + Uri.EscapeDataString(userId); + + _logger.LogInformation("GetSignalRConnection: remoteIp={Remote} lan={Lan} uid={Uid} -> {Url}", remote, lan, userId, url); return Task.FromResult(new FYGetSignalRConnectionResult { diff --git a/src/Prospect.Server.Api/Services/UserData/TitleDataDefault.cs b/src/Prospect.Server.Api/Services/UserData/TitleDataDefault.cs index c9c270b..4501f80 100644 --- a/src/Prospect.Server.Api/Services/UserData/TitleDataDefault.cs +++ b/src/Prospect.Server.Api/Services/UserData/TitleDataDefault.cs @@ -19,7 +19,7 @@ public static class TitleDataDefault ["FactionProgressionICA"] = "[{\"Level\":1,\"Reputation\":0},{\"Level\":2,\"Reputation\":100},{\"Level\":3,\"Reputation\":250},{\"Level\":4,\"Reputation\":450},{\"Level\":5,\"Reputation\":750},{\"Level\":6,\"Reputation\":1200},{\"Level\":7,\"Reputation\":1800},{\"Level\":8,\"Reputation\":2700},{\"Level\":9,\"Reputation\":3900},{\"Level\":10,\"Reputation\":5700},{\"Level\":11,\"Reputation\":8200},{\"Level\":12,\"Reputation\":12000},{\"Level\":13,\"Reputation\":16000},{\"Level\":14,\"Reputation\":23000},{\"Level\":15,\"Reputation\":32000},{\"Level\":16,\"Reputation\":43000},{\"Level\":17,\"Reputation\":59000},{\"Level\":18,\"Reputation\":82000},{\"Level\":19,\"Reputation\":113000},{\"Level\":20,\"Reputation\":159000}]", ["FactionProgressionKorolev"] = "[{\"Level\":1,\"Reputation\":0},{\"Level\":2,\"Reputation\":100},{\"Level\":3,\"Reputation\":250},{\"Level\":4,\"Reputation\":450},{\"Level\":5,\"Reputation\":750},{\"Level\":6,\"Reputation\":1200},{\"Level\":7,\"Reputation\":1800},{\"Level\":8,\"Reputation\":2700},{\"Level\":9,\"Reputation\":3900},{\"Level\":10,\"Reputation\":5700},{\"Level\":11,\"Reputation\":8200},{\"Level\":12,\"Reputation\":12000},{\"Level\":13,\"Reputation\":16000},{\"Level\":14,\"Reputation\":23000},{\"Level\":15,\"Reputation\":32000},{\"Level\":16,\"Reputation\":43000},{\"Level\":17,\"Reputation\":59000},{\"Level\":18,\"Reputation\":82000},{\"Level\":19,\"Reputation\":113000},{\"Level\":20,\"Reputation\":159000}]", ["FactionProgressionOsiris"] = "[{\"Level\":1,\"Reputation\":0},{\"Level\":2,\"Reputation\":100},{\"Level\":3,\"Reputation\":250},{\"Level\":4,\"Reputation\":450},{\"Level\":5,\"Reputation\":750},{\"Level\":6,\"Reputation\":1200},{\"Level\":7,\"Reputation\":1800},{\"Level\":8,\"Reputation\":2700},{\"Level\":9,\"Reputation\":3900},{\"Level\":10,\"Reputation\":5700},{\"Level\":11,\"Reputation\":8200},{\"Level\":12,\"Reputation\":12000},{\"Level\":13,\"Reputation\":16000},{\"Level\":14,\"Reputation\":23000},{\"Level\":15,\"Reputation\":32000},{\"Level\":16,\"Reputation\":43000},{\"Level\":17,\"Reputation\":59000},{\"Level\":18,\"Reputation\":82000},{\"Level\":19,\"Reputation\":113000},{\"Level\":20,\"Reputation\":159000}]", - ["FeatureToggles"] = "[{\"m_isMapUnlockEnabled\":true,\"m_useFullTimeAsyncLoadingThread\":true,\"m_playerReplicatingClientSpawnDependency\":true,\"m_voiceChatEnabled\":true,\"m_autoRequeueingEnabled\":false,\"m_useIdleDetection\":false,\"m_enableColorBlindOptions\":true,\"m_automaticImportPlatformFriends\":false,\"m_eosStatsEnabled\":false,\"m_canCraftWeapons\":true,\"m_isModFunctionalityEnabled\":true,\"m_enableBugReporterInShipping\":false,\"m_enableBugReporter\":true,\"m_isProneEnabled\":false,\"m_isLeaningEnabled\":true,\"m_isAccountLinkingEnabled\":true,\"m_isFriendsImportEnabled\":true,\"m_isFriendsLimitEnabled\":false,\"m_showMatchMapsSelector\":true,\"m_newMeleeSystemEnabled\":true,\"m_enableEffortsComponent\":true,\"m_squadsEnabled\":true,\"m_socialEnabled\":true,\"m_sessionServerShutdownEnabled\":true,\"m_multiplayerStationEnabled\":true,\"m_replicationGraphEnabled\":true,\"m_lootCollisionTraceEnabled\":true,\"m_isOnboardingEnabled\":true,\"m_isPremiumShopEnabled\":true,\"m_areRealMoneyPurchasesEnabled\":false,\"m_isFortunaPassEnabled\":true,\"m_isTutorialEnabled\":true,\"m_isCharacterSelectionEnabled\":true,\"m_showSeasonDateInfoOnRetentionPopup\":false,\"m_enableBIEventsServer\":true,\"m_BIEventsServerRatio\":0.05,\"m_BIEventsUserSamplingRatio\":0.05,\"m_enableBIEventsClient\":true,\"m_playfabCouponsEnabled\":true,\"m_AlienForgeEnabled\":true,\"m_enableInteractionAmountLimit\":true,\"m_safeTeleportWhenStuck\":true,\"m_safeTeleportFallingThroughWorld\":true,\"m_basicInsuranceEnabled\":true,\"m_premiumInsuranceEnabled\":true,\"m_relevantPlayerControllerCachingEnabled\":false,\"m_interruptionManagerTravelEnabled\":true,\"m_enableBulletPooling\":false,\"m_isTOCDataMigrationEnabled\":true,\"m_isInventoryLimitEnabled\":true,\"m_checkClientVersionUpToDate\":true,\"m_allowDebugShippingServerCrashes\":false,\"m_disableTargetingInAir\":false,\"m_spawnScoresAffectMatchmaker\":true,\"m_frontendCheatWeight\":1.5,\"m_frontendAutoBanEnabled\":true,\"m_backendCheatWeight\":1.5,\"m_backendAutoBanEnabled\":true,\"m_cheatFeatureToggle_11\":true,\"m_cheatFeatureToggle_15\":true,\"m_cheatFeatureToggle_35\":true,\"m_cheatFeatureToggle_48\":true,\"m_cheatFeatureToggle_53\":true,\"m_cheatFeatureToggle_54\":true,\"m_cheatSettings_38\":{\"m_defaultValue\":300.0,\"m_overridenValues\":{\"NorthEurope\":300.0,\"JapanEast\":130.0}},\"m_cheatSettings_39\":10.0,\"m_cheatSettings_40\":6,\"m_cheatSettings_41\":30.0,\"m_cheatSettingBackend_04\":{\"m_miscSetting_01\":1000,\"m_miscSetting_02\":14,\"m_miscSetting_03\":2.0,\"m_miscSetting_04\":14,\"m_miscSetting_05\":60,\"m_miscSetting_06\":20,\"m_miscSetting_07\":true,\"m_miscSetting_08\":true},\"m_isBattlEyeKickingActive\":false,\"m_isBattlEyeActive\":false,\"m_isBattlEyeKickReasonChecksActive\":false,\"m_levelStreamingFailsafeEnabled\":false,\"m_useCustomOcclusionAudioAsyncLimitation\":true,\"m_useCustomOcclusionAudioSyncLimitation\":true,\"m_isUsingSingleNvrBracket\":false,\"m_isUsingSingleKdrBracket\":false,\"m_sampleBIEvents\":true,\"m_shutDownInstancesOfExistingConnections\":false,\"m_vivoxRejoinOnDisconnect\":false,\"m_cheatProtectionSession\":true,\"m_isMergingMeshComponentsDefaultStation\":true,\"m_isMergingMeshComponentsDefaultMatch\":true,\"m_submixByPassEnabled\":false,\"m_reconnectFeatureEnabled\":true,\"m_autoFetchTitleData\":true,\"m_fetchingIntervals\":{\"FeatureToggles\":1800.0},\"m_cheatingVictimCompensationEnabled\":true,\"m_cheatingVictimCompensationIgnoreItemsByWeightEnabled\":true,\"m_kickingStorageQueueEnabled\":true,\"m_playFabIdServerValidation\":true,\"m_playFabNickNameServerValidation\":true,\"m_battlEyeEndPointEnabled\":false,\"m_enableShieldedMatchmaking\":true,\"m_enableUsingSpentMoneyThreshold\":true,\"m_enableUsingSteamAccountStatus\":true,\"m_enableUsingVeteranPoints\":true,\"m_enableBackendOptimalPingCheck\":false,\"m_enableBackendRegionBoundaryCheck\":false,\"m_enableProjectileSimulatedDamagePropagation\":false,\"m_enableResponsivenessCheck\":true,\"m_deactivatedItems\":[],\"m_rolledPerkActivated\":true,\"m_VPNDetectionEnabled\":false,\"m_enableLedgeClimbServerValidation\":true,\"m_allowGameClientTelemetryCustomEvents\":true,\"m_allowGameServerTelemetryCustomEvents\":true,\"m_newReportEnabled\":true,\"m_playerSupportZendeskEndPointEnabled\":true,\"m_playerSupportBIEndPointEnabled\":true,\"m_clientPerformanceTrackingEnabled\":true,\"m_serverPerformanceTrackingEnabled\":true,\"m_rowName\":\"FeatureToggles\",\"Name\":\"FeatureToggles\"}]", + ["FeatureToggles"] = "[{\"m_isMapUnlockEnabled\":true,\"m_useFullTimeAsyncLoadingThread\":true,\"m_playerReplicatingClientSpawnDependency\":true,\"m_voiceChatEnabled\":true,\"m_autoRequeueingEnabled\":false,\"m_useIdleDetection\":false,\"m_enableColorBlindOptions\":true,\"m_automaticImportPlatformFriends\":true,\"m_eosStatsEnabled\":false,\"m_canCraftWeapons\":true,\"m_isModFunctionalityEnabled\":true,\"m_enableBugReporterInShipping\":false,\"m_enableBugReporter\":true,\"m_isProneEnabled\":false,\"m_isLeaningEnabled\":true,\"m_isAccountLinkingEnabled\":true,\"m_isFriendsImportEnabled\":true,\"m_isFriendsLimitEnabled\":false,\"m_showMatchMapsSelector\":true,\"m_newMeleeSystemEnabled\":true,\"m_enableEffortsComponent\":true,\"m_squadsEnabled\":true,\"m_socialEnabled\":true,\"m_sessionServerShutdownEnabled\":true,\"m_multiplayerStationEnabled\":true,\"m_replicationGraphEnabled\":true,\"m_lootCollisionTraceEnabled\":true,\"m_isOnboardingEnabled\":true,\"m_isPremiumShopEnabled\":true,\"m_areRealMoneyPurchasesEnabled\":false,\"m_isFortunaPassEnabled\":true,\"m_isTutorialEnabled\":true,\"m_isCharacterSelectionEnabled\":true,\"m_showSeasonDateInfoOnRetentionPopup\":false,\"m_enableBIEventsServer\":true,\"m_BIEventsServerRatio\":0.05,\"m_BIEventsUserSamplingRatio\":0.05,\"m_enableBIEventsClient\":true,\"m_playfabCouponsEnabled\":true,\"m_AlienForgeEnabled\":true,\"m_enableInteractionAmountLimit\":true,\"m_safeTeleportWhenStuck\":true,\"m_safeTeleportFallingThroughWorld\":true,\"m_basicInsuranceEnabled\":true,\"m_premiumInsuranceEnabled\":true,\"m_relevantPlayerControllerCachingEnabled\":false,\"m_interruptionManagerTravelEnabled\":true,\"m_enableBulletPooling\":false,\"m_isTOCDataMigrationEnabled\":true,\"m_isInventoryLimitEnabled\":true,\"m_checkClientVersionUpToDate\":true,\"m_allowDebugShippingServerCrashes\":false,\"m_disableTargetingInAir\":false,\"m_spawnScoresAffectMatchmaker\":true,\"m_frontendCheatWeight\":1.5,\"m_frontendAutoBanEnabled\":true,\"m_backendCheatWeight\":1.5,\"m_backendAutoBanEnabled\":true,\"m_cheatFeatureToggle_11\":true,\"m_cheatFeatureToggle_15\":true,\"m_cheatFeatureToggle_35\":true,\"m_cheatFeatureToggle_48\":true,\"m_cheatFeatureToggle_53\":true,\"m_cheatFeatureToggle_54\":true,\"m_cheatSettings_38\":{\"m_defaultValue\":300.0,\"m_overridenValues\":{\"NorthEurope\":300.0,\"JapanEast\":130.0}},\"m_cheatSettings_39\":10.0,\"m_cheatSettings_40\":6,\"m_cheatSettings_41\":30.0,\"m_cheatSettingBackend_04\":{\"m_miscSetting_01\":1000,\"m_miscSetting_02\":14,\"m_miscSetting_03\":2.0,\"m_miscSetting_04\":14,\"m_miscSetting_05\":60,\"m_miscSetting_06\":20,\"m_miscSetting_07\":true,\"m_miscSetting_08\":true},\"m_isBattlEyeKickingActive\":false,\"m_isBattlEyeActive\":false,\"m_isBattlEyeKickReasonChecksActive\":false,\"m_levelStreamingFailsafeEnabled\":false,\"m_useCustomOcclusionAudioAsyncLimitation\":true,\"m_useCustomOcclusionAudioSyncLimitation\":true,\"m_isUsingSingleNvrBracket\":false,\"m_isUsingSingleKdrBracket\":false,\"m_sampleBIEvents\":true,\"m_shutDownInstancesOfExistingConnections\":false,\"m_vivoxRejoinOnDisconnect\":false,\"m_cheatProtectionSession\":true,\"m_isMergingMeshComponentsDefaultStation\":true,\"m_isMergingMeshComponentsDefaultMatch\":true,\"m_submixByPassEnabled\":false,\"m_reconnectFeatureEnabled\":true,\"m_autoFetchTitleData\":true,\"m_fetchingIntervals\":{\"FeatureToggles\":1800.0},\"m_cheatingVictimCompensationEnabled\":true,\"m_cheatingVictimCompensationIgnoreItemsByWeightEnabled\":true,\"m_kickingStorageQueueEnabled\":true,\"m_playFabIdServerValidation\":true,\"m_playFabNickNameServerValidation\":true,\"m_battlEyeEndPointEnabled\":false,\"m_enableShieldedMatchmaking\":true,\"m_enableUsingSpentMoneyThreshold\":true,\"m_enableUsingSteamAccountStatus\":true,\"m_enableUsingVeteranPoints\":true,\"m_enableBackendOptimalPingCheck\":false,\"m_enableBackendRegionBoundaryCheck\":false,\"m_enableProjectileSimulatedDamagePropagation\":false,\"m_enableResponsivenessCheck\":true,\"m_deactivatedItems\":[],\"m_rolledPerkActivated\":true,\"m_VPNDetectionEnabled\":false,\"m_enableLedgeClimbServerValidation\":true,\"m_allowGameClientTelemetryCustomEvents\":true,\"m_allowGameServerTelemetryCustomEvents\":true,\"m_newReportEnabled\":true,\"m_playerSupportZendeskEndPointEnabled\":true,\"m_playerSupportBIEndPointEnabled\":true,\"m_clientPerformanceTrackingEnabled\":true,\"m_serverPerformanceTrackingEnabled\":true,\"m_rowName\":\"FeatureToggles\",\"Name\":\"FeatureToggles\"}]", ["DefaultInventoryInfo"] = "{\"inventoryStashLimit\":90,\"inventoryBagLimit\":300,\"inventorySafeLimit\":5}", ["InventoryInsurance"] = "{\"Default\":{\"InsuranceId\":\"Default\",\"Cost\":0.2,\"Payout\":0.5}}", ["MatchmakingSetup"] = "[]", @@ -46,7 +46,7 @@ public static class TitleDataDefault ["FactionProgressionICA"] = "[{\"Level\":1,\"Reputation\":0},{\"Level\":2,\"Reputation\":100},{\"Level\":3,\"Reputation\":250},{\"Level\":4,\"Reputation\":450},{\"Level\":5,\"Reputation\":750},{\"Level\":6,\"Reputation\":1200},{\"Level\":7,\"Reputation\":1800},{\"Level\":8,\"Reputation\":2700},{\"Level\":9,\"Reputation\":3900},{\"Level\":10,\"Reputation\":5700},{\"Level\":11,\"Reputation\":8200},{\"Level\":12,\"Reputation\":12000},{\"Level\":13,\"Reputation\":16000},{\"Level\":14,\"Reputation\":23000},{\"Level\":15,\"Reputation\":32000},{\"Level\":16,\"Reputation\":43000},{\"Level\":17,\"Reputation\":59000},{\"Level\":18,\"Reputation\":92000},{\"Level\":19,\"Reputation\":133000},{\"Level\":20,\"Reputation\":189000}]", ["FactionProgressionKorolev"] = "[{\"Level\":1,\"Reputation\":0},{\"Level\":2,\"Reputation\":100},{\"Level\":3,\"Reputation\":250},{\"Level\":4,\"Reputation\":450},{\"Level\":5,\"Reputation\":750},{\"Level\":6,\"Reputation\":1200},{\"Level\":7,\"Reputation\":1800},{\"Level\":8,\"Reputation\":2700},{\"Level\":9,\"Reputation\":3900},{\"Level\":10,\"Reputation\":5700},{\"Level\":11,\"Reputation\":8200},{\"Level\":12,\"Reputation\":12000},{\"Level\":13,\"Reputation\":16000},{\"Level\":14,\"Reputation\":23000},{\"Level\":15,\"Reputation\":32000},{\"Level\":16,\"Reputation\":43000},{\"Level\":17,\"Reputation\":59000},{\"Level\":18,\"Reputation\":92000},{\"Level\":19,\"Reputation\":133000},{\"Level\":20,\"Reputation\":189000}]", ["FactionProgressionOsiris"] = "[{\"Level\":1,\"Reputation\":0},{\"Level\":2,\"Reputation\":100},{\"Level\":3,\"Reputation\":250},{\"Level\":4,\"Reputation\":450},{\"Level\":5,\"Reputation\":750},{\"Level\":6,\"Reputation\":1200},{\"Level\":7,\"Reputation\":1800},{\"Level\":8,\"Reputation\":2700},{\"Level\":9,\"Reputation\":3900},{\"Level\":10,\"Reputation\":5700},{\"Level\":11,\"Reputation\":8200},{\"Level\":12,\"Reputation\":12000},{\"Level\":13,\"Reputation\":16000},{\"Level\":14,\"Reputation\":23000},{\"Level\":15,\"Reputation\":32000},{\"Level\":16,\"Reputation\":43000},{\"Level\":17,\"Reputation\":59000},{\"Level\":18,\"Reputation\":92000},{\"Level\":19,\"Reputation\":133000},{\"Level\":20,\"Reputation\":189000}]", - ["FeatureToggles"] = "[{\"m_isMapUnlockEnabled\":true,\"m_useFullTimeAsyncLoadingThread\":true,\"m_playerReplicatingClientSpawnDependency\":true,\"m_voiceChatEnabled\":true,\"m_autoRequeueingEnabled\":false,\"m_useIdleDetection\":false,\"m_enableColorBlindOptions\":true,\"m_automaticImportPlatformFriends\":false,\"m_eosStatsEnabled\":false,\"m_canCraftWeapons\":true,\"m_isModFunctionalityEnabled\":true,\"m_enableBugReporterInShipping\":false,\"m_enableBugReporter\":true,\"m_isProneEnabled\":false,\"m_isLeaningEnabled\":true,\"m_isAccountLinkingEnabled\":true,\"m_isFriendsImportEnabled\":true,\"m_isFriendsLimitEnabled\":false,\"m_showMatchMapsSelector\":true,\"m_newMeleeSystemEnabled\":true,\"m_enableEffortsComponent\":true,\"m_squadsEnabled\":true,\"m_socialEnabled\":true,\"m_sessionServerShutdownEnabled\":true,\"m_multiplayerStationEnabled\":true,\"m_replicationGraphEnabled\":true,\"m_lootCollisionTraceEnabled\":true,\"m_isOnboardingEnabled\":true,\"m_isPremiumShopEnabled\":true,\"m_areRealMoneyPurchasesEnabled\":false,\"m_isFortunaPassEnabled\":true,\"m_isTutorialEnabled\":true,\"m_isCharacterSelectionEnabled\":true,\"m_showSeasonDateInfoOnRetentionPopup\":false,\"m_enableBIEventsServer\":true,\"m_BIEventsServerRatio\":0.05,\"m_BIEventsUserSamplingRatio\":0.05,\"m_enableBIEventsClient\":true,\"m_playfabCouponsEnabled\":true,\"m_AlienForgeEnabled\":true,\"m_enableInteractionAmountLimit\":true,\"m_safeTeleportWhenStuck\":true,\"m_safeTeleportFallingThroughWorld\":true,\"m_fallingThroughWorldZ\":-50000.0,\"m_basicInsuranceEnabled\":true,\"m_premiumInsuranceEnabled\":true,\"m_relevantPlayerControllerCachingEnabled\":false,\"m_interruptionManagerTravelEnabled\":true,\"m_enableBulletPooling\":false,\"m_isTOCDataMigrationEnabled\":true,\"m_isInventoryLimitEnabled\":true,\"m_checkClientVersionUpToDate\":true,\"m_allowDebugShippingServerCrashes\":false,\"m_disableTargetingInAir\":false,\"m_spawnScoresAffectMatchmaker\":true,\"m_freeLoadoutsEnabled\":true,\"m_frontendCheatWeight\":1.5,\"m_frontendAutoBanEnabled\":true,\"m_backendCheatWeight\":1.5,\"m_backendAutoBanEnabled\":true,\"m_isUserJoiningUnassignedSessionPreventionEnabled\":true,\"m_kickingStorageQueueEnabled\":true,\"m_playFabIdServerValidation\":true,\"m_playFabNickNameServerValidation\":true,\"m_cheatFeatureToggle_01\":true,\"m_cheatFeatureToggle_02\":true,\"m_cheatFeatureToggle_03\":700.0,\"m_cheatFeatureToggle_04\":3000.0,\"m_cheatFeatureToggle_05\":1.0,\"m_cheatFeatureToggle_06\":500.0,\"m_cheatFeatureToggle_07\":1500.0,\"m_cheatFeatureToggle_08\":700.0,\"m_cheatFeatureToggle_09\":60.0,\"m_cheatFeatureToggle_10\":20.0,\"m_isBadPingInsideSquadKickingEnabled\":true,\"m_badPingThresholds\":{\"m_defaultValue\":300.0,\"m_overridenValues\":{\"NorthEurope\":300.0,\"JapanEast\":130.0}},\"m_badPingMinTimeInSeconds\":10.0,\"m_badPingMaxOccurrences\":6,\"m_badPingResetTime\":30.0,\"m_isBattlEyeKickingActive\":false,\"m_isBattlEyeActive\":false,\"m_isBattlEyeKickReasonChecksActive\":false,\"m_battlEyeEndPointEnabled\":false,\"m_cheatingVictimCompensationEnabled\":true,\"m_cheatingVictimCompensationIgnoreItemsByWeightEnabled\":true,\"m_victimCompensationSettings\":{\"m_killSnapshotCountLimit\":1000,\"m_killSnapshotDaysLimit\":14,\"m_processVictimCompensationsDelayInHours\":2.0,\"m_deathSnapshotDaysLimit\":14,\"m_deathSnapshotCountLimit\":60,\"m_itemsToCompensateCountLimit\":20,\"m_filterItemsInEndOfMatchSafePockets\":true,\"m_enableDoubleCheaterProcessing\":true},\"m_levelStreamingFailsafeEnabled\":false,\"m_useCustomOcclusionAudioAsyncLimitation\":true,\"m_useCustomOcclusionAudioSyncLimitation\":true,\"m_isUsingSingleNvrBracket\":false,\"m_isUsingSingleKdrBracket\":false,\"m_sampleBIEvents\":true,\"m_shutDownInstancesOfExistingConnections\":false,\"m_vivoxRejoinOnDisconnect\":false,\"m_cheatProtectionSession\":true,\"m_isMergingMeshComponentsDefaultStation\":true,\"m_isMergingMeshComponentsDefaultMatch\":true,\"m_reconnectFeatureEnabled\":true,\"m_autoFetchTitleData\":true,\"m_fetchingIntervals\":{\"FeatureToggles\":1800.0},\"m_enableShieldedMatchmaking\":true,\"m_enableUsingSpentMoneyThreshold\":true,\"m_enableUsingSteamAccountStatus\":true,\"m_enableUsingVeteranPoints\":true,\"m_enableUsingTotalCompletedContracts\":true,\"m_enableUsingTotalEvacs\":false,\"m_enableBackendOptimalPingCheck\":false,\"m_enableBackendRegionBoundaryCheck\":false,\"m_enableProjectileSimulatedDamagePropagation\":false,\"m_enableResponsivenessCheck\":true,\"m_deactivatedItems\":[],\"m_rolledPerkActivated\":true,\"m_VPNDetectionEnabled\":false,\"m_enableLedgeClimbServerValidation\":true,\"m_allowGameClientTelemetryCustomEvents\":true,\"m_allowGameServerTelemetryCustomEvents\":true,\"m_newReportEnabled\":true,\"m_playerSupportZendeskEndPointEnabled\":true,\"m_playerSupportBIEndPointEnabled\":true,\"m_battlEyeReportPlayerEndPointEnabled\":true,\"m_clientPerformanceTrackingEnabled\":true,\"m_serverPerformanceTrackingEnabled\":true,\"m_timeSlicedMeshMergingEnabled\":true,\"m_uiLazyScrollGridEnabled\":false,\"m_loadoutPresetEnabled\":true,\"m_howlerLootMapMarkerEnabled\":false,\"m_couponsEnabled\":true,\"m_enableFtueReconnectRestart\":true,\"m_enableClientAuthoritativeFtueFlow\":false,\"m_badumsQuestlineEnabled\":true,\"m_evacV2Enabled\":true,\"m_steamDLCSettings\":{\"m_showDiscountedPriceDLC1\":false,\"m_showDiscountedPriceDLC2\":false,\"m_showDiscountedPriceDLC3\":false,\"m_showDiscountedPriceDLC4\":false,\"m_showDiscountedPriceDLCPrimeTime\":false,\"m_showDiscountedPriceDLCHowlerTamer\":false,\"m_showDiscountedPriceDLCVividPartyStyle\":false,\"m_showDiscountedPriceDLCAuthorityPeacekeeper\":false},\"m_clearCombatTargetOnAggroLossForAllAI\":true,\"m_updateWeaponEquippedDataEveryFrame\":false,\"m_aiProximitySenseBehaviourEnabled\":true,\"m_rowName\":\"FeatureToggles\",\"Name\":\"FeatureToggles\"}]", + ["FeatureToggles"] = "[{\"m_isMapUnlockEnabled\":true,\"m_useFullTimeAsyncLoadingThread\":true,\"m_playerReplicatingClientSpawnDependency\":true,\"m_voiceChatEnabled\":true,\"m_autoRequeueingEnabled\":false,\"m_useIdleDetection\":false,\"m_enableColorBlindOptions\":true,\"m_automaticImportPlatformFriends\":true,\"m_eosStatsEnabled\":false,\"m_canCraftWeapons\":true,\"m_isModFunctionalityEnabled\":true,\"m_enableBugReporterInShipping\":false,\"m_enableBugReporter\":true,\"m_isProneEnabled\":false,\"m_isLeaningEnabled\":true,\"m_isAccountLinkingEnabled\":true,\"m_isFriendsImportEnabled\":true,\"m_isFriendsLimitEnabled\":false,\"m_showMatchMapsSelector\":true,\"m_newMeleeSystemEnabled\":true,\"m_enableEffortsComponent\":true,\"m_squadsEnabled\":true,\"m_socialEnabled\":true,\"m_sessionServerShutdownEnabled\":true,\"m_multiplayerStationEnabled\":true,\"m_replicationGraphEnabled\":true,\"m_lootCollisionTraceEnabled\":true,\"m_isOnboardingEnabled\":true,\"m_isPremiumShopEnabled\":true,\"m_areRealMoneyPurchasesEnabled\":false,\"m_isFortunaPassEnabled\":true,\"m_isTutorialEnabled\":true,\"m_isCharacterSelectionEnabled\":true,\"m_showSeasonDateInfoOnRetentionPopup\":false,\"m_enableBIEventsServer\":true,\"m_BIEventsServerRatio\":0.05,\"m_BIEventsUserSamplingRatio\":0.05,\"m_enableBIEventsClient\":true,\"m_playfabCouponsEnabled\":true,\"m_AlienForgeEnabled\":true,\"m_enableInteractionAmountLimit\":true,\"m_safeTeleportWhenStuck\":true,\"m_safeTeleportFallingThroughWorld\":true,\"m_fallingThroughWorldZ\":-50000.0,\"m_basicInsuranceEnabled\":true,\"m_premiumInsuranceEnabled\":true,\"m_relevantPlayerControllerCachingEnabled\":false,\"m_interruptionManagerTravelEnabled\":true,\"m_enableBulletPooling\":false,\"m_isTOCDataMigrationEnabled\":true,\"m_isInventoryLimitEnabled\":true,\"m_checkClientVersionUpToDate\":true,\"m_allowDebugShippingServerCrashes\":false,\"m_disableTargetingInAir\":false,\"m_spawnScoresAffectMatchmaker\":true,\"m_freeLoadoutsEnabled\":true,\"m_frontendCheatWeight\":1.5,\"m_frontendAutoBanEnabled\":true,\"m_backendCheatWeight\":1.5,\"m_backendAutoBanEnabled\":true,\"m_isUserJoiningUnassignedSessionPreventionEnabled\":true,\"m_kickingStorageQueueEnabled\":true,\"m_playFabIdServerValidation\":true,\"m_playFabNickNameServerValidation\":true,\"m_cheatFeatureToggle_01\":true,\"m_cheatFeatureToggle_02\":true,\"m_cheatFeatureToggle_03\":700.0,\"m_cheatFeatureToggle_04\":3000.0,\"m_cheatFeatureToggle_05\":1.0,\"m_cheatFeatureToggle_06\":500.0,\"m_cheatFeatureToggle_07\":1500.0,\"m_cheatFeatureToggle_08\":700.0,\"m_cheatFeatureToggle_09\":60.0,\"m_cheatFeatureToggle_10\":20.0,\"m_isBadPingInsideSquadKickingEnabled\":true,\"m_badPingThresholds\":{\"m_defaultValue\":300.0,\"m_overridenValues\":{\"NorthEurope\":300.0,\"JapanEast\":130.0}},\"m_badPingMinTimeInSeconds\":10.0,\"m_badPingMaxOccurrences\":6,\"m_badPingResetTime\":30.0,\"m_isBattlEyeKickingActive\":false,\"m_isBattlEyeActive\":false,\"m_isBattlEyeKickReasonChecksActive\":false,\"m_battlEyeEndPointEnabled\":false,\"m_cheatingVictimCompensationEnabled\":true,\"m_cheatingVictimCompensationIgnoreItemsByWeightEnabled\":true,\"m_victimCompensationSettings\":{\"m_killSnapshotCountLimit\":1000,\"m_killSnapshotDaysLimit\":14,\"m_processVictimCompensationsDelayInHours\":2.0,\"m_deathSnapshotDaysLimit\":14,\"m_deathSnapshotCountLimit\":60,\"m_itemsToCompensateCountLimit\":20,\"m_filterItemsInEndOfMatchSafePockets\":true,\"m_enableDoubleCheaterProcessing\":true},\"m_levelStreamingFailsafeEnabled\":false,\"m_useCustomOcclusionAudioAsyncLimitation\":true,\"m_useCustomOcclusionAudioSyncLimitation\":true,\"m_isUsingSingleNvrBracket\":false,\"m_isUsingSingleKdrBracket\":false,\"m_sampleBIEvents\":true,\"m_shutDownInstancesOfExistingConnections\":false,\"m_vivoxRejoinOnDisconnect\":false,\"m_cheatProtectionSession\":true,\"m_isMergingMeshComponentsDefaultStation\":true,\"m_isMergingMeshComponentsDefaultMatch\":true,\"m_reconnectFeatureEnabled\":true,\"m_autoFetchTitleData\":true,\"m_fetchingIntervals\":{\"FeatureToggles\":1800.0},\"m_enableShieldedMatchmaking\":true,\"m_enableUsingSpentMoneyThreshold\":true,\"m_enableUsingSteamAccountStatus\":true,\"m_enableUsingVeteranPoints\":true,\"m_enableUsingTotalCompletedContracts\":true,\"m_enableUsingTotalEvacs\":false,\"m_enableBackendOptimalPingCheck\":false,\"m_enableBackendRegionBoundaryCheck\":false,\"m_enableProjectileSimulatedDamagePropagation\":false,\"m_enableResponsivenessCheck\":true,\"m_deactivatedItems\":[],\"m_rolledPerkActivated\":true,\"m_VPNDetectionEnabled\":false,\"m_enableLedgeClimbServerValidation\":true,\"m_allowGameClientTelemetryCustomEvents\":true,\"m_allowGameServerTelemetryCustomEvents\":true,\"m_newReportEnabled\":true,\"m_playerSupportZendeskEndPointEnabled\":true,\"m_playerSupportBIEndPointEnabled\":true,\"m_battlEyeReportPlayerEndPointEnabled\":true,\"m_clientPerformanceTrackingEnabled\":true,\"m_serverPerformanceTrackingEnabled\":true,\"m_timeSlicedMeshMergingEnabled\":true,\"m_uiLazyScrollGridEnabled\":false,\"m_loadoutPresetEnabled\":true,\"m_howlerLootMapMarkerEnabled\":false,\"m_couponsEnabled\":true,\"m_enableFtueReconnectRestart\":true,\"m_enableClientAuthoritativeFtueFlow\":false,\"m_badumsQuestlineEnabled\":true,\"m_evacV2Enabled\":true,\"m_steamDLCSettings\":{\"m_showDiscountedPriceDLC1\":false,\"m_showDiscountedPriceDLC2\":false,\"m_showDiscountedPriceDLC3\":false,\"m_showDiscountedPriceDLC4\":false,\"m_showDiscountedPriceDLCPrimeTime\":false,\"m_showDiscountedPriceDLCHowlerTamer\":false,\"m_showDiscountedPriceDLCVividPartyStyle\":false,\"m_showDiscountedPriceDLCAuthorityPeacekeeper\":false},\"m_clearCombatTargetOnAggroLossForAllAI\":true,\"m_updateWeaponEquippedDataEveryFrame\":false,\"m_aiProximitySenseBehaviourEnabled\":true,\"m_rowName\":\"FeatureToggles\",\"Name\":\"FeatureToggles\"}]", ["DefaultInventoryInfo"] = "{\"inventoryStashLimit\":90,\"inventoryBagLimit\":300,\"inventorySafeLimit\":5}", ["InventoryInsurance"] = "{\"Default\":{\"InsuranceId\":\"Default\",\"Cost\":0.2,\"Payout\":0.5}}", ["MatchmakingSetup"] = "[]", diff --git a/src/Prospect.Server.Api/Startup.cs b/src/Prospect.Server.Api/Startup.cs index a294d5e..96e42a1 100644 --- a/src/Prospect.Server.Api/Startup.cs +++ b/src/Prospect.Server.Api/Startup.cs @@ -36,6 +36,7 @@ public class Startup services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddHostedService(); services.AddSingleton();