finish off eventoutputholder
This commit is contained in:
@@ -49,7 +49,7 @@ public class HideoutHelper(
|
||||
/// </summary>
|
||||
/// <param name="productive"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsProductionType(Productive productive)
|
||||
public bool IsProductionType(Production Production)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public class HideoutHelper(
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected void FlagCultistCircleCraftAsComplete(Productive production)
|
||||
protected void FlagCultistCircleCraftAsComplete(Production Production)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -342,7 +342,7 @@ public class HideoutHelper(
|
||||
|
||||
protected void UpdateBitcoinFarm(
|
||||
PmcData playerProfile,
|
||||
Productive btcProduction,
|
||||
Production btcProduction,
|
||||
int btcFarmCGs,
|
||||
bool isGeneratorOn)
|
||||
{
|
||||
@@ -431,7 +431,7 @@ public class HideoutHelper(
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsProduction(Productive productive)
|
||||
public bool IsProduction(Production Production)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -545,7 +545,7 @@ public record HideoutImprovement
|
||||
public long? ImproveCompleteTimestamp { get; set; }
|
||||
}
|
||||
|
||||
public record Productive
|
||||
public record Production // use this instead of productive and scavcase
|
||||
{
|
||||
public List<Product>? Products { get; set; }
|
||||
|
||||
@@ -592,17 +592,7 @@ public record Productive
|
||||
// Craft is cultist circle sacrifice
|
||||
[JsonPropertyName("sptIsCultistCircle")]
|
||||
public bool? SptIsCultistCircle { get; set; }
|
||||
}
|
||||
|
||||
public record Production : Productive
|
||||
{
|
||||
public string? RecipeId { get; set; }
|
||||
public int? SkipTime { get; set; }
|
||||
public int? ProductionTime { get; set; }
|
||||
}
|
||||
|
||||
public record ScavCase : Productive
|
||||
{
|
||||
|
||||
public string? RecipeId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public record ProfileChange
|
||||
public ItemChanges? Items { get; set; }
|
||||
|
||||
[JsonPropertyName("production")]
|
||||
public Dictionary<string, Productive>? Production { get; set; }
|
||||
public Dictionary<string, Production>? Production { get; set; }
|
||||
|
||||
/** Hideout area improvement id */
|
||||
[JsonPropertyName("improvements")]
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using SptCommon.Annotations;
|
||||
using Core.Helpers;
|
||||
using Core.Models.Eft.Common;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Eft.ItemEvent;
|
||||
using Core.Models.Utils;
|
||||
using Core.Utils;
|
||||
using Core.Utils.Cloners;
|
||||
|
||||
@@ -10,18 +12,22 @@ namespace Core.Routers;
|
||||
[Injectable]
|
||||
public class EventOutputHolder
|
||||
{
|
||||
protected ISptLogger<EventOutputHolder> _logger;
|
||||
protected ProfileHelper _profileHelper;
|
||||
protected TimeUtil _timeUtil;
|
||||
protected ICloner _cloner;
|
||||
|
||||
protected Dictionary<string, ItemEventRouterResponse> _outputStore = new();
|
||||
protected Dictionary<string, Dictionary<string, bool>> _clientActiveSessionStorage = new();
|
||||
|
||||
public EventOutputHolder(
|
||||
ISptLogger<EventOutputHolder> logger,
|
||||
ProfileHelper profileHelper,
|
||||
TimeUtil timeUtil,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_profileHelper = profileHelper;
|
||||
_timeUtil = timeUtil;
|
||||
_cloner = cloner;
|
||||
@@ -46,37 +52,149 @@ public class EventOutputHolder
|
||||
{
|
||||
var pmcProfile = _profileHelper.GetPmcProfile(sessionId);
|
||||
|
||||
_outputStore.Add(sessionId, new ItemEventRouterResponse
|
||||
{
|
||||
ProfileChanges = new Dictionary<string, ProfileChange>()
|
||||
_outputStore.Add(
|
||||
sessionId,
|
||||
new ItemEventRouterResponse
|
||||
{
|
||||
ProfileChanges = new Dictionary<string, ProfileChange>()
|
||||
{
|
||||
sessionId, new ProfileChange
|
||||
{
|
||||
Id = sessionId,
|
||||
Experience = pmcProfile.Info.Experience,
|
||||
Quests = [],
|
||||
RagFairOffers = [],
|
||||
WeaponBuilds = [],
|
||||
EquipmentBuilds = [],
|
||||
Items = new ItemChanges(){ NewItems = [], ChangedItems = [], DeletedItems = []},
|
||||
Production = new Dictionary<string, Productive>(),
|
||||
Improvements = new Dictionary<string, HideoutImprovement>(),
|
||||
Skills = new Skills{ Common = [], Mastering = [], Points = 0},
|
||||
Health = _cloner.Clone(pmcProfile.Health),
|
||||
TraderRelations = new Dictionary<string, TraderData>(),
|
||||
RecipeUnlocked = {},
|
||||
QuestsStatus = []
|
||||
sessionId, new ProfileChange
|
||||
{
|
||||
Id = sessionId,
|
||||
Experience = pmcProfile.Info.Experience,
|
||||
Quests = [],
|
||||
RagFairOffers = [],
|
||||
WeaponBuilds = [],
|
||||
EquipmentBuilds = [],
|
||||
Items = new ItemChanges { NewItems = [], ChangedItems = [], DeletedItems = [] },
|
||||
Production = new Dictionary<string, Production>(),
|
||||
Improvements = new Dictionary<string, HideoutImprovement>(),
|
||||
Skills = new Skills { Common = [], Mastering = [], Points = 0 },
|
||||
Health = _cloner.Clone(pmcProfile.Health),
|
||||
TraderRelations = new Dictionary<string, TraderData>(),
|
||||
RecipeUnlocked = { },
|
||||
QuestsStatus = []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Warnings = {}
|
||||
});
|
||||
},
|
||||
Warnings = { }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void UpdateOutputProperties(string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
PmcData pmcData = _profileHelper.GetPmcProfile(sessionId);
|
||||
ProfileChange profileChanges = _outputStore[sessionId].ProfileChanges[sessionId];
|
||||
|
||||
profileChanges.Experience = pmcData.Info.Experience;
|
||||
profileChanges.Health = _cloner.Clone(pmcData.Health);
|
||||
profileChanges.Skills.Common = _cloner.Clone(pmcData.Skills.Common); // Always send skills for Item event route response
|
||||
profileChanges.Skills.Mastering = _cloner.Clone(pmcData.Skills.Mastering);
|
||||
|
||||
// Clone productions to ensure we preseve the profile jsons data
|
||||
profileChanges.Production = GetProductionsFromProfileAndFlagComplete(
|
||||
_cloner.Clone(pmcData.Hideout.Production),
|
||||
sessionId
|
||||
);
|
||||
profileChanges.Improvements = _cloner.Clone(GetImprovementsFromProfileAndFlagComplete(pmcData));
|
||||
profileChanges.TraderRelations = ConstructTraderRelations(pmcData.TradersInfo);
|
||||
|
||||
ResetMoneyTransferLimit(pmcData.MoneyTransferLimitData);
|
||||
profileChanges.MoneyTransferLimitData = pmcData.MoneyTransferLimitData;
|
||||
|
||||
// Fixes container craft from water collector not resetting after collection + removed completed normal crafts
|
||||
CleanUpCompleteCraftsInProfile(pmcData.Hideout.Production);
|
||||
}
|
||||
|
||||
private void CleanUpCompleteCraftsInProfile(Dictionary<string, Production>? productions)
|
||||
{
|
||||
foreach (var production in productions)
|
||||
{
|
||||
if ((production.Value.SptIsComplete ?? false) && (production.Value.SptIsContinuous ?? false))
|
||||
{
|
||||
// Water collector / Bitcoin etc
|
||||
production.Value.SptIsComplete = false;
|
||||
production.Value.Progress = 0;
|
||||
production.Value.StartTimestamp = _timeUtil.GetTimeStamp().ToString();
|
||||
}
|
||||
else if (!production.Value.InProgress ?? false)
|
||||
{
|
||||
// Normal completed craft, delete
|
||||
productions.Remove(production.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, HideoutImprovement>? GetImprovementsFromProfileAndFlagComplete(PmcData pmcData)
|
||||
{
|
||||
foreach (var improvementKey in pmcData.Hideout.Improvements)
|
||||
{
|
||||
var improvement = pmcData.Hideout.Improvements[improvementKey.Key];
|
||||
|
||||
// Skip completed
|
||||
if (improvement.Completed ?? false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (improvement.ImproveCompleteTimestamp < _timeUtil.GetTimeStamp())
|
||||
{
|
||||
improvement.Completed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return pmcData.Hideout.Improvements;
|
||||
}
|
||||
|
||||
private Dictionary<string, Production>? GetProductionsFromProfileAndFlagComplete(Dictionary<string, Production>? productions, string sessionId)
|
||||
{
|
||||
foreach (var production in productions)
|
||||
{
|
||||
if (production.Value is null)
|
||||
{
|
||||
// Could be cancelled production, skip item to save processing
|
||||
continue;
|
||||
}
|
||||
|
||||
// Complete and is Continuous e.g. water collector
|
||||
if ((production.Value.SptIsComplete ?? false) && (production.Value.SptIsContinuous ?? false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip completed
|
||||
if (!production.Value.InProgress ?? false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Client informed of craft, remove from data returned
|
||||
Dictionary<string, bool>? storageForSessionId = null;
|
||||
if (!_clientActiveSessionStorage.TryGetValue(sessionId, out storageForSessionId))
|
||||
{
|
||||
_clientActiveSessionStorage.Add(sessionId, new Dictionary<string, bool>());
|
||||
storageForSessionId = _clientActiveSessionStorage[sessionId];
|
||||
}
|
||||
|
||||
// Ensure we don't inform client of production again
|
||||
if (storageForSessionId[production.Key])
|
||||
{
|
||||
productions.Remove(production.Key);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Flag started craft as having been seen by client so it won't happen subsequent times
|
||||
if (production.Value.Progress > 0 && !storageForSessionId[production.Key])
|
||||
{
|
||||
storageForSessionId[production.Key] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return undefined if there's no crafts to send to client to match live behaviour
|
||||
return productions.Keys.Count > 0 ? productions : null;
|
||||
}
|
||||
|
||||
private void ResetMoneyTransferLimit(MoneyTransferLimits limit)
|
||||
@@ -90,13 +208,16 @@ public class EventOutputHolder
|
||||
|
||||
private Dictionary<string, TraderData> ConstructTraderRelations(Dictionary<string, TraderInfo> traderData)
|
||||
{
|
||||
return traderData.ToDictionary(trader => trader.Key, trader => new TraderData()
|
||||
{
|
||||
SalesSum = trader.Value.SalesSum,
|
||||
Disabled = trader.Value.Disabled,
|
||||
Loyalty = trader.Value.LoyaltyLevel,
|
||||
Standing = trader.Value.Standing,
|
||||
Unlocked = trader.Value.Unlocked,
|
||||
});
|
||||
return traderData.ToDictionary(
|
||||
trader => trader.Key,
|
||||
trader => new TraderData()
|
||||
{
|
||||
SalesSum = trader.Value.SalesSum,
|
||||
Disabled = trader.Value.Disabled,
|
||||
Loyalty = trader.Value.LoyaltyLevel,
|
||||
Standing = trader.Value.Standing,
|
||||
Unlocked = trader.Value.Unlocked,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user