Merge pull request #29 from CWXDEV/main

More Type scaffolding
This commit is contained in:
clodanSPT
2025-01-09 19:29:38 +00:00
committed by GitHub
58 changed files with 4928 additions and 3 deletions
+9
View File
@@ -0,0 +1,9 @@
namespace Core.Models.Enums;
public enum GiftSentResult
{
FAILED_UNKNOWN = 1,
FAILED_GIFT_ALREADY_RECEIVED = 2,
FAILED_GIFT_DOESNT_EXIST = 3,
SUCCESS = 4,
}
+2 -2
View File
@@ -81,7 +81,7 @@ public class CultistCircleSettings
public int HideoutCraftSacrificeThresholdRub { get; set; }
[JsonPropertyName("craftTimeThreshholds")]
public List<CraftTimeThreshhold> CraftTimeThreshholds { get; set; }
public List<CraftTimeThreshold> CraftTimeThreshholds { get; set; }
/// <summary>
/// -1 means no override, value in seconds
@@ -117,7 +117,7 @@ public class CultistCircleSettings
public Dictionary<string, MinMax> CurrencyRewards { get; set; }
}
public class CraftTimeThreshhold : MinMax
public class CraftTimeThreshold : MinMax
{
[JsonPropertyName("craftTimeSeconds")]
public int CraftTimeSeconds { get; set; }
@@ -16,5 +16,5 @@ public class CircleCraftDetails
public int? RewardAmountRoubles { get; set; }
[JsonPropertyName("rewardDetails")]
public CraftTimeThreshhold? RewardDetails { get; set; }
public CraftTimeThreshold? RewardDetails { get; set; }
}
+55
View File
@@ -0,0 +1,55 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Location;
using Core.Models.Enums;
using Core.Models.Spt.Services;
namespace Core.Services;
public class AirdropService
{
public GetAirdropLootResponse GenerateCustomAirdropLoot(GetAirdropLootRequest request)
{
throw new NotImplementedException();
}
/// <summary>
/// Handle client/location/getAirdropLoot
/// Get loot for an airdrop container
/// Generates it randomly based on config/airdrop.json values
/// </summary>
/// <param name="forcedAirdropType">OPTIONAL - Desired airdrop type, randomised when not provided</param>
/// <returns>List of LootItem objects</returns>
public GetAirdropLootResponse GenerateAirdropLoot(string forcedAirdropType = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a container create item based on passed in airdrop type
/// </summary>
/// <param name="airdropType">What type of container: weapon/common etc</param>
/// <returns>Item</returns>
protected Item GetAirdropCrateItem(SptAirdropTypeEnum airdropType)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomly pick a type of airdrop loot using weighted values from config
/// </summary>
/// <returns>airdrop type value</returns>
protected SptAirdropTypeEnum ChooseAirdropType()
{
throw new NotImplementedException();
}
/// <summary>
/// Get the configuration for a specific type of airdrop
/// </summary>
/// <param name="airdropType">Type of airdrop to get settings for</param>
/// <returns>LootRequest</returns>
protected LootRequest GetAirdropLootConfigByType(AirdropTypeEnum airdropType)
{
throw new NotImplementedException();
}
}
+137
View File
@@ -0,0 +1,137 @@
namespace Core.Services;
public class BackupService
{
/**
* Initializes the backup process.
*
* This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning
* up old backups if the number exceeds the configured maximum.
*
* @returns A promise that resolves when the backup process is complete.
*/
public async Task InitAsync()
{
throw new NotImplementedException();
}
/**
* Fetches the names of all JSON files in the profile directory.
*
* This method normalizes the profile directory path and reads all files within it. It then filters the files to
* include only those with a `.json` extension and returns their names.
*
* @returns A promise that resolves to a List of JSON file names.
*/
protected async Task<List<string>> FetchProfileFilesAsync()
{
throw new NotImplementedException();
}
/**
* Check to see if the backup service is enabled via the config.
*
* @returns True if enabled, false otherwise.
*/
protected bool IsEnabled()
{
throw new NotImplementedException();
}
/**
* Generates the target directory path for the backup. The directory path is constructed using the `directory` from
* the configuration and the current backup date.
*
* @returns The target directory path for the backup.
*/
protected string GenerateBackupTargetDir()
{
throw new NotImplementedException();
}
/**
* Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`.
*
* @returns The formatted backup date string.
*/
protected string GenerateBackupDate()
{
throw new NotImplementedException();
}
/**
* Cleans up old backups in the backup directory.
*
* This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds
* the configured maximum, it deletes the oldest backups.
*
* @returns A promise that resolves when the cleanup is complete.
*/
protected async Task CleanBackupsAsync()
{
throw new NotImplementedException();
}
/**
* Retrieves and sorts the backup file paths from the specified directory.
*
* @param dir - The directory to search for backup files.
* @returns A promise that resolves to a List of sorted backup file paths.
*/
private async Task<List<string>> GetBackupPathsAsync(string dir)
{
throw new NotImplementedException();
}
/**
* Compares two backup folder names based on their extracted dates.
*
* @param a - The name of the first backup folder.
* @param b - The name of the second backup folder.
* @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid.
*/
private long? CompareBackupDates(string a, string b)
{
throw new NotImplementedException();
}
/**
* Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`.
*
* @param folderName - The name of the folder from which to extract the date.
* @returns A DateTime object if the folder name is in the correct format, otherwise null.
*/
private DateTime? ExtractDateFromFolderName(string folderName)
{
throw new NotImplementedException();
}
/**
* Removes excess backups from the backup directory.
*
* @param backups - A List of backup file names to be removed.
* @returns A promise that resolves when all specified backups have been removed.
*/
private async Task RemoveExcessBackupsAsync(List<string> backups)
{
throw new NotImplementedException();
}
/**
* Start the backup interval if enabled in the configuration.
*/
protected void StartBackupInterval()
{
throw new NotImplementedException();
}
/**
* Get a List of active server mod details.
*
* @returns A List of mod names.
*/
protected List<string> GetActiveServerMods()
{
throw new NotImplementedException();
}
}
+156
View File
@@ -0,0 +1,156 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Bots;
using Core.Models.Spt.Config;
namespace Core.Services;
public class BotEquipmentFilterService
{
/// <summary>
/// Filter a bots data to exclude equipment and cartridges defines in the botConfig
/// </summary>
/// <param name="sessionId">Players id</param>
/// <param name="baseBotNode">bots json data to filter</param>
/// <param name="botLevel">Level of the bot</param>
/// <param name="botGenerationDetails">details on how to generate a bot</param>
public void FilterBotEquipment(
string sessionId,
BotType baseBotNode,
int botLevel,
BotGenerationDetails botGenerationDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Iterate over the changes passed in and apply them to baseValues parameter
/// </summary>
/// <param name="equipmentChanges">Changes to apply</param>
/// <param name="baseValues">data to update</param>
protected void AdjustChances(
Dictionary<string, int> equipmentChanges,
EquipmentChances baseValues)
{
throw new NotImplementedException();
}
/// <summary>
/// Iterate over the Generation changes and alter data in baseValues.Generation
/// </summary>
/// <param name="generationChanges">Changes to apply</param>
/// <param name="baseBotGeneration">dictionary to update</param>
protected void AdjustGenerationChances(
Dictionary<string, GenerationData> generationChanges,
Generation baseBotGeneration)
{
throw new NotImplementedException();
}
/// <summary>
/// Get equipment settings for bot
/// </summary>
/// <param name="botEquipmentRole">equipment role to return</param>
/// <returns>EquipmentFilters object</returns>
public EquipmentFilters GetBotEquipmentSettings(string botEquipmentRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Get weapon sight whitelist for a specific bot type
/// </summary>
/// <param name="botEquipmentRole">equipment role of bot to look up</param>
/// <returns>Dictionary of weapon type and their whitelisted scope types</returns>
public Dictionary<string, List<string>> GetBotWeaponSightWhitelist(string botEquipmentRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Get an object that contains equipment and cartridge blacklists for a specified bot type
/// </summary>
/// <param name="botRole">Role of the bot we want the blacklist for</param>
/// <param name="playerLevel">Level of the player</param>
/// <returns>EquipmentBlacklistDetails object</returns>
public EquipmentFilterDetails GetBotEquipmentBlacklist(string botRole, int playerLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the whitelist for a specific bot type that's within the players level
/// </summary>
/// <param name="botRole">Bot type</param>
/// <param name="playerLevel">Players level</param>
/// <returns>EquipmentFilterDetails object</returns>
protected EquipmentFilterDetails GetBotEquipmentWhitelist(string botRole, int playerLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Retrieve item weighting adjustments from bot.json config based on bot level
/// </summary>
/// <param name="botRole">Bot type to get adjustments for</param>
/// <param name="botLevel">Level of bot</param>
/// <returns>Weighting adjustments for bot items</returns>
protected WeightingAdjustmentDetails GetBotWeightingAdjustments(string botRole, int botLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Retrieve item weighting adjustments from bot.json config based on player level
/// </summary>
/// <param name="botRole">Bot type to get adjustments for</param>
/// <param name="playerlevel">Level of bot</param>
/// <returns>Weighting adjustments for bot items</returns>
protected WeightingAdjustmentDetails GetBotWeightingAdjustmentsByPlayerLevel(string botRole, int playerlevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Filter bot equipment based on blacklist and whitelist from config/bot.json
/// Prioritizes whitelist first, if one is found blacklist is ignored
/// </summary>
/// <param name="baseBotNode">bot .json file to update</param>
/// <param name="blacklist">equipment blacklist</param>
/// <returns>Filtered bot file</returns>
protected void FilterEquipment(
BotType baseBotNode,
EquipmentFilterDetails blacklist,
EquipmentFilterDetails whitelist)
{
throw new NotImplementedException();
}
/// <summary>
/// Filter bot cartridges based on blacklist and whitelist from config/bot.json
/// Prioritizes whitelist first, if one is found blacklist is ignored
/// </summary>
/// <param name="baseBotNode">bot .json file to update</param>
/// <param name="blacklist">equipment on this list should be excluded from the bot</param>
/// <param name="whitelist">equipment on this list should be used exclusively</param>
/// <returns>Filtered bot file</returns>
protected void FilterCartridges(
BotType baseBotNode,
EquipmentFilterDetails blacklist,
EquipmentFilterDetails whitelist)
{
throw new NotImplementedException();
}
/// <summary>
/// Add/Edit weighting changes to bot items using values from config/bot.json/equipment
/// </summary>
/// <param name="weightingAdjustments">Weighting change to apply to bot</param>
/// <param name="botItemPool">Bot item dictionary to adjust</param>
protected void AdjustWeighting(
AdjustmentDetails weightingAdjustments,
Dictionary<string, object> botItemPool,
bool showEditWarnings = true)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,81 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Services;
public class BotEquipmentModPoolService
{
/**
* Store dictionary of mods for each item passed in
* @param items items to find related mods and store in modPool
*/
protected void GeneratePool(List<TemplateItem> items, string poolType)
{
throw new NotImplementedException();
}
/**
* Empty the mod pool
*/
public void ResetPool()
{
throw new NotImplementedException();
}
/**
* Get array of compatible mods for an items mod slot (generate pool if it doesnt exist already)
* @param itemTpl item to look up
* @param slotName slot to get compatible mods for
* @returns tpls that fit the slot
*/
public List<string> GetCompatibleModsForWeaponSlot(string itemTpl, string slotName)
{
throw new NotImplementedException();
}
/**
* Get array of compatible mods for an items mod slot (generate pool if it doesnt exist already)
* @param itemTpl item to look up
* @param slotName slot to get compatible mods for
* @returns tpls that fit the slot
*/
public List<string> GetCompatibleModsForGearSlot(string itemTpl, string slotName)
{
throw new NotImplementedException();
}
/**
* Get mods for a piece of gear by its tpl
* @param itemTpl items tpl to look up mods for
* @returns Dictionary of mods (keys are mod slot names) with array of compatible mod tpls as value
*/
public Dictionary<string, List<string>> GetModsForGearSlot(string itemTpl)
{
throw new NotImplementedException();
}
/**
* Get mods for a weapon by its tpl
* @param itemTpl Weapons tpl to look up mods for
* @returns Dictionary of mods (keys are mod slot names) with array of compatible mod tpls as value
*/
public Dictionary<string, List<string>> GetModsForWeaponSlot(string itemTpl)
{
throw new NotImplementedException();
}
/**
* Create weapon mod pool and set generated flag to true
*/
protected void GenerateWeaponPool()
{
throw new NotImplementedException();
}
/**
* Create gear mod pool and set generated flag to true
*/
protected void GenerateGearPool()
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,73 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Services;
public class BotGenerationCacheService
{
/**
* Store list of bots in cache, shuffle results before storage
* @param botsToStore Bots we want to store in the cache
*/
public void StoreBots(string key, List<BotBase> botsToStore)
{
throw new NotImplementedException();
}
/**
* Find and return a bot based on its role
* Remove bot from internal list so it can't be retrieved again
* @param key role to retrieve (assault/bossTagilla etc)
* @returns BotBase object
*/
public BotBase GetBot(string key)
{
throw new NotImplementedException();
}
/**
* Cache a bot that has been sent to the client in memory for later use post-raid to determine if player killed a traitor scav
* @param botToStore Bot object to store
*/
public void StoreUsedBot(BotBase botToStore)
{
throw new NotImplementedException();
}
/**
* Get a bot by its profileId that has been generated and sent to client for current raid
* Cache is wiped post-raid in client/match/offline/end endOfflineRaid()
* @param profileId Id of bot to get
* @returns BotBase
*/
public BotBase GetUsedBot(string profileId)
{
throw new NotImplementedException();
}
/**
* Remove all cached bot profiles from memory
*/
public void ClearStoredBots()
{
throw new NotImplementedException();
}
/**
* Does cache have a bot with requested key
* @returns false if empty
*/
public bool CacheHasBotWithKey(string key, int size = 0)
{
throw new NotImplementedException();
}
public int GetCachedBotCount(string key)
{
throw new NotImplementedException();
}
public string CreateCacheKey(string role, string difficulty)
{
throw new NotImplementedException();
}
}
+144
View File
@@ -0,0 +1,144 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Bots;
using Props = Core.Models.Eft.Common.Props;
namespace Core.Services;
public class BotLootCacheService
{
/// <summary>
/// Remove cached bot loot data
/// </summary>
public void ClearCache()
{
throw new NotImplementedException();
}
/// <summary>
/// Get the fully created loot array, ordered by price low to high
/// </summary>
/// <param name="botRole">bot to get loot for</param>
/// <param name="isPmc">is the bot a pmc</param>
/// <param name="lootType">what type of loot is needed (backpack/pocket/stim/vest etc)</param>
/// <param name="botJsonTemplate">Base json db file for the bot having its loot generated</param>
/// <returns>Dictionary<string, int></returns>
public Dictionary<string, int> GetLootFromCache(
string botRole,
bool isPmc,
string lootType,
BotType botJsonTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Generate loot for a bot and store inside a private class property
/// </summary>
/// <param name="botRole">bots role (assault / pmcBot etc)</param>
/// <param name="isPmc">Is the bot a PMC (alteres what loot is cached)</param>
/// <param name="botJsonTemplate">db template for bot having its loot generated</param>
protected void AddLootToCache(string botRole, bool isPmc, BotType botJsonTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Add unique items into combined pool
/// </summary>
/// <param name="poolToAddTo">Pool of items to add to</param>
/// <param name="itemsToAdd">items to add to combined pool if unique</param>
protected void AddUniqueItemsToPool(List<TemplateItem> poolToAddTo, List<TemplateItem> itemsToAdd)
{
throw new NotImplementedException();
}
protected void AddItemsToPool(Dictionary<string, int> poolToAddTo, Dictionary<string, int> poolOfItemsToAdd)
{
throw new NotImplementedException();
}
/// <summary>
/// Ammo/grenades have this property
/// </summary>
/// <param name="props"></param>
/// <returns></returns>
protected bool IsBulletOrGrenade(Props props)
{
throw new NotImplementedException();
}
/// <summary>
/// Internal and external magazine have this property
/// </summary>
/// <param name="props"></param>
/// <returns></returns>
protected bool IsMagazine(Props props)
{
throw new NotImplementedException();
}
/// <summary>
/// Medical use items (e.g. morphine/lip balm/grizzly)
/// </summary>
/// <param name="props"></param>
/// <returns></returns>
protected bool IsMedicalItem(Props props)
{
throw new NotImplementedException();
}
/// <summary>
/// Grenades have this property (e.g. smoke/frag/flash grenades)
/// </summary>
/// <param name="props"></param>
/// <returns></returns>
protected bool IsGrenade(Props props)
{
throw new NotImplementedException();
}
protected bool IsFood(string tpl)
{
throw new NotImplementedException();
}
protected bool IsDrink(string tpl)
{
throw new NotImplementedException();
}
protected bool IsCurrency(string tpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if a bot type exists inside the loot cache
/// </summary>
/// <param name="botRole">role to check for</param>
/// <returns>true if they exist</returns>
protected bool BotRoleExistsInCache(string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// If lootcache is undefined, init with empty property arrays
/// </summary>
/// <param name="botRole">Bot role to hydrate</param>
protected void InitCacheForBotRole(string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Compares two item prices by their flea (or handbook if that doesnt exist) price
/// </summary>
/// <param name="itemAPrice"></param>
/// <param name="itemBPrice"></param>
/// <returns></returns>
protected int CompareByValue(int itemAPrice, int itemBPrice)
{
throw new NotImplementedException();
}
}
+51
View File
@@ -0,0 +1,51 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Bots;
namespace Core.Services;
public class BotNameService
{
/// <summary>
/// Clear out any entries in Name Set
/// </summary>
public void ClearNameCache()
{
throw new NotImplementedException();
}
/// <summary>
/// Create a unique bot nickname
/// </summary>
/// <param name="botJsonTemplate">bot JSON data from db</param>
/// <param name="botGenerationDetails"></param>
/// <param name="botRole">role of bot e.g. assault</param>
/// <param name="uniqueRoles">Lowercase roles to always make unique</param>
/// <param name="sessionId">OPTIONAL: profile session id</param>
/// <returns>Nickname for bot</returns>
public string GenerateUniqueBotNickname(
BotType botJsonTemplate,
BotGenerationDetails botGenerationDetails,
string botRole,
List<string> uniqueRoles = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Add random PMC name to bots MainProfileNickname property
/// </summary>
/// <param name="bot">Bot to update</param>
public void AddRandomPmcNameToBotMainProfileNicknameProperty(BotBase bot)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose a random PMC name from bear or usec bot jsons
/// </summary>
/// <returns>PMC name as string</returns>
protected string GetRandomPMCName()
{
throw new NotImplementedException();
}
}
+57
View File
@@ -0,0 +1,57 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Bots;
namespace Core.Services;
public class BotWeaponModLimitService
{
/// <summary>
/// Initalise mod limits to be used when generating a weapon
/// </summary>
/// <param name="botRole">"assault", "bossTagilla" or "pmc"</param>
/// <returns>BotModLimits object</returns>
public BotModLimits GetWeaponModLimits(string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if weapon mod item is on limited list + has surpassed the limit set for it
/// Exception: Always allow ncstar backup mount
/// Exception: Always allow scopes with a scope for a parent
/// Exception: Always disallow mounts that hold only scopes once scope limit reached
/// Exception: Always disallow mounts that hold only flashlights once flashlight limit reached
/// </summary>
/// <param name="botRole">role the bot has e.g. assault</param>
/// <param name="modTemplate">mods template data</param>
/// <param name="modLimits">limits set for weapon being generated for this bot</param>
/// <param name="modsParent">The parent of the mod to be checked</param>
/// <param name="weapon">Array of IItem</param>
/// <returns>true if over item limit</returns>
public bool WeaponModHasReachedLimit(
string botRole,
TemplateItem modTemplate,
BotModLimits modLimits,
TemplateItem modsParent,
List<Item> weapon)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if the specific item type on the weapon has reached the set limit
/// </summary>
/// <param name="modTpl">log mod tpl if over type limit</param>
/// <param name="currentCount">current number of this item on gun</param>
/// <param name="maxLimit">mod limit allowed</param>
/// <param name="botRole">role of bot we're checking weapon of</param>
/// <returns>true if limit reached</returns>
protected bool WeaponModLimitReached(
string modTpl,
object currentCount,
int maxLimit,
string botRole)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,29 @@
namespace Core.Services.Cache;
public class BundleHashCacheService
{
public int GetStoredValue(string key)
{
throw new NotImplementedException();
}
public void StoreValue(string key, int value)
{
throw new NotImplementedException();
}
public bool MatchWithStoredHash(string bundlePath, int hash)
{
throw new NotImplementedException();
}
public bool CalculateAndMatchHash(string bundlePath)
{
throw new NotImplementedException();
}
public void CalculateAndStoreHash(string bundlePath)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,29 @@
namespace Core.Services.Cache;
public class ModHashCacheService
{
public string GetStoredValue(string key)
{
throw new NotImplementedException();
}
public void StoreValue(string key, string value)
{
throw new NotImplementedException();
}
public bool MatchWithStoredHash(string modName, string hash)
{
throw new NotImplementedException();
}
public bool CalculateAndCompareHash(string modName, string modContent)
{
throw new NotImplementedException();
}
public void CalculateAndStoreHash(string modName, string modContent)
{
throw new NotImplementedException();
}
}
+298
View File
@@ -0,0 +1,298 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Hideout;
using Core.Models.Eft.ItemEvent;
using Core.Models.Spt.Config;
using Core.Models.Spt.Hideout;
using Hideout = Core.Models.Eft.Common.Tables.Hideout;
namespace Core.Services;
public class CircleOfCultistService
{
/// <summary>
/// Start a sacrifice event
/// Generate rewards
/// Delete sacrificed items
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Player profile doing sacrifice</param>
/// <param name="request">Client request</param>
/// <returns>ItemEventRouterResponse</returns>
public ItemEventRouterResponse StartSacrifice(
string sessionId,
PmcData pmcData,
HideoutCircleOfCultistProductionStartRequestData request
)
{
throw new NotImplementedException();
}
/// <summary>
/// Attempt to add all rewards to cultist circle, if they don't fit remove one and try again until they fit
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Player profile</param>
/// <param name="rewards">Rewards to send to player</param>
/// <param name="containerGrid">Cultist grid to add rewards to</param>
/// <param name="cultistCircleStashId">Stash id</param>
/// <param name="output">Client output</param>
protected void AddRewardsToCircleContainer(
string sessionId,
PmcData pmcData,
List<List<Item>> rewards,
List<List<int>> containerGrid,
string cultistCircleStashId,
ItemEventRouterResponse output
)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a map of the possible direct rewards, keyed by the items needed to be sacrificed
/// </summary>
/// <param name="directRewards">Direct rewards array from hideout config</param>
/// <returns>Dictionary</returns>
protected Dictionary<string, DirectRewardSettings> GenerateSacrificedItemsCache(List<DirectRewardSettings> directRewards)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="cultistCircleSettings">Circle config settings</param>
/// <returns>Reward Amount Multiplier</returns>
protected double GetRewardAmountMultiplier(PmcData pmcData, CultistCircleSettings cultistCircleSettings)
{
throw new NotImplementedException();
}
/// <summary>
/// Register production inside player profile
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Player profile</param>
/// <param name="recipeId">Recipe id</param>
/// <param name="sacrificedItems">Items player sacrificed</param>
/// <param name="craftingTime">How long the ritual should take</param>
protected void RegisterCircleOfCultistProduction(
string sessionId,
PmcData pmcData,
string recipeId,
List<Item> sacrificedItems,
double craftingTime
)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the circle craft time as seconds, value is based on reward item value
/// And get the bonus status to determine what tier of reward is given
/// </summary>
/// <param name="rewardAmountRoubles">Value of rewards in roubles</param>
/// <param name="circleConfig">Circle config values</param>
/// <param name="directRewardSettings">OPTIONAL - Values related to direct reward being given</param>
/// <returns>craft time + type of reward + reward details</returns>
protected CircleCraftDetails GetCircleCraftingInfo(
double rewardAmountRoubles,
CultistCircleSettings circleConfig,
DirectRewardSettings directRewardSettings = null
)
{
throw new NotImplementedException();
}
protected CraftTimeThreshold GetMatchingThreshold(
List<CraftTimeThreshold> thresholds,
double rewardAmountRoubles
)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the items player sacrificed in circle
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <returns>Array of items from player inventory</returns>
protected List<Item> GetSacrificedItems(PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Given a pool of items + rouble budget, pick items until the budget is reached
/// </summary>
/// <param name="rewardItemTplPool">Items that can be picked</param>
/// <param name="rewardBudget">Rouble budget to reach</param>
/// <param name="cultistCircleStashId">Id of stash item</param>
/// <returns>Array of item arrays</returns>
protected List<List<Item>> GetRewardsWithinBudget(
List<string> rewardItemTplPool,
double rewardBudget,
string cultistCircleStashId,
CultistCircleSettings circleConfig
)
{
throw new NotImplementedException();
}
/// <summary>
/// Get direct rewards
/// </summary>
/// <param name="sessionId">sessionId</param>
/// <param name="directReward">Items sacrificed</param>
/// <param name="cultistCircleStashId">Id of stash item</param>
/// <returns>The reward object</returns>
protected List<List<Item>> GetDirectRewards(
string sessionId,
DirectRewardSettings directReward,
string cultistCircleStashId
)
{
throw new NotImplementedException();
}
/// <summary>
/// Check for direct rewards from what player sacrificed
/// </summary>
/// <param name="sessionId">sessionId</param>
/// <param name="sacrificedItems">Items sacrificed</param>
/// <returns>Direct reward items to send to player</returns>
protected DirectRewardSettings CheckForDirectReward(
string sessionId,
List<Item> sacrificedItems,
Dictionary<string, DirectRewardSettings> directRewardsCache
)
{
throw new NotImplementedException();
}
/// <summary>
/// Create an md5 key of the sacrificed + reward items
/// </summary>
/// <param name="directReward">Direct reward to create key for</param>
/// <returns>Key</returns>
protected string GetDirectRewardHashKey(DirectRewardSettings directReward)
{
throw new NotImplementedException();
}
/// <summary>
/// Explicit rewards have their own stack sizes as they don't use a reward rouble pool
/// </summary>
/// <param name="rewardTpl">Item being rewarded to get stack size of</param>
/// <returns>stack size of item</returns>
protected int GetDirectRewardBaseTypeStackSize(string rewardTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Add a record to the player's profile to signal they have accepted a non-repeatable direct reward
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="directReward">Reward sent to player</param>
protected void FlagDirectRewardAsAcceptedInProfile(string sessionId, DirectRewardSettings directReward)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the size of a reward item's stack
/// 1 for everything except ammo, ammo can be between min stack and max stack
/// </summary>
/// <param name="itemTpl">Item chosen</param>
/// <param name="rewardPoolRemaining">Rouble amount of pool remaining to fill</param>
/// <returns>Size of stack</returns>
protected int GetRewardStackSize(string itemTpl, int rewardPoolRemaining)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Profile of player who will be getting the rewards</param>
/// <param name="rewardType">Do we return bonus items (hideout/task items)</param>
/// <param name="cultistCircleConfig">Circle config</param>
/// <returns>Array of tpls</returns>
protected string[] GetCultistCircleRewardPool(
string sessionId,
PmcData pmcData,
CircleCraftDetails craftingInfo,
CultistCircleSettings cultistCircleConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// Check player's profile for quests with hand-in requirements and add those required items to the pool
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="itemRewardBlacklist">Items not to add to pool</param>
/// <param name="rewardPool">Pool to add items to</param>
protected void AddTaskItemRequirementsToRewardPool(
PmcData pmcData,
HashSet<string> itemRewardBlacklist,
HashSet<string> rewardPool)
{
throw new NotImplementedException();
}
/// <summary>
/// Adds items the player needs to complete hideout crafts/upgrades to the reward pool
/// </summary>
/// <param name="hideoutDbData">Hideout area data</param>
/// <param name="pmcData">Player profile</param>
/// <param name="itemRewardBlacklist">Items not to add to pool</param>
/// <param name="rewardPool">Pool to add items to</param>
protected void AddHideoutUpgradeRequirementsToRewardPool(
Hideout hideoutDbData,
PmcData pmcData,
HashSet<string> itemRewardBlacklist,
HashSet<string> rewardPool)
{
throw new NotImplementedException();
}
/// <summary>
/// Get all active hideout areas
/// </summary>
/// <param name="areas">Hideout areas to iterate over</param>
/// <returns>Active area array</returns>
protected BotHideoutArea[] GetPlayerAccessibleHideoutAreas(BotHideoutArea[] areas)
{
throw new NotImplementedException();
}
/// <summary>
/// Get array of random reward items
/// </summary>
/// <param name="rewardPool">Reward pool to add to</param>
/// <param name="itemRewardBlacklist">Item tpls to ignore</param>
/// <param name="itemsShouldBeHighValue">Should these items meet the valuable threshold</param>
/// <returns>Set of item tpls</returns>
protected HashSet<string> GenerateRandomisedItemsAndAddToRewardPool(
HashSet<string> rewardPool,
HashSet<string> itemRewardBlacklist,
bool itemsShouldBeHighValue)
{
throw new NotImplementedException();
}
/// <summary>
/// Iterate over passed in hideout requirements and return the Item
/// </summary>
/// <param name="requirements">Requirements to iterate over</param>
/// <returns>Array of item requirements</returns>
protected (StageRequirement[] StageRequirement, Requirement[] Requirement) GetItemRequirements(RequirementBase[] requirements)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,52 @@
using Core.Models.Eft.Common;
namespace Core.Services;
public class CustomLocationWaveService
{
/// <summary>
/// Add a boss wave to a map
/// </summary>
/// <param name="locationId">e.g. factory4_day, bigmap</param>
/// <param name="waveToAdd">Boss wave to add to map</param>
public void AddBossWaveToMap(string locationId, BossLocationSpawn waveToAdd)
{
throw new NotImplementedException();
}
/// <summary>
/// Add a normal bot wave to a map
/// </summary>
/// <param name="locationId">e.g. factory4_day, bigmap</param>
/// <param name="waveToAdd">Wave to add to map</param>
public void AddNormalWaveToMap(string locationId, Wave waveToAdd)
{
throw new NotImplementedException();
}
/// <summary>
/// Clear all custom boss waves from a map
/// </summary>
/// <param name="locationId">e.g. factory4_day, bigmap</param>
public void ClearBossWavesForMap(string locationId)
{
throw new NotImplementedException();
}
/// <summary>
/// Clear all custom normal waves from a map
/// </summary>
/// <param name="locationId">e.g. factory4_day, bigmap</param>
public void ClearNormalWavesForMap(string locationId)
{
throw new NotImplementedException();
}
/// <summary>
/// Add custom boss and normal waves to maps found in config/location.json to db
/// </summary>
public void ApplyWaveChangesToAllMaps()
{
throw new NotImplementedException();
}
}
+512
View File
@@ -0,0 +1,512 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
using Core.Models.Spt.Fence;
namespace Core.Services;
public class FenceService
{
/// <summary>
/// Replace main fence assort with new assort
/// </summary>
/// <param name="assort">New assorts to replace old with</param>
public void SetFenceAssort(TraderAssort assort)
{
throw new NotImplementedException();
}
/// <summary>
/// Replace discount fence assort with new assort
/// </summary>
/// <param name="assort">New assorts to replace old with</param>
public void SetDiscountFenceAssort(TraderAssort assort)
{
throw new NotImplementedException();
}
/// <summary>
/// Get main fence assort
/// </summary>
/// <returns>TraderAssort</returns>
public TraderAssort GetMainFenceAssort()
{
throw new NotImplementedException();
}
/// <summary>
/// Get discount fence assort
/// </summary>
/// <returns>TraderAssort</returns>
public TraderAssort GetDiscountFenceAssort()
{
throw new NotImplementedException();
}
/// <summary>
/// Replace high rep level fence assort with new assort
/// </summary>
/// <param name="discountAssort">New assorts to replace old with</param>
public void SetFenceDiscountAssort(TraderAssort discountAssort)
{
throw new NotImplementedException();
}
/// <summary>
/// Get assorts player can purchase
/// Adjust prices based on fence level of player
/// </summary>
/// <param name="pmcProfile">Player profile</param>
/// <returns>TraderAssort</returns>
public TraderAssort GetFenceAssorts(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Adds to fence assort a single item (with its children)
/// </summary>
/// <param name="items">the items to add with all its childrens</param>
/// <param name="mainItem">the most parent item of the array</param>
public void AddItemsToFenceAssort(List<Item> items, Item mainItem)
{
throw new NotImplementedException();
}
/// <summary>
/// Calculates the overall price for an item (with all its children)
/// </summary>
/// <param name="itemTpl">the item tpl to calculate the fence price for</param>
/// <param name="items">the items (with its children) to calculate fence price for</param>
/// <returns>the fence price of the item</returns>
public double GetItemPrice(string itemTpl, List<Item> items)
{
throw new NotImplementedException();
}
/// <summary>
/// Calculate the overall price for an ammo box, where only one item is
/// the ammo box itself and every other items are the bullets in that box
/// </summary>
/// <param name="items">the ammo box (and all its children ammo items)</param>
/// <returns>the price of the ammo box</returns>
protected double GetAmmoBoxPrice(List<Item> items)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust all items contained inside an assort by a multiplier
/// </summary>
/// <param name="assort">(clone)Assort that contains items with prices to adjust</param>
/// <param name="itemMultipler">multipler to use on items</param>
/// <param name="presetMultiplier">preset multipler to use on presets</param>
protected void AdjustAssortItemPricesByConfigMultiplier(
TraderAssort assort,
double itemMultipler,
double presetMultiplier)
{
throw new NotImplementedException();
}
/// <summary>
/// Merge two trader assort files together
/// </summary>
/// <param name="firstAssort">assort 1#</param>
/// <param name="secondAssort">assort #2</param>
/// <returns>merged assort</returns>
protected TraderAssort MergeAssorts(TraderAssort firstAssort, TraderAssort secondAssort)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust assorts price by a modifier
/// </summary>
/// <param name="item">assort item details</param>
/// <param name="assort">assort to be modified</param>
/// <param name="modifier">value to multiply item price by</param>
/// <param name="presetModifier">value to multiply preset price by</param>
protected void AdjustItemPriceByModifier(
Item item,
TraderAssort assort,
double modifier,
double presetModifier)
{
throw new NotImplementedException();
}
/// <summary>
/// Get fence assorts with no price adjustments based on fence rep
/// </summary>
/// <returns>TraderAssort</returns>
public TraderAssort GetRawFenceAssorts()
{
throw new NotImplementedException();
}
/// <summary>
/// Does fence need to perform a partial refresh because its passed the refresh timer defined in trader.json
/// </summary>
/// <returns>true if it needs a partial refresh</returns>
public bool NeedsPartialRefresh()
{
throw new NotImplementedException();
}
/// <summary>
/// Replace a percentage of fence assorts with freshly generated items
/// </summary>
public void PerformPartialRefresh()
{
throw new NotImplementedException();
}
/// <summary>
/// Handle the process of folding new assorts into existing assorts, when a new assort exists already, increment its StackObjectsCount instead
/// </summary>
/// <param name="newFenceAssorts">Assorts to fold into existing fence assorts</param>
/// <param name="existingFenceAssorts">Current fence assorts new assorts will be added to</param>
protected void UpdateFenceAssorts(
CreateFenceAssortsResult newFenceAssorts,
TraderAssort existingFenceAssorts
)
{
throw new NotImplementedException();
}
/// <summary>
/// Increment fence next refresh timestamp by current timestamp + partialRefreshTimeSeconds from config
/// </summary>
protected void IncrementPartialRefreshTime()
{
throw new NotImplementedException();
}
/// <summary>
/// Get values that will hydrate the passed in assorts back to the desired counts
/// </summary>
/// <param name="assortItems">Current assorts after items have been removed</param>
/// <param name="generationValues">Base counts assorts should be adjusted to</param>
/// <returns>GenerationAssortValues object with adjustments needed to reach desired state</returns>
protected GenerationAssortValues GetItemCountsToGenerate(
Item[] assortItems,
GenerationAssortValues generationValues
)
{
throw new NotImplementedException();
}
/// <summary>
/// Delete desired number of items from assort (including children)
/// </summary>
/// <param name="itemCountToReplace"></param>
/// <param name="assort"></param>
protected void DeleteRandomAssorts(int itemCountToReplace, TraderAssort assort)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose an item at random and remove it + mods from assorts
/// </summary>
/// <param name="assort">Trader assort to remove item from</param>
/// <param name="rootItems">Pool of root items to pick from to remove</param>
protected void RemoveRandomItemFromAssorts(TraderAssort assort, Item[] rootItems)
{
throw new NotImplementedException();
}
/// <summary>
/// Get an integer rounded count of items to replace based on percentrage from traderConfig value
/// </summary>
/// <param name="totalItemCount">total item count</param>
/// <returns>rounded int of items to replace</returns>
protected int GetCountOfItemsToReplace(int totalItemCount)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the count of items fence offers
/// </summary>
/// <returns>int</returns>
public int GetOfferCount()
{
throw new NotImplementedException();
}
/// <summary>
/// Create trader assorts for fence and store in fenceService cache
/// Uses fence base cache generated on server start as a base
/// </summary>
public void GenerateFenceAssorts()
{
throw new NotImplementedException();
}
/// <summary>
/// Convert the intermediary assort data generated into format client can process
/// </summary>
/// <param name="intermediaryAssorts">Generated assorts that will be converted</param>
/// <returns>TraderAssort</returns>
protected TraderAssort ConvertIntoFenceAssort(CreateFenceAssortsResult intermediaryAssorts)
{
throw new NotImplementedException();
}
/// <summary>
/// Create object that contains calculated fence assort item values to make based on config
/// Stored in this.DesiredAssortCounts
/// </summary>
protected void CreateInitialFenceAssortGenerationValues()
{
throw new NotImplementedException();
}
/// <summary>
/// Create skeleton to hold assort items
/// </summary>
/// <returns>TraderAssort object</returns>
protected TraderAssort CreateFenceAssortSkeleton()
{
throw new NotImplementedException();
}
/// <summary>
/// Hydrate assorts parameter object with generated assorts
/// </summary>
/// <param name="itemCounts">Number of assorts to generate</param>
/// <param name="loyaltyLevel">Loyalty level to set new item to</param>
/// <returns>CreateFenceAssortsResult</returns>
protected CreateFenceAssortsResult CreateAssorts(GenerationAssortValues itemCounts, int loyaltyLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Add item assorts to existing assort data
/// </summary>
/// <param name="assortCount">Number to add</param>
/// <param name="assorts">Assorts data to add to</param>
/// <param name="baseFenceAssortClone">Base data to draw from</param>
/// <param name="itemTypeLimits"></param>
/// <param name="loyaltyLevel">Loyalty level to set new item to</param>
protected void AddItemAssorts(
int assortCount,
CreateFenceAssortsResult assorts,
TraderAssort baseFenceAssortClone,
Dictionary<string, (int current, int max)> itemTypeLimits,
int loyaltyLevel
)
{
throw new NotImplementedException();
}
/// <summary>
/// Find an assort item that matches the first parameter, also matches based on upd properties
/// e.g. salewa hp resource units left
/// </summary>
/// <param name="rootItemBeingAdded">item to look for a match against</param>
/// <param name="itemDbDetails">Db details of matching item</param>
/// <param name="itemsWithChildren">Items to search through</param>
/// <returns>Matching assort item</returns>
protected virtual Item GetMatchingItem(
Item rootItemBeingAdded,
TemplateItem itemDbDetails,
List<List<Item>> itemsWithChildren)
{
throw new NotImplementedException();
}
/// <summary>
/// Should this item be forced into only 1 stack on fence
/// </summary>
/// <param name="existingItem">Existing item from fence assort</param>
/// <param name="itemDbDetails">Item we want to add db details</param>
/// <returns>True item should be force stacked</returns>
protected virtual bool ItemShouldBeForceStacked(Item existingItem, TemplateItem itemDbDetails)
{
throw new NotImplementedException();
}
protected virtual bool ItemInPreventDupeCategoryList(string tpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust price of item based on what is left to buy (resource/uses left)
/// </summary>
/// <param name="barterSchemes">All barter scheme for item having price adjusted</param>
/// <param name="itemRoot">Root item having price adjusted</param>
/// <param name="itemTemplate">Db template of item</param>
protected virtual void AdjustItemPriceByQuality(
Dictionary<string, List<List<BarterScheme>>> barterSchemes,
Item itemRoot,
TemplateItem itemTemplate)
{
throw new NotImplementedException();
}
protected virtual Dictionary<string, (int current, int max)> GetMatchingItemLimit(
Dictionary<string, (int current, int max)> itemTypeLimits,
string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Find presets in base fence assort and add desired number to 'assorts' parameter
/// </summary>
/// <param name="desiredWeaponPresetsCount"></param>
/// <param name="assorts">Assorts to add preset to</param>
/// <param name="baseFenceAssort">Base data to draw from</param>
/// <param name="loyaltyLevel">Which loyalty level is required to see/buy item</param>
protected virtual void AddPresetsToAssort(
int desiredWeaponPresetsCount,
int desiredEquipmentPresetsCount,
CreateFenceAssortsResult assorts,
TraderAssort baseFenceAssort,
int loyaltyLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust plate / soft insert durability values
/// </summary>
/// <param name="armor">Armor item array to add mods into</param>
/// <param name="itemDbDetails">Armor items db template</param>
protected virtual void RandomiseArmorModDurability(List<Item> armor, TemplateItem itemDbDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomise the durability values of items on armor with a passed in slot
/// </summary>
/// <param name="softInsertSlots">Slots of items to randomise</param>
/// <param name="armorItemAndMods">Array of armor + inserts to get items from</param>
protected virtual void RandomiseArmorSoftInsertDurabilities(List<Slot> softInsertSlots, List<Item> armorItemAndMods)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomise the durability values of plate items in armor
/// Has chance to remove plate
/// </summary>
/// <param name="plateSlots">Slots of items to randomise</param>
/// <param name="armorItemAndMods">Array of armor + inserts to get items from</param>
protected virtual void RandomiseArmorInsertsDurabilities(List<Slot> plateSlots, List<Item> armorItemAndMods)
{
throw new NotImplementedException();
}
/// <summary>
/// Get stack size of a singular item (no mods)
/// </summary>
/// <param name="itemDbDetails">item being added to fence</param>
/// <returns>Stack size</returns>
protected virtual int GetSingleItemStackCount(TemplateItem itemDbDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Remove parts of a weapon prior to being listed on flea
/// </summary>
/// <param name="itemAndMods">Weapon to remove parts from</param>
protected virtual void RemoveRandomModsOfItem(List<Item> itemAndMods)
{
throw new NotImplementedException();
}
/// <summary>
/// Roll % chance check to see if item should be removed
/// </summary>
/// <param name="weaponMod">Weapon mod being checked</param>
/// <param name="itemsBeingDeleted">Current list of items on weapon being deleted</param>
/// <returns>True if item will be removed</returns>
protected virtual bool PresetModItemWillBeRemoved(Item weaponMod, List<string> itemsBeingDeleted)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomise items' upd properties e.g. med packs/weapons/armor
/// </summary>
/// <param name="itemDetails">Item being randomised</param>
/// <param name="itemToAdjust">Item being edited</param>
protected virtual void RandomiseItemUpdProperties(TemplateItem itemDetails, Item itemToAdjust)
{
throw new NotImplementedException();
}
/// <summary>
/// Generate a randomised current and max durabiltiy value for an armor item
/// </summary>
/// <param name="itemDetails">Item to create values for</param>
/// <param name="equipmentDurabilityLimits">Max durabiltiy percent min/max values</param>
/// <returns>Durability + MaxDurability values</returns>
protected virtual UpdRepairable GetRandomisedArmorDurabilityValues(
TemplateItem itemDetails,
ItemDurabilityCurrentMax equipmentDurabilityLimits)
{
throw new NotImplementedException();
}
/// <summary>
/// Construct item limit record to hold max and current item count
/// </summary>
/// <param name="limits">limits as defined in config</param>
/// <returns>record, key: item tplId, value: current/max item count allowed</returns>
protected Dictionary<string, (int current, int max)> InitItemLimitCounter(Dictionary<string, int> limits)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the next update timestamp for fence
/// </summary>
/// <returns>future timestamp</returns>
public int GetNextFenceUpdateTimestamp()
{
throw new NotImplementedException();
}
/// <summary>
/// Get fence refresh time in seconds
/// </summary>
/// <returns>Refresh time in seconds</returns>
protected int GetFenceRefreshTime()
{
throw new NotImplementedException();
}
/// <summary>
/// Get fence level the passed in profile has
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <returns>FenceLevel object</returns>
public FenceLevel GetFenceInfo(PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Remove or lower stack size of an assort from fence by id
/// </summary>
/// <param name="assortId">assort id to adjust</param>
/// <param name="buyCount">Count of items bought</param>
public void AmendOrRemoveFenceOffer(string assortId, int buyCount)
{
throw new NotImplementedException();
}
protected void DeleteOffer(string assortId, List<Item> assorts)
{
throw new NotImplementedException();
}
}
+81
View File
@@ -0,0 +1,81 @@
using Core.Models.Enums;
using Core.Models.Spt.Config;
namespace Core.Services;
public class GiftService
{
/**
* Does a gift with a specific ID exist in db
* @param giftId Gift id to check for
* @returns True if it exists in db
*/
public bool GiftExists(string giftId)
{
throw new NotImplementedException();
}
public Gift GetGiftById(string giftId)
{
throw new NotImplementedException();
}
/**
* Get dictionary of all gifts
* @returns Dict keyed by gift id
*/
public Dictionary<string, Gift> GetGifts()
{
throw new NotImplementedException();
}
/**
* Get an array of all gift ids
* @returns string array of gift ids
*/
public List<string> GetGiftIds()
{
throw new NotImplementedException();
}
/**
* Send player a gift from a range of sources
* @param playerId Player to send gift to / sessionId
* @param giftId Id of gift in configs/gifts.json to send player
* @returns outcome of sending gift to player
*/
public GiftSentResult SendGiftToPlayer(string playerId, string giftId)
{
throw new NotImplementedException();
}
/**
* Get sender id based on gifts sender type enum
* @param giftData Gift to send player
* @returns trader/user/system id
*/
protected string? GetSenderId(Gift giftData)
{
throw new NotImplementedException();
}
/**
* Convert GiftSenderType into a dialog MessageType
* @param giftData Gift to send player
* @returns MessageType enum value
*/
protected MessageType? GetMessageType(Gift giftData)
{
throw new NotImplementedException();
}
/**
* Prapor sends gifts to player for first week after profile creation
* @param sessionId Player id
* @param day What day to give gift for
*/
public void SendPraporStartingGift(string sessionId, int day)
{
throw new NotImplementedException();
}
}
+35
View File
@@ -0,0 +1,35 @@
namespace Core.Services;
public class InMemoryCacheService
{
// Store data into an in-memory object
// key to store data against
// Data to store in cache
public void StoreByKey(string key, object dataToCache)
{
throw new NotImplementedException();
}
// Retreve data stored by a key
// key
// Stored data
public T GetDataByKey<T>(string key)
{
throw new NotImplementedException();
}
// Does data exists against the provided key
// Key to check for data against
// true if exists
public bool HasStoredDataByKey(string key)
{
throw new NotImplementedException();
}
// Remove data stored against key
// Key to remove data against
public void ClearDataStoredByKey(string key)
{
throw new NotImplementedException();
}
}
+150
View File
@@ -0,0 +1,150 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Services;
namespace Core.Services;
public class InsuranceService
{
/// <summary>
/// Does player have insurance dictionary exists
/// </summary>
/// <param name="sessionId">Player id</param>
/// <returns>True if exists</returns>
public bool InsuranceDictionaryExists(string sessionId)
{
throw new NotImplementedException();
}
/// <summary>
/// Get all insured items by all traders for a profile
/// </summary>
/// <param name="sessionId">Profile id (session id)</param>
/// <returns>Item list</returns>
public Dictionary<string, List<Item>> GetInsurance(string sessionId)
{
throw new NotImplementedException();
}
public void ResetInsurance(string sessionId)
{
throw new NotImplementedException();
}
/// <summary>
/// Sends 'I will go look for your stuff' trader message +
/// Store lost insurance items inside profile for later retrieval
/// </summary>
/// <param name="pmcData">Profile to send insured items to</param>
/// <param name="sessionID">SessionId of current player</param>
/// <param name="mapId">Id of the location player died/exited that caused the insurance to be issued on</param>
public void StartPostRaidInsuranceLostProcess(PmcData pmcData, string sessionID, string mapId)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a timestamp of when insurance items should be sent to player based on trader used to insure
/// Apply insurance return bonus if found in profile
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="trader">Trader base used to insure items</param>
/// <returns>Timestamp to return items to player in seconds</returns>
protected double GetInsuranceReturnTimestamp(PmcData pmcData, TraderBase trader)
{
throw new NotImplementedException();
}
protected double GetMaxInsuranceStorageTime(TraderBase traderBase)
{
throw new NotImplementedException();
}
/// <summary>
/// Store lost gear post-raid inside profile, ready for later code to pick it up and mail it
/// </summary>
/// <param name="equipmentPkg">Gear to store - generated by GetGearLostInRaid()</param>
public void StoreGearLostInRaidToSendLater(string sessionID, List<InsuranceEquipmentPkg> equipmentPkg)
{
throw new NotImplementedException();
}
/// <summary>
/// For the passed in items, find the trader it was insured against
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="lostInsuredItems">Insured items lost in a raid</param>
/// <param name="pmcProfile">Player profile</param>
/// <returns>InsuranceEquipmentPkg list</returns>
public List<InsuranceEquipmentPkg> MapInsuredItemsToTrader(
string sessionId,
List<Item> lostInsuredItems,
PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Some items should never be returned in insurance but BSG send them in the request
/// </summary>
/// <param name="lostItem">Item being returned in insurance</param>
/// <param name="inventoryItems">Player inventory</param>
/// <returns>True if item</returns>
protected bool ItemCannotBeLostOnDeath(Item lostItem, List<Item> inventoryItems)
{
throw new NotImplementedException();
}
/// <summary>
/// Add gear item to InsuredItems list in player profile
/// </summary>
/// <param name="gear">Gear to send</param>
protected void AddGearToSend(InsuranceEquipmentPkg gear)
{
throw new NotImplementedException();
}
/// <summary>
/// Does insurance exist for a player and by trader
/// </summary>
/// <param name="sessionId">Player id (session id)</param>
/// <param name="traderId">Trader items insured with</param>
/// <returns>True if exists</returns>
protected bool InsuranceTraderArrayExists(string sessionId, string traderId)
{
throw new NotImplementedException();
}
/// <summary>
/// Empty out list holding insured items by sessionid + traderid
/// </summary>
/// <param name="sessionId">Player id (session id)</param>
/// <param name="traderId">Trader items insured with</param>
public void ResetInsuranceTraderArray(string sessionId, string traderId)
{
throw new NotImplementedException();
}
/// <summary>
/// Store insured item
/// </summary>
/// <param name="sessionId">Player id (session id)</param>
/// <param name="traderId">Trader item insured with</param>
/// <param name="itemToAdd">Insured item (with children)</param>
public void AddInsuranceItemToArray(string sessionId, string traderId, Item itemToAdd)
{
throw new NotImplementedException();
}
/// <summary>
/// Get price of insurance * multiplier from config
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="inventoryItem">Item to be insured</param>
/// <param name="traderId">Trader item is insured with</param>
/// <returns>price in roubles</returns>
public double GetRoublePriceToInsureItemWithTrader(PmcData pmcData, Item inventoryItem, string traderId)
{
throw new NotImplementedException();
}
}
+56
View File
@@ -0,0 +1,56 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Services;
public class ItemBaseClassService
{
/**
* Create cache and store inside ItemBaseClassService
* Store a dict of an items tpl to the base classes it and its parents have
*/
public void HydrateItemBaseClassCache()
{
throw new NotImplementedException();
}
/**
* Helper method, recursively iterate through items parent items, finding and adding ids to dictionary
* @param itemIdToUpdate item tpl to store base ids against in dictionary
* @param item item being checked
*/
protected void AddBaseItems(string itemIdToUpdate, TemplateItem item)
{
throw new NotImplementedException();
}
/**
* Does item tpl inherit from the requested base class
* @param itemTpl item to check base classes of
* @param baseClass base class to check for
* @returns true if item inherits from base class passed in
*/
public bool ItemHasBaseClass(string itemTpl, List<string> baseClasses)
{
throw new NotImplementedException();
}
/**
* Check if cached item template is of type Item
* @param itemTemplateId item to check
* @returns true if item is of type Item
*/
private bool CachedItemIsOfItemType(string itemTemplateId)
{
throw new NotImplementedException();
}
/**
* Get base classes item inherits from
* @param itemTpl item to get base classes for
* @returns array of base classes
*/
public List<string> GetItemBaseClasses(string itemTpl)
{
throw new NotImplementedException();
}
}
+89
View File
@@ -0,0 +1,89 @@
namespace Core.Services;
public class ItemFilterService
{
/**
* Check if the provided template id is blacklisted in config/item.json/blacklist
* @param tpl template id
* @returns true if blacklisted
*/
public bool ItemBlacklisted(string tpl)
{
throw new NotImplementedException();
}
/**
* Check if the provided template id is blacklisted in config/item.json/lootableItemBlacklist
* @param tpl template id
* @returns true if blacklisted
*/
public bool LootableItemBlacklisted(string tpl)
{
throw new NotImplementedException();
}
/**
* Check if item is blacklisted from being a reward for player
* @param tpl item tpl to check is on blacklist
* @returns True when blacklisted
*/
public bool ItemRewardBlacklisted(string tpl)
{
throw new NotImplementedException();
}
/**
* Get an array of items that should never be given as a reward to player
* @returns string array of item tpls
*/
public List<string> GetItemRewardBlacklist()
{
throw new NotImplementedException();
}
/**
* Get an array of item types that should never be given as a reward to player
* @returns string array of item base ids
*/
public List<string> GetItemRewardBaseTypeBlacklist()
{
throw new NotImplementedException();
}
/**
* Return every template id blacklisted in config/item.json
* @returns string array of blacklisted template ids
*/
public List<string> GetBlacklistedItems()
{
throw new NotImplementedException();
}
/**
* Return every template id blacklisted in config/item.json/lootableItemBlacklist
* @returns string array of blacklisted template ids
*/
public List<string> GetBlacklistedLootableItems()
{
throw new NotImplementedException();
}
/**
* Check if the provided template id is boss item in config/item.json
* @param tpl template id
* @returns true if boss item
*/
public bool BossItem(string tpl)
{
throw new NotImplementedException();
}
/**
* Return boss items in config/item.json
* @returns string array of boss item template ids
*/
public List<string> GetBossItems()
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,75 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common;
using Core.Models.Eft.Match;
namespace Core.Services;
public class LegacyLocationLifecycleService
{
/// <summary>
/// Handle client/match/offline/end
/// </summary>
public void endOfflineRaid(EndOfflineRaidRequestData info, string sessionId)
{
throw new NotImplementedException();
}
/// <summary>
/// Handle when a player extracts using a car - Add rep to fence
/// </summary>
/// <param name="extractName">name of the extract used</param>
/// <param name="pmcData">Player profile</param>
/// <param name="sessionId">Session id</param>
protected void handleCarExtract(string extractName, PmcData pmcData, string sessionId)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the fence rep gain from using a car or coop extract
/// </summary>
/// <param name="pmcData">Profile</param>
/// <param name="baseGain">amount gained for the first extract</param>
/// <param name="extractCount">Number of times extract was taken</param>
/// <returns>Fence standing after taking extract</returns>
protected int getFenceStandingAfterExtract(PmcData pmcData, int baseGain, int extractCount)
{
throw new NotImplementedException();
}
/// <summary>
/// Was extract by car
/// </summary>
/// <param name="extractName">name of extract</param>
/// <returns>true if car extract</returns>
protected bool extractWasViaCar(string extractName)
{
throw new NotImplementedException();
}
/// <summary>
/// Did player take a COOP extract
/// </summary>
/// <param name="extractName">Name of extract player took</param>
/// <returns>True if coop extract</returns>
protected bool extractWasViaCoop(string extractName)
{
throw new NotImplementedException();
}
/// <summary>
/// Handle when a player extracts using a coop extract - add rep to fence
/// </summary>
/// <param name="sessionId">Session/player id</param>
/// <param name="pmcData">Profile</param>
/// <param name="extractName">Name of extract taken</param>
protected void handleCoopExtract(string sessionId, PmcData pmcData, string extractName)
{
throw new NotImplementedException();
}
protected void sendCoopTakenFenceMessage(string sessionId)
{
throw new NotImplementedException();
}
}
+255
View File
@@ -0,0 +1,255 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Match;
namespace Core.Services;
public class LocationLifecycleService
{
/** Handle client/match/local/start */
public void StartLocalRaid(string sessionId, StartLocalRaidRequestData request)
{
throw new NotImplementedException();
}
/**
* Replace map exits with scav exits when player is scavving
* @param playerSide Players side (savage/usec/bear)
* @param location id of map being loaded
* @param locationData Maps location base data
*/
protected void AdjustExtracts(string playerSide, string location, LocationBase locationData)
{
throw new NotImplementedException();
}
/**
* Adjust the bot hostility values prior to entering a raid
* @param location map to adjust values of
*/
protected void AdjustBotHostilitySettings(LocationBase location)
{
throw new NotImplementedException();
}
/**
* Generate a maps base location (cloned) and loot
* @param name Map name
* @param generateLoot OPTIONAL - Should loot be generated for the map before being returned
* @returns LocationBase
*/
protected LocationBase GenerateLocationAndLoot(string name, bool generateLoot = true)
{
throw new NotImplementedException();
}
/** Handle client/match/local/end */
public void EndLocalRaid(string sessionId, EndLocalRaidRequestData request)
{
throw new NotImplementedException();
}
/**
* Was extract by car
* @param extractName name of extract
* @returns True if extract was by car
*/
protected bool ExtractWasViaCar(string extractName)
{
throw new NotImplementedException();
}
/**
* Handle when a player extracts using a car - Add rep to fence
* @param extractName name of the extract used
* @param pmcData Player profile
* @param sessionId Session id
*/
protected void HandleCarExtract(string extractName, PmcData pmcData, string sessionId)
{
throw new NotImplementedException();
}
/**
* Handle when a player extracts using a coop extract - add rep to fence
* @param sessionId Session/player id
* @param pmcData Profile
* @param extractName Name of extract taken
*/
protected void HandleCoopExtract(string sessionId, PmcData pmcData, string extractName)
{
throw new NotImplementedException();
}
/**
* Get the fence rep gain from using a car or coop extract
* @param pmcData Profile
* @param baseGain amount gained for the first extract
* @param extractCount Number of times extract was taken
* @returns Fence standing after taking extract
*/
protected int GetFenceStandingAfterExtract(PmcData pmcData, int baseGain, int extractCount)
{
throw new NotImplementedException();
}
/**
* Did player take a COOP extract
* @param extractName Name of extract player took
* @returns True if coop extract
*/
protected bool ExtractTakenWasCoop(string extractName)
{
throw new NotImplementedException();
}
protected void HandlePostRaidPlayerScav(
string sessionId,
PmcData pmcProfile,
PmcData scavProfile,
bool isDead,
bool isTransfer,
EndLocalRaidRequestData request)
{
throw new NotImplementedException();
}
/**
*
* @param sessionId Player id
* @param pmcProfile Pmc profile
* @param scavProfile Scav profile
* @param isDead Player died/got left behind in raid
* @param isSurvived Not same as opposite of `isDead`, specific status
* @param request
* @param locationName
*/
protected void HandlePostRaidPmc(
string sessionId,
PmcData pmcProfile,
PmcData scavProfile,
bool isDead,
bool isSurvived,
bool isTransfer,
EndLocalRaidRequestData request,
string locationName)
{
throw new NotImplementedException();
}
protected void CheckForAndFixPickupQuestsAfterDeath(
string sessionId,
List<Item> lostQuestItems,
List<QuestStatus> profileQuests
)
{
throw new NotImplementedException();
}
/*
* In 0.15 Lightkeeper quests do not give rewards in PvE, this issue also occurs in spt
* We check for newly completed Lk quests and run them through the servers `CompleteQuest` process
* This rewards players with items + craft unlocks + new trader assorts
*/
protected void LightkeeperQuestWorkaround(
string sessionId,
List<QuestStatus> postRaidQuests,
List<QuestStatus> preRaidQuests,
PmcData pmcProfile
)
{
throw new NotImplementedException();
}
/*
* Convert post-raid quests into correct format
* Quest status comes back as a string version of the enum `Success`, not the expected value of 1
*/
protected List<QuestStatus> ProcessPostRaidQuests(List<QuestStatus> questsToProcess)
{
throw new NotImplementedException();
}
/*
* Adjust server trader settings if they differ from data sent by client
*/
protected void ApplyTraderStandingAdjustments(
Dictionary<string, TraderInfo> tradersServerProfile,
Dictionary<string, TraderInfo> tradersClientProfile
)
{
throw new NotImplementedException();
}
/*
* Check if player used BTR or transit item sending service and send items to player via mail if found
*/
protected void HandleItemTransferEvent(string sessionId, EndLocalRaidRequestData request)
{
throw new NotImplementedException();
}
protected void TransferItemDelivery(string sessionId, string traderId, List<Item> items)
{
throw new NotImplementedException();
}
protected void HandleInsuredItemLostEvent(
string sessionId,
PmcData preRaidPmcProfile,
EndLocalRaidRequestData request,
string locationName
)
{
throw new NotImplementedException();
}
/*
* Return the equipped items from a players inventory
*/
protected List<Item> GetEquippedGear(List<Item> items)
{
throw new NotImplementedException();
}
/*
* Checks to see if player survives. run through will return false
*/
protected bool IsPlayerSurvived(EndRaidResult results)
{
throw new NotImplementedException();
}
/*
* Is the player dead after a raid - dead = anything other than "survived" / "runner"
*/
protected bool IsPlayerDead(EndRaidResult results)
{
throw new NotImplementedException();
}
/*
* Has the player moved from one map to another
*/
protected bool IsMapToMapTransfer(EndRaidResult results)
{
throw new NotImplementedException();
}
/*
* Reset the skill points earned in a raid to 0, ready for next raid
*/
protected void ResetSkillPointsEarnedDuringRaid(List<Common> commonSkills)
{
throw new NotImplementedException();
}
/*
* merge two dictionaries together
* Prioritise pair that has true as a value
*/
protected void MergePmcAndScavEncyclopedias(PmcData primary, PmcData secondary)
{
throw new NotImplementedException();
}
}
+240
View File
@@ -0,0 +1,240 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Inventory;
using Core.Models.Eft.Profile;
using Core.Models.Enums;
using Core.Models.Spt.Dialog;
namespace Core.Services;
public class MapMarkerService
{
/// <summary>
/// Add note to a map item in player inventory
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="request">Add marker request</param>
/// <returns>Item</returns>
public Item CreateMarkerOnMap(PmcData pmcData, InventoryCreateMarkerRequestData request)
{
throw new NotImplementedException();
}
/// <summary>
/// Delete a map marker
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="request">Delete marker request</param>
/// <returns>Item</returns>
public Item DeleteMarkerFromMap(PmcData pmcData, InventoryDeleteMarkerRequestData request)
{
throw new NotImplementedException();
}
/// <summary>
/// Edit an existing map marker
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="request">Edit marker request</param>
/// <returns>Item</returns>
public Item EditMarkerOnMap(PmcData pmcData, InventoryEditMarkerRequestData request)
{
throw new NotImplementedException();
}
/// <summary>
/// Strip out characters from note string that are not: letter/numbers/unicode/spaces
/// </summary>
/// <param name="mapNoteText">Marker text to sanitise</param>
/// <returns>Sanitised map marker text</returns>
protected string SanitiseMapMarkerText(string mapNoteText)
{
throw new NotImplementedException();
}
/// <summary>
/// Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
/// </summary>
/// <param name="sessionId">The session ID to send the message to</param>
/// <param name="trader">The trader sending the message</param>
/// <param name="messageType">What type the message will assume (e.g. QUEST_SUCCESS)</param>
/// <param name="message">Text to send to the player</param>
/// <param name="items">Optional items to send to player</param>
/// <param name="maxStorageTimeSeconds">Optional time to collect items before they expire</param>
public void SendDirectNpcMessageToPlayer(
string sessionId,
object trader,
MessageType messageType,
string message,
List<Item> items = null,
int? maxStorageTimeSeconds = null,
SystemData systemData = null,
MessageContentRagfair ragfair = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Send a message from an NPC (e.g. prapor) to the player with or without items
/// </summary>
/// <param name="sessionId">The session ID to send the message to</param>
/// <param name="trader">The trader sending the message</param>
/// <param name="messageType">What type the message will assume (e.g. QUEST_SUCCESS)</param>
/// <param name="messageLocaleId">The localised text to send to player</param>
/// <param name="items">Optional items to send to player</param>
/// <param name="maxStorageTimeSeconds">Optional time to collect items before they expire</param>
public void SendLocalisedNpcMessageToPlayer(
string sessionId,
object trader,
MessageType messageType,
string messageLocaleId,
List<Item> items = null,
int? maxStorageTimeSeconds = null,
SystemData systemData = null,
MessageContentRagfair ragfair = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Send a message from SYSTEM to the player with or without items
/// </summary>
/// <param name="sessionId">The session ID to send the message to</param>
/// <param name="message">The text to send to player</param>
/// <param name="items">Optional items to send to player</param>
/// <param name="maxStorageTimeSeconds">Optional time to collect items before they expire</param>
public void SendSystemMessageToPlayer(
string sessionId,
string message,
List<Item> items = null,
int? maxStorageTimeSeconds = null,
List<ProfileChangeEvent> profileChangeEvents = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Send a message from SYSTEM to the player with or without items with localised text
/// </summary>
/// <param name="sessionId">The session ID to send the message to</param>
/// <param name="messageLocaleId">Id of key from locale file to send to player</param>
/// <param name="items">Optional items to send to player</param>
/// <param name="maxStorageTimeSeconds">Optional time to collect items before they expire</param>
public void SendLocalisedSystemMessageToPlayer(
string sessionId,
string messageLocaleId,
List<Item> items = null,
List<ProfileChangeEvent> profileChangeEvents = null,
int? maxStorageTimeSeconds = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Send a USER message to a player with or without items
/// </summary>
/// <param name="sessionId">The session ID to send the message to</param>
/// <param name="senderDetails">Who is sending the message</param>
/// <param name="message">The text to send to player</param>
/// <param name="items">Optional items to send to player</param>
/// <param name="maxStorageTimeSeconds">Optional time to collect items before they expire</param>
public void SendUserMessageToPlayer(
string sessionId,
UserDialogInfo senderDetails,
string message,
List<Item> items = null,
int? maxStorageTimeSeconds = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
/// Helper functions in this class are available to simplify common actions
/// </summary>
/// <param name="messageDetails">Details needed to send a message to the player</param>
public void SendMessageToPlayer(SendMessageDetails messageDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Send a message from the player to an NPC
/// </summary>
/// <param name="sessionId">Player id</param>
/// <param name="targetNpcId">NPC message is sent to</param>
/// <param name="message">Text to send to NPC</param>
public void SendPlayerMessageToNpc(string sessionId, string targetNpcId, string message)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a message for storage inside a dialog in the player profile
/// </summary>
/// <param name="senderDialog">Id of dialog that will hold the message</param>
/// <param name="messageDetails">Various details on what the message must contain/do</param>
/// <returns>Message</returns>
protected Message CreateDialogMessage(string dialogId, SendMessageDetails messageDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Add items to message and adjust various properties to reflect the items being added
/// </summary>
/// <param name="message">Message to add items to</param>
/// <param name="itemsToSendToPlayer">Items to add to message</param>
/// <param name="maxStorageTimeSeconds">total time items are stored in mail before being deleted</param>
protected void AddRewardItemsToMessage(
Message message,
List<MessageItems> itemsToSendToPlayer,
int? maxStorageTimeSeconds)
{
throw new NotImplementedException();
}
/// <summary>
/// perform various sanitising actions on the items before they're considered ready for insertion into message
/// </summary>
/// <param name="dialogType">The type of the dialog that will hold the reward items being processed</param>
/// <param name="messageDetails"></param>
/// <returns>Sanitised items</returns>
protected List<MessageItems> ProcessItemsBeforeAddingToMail(
MessageType dialogType,
SendMessageDetails messageDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Try to find the most correct item to be the 'primary' item in a reward mail
/// </summary>
/// <param name="items">Possible items to choose from</param>
/// <returns>Chosen 'primary' item</returns>
protected Item GetBaseItemFromRewards(List<Item> items)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a dialog with a specified entity (user/trader)
/// Create and store empty dialog if none exists in profile
/// </summary>
/// <param name="messageDetails">Data on what message should do</param>
/// <returns>Relevant Dialogue</returns>
protected Dialogue GetDialog(SendMessageDetails messageDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the appropriate sender id by the sender enum type
/// </summary>
/// <param name="messageDetails"></param>
/// <returns>gets an id of the individual sending it</returns>
protected string GetMessageSenderIdByType(SendMessageDetails messageDetails)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,34 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Services;
public class MatchBotDeatilsCacheService
{
/// <summary>
/// Store a bot in the cache, keyed by its name
/// </summary>
/// <param name="botToCache">Bot details to cache</param>
public void CacheBot(BotBase botToCache)
{
throw new NotImplementedException();
}
/// <summary>
/// Clean the cache of all bot details
/// </summary>
public void ClearCache()
{
throw new NotImplementedException();
}
/// <summary>
/// Find a bot in the cache by its name and side
/// </summary>
/// <param name="botName">Name of bot to find</param>
/// <param name="botSide">Side of the bot to find</param>
/// <returns>Bot details</returns>
public BotBase GetBotByNameAndSide(string botName, string botSide)
{
throw new NotImplementedException();
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace Core.Services;
public class MatchLocationService
{
public void DeleteGroup(object info)
{
throw new NotImplementedException();
}
}
+124
View File
@@ -0,0 +1,124 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Mod;
namespace Core.Services.Mod;
public class CustomItemService
{
/**
* Create a new item from a cloned item base
* WARNING - If no item id is supplied, an id will be generated, this id will be random every time you add an item and will not be the same on each subsequent server start
* Add to the items db
* Add to the flea market
* Add to the handbook
* Add to the locales
* @param newItemDetails Item details for the new item to be created
* @returns tplId of the new item created
*/
public CreateItemResult CreateItemFromClone(NewItemFromCloneDetails newItemDetails)
{
throw new NotImplementedException();
}
/**
* Create a new item without using an existing item as a template
* Add to the items db
* Add to the flea market
* Add to the handbook
* Add to the locales
* @param newItemDetails Details on what the item to be created
* @returns CreateItemResult containing the completed items Id
*/
public CreateItemResult CreateItem(NewItemDetails newItemDetails)
{
throw new NotImplementedException();
}
/**
* If the id provided is an empty string, return a randomly generated guid, otherwise return the newId parameter
* @param newId id supplied to code
* @returns item id
*/
protected string GetOrGenerateIdForItem(string newId)
{
throw new NotImplementedException();
}
/**
* Iterates through supplied properties and updates the cloned items properties with them
* Complex objects cannot have overrides, they must be fully hydrated with values if they are to be used
* @param overrideProperties new properties to apply
* @param itemClone item to update
*/
protected void UpdateBaseItemPropertiesWithOverrides(Props overrideProperties, TemplateItem itemClone)
{
throw new NotImplementedException();
}
/**
* Addd a new item object to the in-memory representation of items.json
* @param newItemId id of the item to add to items.json
* @param itemToAdd Item to add against the new id
*/
protected void AddToItemsDb(string newItemId, TemplateItem itemToAdd)
{
throw new NotImplementedException();
}
/**
* Add a handbook price for an item
* @param newItemId id of the item being added
* @param parentId parent id of the item being added
* @param priceRoubles price of the item being added
*/
protected void AddToHandbookDb(string newItemId, string parentId, decimal priceRoubles)
{
throw new NotImplementedException();
}
/**
* Iterate through the passed in locale data and add to each locale in turn
* If data is not provided for each langauge eft uses, the first object will be used in its place
* e.g.
* en[0]
* fr[1]
*
* No jp provided, so english will be used as a substitute
* @param localeDetails key is language, value are the new locale details
* @param newItemId id of the item being created
*/
protected void AddToLocaleDbs(Dictionary<string, LocaleDetails> localeDetails, string newItemId)
{
throw new NotImplementedException();
}
/**
* Add a price to the in-memory representation of prices.json, used to inform the flea of an items price on the market
* @param newItemId id of the new item
* @param fleaPriceRoubles Price of the new item
*/
protected void AddToFleaPriceDb(string newItemId, decimal fleaPriceRoubles)
{
throw new NotImplementedException();
}
/**
* Add a weapon to the hideout weapon shelf whitelist
* @param newItemId Weapon id to add
*/
protected void AddToWeaponShelf(string newItemId)
{
throw new NotImplementedException();
}
/**
* Add a custom weapon to PMCs loadout
* @param weaponTpl Custom weapon tpl to add to PMCs
* @param weaponWeight The weighting for the weapon to be picked vs other weapons
* @param weaponSlot The slot the weapon should be added to (e.g. FirstPrimaryWeapon/SecondPrimaryWeapon/Holster)
*/
public void AddCustomWeaponToPMCs(string weaponTpl, decimal weaponWeight, string weaponSlot)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,9 @@
namespace Core.Services.Mod.DynamicRouter;
public class DynamicRouterMod
{
public string GetTopLevelRoute()
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,11 @@
namespace Core.Services.Mod.DynamicRouter;
public class DynamicRouterModService
{
public void RegisterDynamicRouter(string name, List<object> routes, string topLevelRoute)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,14 @@
namespace Core.Services.Mod.HttpListener;
public class HttpListenerMod
{
public bool CanHandle(string sessionId, object req)
{
throw new NotImplementedException();
}
public async Task Handle(string sessionId, object req, object resp)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,9 @@
namespace Core.Services.Mod.HttpListener;
public class HttpListenerModService
{
public void RegisterHttpListener(string name, object canHandleOverride, object handleOverride)
{
throw new NotImplementedException();
}
}
+14
View File
@@ -0,0 +1,14 @@
namespace Core.Services.Mod.OnLoad;
public class OnLoadMod
{
public async Task OnLoad()
{
throw new NotImplementedException();
}
public string GetRoute()
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,9 @@
namespace Core.Services.Mod.OnLoad;
public class OnLoadModService
{
public void RegisterOnLoad(string name, object onLoad, object getRoute)
{
throw new NotImplementedException();
}
}
+14
View File
@@ -0,0 +1,14 @@
namespace Core.Services.Mod.OnUpdate;
public class OnUpdateMod
{
public async Task<bool> OnUpdate(double timeSinceLastRun)
{
throw new NotImplementedException();
}
public string GetRoute()
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,9 @@
namespace Core.Services.Mod.OnUpdate;
public class OnUpdateModService
{
public void RegisterOnUpdate(string name, object onUpdate, object getRoute)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,9 @@
namespace Core.Services.Mod.StaticRouter;
public class StaticRouterMod // TODO: : StaticRouter
{
public string GetTopLevelRoute()
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,9 @@
namespace Core.Services.Mod.StaticRouter;
public class StaticRouterModService
{
public void RegisterStaticRouter(string name, List<object> routes, string topLevelRoute) // TODO: was List<RouteAction> routes
{
throw new NotImplementedException();
}
}
+50
View File
@@ -0,0 +1,50 @@
namespace Core.Services;
public class ModCompilerService
{
/// <summary>
/// Convert a mods TS into JS
/// </summary>
/// <param name="modName">Name of mod</param>
/// <param name="modPath">Dir path to mod</param>
/// <param name="modTypeScriptFiles"></param>
/// <returns></returns>
public async Task CompileMod(string modName, string modPath, List<string> modTypeScriptFiles)
{
throw new NotImplementedException();
}
/// <summary>
/// Convert a TS file into JS
/// </summary>
/// <param name="fileNames">Paths to TS files</param>
/// <param name="options">Compiler options</param>
/// <returns></returns>
protected async Task Compile(List<string> fileNames, object options)
{
throw new NotImplementedException();
}
/// <summary>
/// Do the files at the provided paths exist
/// </summary>
/// <param name="fileNames"></param>
/// <returns></returns>
protected bool AreFilesReady(List<string> fileNames)
{
throw new NotImplementedException();
}
/// <summary>
/// Wait the provided number of milliseconds
/// </summary>
/// <param name="ms">Milliseconds</param>
/// <returns></returns>
protected async Task Delay(int ms)
{
throw new NotImplementedException();
}
}
// TODO: this probably isnt needed but AI go brr so i did
+51
View File
@@ -0,0 +1,51 @@
using Core.Models.Eft.Ws;
namespace Core.Services;
public class NotificationService
{
public Dictionary<string, List<object>> GetMessageQueue()
{
throw new NotImplementedException();
}
public List<object> GetMessageFromQueue(string sessionId)
{
throw new NotImplementedException();
}
public void UpdateMessageOnQueue(string sessionId, List<object> value)
{
throw new NotImplementedException();
}
public bool Has(string sessionID)
{
throw new NotImplementedException();
}
/// <summary>
/// Pop first message from queue.
/// </summary>
public object Pop(string sessionID)
{
throw new NotImplementedException();
}
/// <summary>
/// Add message to queue
/// </summary>
public void Add(string sessionID, WsNotificationEvent message)
{
throw new NotImplementedException();
}
/// <summary>
/// Get message queue for session
/// </summary>
/// <param name="sessionID"></param>
public List<object> Get(string sessionID)
{
throw new NotImplementedException();
}
}
+22
View File
@@ -0,0 +1,22 @@
namespace Core.Services;
public class OpenZoneService
{
/// <summary>
/// Add open zone to specified map
/// </summary>
/// <param name="locationId">map location (e.g. factory4_day)</param>
/// <param name="zoneToAdd">zone to add</param>
public void AddZoneToMap(string locationId, string zoneToAdd)
{
throw new NotImplementedException();
}
/// <summary>
/// Add open zones to all maps found in config/location.json to db
/// </summary>
public void ApplyZoneChangesToAllMaps()
{
throw new NotImplementedException();
}
}
+66
View File
@@ -0,0 +1,66 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.ItemEvent;
namespace Core.Services;
public class PaymentService
{
/**
* Remove currency from player stash/inventory and update client object with changes
* @param pmcData Player profile to find and remove currency from
* @param currencyTpl Type of currency to pay
* @param amountToPay money value to pay
* @param sessionID Session id
* @param output output object to send to client
*/
public void AddPaymentToOutput(
PmcData pmcData,
string currencyTpl,
decimal amountToPay,
string sessionID,
ItemEventRouterResponse output
)
{
throw new NotImplementedException();
}
/**
* TODO - ensure money in containers inside secure container are LAST
* Get all money stacks in inventory and prioritise items in stash
* @param pmcData Player profile
* @param currencyTpl
* @param playerStashId Players stash id
* @returns Sorting money items
*/
protected List<Item> GetSortedMoneyItemsInInventory(PmcData pmcData, string currencyTpl, string playerStashId)
{
throw new NotImplementedException();
}
/**
* Prioritise player stash first over player inventory
* Post-raid healing would often take money out of the players pockets/secure container
* @param a First money stack item
* @param b Second money stack item
* @param inventoryItems players inventory items
* @param playerStashId Players stash id
* @returns sort order
*/
protected int PrioritiseStashSort(Item a, Item b, List<Item> inventoryItems, string playerStashId)
{
throw new NotImplementedException();
}
/**
* Recursively check items parents to see if it is inside the players inventory, not stash
* @param itemId item id to check
* @param inventoryItems player inventory
* @param playerStashId Players stash id
* @returns true if its in inventory
*/
protected bool IsInStash(string itemId, List<Item> inventoryItems, string playerStashId)
{
throw new NotImplementedException();
}
}
+11
View File
@@ -0,0 +1,11 @@
using Core.Models.Eft.Common;
namespace Core.Services;
public class PlayerService
{
public int CalculateLevel(PmcData pmcData)
{
throw new NotImplementedException();
}
}
+133
View File
@@ -0,0 +1,133 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Profile;
namespace Core.Services;
public class PmcChatResponseService
{
/**
* For each PMC victim of the player, have a chance to send a message to the player, can be positive or negative
* @param sessionId Session id
* @param pmcVictims List of bots killed by player
* @param pmcData Player profile
*/
public void SendVictimResponse(string sessionId, List<Victim> pmcVictims, PmcData pmcData)
{
throw new System.NotImplementedException();
}
/**
* Not fully implemented yet, needs method of acquiring killers details after raid
* @param sessionId Session id
* @param pmcData Players profile
* @param killer The bot who killed the player
*/
public void SendKillerResponse(string sessionId, PmcData pmcData, Aggressor killer)
{
throw new System.NotImplementedException();
}
/**
* Choose a localised message to send the player (different if sender was killed or killed player)
* @param isVictim Is the message coming from a bot killed by the player
* @param pmcData Player profile
* @param victimData OPTIMAL - details of the pmc killed
* @returns Message from PMC to player
*/
protected string? ChooseMessage(bool isVictim, PmcData pmcData, Victim? victimData = null)
{
throw new System.NotImplementedException();
}
/**
* use map key to get a localised location name
* e.g. factory4_day becomes "Factory"
* @param locationKey location key to localise
* @returns Localised location name
*/
protected string GetLocationName(string locationKey)
{
throw new System.NotImplementedException();
}
/**
* Should capitalisation be stripped from the message response before sending
* @param isVictim Was responder a victim of player
* @returns true = should be stripped
*/
protected bool StripCapitalisation(bool isVictim)
{
throw new System.NotImplementedException();
}
/**
* Should capitalisation be stripped from the message response before sending
* @param isVictim Was responder a victim of player
* @returns true = should be stripped
*/
protected bool AllCaps(bool isVictim)
{
throw new System.NotImplementedException();
}
/**
* Should a suffix be appended to the end of the message being sent to player
* @param isVictim Was responder a victim of player
* @returns true = should be stripped
*/
protected bool AppendSuffixToMessageEnd(bool isVictim)
{
throw new System.NotImplementedException();
}
/**
* Choose a type of response based on the weightings in pmc response config
* @param isVictim Was responder killed by player
* @returns Response type (positive/negative)
*/
protected string ChooseResponseType(bool isVictim = true)
{
throw new System.NotImplementedException();
}
/**
* Get locale keys related to the type of response to send (victim/killer)
* @param keyType Positive/negative
* @param isVictim Was responder killed by player
* @returns
*/
protected List<string> GetResponseLocaleKeys(string keyType, bool isVictim = true)
{
throw new System.NotImplementedException();
}
/**
* Get all locale keys that start with `pmcresponse-suffix`
* @returns list of keys
*/
protected List<string> GetResponseSuffixLocaleKeys()
{
throw new System.NotImplementedException();
}
/**
* Randomly draw a victim of the list and return their details
* @param pmcVictims Possible victims to choose from
* @returns IUserDialogInfo
*/
protected UserDialogInfo ChooseRandomVictim(List<Victim> pmcVictims)
{
throw new System.NotImplementedException();
}
/**
* Convert a victim object into a IUserDialogInfo object
* @param pmcVictim victim to convert
* @returns IUserDialogInfo
*/
protected UserDialogInfo GetVictimDetails(Victim pmcVictim)
{
throw new System.NotImplementedException();
}
}
+103
View File
@@ -0,0 +1,103 @@
namespace Core.Services;
public class PostDbLoadService
{
public void PerformPostDbLoadActions()
{
throw new NotImplementedException();
}
protected void AdjustMinReserveRaiderSpawnChance()
{
throw new NotImplementedException();
}
protected void AddCustomLooseLootPositions()
{
throw new NotImplementedException();
}
// BSG have two values for shotgun dispersion, we make sure both have the same value
protected void FixShotgunDispersions()
{
throw new NotImplementedException();
}
// Apply custom limits on bot types as defined in configs/location.json/botTypeLimits
protected void AdjustMapBotLimits()
{
throw new NotImplementedException();
}
protected void AdjustLooseLootSpawnProbabilities()
{
throw new NotImplementedException();
}
protected void AdjustLocationBotValues()
{
throw new NotImplementedException();
}
// Make Rogues spawn later to allow for scavs to spawn first instead of rogues filling up all spawn positions
protected void FixRoguesSpawningInstantlyOnLighthouse()
{
throw new NotImplementedException();
}
// Find and split waves with large numbers of bots into smaller waves - BSG appears to reduce the size of these
// waves to one bot when they're waiting to spawn for too long
protected void SplitBotWavesIntoSingleWaves()
{
throw new NotImplementedException();
}
// Make non-trigger-spawned raiders spawn earlier + always
protected void AdjustLabsRaiderSpawnRate()
{
throw new NotImplementedException();
}
protected void AdjustHideoutCraftTimes(int overrideSeconds)
{
throw new NotImplementedException();
}
// Adjust all hideout craft times to be no higher than the override
protected void AdjustHideoutBuildTimes(int overrideSeconds)
{
throw new NotImplementedException();
}
// Blank out the "test" mail message from prapor
protected void RemovePraporTestMessage()
{
throw new NotImplementedException();
}
// Check for any missing assorts inside each traders assort.json data, checking against traders questassort.json
protected void ValidateQuestAssortUnlocksExist()
{
throw new NotImplementedException();
}
protected void SetAllDbItemsAsSellableOnFlea()
{
throw new NotImplementedException();
}
protected void AddMissingTraderBuyRestrictionMaxValue()
{
throw new NotImplementedException();
}
protected void ApplyFleaPriceOverrides()
{
throw new NotImplementedException();
}
protected void AddCustomItemPresetsToGlobals()
{
throw new NotImplementedException();
}
}
+34
View File
@@ -0,0 +1,34 @@
namespace Core.Services;
public class ProfileActivityService
{
/**
* Was the requested profile active in the last requested minutes
* @param sessionId Profile to check
* @param minutes Minutes to check for activity in
* @returns True when profile was active within past x minutes
*/
public bool ActiveWithinLastMinutes(string sessionId, int minutes)
{
throw new NotImplementedException();
}
/**
* Get a list of profile ids that were active in the last x minutes
* @param minutes How many minutes from now to search for profiles
* @returns List of profile ids
*/
public List<string> GetActiveProfileIdsWithinMinutes(int minutes)
{
throw new NotImplementedException();
}
/**
* Update the timestamp a profile was last observed active
* @param sessionId Profile to update
*/
public void SetActivityTimestamp(string sessionId)
{
throw new NotImplementedException();
}
}
+206
View File
@@ -0,0 +1,206 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Hideout;
using Core.Models.Eft.Profile;
using Core.Models.Enums;
namespace Core.Services;
public class ProfileFixerService
{
/// <summary>
/// Find issues in the pmc profile data that may cause issues and fix them
/// </summary>
/// <param name="pmcProfile">profile to check and fix</param>
public void CheckForAndFixPmcProfileIssues(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Resolve any dialogue attachments that were accidentally created using the player's equipment ID as
/// the stash root object ID
/// </summary>
/// <param name="fullProfile"></param>
public void CheckForAndFixDialogueAttachments(SptProfile fullProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Find issues in the scav profile data that may cause issues
/// </summary>
/// <param name="scavProfile">profile to check and fix</param>
public void CheckForAndFixScavProfileIssues(PmcData scavProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Attempt to fix common item issues that corrupt profiles
/// </summary>
/// <param name="pmcProfile">Profile to check items of</param>
public void FixProfileBreakingInventoryItemIssues(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// TODO - make this non-public - currently used by RepeatableQuestController
/// Remove unused condition counters
/// </summary>
/// <param name="pmcProfile">profile to remove old counters from</param>
public void RemoveDanglingConditionCounters(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Repeatable quests leave behind TaskConditionCounter objects that make the profile bloat with time, remove them
/// </summary>
/// <param name="pmcProfile">Player profile to check</param>
protected void RemoveDanglingTaskConditionCounters(PmcData pmcProfile)
{
throw new NotImplementedException();
}
protected List<RepeatableQuest> GetActiveRepeatableQuests(List<PmcDataRepeatableQuest> repeatableQuests)
{
throw new NotImplementedException();
}
/// <summary>
/// After removing mods that add quests, the quest panel will break without removing these
/// </summary>
/// <param name="pmcProfile">Profile to remove dead quests from</param>
protected void RemoveOrphanedQuests(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Verify that all quest production unlocks have been applied to the PMC Profile
/// </summary>
/// <param name="pmcProfile">The profile to validate quest productions for</param>
protected void VerifyQuestProductionUnlocks(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Validate that the given profile has the given quest reward production scheme unlocked, and add it if not
/// </summary>
/// <param name="pmcProfile">Profile to check</param>
/// <param name="productionUnlockReward">The quest reward to validate</param>
/// <param name="questDetails">The quest the reward belongs to</param>
protected void VerifyQuestProductionUnlock(PmcData pmcProfile, QuestReward productionUnlockReward, Quest questDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Initial release of SPT 3.10 used an incorrect favorites structure, reformat
/// the structure to the correct MongoID array structure
/// </summary>
/// <param name="pmcProfile"></param>
protected void FixFavorites(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// If the profile has elite Hideout Managment skill, add the additional slots from globals
/// NOTE: This seems redundant, but we will leave it here just in case.
/// </summary>
/// <param name="pmcProfile">profile to add slots to</param>
protected void AddHideoutEliteSlots(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// add in objects equal to the number of slots
/// </summary>
/// <param name="areaType">area to check</param>
/// <param name="emptyItemCount">area to update</param>
/// <param name="pmcProfile">profile to update</param>
protected void AddEmptyObjectsToHideoutAreaSlots(HideoutAreas areaType, int emptyItemCount, PmcData pmcProfile)
{
throw new NotImplementedException();
}
protected IList<HideoutSlot> AddObjectsToList(int count, List<HideoutSlot> slots)
{
throw new NotImplementedException();
}
/**
* Check for and cap profile skills at 5100.
* @param pmcProfile profile to check and fix
*/
protected void CheckForSkillsOverMaxLevel(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/**
* Checks profile inventory for items that do not exist inside the items db
* @param sessionId Session id
* @param pmcProfile Profile to check inventory of
*/
public void CheckForOrphanedModdedItems(string sessionId, SptProfile fullProfile)
{
throw new NotImplementedException();
}
/**
* @param buildType The type of build, used for logging only
* @param build The build to check for invalid items
* @param itemsDb The items database to use for item lookup
* @returns True if the build should be removed from the build list, false otherwise
*/
protected bool ShouldRemoveWeaponEquipmentBuild(
string buildType,
WeaponBuild equipmentBuild,
Dictionary<string, TemplateItem> itemsDb)
{
throw new NotImplementedException();
}
/**
* @param magazineBuild The magazine build to check for validity
* @param itemsDb The items database to use for item lookup
* @returns True if the build should be removed from the build list, false otherwise
*/
protected bool ShouldRemoveMagazineBuild(
MagazineBuild magazineBuild,
Dictionary<string, TemplateItem> itemsDb)
{
throw new NotImplementedException();
}
/**
* REQUIRED for dev profiles
* Iterate over players hideout areas and find what's built, look for missing bonuses those areas give and add them if missing
* @param pmcProfile Profile to update
*/
public void AddMissingHideoutBonusesToProfile(PmcData pmcProfile)
{
throw new NotImplementedException();
}
/**
* @param profileBonuses bonuses from profile
* @param bonus bonus to find
* @returns matching bonus
*/
protected Bonus GetBonusFromProfile(List<Bonus> profileBonuses, StageBonus bonus)
{
throw new NotImplementedException();
}
public void CheckForAndRemoveInvalidTraders(SptProfile fullProfile)
{
throw new NotImplementedException();
}
}
+21
View File
@@ -0,0 +1,21 @@
using Core.Models.Eft.Ragfair;
namespace Core.Services;
public class RagfairCategoriesService
{
/// <summary>
/// Get a dictionary of each item the play can see in their flea menu, filtered by what is available for them to buy
/// </summary>
/// <param name="offers">All offers in flea</param>
/// <param name="searchRequestData">Search criteria requested</param>
/// <param name="fleaUnlocked">Can player see full flea yet (level 15 by default)</param>
/// <returns>KVP of item tpls + count of offers</returns>
public Dictionary<string, int> GetCategoriesFromOffers(
List<RagfairOffer> offers,
SearchRequestData searchRequestData,
bool fleaUnlocked)
{
throw new NotImplementedException();
}
}
+52
View File
@@ -0,0 +1,52 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Services;
public class RagfairLinkedItemService
{
public HashSet<string> GetLinkedItems(string linkedSearchId)
{
throw new NotImplementedException();
}
/// <summary>
/// Use ragfair linked item service to get an array of items that can fit on or in designated itemtpl
/// </summary>
/// <param name="itemTpl">Item to get sub-items for</param>
/// <returns>TemplateItem array</returns>
public List<TemplateItem> GetLinkedDbItems(string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Create Dictionary of every item and the items associated with it
/// </summary>
protected void BuildLinkedItemTable()
{
throw new NotImplementedException();
}
/// <summary>
/// Add ammo to revolvers linked item dictionary
/// </summary>
/// <param name="cylinder">Revolvers cylinder</param>
/// <param name="applyLinkedItems"></param>
protected void AddRevolverCylinderAmmoToLinkedItems(
TemplateItem cylinder,
Action<List<string>> applyLinkedItems)
{
throw new NotImplementedException();
}
/// <summary>
/// Scans a given slot type for filters and returns them as a List
/// </summary>
/// <param name="item"></param>
/// <param name="slot"></param>
/// <returns>List of ids</returns>
protected List<string> GetFilters(TemplateItem item, string slot)
{
throw new NotImplementedException();
}
}
+142
View File
@@ -0,0 +1,142 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Ragfair;
namespace Core.Services;
public class RagfairOfferService
{
/// <summary>
/// Get all offers
/// </summary>
/// <returns>List of RagfairOffer</returns>
public List<RagfairOffer> GetOffers()
{
throw new NotImplementedException();
}
public RagfairOffer GetOfferByOfferId(string offerId)
{
throw new NotImplementedException();
}
public List<RagfairOffer> GetOffersOfType(string templateId)
{
throw new NotImplementedException();
}
public void AddOffer(RagfairOffer offer)
{
throw new NotImplementedException();
}
public void AddOfferToExpired(RagfairOffer staleOffer)
{
throw new NotImplementedException();
}
/// <summary>
/// Get total count of current expired offers
/// </summary>
/// <returns>Number of expired offers</returns>
public int GetExpiredOfferCount()
{
throw new NotImplementedException();
}
/// <summary>
/// Get a list of lists of expired offer items + children
/// </summary>
/// <returns>Expired offer assorts</returns>
public List<List<Item>> GetExpiredOfferAssorts()
{
throw new NotImplementedException();
}
/// <summary>
/// Clear out internal expiredOffers dictionary of all items
/// </summary>
public void ResetExpiredOffers()
{
throw new NotImplementedException();
}
/// <summary>
/// Does the offer exist on the ragfair
/// </summary>
/// <param name="offerId">offer id to check for</param>
/// <returns>offer exists - true</returns>
public bool DoesOfferExist(string offerId)
{
throw new NotImplementedException();
}
/// <summary>
/// Remove an offer from ragfair by offer id
/// </summary>
/// <param name="offerId">Offer id to remove</param>
public void RemoveOfferById(string offerId)
{
throw new NotImplementedException();
}
/// <summary>
/// Reduce size of an offer stack by specified amount
/// </summary>
/// <param name="offerId">Offer to adjust stack size of</param>
/// <param name="amount">How much to deduct from offers stack size</param>
public void RemoveOfferStack(string offerId, int amount)
{
throw new NotImplementedException();
}
public void RemoveAllOffersByTrader(string traderId)
{
throw new NotImplementedException();
}
/// <summary>
/// Do the trader offers on flea need to be refreshed
/// </summary>
/// <param name="traderID">Trader to check</param>
/// <returns>true if they do</returns>
public bool TraderOffersNeedRefreshing(string traderID)
{
throw new NotImplementedException();
}
public void AddPlayerOffers()
{
throw new NotImplementedException();
}
public void ExpireStaleOffers()
{
throw new NotImplementedException();
}
/// <summary>
/// Remove stale offer from flea
/// </summary>
/// <param name="staleOffer">Stale offer to process</param>
protected void ProcessStaleOffer(RagfairOffer staleOffer)
{
throw new NotImplementedException();
}
protected void ReturnPlayerOffer(RagfairOffer playerOffer)
{
throw new NotImplementedException();
}
/// <summary>
/// Flea offer items are stacked up often beyond the StackMaxSize limit
/// Unstack the items into a list of root items and their children
/// Will create new items equal to the
/// </summary>
/// <param name="items">Offer items to unstack</param>
/// <returns>Unstacked list of items</returns>
protected List<Item> UnstackOfferItems(List<Item> items)
{
throw new NotImplementedException();
}
}
+222
View File
@@ -0,0 +1,222 @@
using Core.Models.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
namespace Core.Services;
public class RagfairPriceService
{
/// <summary>
/// Generate static (handbook) and dynamic (prices.json) flea prices, store inside class as dictionaries
/// </summary>
public async Task OnLoadAsync()
{
throw new NotImplementedException();
}
public string GetRoute()
{
throw new NotImplementedException();
}
/// <summary>
/// Iterate over all items of type "Item" in db and get template price, store in cache
/// </summary>
public void RefreshStaticPrices()
{
throw new NotImplementedException();
}
/// <summary>
/// Copy the prices.json data into our dynamic price dictionary
/// </summary>
public void RefreshDynamicPrices()
{
throw new NotImplementedException();
}
/// <summary>
/// Get the dynamic price for an item. If value doesn't exist, use static (handbook) value.
/// if no static value, return 1
/// </summary>
/// <param name="tplId">Item tpl id to get price for</param>
/// <returns>price in roubles</returns>
public double GetFleaPriceForItem(string tplId)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the flea price for an offers items + children
/// </summary>
/// <param name="offerItems">offer item + children to process</param>
/// <returns>Rouble price</returns>
public double GetFleaPriceForOfferItems(List<Item> offerItems)
{
throw new NotImplementedException();
}
/// <summary>
/// get the dynamic (flea) price for an item
/// </summary>
/// <param name="itemTpl">item template id to look up</param>
/// <returns>price in roubles</returns>
public double GetDynamicPriceForItem(string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Grab the static (handbook) for an item by its tplId
/// </summary>
/// <param name="itemTpl">item template id to look up</param>
/// <returns>price in roubles</returns>
public double GetStaticPriceForItem(string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Get prices for all items on flea, prioritize handbook prices first, use prices from prices.json if missing
/// This will refresh the caches prior to building the output
/// </summary>
/// <returns>Dictionary of item tpls and rouble cost</returns>
public Dictionary<string, double> GetAllFleaPrices()
{
throw new NotImplementedException();
}
public Dictionary<string, double> GetAllStaticPrices()
{
throw new NotImplementedException();
}
/// <summary>
/// Get the percentage difference between two values
/// </summary>
/// <param name="a">numerical value a</param>
/// <param name="b">numerical value b</param>
/// <returns>different in percent</returns>
protected double GetPriceDifference(double a, double b)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the rouble price for an assorts barter scheme
/// </summary>
/// <param name="barterScheme"></param>
/// <returns>Rouble price</returns>
public double GetBarterPrice(List<BarterScheme> barterScheme)
{
throw new NotImplementedException();
}
/// <summary>
/// Generate a currency cost for an item and its mods
/// </summary>
/// <param name="offerItems">Item with mods to get price for</param>
/// <param name="desiredCurrency">Currency price desired in</param>
/// <param name="isPackOffer">Price is for a pack type offer</param>
/// <returns>cost of item in desired currency</returns>
public double GetDynamicOfferPriceForOffer(List<Item> offerItems, string desiredCurrency, bool isPackOffer)
{
throw new NotImplementedException();
}
/// <summary>
/// </summary>
/// <param name="itemTemplateId">items tpl value</param>
/// <param name="desiredCurrency">Currency to return result in</param>
/// <param name="item">Item object (used for weapon presets)</param>
/// <param name="offerItems"></param>
/// <param name="isPackOffer"></param>
/// <returns></returns>
public double GetDynamicItemPrice(string itemTemplateId, string desiredCurrency, Item item = null, List<Item> offerItems = null, bool? isPackOffer = null)
{
throw new NotImplementedException();
}
/// <summary>
/// using data from config, adjust an items price to be relative to its handbook price
/// </summary>
/// <param name="handbookPrices">Prices of items in handbook</param>
/// <param name="unreasonableItemChange">Change object from config</param>
/// <param name="itemTpl">Item being adjusted</param>
/// <param name="price">Current price of item</param>
/// <returns>Adjusted price of item</returns>
protected decimal AdjustUnreasonablePrice(
List<HandbookItem> handbookPrices,
UnreasonableModPrices unreasonableItemChange,
string itemTpl,
decimal price)
{
throw new NotImplementedException();
}
/// <summary>
/// Get different min/max price multipliers for different offer types (preset/pack/default)
/// </summary>
/// <param name="isPreset">Offer is a preset</param>
/// <param name="isPack">Offer is a pack</param>
/// <returns>MinMax values</returns>
protected MinMax GetOfferTypeRangeValues(bool isPreset, bool isPack)
{
throw new NotImplementedException();
}
/// <summary>
/// Check to see if an items price is below its handbook price and adjust according to values set to config/ragfair.json
/// </summary>
/// <param name="itemPrice">price of item</param>
/// <param name="itemTpl">item template Id being checked</param>
/// <returns>adjusted price value in roubles</returns>
protected decimal AdjustPriceIfBelowHandbook(decimal itemPrice, string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Multiply the price by a randomised curve where n = 2, shift = 2
/// </summary>
/// <param name="existingPrice">price to alter</param>
/// <param name="rangeValues">min and max to adjust price by</param>
/// <returns>multiplied price</returns>
protected decimal RandomiseOfferPrice(decimal existingPrice, MinMax rangeValues)
{
throw new NotImplementedException();
}
/// <summary>
/// Calculate the cost of a weapon preset by adding together the price of its mods + base price of default weapon preset
/// </summary>
/// <param name="weaponRootItem">base weapon</param>
/// <param name="weaponWithChildren">weapon plus mods</param>
/// <param name="existingPrice">price of existing base weapon</param>
/// <returns>price of weapon in roubles</returns>
protected decimal GetWeaponPresetPrice(Item weaponRootItem, List<Item> weaponWithChildren, decimal existingPrice)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the highest price for an item that is stored in handbook or trader assorts
/// </summary>
/// <param name="itemTpl">Item to get highest price of</param>
/// <returns>rouble cost</returns>
protected decimal GetHighestHandbookOrTraderPriceAsRouble(string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Attempt to get the default preset for a weapon, failing that get the first preset in the array
/// (assumes default = has encyclopedia entry)
/// </summary>
/// <param name="presets">weapon presets to choose from</param>
/// <returns>Default preset object</returns>
protected object GetWeaponPreset(Item weapon)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,16 @@
using Core.Models.Eft.Ragfair;
namespace Core.Services;
public class RagfairRequiredItemsService
{
public List<RagfairOffer> GetRequiredItemsById(string searchId)
{
throw new NotImplementedException();
}
public void BuildRequiredItemTable()
{
throw new NotImplementedException();
}
}
+51
View File
@@ -0,0 +1,51 @@
namespace Core.Services;
public class RagfairTaxService
{
public void StoreClientOfferTaxValue(string sessionId, Dictionary<string, object> offer)
{
throw new NotImplementedException();
}
public void ClearStoredOfferTaxById(string offerIdToRemove)
{
throw new NotImplementedException();
}
public Dictionary<string, object> GetStoredClientOfferTaxValueById(string offerIdToGet)
{
throw new NotImplementedException();
}
/**
// This method, along with CalculateItemWorth, is trying to mirror the client-side code found in the method "CalculateTaxPrice".
// It's structured to resemble the client-side code as closely as possible - avoid making any big structure changes if it's not necessary.
* @param item Item being sold on flea
* @param pmcData player profile
* @param requirementsValue
* @param offerItemCount Number of offers being created
* @param sellInOnePiece
* @returns Tax in roubles
*/
public double CalculateTax(
Dictionary<string, object> item,
Dictionary<string, object> pmcData,
double requirementsValue,
int offerItemCount,
bool sellInOnePiece)
{
throw new NotImplementedException();
}
// This method is trying to replicate the item worth calculation method found in the client code.
// Any inefficiencies or style issues are intentional and should not be fixed, to preserve the client-side code mirroring.
protected double CalculateItemWorth(
Dictionary<string, object> item,
Dictionary<string, object> itemTemplate,
int itemCount,
Dictionary<string, object> pmcData,
bool isRootItem = true)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,72 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Game;
using Core.Models.Spt.Config;
using Core.Models.Spt.Location;
namespace Core.Services;
public class RaidTimeAdjustmentService
{
/// <summary>
/// Make alterations to the base map data passed in
/// Loot multipliers/waves/wave start times
/// </summary>
/// <param name="raidAdjustments">Changes to process on map</param>
/// <param name="mapBase">Map to adjust</param>
public void MakeAdjustmentsToMap(RaidChanges raidAdjustments, LocationBase mapBase)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust the loot multiplier values passed in to be a % of their original value
/// </summary>
/// <param name="mapLootMultipliers">Multipliers to adjust</param>
/// <param name="loosePercent">Percent to change values to</param>
protected void AdjustLootMultipliers(LootMultiplier mapLootMultipliers, float loosePercent)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust bot waves to act as if player spawned later
/// </summary>
/// <param name="mapBase">Map to adjust</param>
/// <param name="raidAdjustments">Map adjustments</param>
protected void AdjustWaves(LocationBase mapBase, RaidChanges raidAdjustments)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a randomised adjustment to the raid based on map data in location.json
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="request">Raid adjustment request</param>
/// <returns>Response to send to client</returns>
public GetRaidTimeResponse GetRaidAdjustments(string sessionId, GetRaidTimeRequest request)
{
throw new NotImplementedException();
}
/// <summary>
/// Get raid start time settings for specific map
/// </summary>
/// <param name="location">Map Location e.g. bigmap</param>
/// <returns>ScavRaidTimeLocationSettings</returns>
protected ScavRaidTimeLocationSettings GetMapSettings(string location)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust exit times to handle scavs entering raids part-way through
/// </summary>
/// <param name="mapBase">Map base file player is on</param>
/// <param name="newRaidTimeMinutes">How long raid is in minutes</param>
/// <returns>List of exit changes to send to client</returns>
protected List<ExtractChange> GetExitAdjustments(LocationBase mapBase, int newRaidTimeMinutes)
{
throw new NotImplementedException();
}
}
+48
View File
@@ -0,0 +1,48 @@
using Core.Models.Eft.Weather;
using Core.Models.Enums;
namespace Core.Services;
public class RaidWeatherService
{
/// <summary>
/// Generate 24 hours of weather data starting from midnight today
/// </summary>
public void GenerateWeather(Season currentSeason)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a time period to increment by, e.g 15 or 30 minutes as milliseconds
/// </summary>
/// <returns>milliseconds</returns>
protected long GetWeightedWeatherTimePeriodMs()
{
throw new NotImplementedException();
}
/// <summary>
/// Find the first matching weather object that applies to the current time
/// </summary>
public Weather GetCurrentWeather()
{
throw new NotImplementedException();
}
/// <summary>
/// Find the first matching weather object that applies to the current time + all following weather data generated
/// </summary>
public List<Weather> GetUpcomingWeather()
{
throw new NotImplementedException();
}
/// <summary>
/// Ensure future weather data exists
/// </summary>
protected void ValidateWeatherDataExists(Season currentSeason)
{
throw new NotImplementedException();
}
}
+212
View File
@@ -0,0 +1,212 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.ItemEvent;
using Core.Models.Eft.Repair;
using Core.Models.Enums;
namespace Core.Services;
public class RepairService
{
/// <summary>
/// Use trader to repair an items durability
/// </summary>
/// <param name="sessionID">Session id</param>
/// <param name="pmcData">Profile to find item to repair in</param>
/// <param name="repairItemDetails">Details of the item to repair</param>
/// <param name="traderId">Trader being used to repair item</param>
/// <returns>RepairDetails object</returns>
public RepairDetails RepairItemByTrader(
string sessionID,
PmcData pmcData,
RepairItem repairItemDetails,
string traderId
)
{
throw new NotImplementedException();
}
/// <summary>
/// </summary>
/// <param name="sessionID">Session id</param>
/// <param name="pmcData">Profile to take money from</param>
/// <param name="repairedItemId">Repaired item id</param>
/// <param name="repairCost">Cost to repair item in roubles</param>
/// <param name="traderId">Id of the trader who repaired the item / who is paid</param>
/// <param name="output"></param>
public void PayForRepair(
string sessionID,
PmcData pmcData,
string repairedItemId,
decimal repairCost,
string traderId,
ItemEventRouterResponse output
)
{
throw new NotImplementedException();
}
/// <summary>
/// Add skill points to profile after repairing an item
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="repairDetails">Details of item repaired, cost/item</param>
/// <param name="pmcData">Profile to add points to</param>
public void AddRepairSkillPoints(string sessionId, RepairDetails repairDetails, PmcData pmcData)
{
throw new NotImplementedException();
}
protected decimal GetIntellectGainedFromRepair(RepairDetails repairDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Return an approximation of the amount of skill points live would return for the given repairDetails
/// </summary>
/// <param name="repairDetails">The repair details to calculate skill points for</param>
/// <returns>The number of skill points to reward the user</returns>
protected decimal GetWeaponRepairSkillPoints(RepairDetails repairDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Profile to update repaired item in</param>
/// <param name="repairKits">List of Repair kits to use</param>
/// <param name="itemToRepairId">Item id to repair</param>
/// <param name="output">ItemEventRouterResponse</param>
/// <returns>Details of repair, item/price</returns>
public RepairDetails RepairItemByKit(
string sessionId,
PmcData pmcData,
List<RepairKitsInfo> repairKits,
string itemToRepairId,
ItemEventRouterResponse output
)
{
throw new NotImplementedException();
}
/// <summary>
/// Calculate value repairkit points need to be divided by to get the durability points to be added to an item
/// </summary>
/// <param name="itemToRepairDetails">Item to repair details</param>
/// <param name="isArmor">Is the item being repaired armor</param>
/// <param name="pmcData">Player profile</param>
/// <returns>Number to divide kit points by</returns>
protected decimal GetKitDivisor(TemplateItem itemToRepairDetails, bool isArmor, PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the bonus multiplier for a skill from a player profile
/// </summary>
/// <param name="skillBonus">Bonus to get multiplier of</param>
/// <param name="pmcData">Player profile to look in for skill</param>
/// <returns>Multiplier value</returns>
protected decimal GetBonusMultiplierValue(BonusType skillBonus, PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Should a repair kit apply total durability loss on repair
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="applyRandomizeDurabilityLoss">Value from repair config</param>
/// <returns>True if loss should be applied</returns>
protected bool ShouldRepairKitApplyDurabilityLoss(PmcData pmcData, bool applyRandomizeDurabilityLoss)
{
throw new NotImplementedException();
}
/// <summary>
/// Update repair kits Resource object if it doesn't exist
/// </summary>
/// <param name="repairKitDetails">Repair kit details from db</param>
/// <param name="repairKitInInventory">Repair kit to update</param>
protected void AddMaxResourceToKitIfMissing(TemplateItem repairKitDetails, Item repairKitInInventory)
{
throw new NotImplementedException();
}
/// <summary>
/// Chance to apply buff to an item (Armor/weapon) if repaired by armor kit
/// </summary>
/// <param name="repairDetails">Repair details of item</param>
/// <param name="pmcData">Player profile</param>
public void AddBuffToItem(RepairDetails repairDetails, PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Add random buff to item
/// </summary>
/// <param name="itemConfig">weapon/armor config</param>
/// <param name="repairDetails">Details for item to repair</param>
public void AddBuff(BonusSettings itemConfig, Item item)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if item should be buffed by checking the item type and relevant player skill level
/// </summary>
/// <param name="repairDetails">Item that was repaired</param>
/// <param name="itemTpl">tpl of item to be buffed</param>
/// <param name="pmcData">Player profile</param>
/// <returns>True if item should have buff applied</returns>
protected bool ShouldBuffItem(RepairDetails repairDetails, PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Based on item, what underlying skill does this item use for buff settings
/// </summary>
/// <param name="itemTemplate">Item to check for skill</param>
/// <returns>Skill name</returns>
protected SkillTypes? GetItemSkillType(TemplateItem itemTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Ensure multiplier is between 1 and 0.01
/// </summary>
/// <param name="receiveDurabilityMaxPercent">Max durability percent</param>
/// <param name="receiveDurabilityPercent">current durability percent</param>
/// <returns>durability multiplier value</returns>
protected double GetDurabilityMultiplier(double receiveDurabilityMaxPercent, double receiveDurabilityPercent)
{
throw new NotImplementedException();
}
}
public class RepairDetails
{
[JsonPropertyName("repairCost")]
public double? RepairCost { get; set; }
[JsonPropertyName("repairPoints")]
public double? RepairPoints { get; set; }
[JsonPropertyName("repairedItem")]
public Item? RepairedItem { get; set; }
[JsonPropertyName("repairedItemIsArmor")]
public bool? RepairedItemIsArmor { get; set; }
[JsonPropertyName("repairAmount")]
public double? RepairAmount { get; set; }
[JsonPropertyName("repairedByKit")]
public bool? RepairedByKit { get; set; }
}
+402
View File
@@ -0,0 +1,402 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Enums;
using Core.Models.Spt.Config;
namespace Core.Services;
public class SeasonalEventService
{
/// <summary>
/// Get an array of christmas items found in bots inventories as loot
/// </summary>
/// <returns>array</returns>
public string[] GetChristmasEventItems()
{
throw new NotImplementedException();
}
/// <summary>
/// Get an array of halloween items found in bots inventories as loot
/// </summary>
/// <returns>array</returns>
public string[] GetHalloweenEventItems()
{
throw new NotImplementedException();
}
public bool ItemIsChristmasRelated(string itemTpl)
{
throw new NotImplementedException();
}
public bool ItemIsHalloweenRelated(string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if item id exists in christmas or halloween event arrays
/// </summary>
/// <param name="itemTpl">item tpl to check for</param>
/// <returns></returns>
public bool ItemIsSeasonalRelated(string itemTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Get active seasonal events
/// </summary>
/// <returns>Array of active events</returns>
public List<SeasonalEvent> GetActiveEvents()
{
throw new NotImplementedException();
}
/// <summary>
/// Get an array of seasonal items that should not appear
/// e.g. if halloween is active, only return christmas items
/// or, if halloween and christmas are inactive, return both sets of items
/// </summary>
/// <returns>array of tpl strings</returns>
public string[] GetInactiveSeasonalEventItems()
{
throw new NotImplementedException();
}
/// <summary>
/// Is a seasonal event currently active
/// </summary>
/// <returns>true if event is active</returns>
public bool SeasonalEventEnabled()
{
throw new NotImplementedException();
}
/// <summary>
/// Is christmas event active
/// </summary>
/// <returns>true if active</returns>
public bool ChristmasEventEnabled()
{
throw new NotImplementedException();
}
/// <summary>
/// is halloween event active
/// </summary>
/// <returns>true if active</returns>
public bool HalloweenEventEnabled()
{
throw new NotImplementedException();
}
/// <summary>
/// Is detection of seasonal events enabled (halloween / christmas)
/// </summary>
/// <returns>true if seasonal events should be checked for</returns>
public bool IsAutomaticEventDetectionEnabled()
{
throw new NotImplementedException();
}
/// <summary>
/// Get a dictionary of gear changes to apply to bots for a specific event e.g. Christmas/Halloween
/// </summary>
/// <param name="eventName">Name of event to get gear changes for</param>
/// <returns>bots with equipment changes</returns>
protected Dictionary<string, Dictionary<string, Dictionary<string, int>>> GetEventBotGear(SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a dictionary of loot changes to apply to bots for a specific event e.g. Christmas/Halloween
/// </summary>
/// <param name="eventName">Name of event to get gear changes for</param>
/// <returns>bots with loot changes</returns>
protected Dictionary<string, Dictionary<string, Dictionary<string, int>>> GetEventBotLoot(SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the dates each seasonal event starts and ends at
/// </summary>
/// <returns>Record with event name + start/end date</returns>
public List<SeasonalEvent> GetEventDetails()
{
throw new NotImplementedException();
}
/// <summary>
/// Look up quest in configs/quest.json
/// </summary>
/// <param name="questId">Quest to look up</param>
/// <param name="event">event type (Christmas/Halloween/None)</param>
/// <returns>true if related</returns>
public bool IsQuestRelatedToEvent(string questId, SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Handle activating seasonal events
/// </summary>
public void EnableSeasonalEvents()
{
throw new NotImplementedException();
}
/// <summary>
/// Force a seasonal event to be active
/// </summary>
/// <param name="eventType">Event to force active</param>
/// <returns>True if event was successfully force enabled</returns>
public bool ForceSeasonalEvent(SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Store active events inside class list property `currentlyActiveEvents` + set class properties: christmasEventActive/halloweenEventActive
/// </summary>
public void CacheActiveEvents()
{
throw new NotImplementedException();
}
/// <summary>
/// Get the currently active weather season e.g. SUMMER/AUTUMN/WINTER
/// </summary>
/// <returns>Season enum value</returns>
public Season GetActiveWeatherSeason()
{
throw new NotImplementedException();
}
/// <summary>
/// Does the provided date fit between the two defined dates?
/// Excludes year
/// Inclusive of end date upto 23 hours 59 minutes
/// </summary>
/// <param name="dateToCheck">Date to check is between 2 dates</param>
/// <param name="startMonth">Lower bound for month</param>
/// <param name="startDay">Lower bound for day</param>
/// <param name="endMonth">Upper bound for month</param>
/// <param name="endDay">Upper bound for day</param>
/// <returns>True when inside date range</returns>
protected bool DateIsBetweenTwoDates(DateTime dateToCheck, int startMonth, int startDay, int endMonth, int endDay)
{
throw new NotImplementedException();
}
/// <summary>
/// Iterate through bots inventory and loot to find and remove christmas items (as defined in SeasonalEventService)
/// </summary>
/// <param name="botInventory">Bots inventory to iterate over</param>
/// <param name="botRole">the role of the bot being processed</param>
public void RemoveChristmasItemsFromBotInventory(BotBaseInventory botInventory, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Make adjusted to server code based on the name of the event passed in
/// </summary>
/// <param name="globalConfig">globals.json</param>
/// <param name="event">Name of the event to enable. e.g. Christmas</param>
protected void UpdateGlobalEvents(Config globalConfig, SeasonalEvent eventType)
{
throw new NotImplementedException();
}
protected void ApplyHalloweenEvent(SeasonalEvent eventType, Config globalConfig)
{
throw new NotImplementedException();
}
protected void ApplyChristmasEvent(SeasonalEvent eventType, Config globalConfig)
{
throw new NotImplementedException();
}
protected void ApplyNewYearsEvent(SeasonalEvent eventType, Config globalConfig)
{
throw new NotImplementedException();
}
protected void AdjustBotAppearanceValues(SeasonalEventType season)
{
throw new NotImplementedException();
}
protected void ReplaceBotHostility(Dictionary<string, AdditionalHostilitySettings[]> hostilitySettings)
{
throw new NotImplementedException();
}
protected void RemoveEntryRequirement(List<string> locationIds)
{
throw new NotImplementedException();
}
public void GivePlayerSeasonalGifts(string sessionId)
{
throw new NotImplementedException();
}
/// <summary>
/// Force zryachiy to always have a melee weapon
/// </summary>
protected void AdjustZryachiyMeleeChance()
{
throw new NotImplementedException();
}
/// <summary>
/// Enable the halloween zryachiy summon event
/// </summary>
protected void EnableHalloweenSummonEvent()
{
throw new NotImplementedException();
}
protected void ConfigureZombies(ZombieSettings zombieSettings)
{
throw new NotImplementedException();
}
/// <summary>
/// Get location ids of maps with an infection above 0
/// </summary>
/// <param name="locationInfections">Dict of locations with their infection percentage</param>
/// <returns>List of location ids</returns>
protected List<string> GetLocationsWithZombies(Dictionary<string, double> locationInfections)
{
throw new NotImplementedException();
}
/// <summary>
/// BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs
/// </summary>
/// <param name="infectedLocationKey">Key to convert</param>
/// <returns>List of locations</returns>
protected List<string> GetLocationFromInfectedLocation(string infectedLocationKey)
{
throw new NotImplementedException();
}
protected void AddEventWavesToMaps(string eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Add event bosses to maps
/// </summary>
/// <param name="eventType">Seasonal event, e.g. HALLOWEEN/CHRISTMAS</param>
/// <param name="mapIdWhitelist">OPTIONAL - Maps to add bosses to</param>
protected void AddEventBossesToMaps(string eventType, List<string> mapIdWhitelist = null)
{
throw new NotImplementedException();
}
/// <summary>
/// Change trader icons to be more event themed (Halloween only so far)
/// </summary>
/// <param name="eventType">What event is active</param>
protected void AdjustTraderIcons(SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Add lootble items from backpack into patrol.ITEMS_TO_DROP difficulty property
/// </summary>
protected void AddLootItemsToGifterDropItemsList()
{
throw new NotImplementedException();
}
/// <summary>
/// Read in data from seasonalEvents.json and add found equipment items to bots
/// </summary>
/// <param name="eventType">Name of the event to read equipment in from config</param>
protected void AddEventGearToBots(SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Read in data from seasonalEvents.json and add found loot items to bots
/// </summary>
/// <param name="eventType">Name of the event to read loot in from config</param>
protected void AddEventLootToBots(SeasonalEventType eventType)
{
throw new NotImplementedException();
}
/// <summary>
/// Add pumpkin loot boxes to scavs
/// </summary>
protected void AddPumpkinsToScavBackpacks()
{
throw new NotImplementedException();
}
protected void RenameBitcoin()
{
throw new NotImplementedException();
}
/// <summary>
/// Set Khorovod(dancing tree) chance to 100% on all maps that support it
/// </summary>
protected void EnableDancingTree()
{
throw new NotImplementedException();
}
/// <summary>
/// Add santa to maps
/// </summary>
protected void AddGifterBotToMaps()
{
throw new NotImplementedException();
}
protected void HandleModEvent(SeasonalEvent seasonalEvent, Config globalConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// Send gift to player if they have not already received it
/// </summary>
/// <param name="playerId">Player to send gift to</param>
/// <param name="giftKey">Key of gift to give</param>
protected void GiveGift(string playerId, string giftKey)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the underlying bot type for an event bot e.g. `peacefullZryachiyEvent` will return `bossZryachiy`
/// </summary>
/// <param name="eventBotRole">Event bot role type</param>
/// <returns>Bot role as string</returns>
public string GetBaseRoleForEventBot(string eventBotRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Force the weather to be snow
/// </summary>
public void EnableSnow()
{
throw new NotImplementedException();
}
}
+21
View File
@@ -0,0 +1,21 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Services;
public class TraderAssortService
{
public TraderAssort GetPristineTraderAssort(string traderId)
{
throw new NotImplementedException();
}
/// <summary>
/// Store trader assorts inside a class property
/// </summary>
/// <param name="traderId">Traderid to store assorts against</param>
/// <param name="assort">Assorts to store</param>
public void SetPristineTraderAssort(string traderId, TraderAssort assort)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,52 @@
using Core.Models.Eft.Profile;
namespace Core.Services;
public class TraderPurchasePersisterService
{
/**
* Get the purchases made from a trader for this profile before the last trader reset
* @param sessionId Session id
* @param traderId Trader to loop up purchases for
* @returns Dictionary of assort id and count purchased
*/
public Dictionary<string, TraderPurchaseData> GetProfileTraderPurchases(
string sessionId,
string traderId)
{
throw new NotImplementedException();
}
/**
* Get a purchase made from a trader for requested profile before the last trader reset
* @param sessionId Session id
* @param traderId Trader to loop up purchases for
* @param assortId Id of assort to get data for
* @returns TraderPurchaseData
*/
public TraderPurchaseData GetProfileTraderPurchase(
string sessionId,
string traderId,
string assortId)
{
throw new NotImplementedException();
}
/**
* Remove all trader purchase records from all profiles that exist
* @param traderId Traders id
*/
public void ResetTraderPurchasesStoredInProfile(string traderId)
{
throw new NotImplementedException();
}
/**
* Iterate over all server profiles and remove specific trader purchase data that has passed the trader refresh time
* @param traderId Trader id
*/
public void RemoveStalePurchasesFromProfiles(string traderId)
{
throw new NotImplementedException();
}
}